public function testProjectSlugs() { $slugs = array('a:b' => 'a_b', 'a!b' => 'a_b', 'a - b' => 'a_-_b', '' => '', 'Demonology: HSA (Hexes, Signs, Alchemy)' => 'demonology_hsa_hexes_signs_alchemy'); foreach ($slugs as $slug => $normal) { $this->assertEqual($normal, PhabricatorSlug::normalizeProjectSlug($slug), pht('Hashtag normalization of "%s"', $slug)); } }
protected function loadProject() { $viewer = $this->getViewer(); $request = $this->getRequest(); $id = nonempty($request->getURIData('projectID'), $request->getURIData('id')); $slug = $request->getURIData('slug'); if ($slug) { $normal_slug = PhabricatorSlug::normalizeProjectSlug($slug); $is_abnormal = $slug !== $normal_slug; $normal_uri = "/tag/{$normal_slug}/"; } else { $is_abnormal = false; } $query = id(new PhabricatorProjectQuery())->setViewer($viewer)->needMembers(true)->needWatchers(true)->needImages(true)->needSlugs(true); if ($slug) { $query->withSlugs(array($slug)); } else { $query->withIDs(array($id)); } $policy_exception = null; try { $project = $query->executeOne(); } catch (PhabricatorPolicyException $ex) { $policy_exception = $ex; $project = null; } if (!$project) { // This project legitimately does not exist, so just 404 the user. if (!$policy_exception) { return new Aphront404Response(); } // Here, the project exists but the user can't see it. If they are // using a non-canonical slug to view the project, redirect to the // canonical slug. If they're already using the canonical slug, rethrow // the exception to give them the policy error. if ($is_abnormal) { return id(new AphrontRedirectResponse())->setURI($normal_uri); } else { throw $policy_exception; } } // The user can view the project, but is using a noncanonical slug. // Redirect to the canonical slug. $primary_slug = $project->getPrimarySlug(); if ($slug && $slug !== $primary_slug) { $primary_uri = "/tag/{$primary_slug}/"; return id(new AphrontRedirectResponse())->setURI($primary_uri); } $this->setProject($project); return null; }
private function getNormalizedURI($slug) { if (!strlen($slug)) { return null; } $normal = PhabricatorSlug::normalizeProjectSlug($slug); if ($normal === $slug) { return null; } $viewer = $this->getViewer(); // Do execute() instead of executeOne() here so we canonicalize before // raising a policy exception. This is a little more polished than letting // the user hit the error on any variant of the slug. $projects = id(new PhabricatorProjectQuery())->setViewer($viewer)->withSlugs(array($normal))->execute(); if (!$projects) { return null; } return "/tag/{$normal}/"; }
/** * Rename the project so that it has a unique slug, by appending (2), (3), etc. * to its name. */ function rename_project($project, $projects) { $suffix = 2; while (true) { $new_name = $project->getName() . ' (' . $suffix . ')'; $new_slug = PhabricatorSlug::normalizeProjectSlug($new_name) . '/'; $okay = true; foreach ($projects as $other) { if ($other->getID() == $project->getID()) { continue; } if ($other->getPhrictionSlug() == $new_slug) { $okay = false; break; } } if ($okay) { break; } else { $suffix++; } } return $new_name; }
protected function willExecute() { $this->slugMap = array(); $this->slugNormals = array(); $this->allSlugs = array(); if ($this->slugs) { foreach ($this->slugs as $slug) { if (PhabricatorSlug::isValidProjectSlug($slug)) { $normal = PhabricatorSlug::normalizeProjectSlug($slug); $this->slugNormals[$slug] = $normal; $this->allSlugs[$normal] = $normal; } // NOTE: At least for now, we query for the normalized slugs but also // for the slugs exactly as entered. This allows older projects with // slugs that are no longer valid to continue to work. $this->allSlugs[$slug] = $slug; } } }
private function normalizeSlugs(array $slugs) { foreach ($slugs as $key => $slug) { $slugs[$key] = PhabricatorSlug::normalizeProjectSlug($slug); } $slugs = array_unique($slugs); $slugs = array_values($slugs); return $slugs; }
foreach (new LiskMigrationIterator($table) as $doc) { $id = $doc->getID(); if ($doc->getViewPolicy() && $doc->getEditPolicy()) { echo pht('Skipping document %d; already has policy set.', $id) . "\n"; continue; } // If this was previously a magical project wiki page (under projects/, but // not projects/ itself) we need to apply the project policies. Otherwise, // apply the default policies. $slug = $doc->getSlug(); $slug = PhabricatorSlug::normalize($slug); $prefix = 'projects/'; if ($slug != $prefix && strncmp($slug, $prefix, strlen($prefix)) === 0) { $parts = explode('/', $slug); $project_slug = $parts[1]; $project_slug = PhabricatorSlug::normalizeProjectSlug($project_slug); $project_slugs = array($project_slug); $project = id(new PhabricatorProjectQuery())->setViewer(PhabricatorUser::getOmnipotentUser())->withSlugs($project_slugs)->executeOne(); if ($project) { $view_policy = nonempty($project->getViewPolicy(), $default_view_policy); $edit_policy = nonempty($project->getEditPolicy(), $default_edit_policy); $project_name = $project->getName(); echo pht("Migrating document %d to project policy %s...\n", $id, $project_name); $doc->setViewPolicy($view_policy); $doc->setEditPolicy($edit_policy); $doc->save(); continue; } } echo pht('Migrating document %d to default install policy...', $id) . "\n"; $doc->setViewPolicy($default_view_policy);
public function getSlug() { return PhabricatorSlug::normalizeProjectSlug($this->getTitle(), true); }
protected function willExecute() { $this->slugMap = array(); $this->slugNormals = array(); if ($this->slugs) { foreach ($this->slugs as $slug) { $normal = PhabricatorSlug::normalizeProjectSlug($slug); $this->slugNormals[$slug] = $normal; } } }
private function addSlug(PhabricatorLiskDAO $object, $name) { $slug = PhabricatorSlug::normalizeProjectSlug($name); $slug_object = id(new PhabricatorProjectSlug())->loadOneWhere('slug = %s', $slug); if ($slug_object) { return; } $new_slug = id(new PhabricatorProjectSlug())->setSlug($slug)->setProjectPHID($object->getPHID())->save(); }
protected function execute(ConduitAPIRequest $request) { $query = new PhabricatorProjectQuery(); $query->setViewer($request->getUser()); $query->needMembers(true); $query->needSlugs(true); $ids = $request->getValue('ids'); if ($ids) { $query->withIDs($ids); } $names = $request->getValue('names'); if ($names) { $query->withNames($names); } $status = $request->getValue('status'); if ($status) { $query->withStatus($status); } $phids = $request->getValue('phids'); if ($phids) { $query->withPHIDs($phids); } $slugs = $request->getValue('slugs'); if ($slugs) { $query->withSlugs($slugs); } $request->getValue('icons'); if ($request->getValue('icons')) { $icons = array(); // the internal 'fa-' prefix is a detail hidden from api clients // but needs to pre prepended to the values in the icons array: foreach ($request->getValue('icons') as $value) { $icons[] = 'fa-' . $value; } $query->withIcons($icons); } $colors = $request->getValue('colors'); if ($colors) { $query->withColors($colors); } $members = $request->getValue('members'); if ($members) { $query->withMemberPHIDs($members); } $limit = $request->getValue('limit'); if ($limit) { $query->setLimit($limit); } $offset = $request->getValue('offset'); if ($offset) { $query->setOffset($offset); } $pager = $this->newPager($request); $results = $query->executeWithCursorPager($pager); $projects = $this->buildProjectInfoDictionaries($results); // TODO: This is pretty hideous. $slug_map = array(); if ($slugs) { foreach ($slugs as $slug) { $normal = PhabricatorSlug::normalizeProjectSlug($slug); foreach ($projects as $project) { if (in_array($normal, $project['slugs'])) { $slug_map[$slug] = $project['phid']; } } } } $result = array('data' => $projects, 'slugMap' => $slug_map); return $this->addPagerResults($result, $pager); }
public function getICSFilename() { return PhabricatorSlug::normalizeProjectSlug($this->getName()) . '.ics'; }