@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Recognize "#project" as a formal object name

Summary: Ref T4264. Ref T4262. Ref T2628. Ref T3190. To write Herald object rules which bind to a project, I want to take the low budget approach and have the user just type `#project` into a text field. Formally recognize `#project` as an object name, by moving all the existing stuff from the remarkup rule to the PHID type declaration.

Test Plan: Typed `#project` into jump nav and `phid.lookup` in Conduit. Typed `#project` into Remarkup.

Reviewers: btrahan

Reviewed By: btrahan

CC: aran

Maniphest Tasks: T3190, T4264, T2628, T4262

Differential Revision: https://secure.phabricator.com/D7882

+65 -33
+50 -2
src/applications/project/phid/PhabricatorProjectPHIDTypeProject.php
··· 41 41 } 42 42 } 43 43 44 + public static function getProjectMonogramPatternFragment() { 45 + // NOTE: This explicitly does not match strings which contain only 46 + // digits, because digit strings like "#123" are used to reference tasks at 47 + // Facebook and are somewhat conventional in general. 48 + return '[^\s.!,:;]*[^\s\d.!,:;]+[^\s.!,:;]*'; 49 + } 50 + 44 51 public function canLoadNamedObject($name) { 45 - // TODO: We should be able to load named projects by hashtag, e.g. "#yolo". 46 - return false; 52 + $fragment = self::getProjectMonogramPatternFragment(); 53 + return preg_match('/^#'.$fragment.'$/i', $name); 47 54 } 55 + 56 + public function loadNamedObjects( 57 + PhabricatorObjectQuery $query, 58 + array $names) { 59 + 60 + // If the user types "#YoloSwag", we still want to match "#yoloswag", so 61 + // we normalize, query, and then map back to the original inputs. 62 + 63 + $map = array(); 64 + foreach ($names as $key => $slug) { 65 + $map[$this->normalizeSlug(substr($slug, 1))][] = $slug; 66 + } 67 + 68 + $projects = id(new PhabricatorProjectQuery()) 69 + ->setViewer($query->getViewer()) 70 + ->withPhrictionSlugs(array_keys($map)) 71 + ->execute(); 72 + 73 + $result = array(); 74 + foreach ($projects as $project) { 75 + $slugs = array($project->getPhrictionSlug()); 76 + foreach ($slugs as $slug) { 77 + foreach ($map[$slug] as $original) { 78 + $result[$original] = $project; 79 + } 80 + } 81 + } 82 + 83 + return $result; 84 + } 85 + 86 + private function normalizeSlug($slug) { 87 + // NOTE: We're using phutil_utf8_strtolower() (and not PhabricatorSlug's 88 + // normalize() method) because this normalization should be only somewhat 89 + // liberal. We want "#YOLO" to match against "#yolo", but "#\\yo!!lo" 90 + // should not. normalize() strips out most punctuation and leads to 91 + // excessively aggressive matches. 92 + 93 + return phutil_utf8_strtolower($slug).'/'; 94 + } 95 + 48 96 49 97 }
+15 -31
src/applications/project/remarkup/ProjectRemarkupRule.php
··· 11 11 } 12 12 13 13 protected function getObjectIDPattern() { 14 - // NOTE: This explicitly does not match strings which contain only 15 - // digits, because digit strings like "#123" are used to reference tasks at 16 - // Facebook and are somewhat conventional in general. 17 - return '[^\s.!,:;]*[^\s\d.!,:;]+[^\s.!,:;]*'; 14 + return 15 + PhabricatorProjectPHIDTypeProject::getProjectMonogramPatternFragment(); 18 16 } 19 17 20 18 protected function loadObjects(array $ids) { 21 19 $viewer = $this->getEngine()->getConfig('viewer'); 22 20 23 - // If the user types "#YoloSwag", we still want to match "#yoloswag", so 24 - // we normalize, query, and then map back to the original inputs. 25 - 26 - $map = array(); 27 - foreach ($ids as $key => $slug) { 28 - $map[$this->normalizeSlug($slug)][] = $slug; 21 + // Put the "#" back on the front of these IDs. 22 + $names = array(); 23 + foreach ($ids as $id) { 24 + $names[] = '#'.$id; 29 25 } 30 26 31 - $projects = id(new PhabricatorProjectQuery()) 27 + // Issue a query by object name. 28 + $query = id(new PhabricatorObjectQuery()) 32 29 ->setViewer($viewer) 33 - ->withPhrictionSlugs(array_keys($map)) 34 - ->execute(); 30 + ->withNames($names); 35 31 32 + $query->execute(); 33 + $projects = $query->getNamedResults(); 34 + 35 + // Slice the "#" off again. 36 36 $result = array(); 37 - foreach ($projects as $project) { 38 - $slugs = array($project->getPhrictionSlug()); 39 - foreach ($slugs as $slug) { 40 - foreach ($map[$slug] as $original) { 41 - $result[$original] = $project; 42 - } 43 - } 37 + foreach ($projects as $name => $project) { 38 + $result[substr($name, 1)] = $project; 44 39 } 45 40 46 - 47 41 return $result; 48 - } 49 - 50 - private function normalizeSlug($slug) { 51 - // NOTE: We're using phutil_utf8_strtolower() (and not PhabricatorSlug's 52 - // normalize() method) because this normalization should be only somewhat 53 - // liberal. We want "#YOLO" to match against "#yolo", but "#\\yo!!lo" 54 - // should not. normalize() strips out most punctuation and leads to 55 - // excessively aggressive matches. 56 - 57 - return phutil_utf8_strtolower($slug).'/'; 58 42 } 59 43 60 44 }