1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-26 00:32:42 +01:00

Implement #yoloswag

Summary:
Ref T3190. #shipit

Likely future work:

  - Extract project mentions from remarkup for ApplicationTransactions; this isn't relevant in any apps right now (but will be in Pholio before tooo long). Ref T3189.
  - Allow projects to have alternate short names. As written, this is fine for most projects ("Differential" is `#differential`) but not so great for other projects ("Phabricator Public & Media Relations" is `#phabricator_public_media_relations`). This also breaks refs when you rename a project. Better would be letting long project names have short aliases (`#pr`) as permitted alternatives.

Since this mention uses `#` instead of a letter, I needed to do a small amount of regexp gymnastics.

Test Plan:
you only #yolo once

{F43615}

Reviewers: btrahan, chad

Reviewed By: btrahan

CC: aran

Maniphest Tasks: T3189, T3190

Differential Revision: https://secure.phabricator.com/D5954
This commit is contained in:
epriestley 2013-05-18 02:46:39 -07:00
parent 0ade49fbe4
commit 79fa8e40cb
4 changed files with 71 additions and 1 deletions

View file

@ -1714,6 +1714,7 @@ phutil_register_library_map(array(
'PonderVotableView' => 'applications/ponder/view/PonderVotableView.php',
'PonderVoteEditor' => 'applications/ponder/editor/PonderVoteEditor.php',
'PonderVoteSaveController' => 'applications/ponder/controller/PonderVoteSaveController.php',
'ProjectRemarkupRule' => 'applications/project/remarkup/ProjectRemarkupRule.php',
'QueryFormattingTestCase' => 'infrastructure/storage/__tests__/QueryFormattingTestCase.php',
'ReleephActiveProjectListView' => 'applications/releeph/view/project/list/ReleephActiveProjectListView.php',
'ReleephAuthorFieldSpecification' => 'applications/releeph/field/specification/ReleephAuthorFieldSpecification.php',
@ -3504,6 +3505,7 @@ phutil_register_library_map(array(
'PonderVotableView' => 'AphrontView',
'PonderVoteEditor' => 'PhabricatorEditor',
'PonderVoteSaveController' => 'PonderController',
'ProjectRemarkupRule' => 'PhabricatorRemarkupRuleObject',
'QueryFormattingTestCase' => 'PhabricatorTestCase',
'ReleephActiveProjectListView' => 'AphrontView',
'ReleephAuthorFieldSpecification' => 'ReleephFieldSpecification',

View file

@ -26,6 +26,12 @@ final class PhabricatorApplicationProject extends PhabricatorApplication {
return self::GROUP_ORGANIZATION;
}
public function getRemarkupRules() {
return array(
new ProjectRemarkupRule(),
);
}
public function getRoutes() {
return array(
'/project/' => array(

View file

@ -0,0 +1,50 @@
<?php
/**
* @group project
*/
final class ProjectRemarkupRule
extends PhabricatorRemarkupRuleObject {
protected function getObjectNamePrefix() {
return '#';
}
protected function getObjectIDPattern() {
// NOTE: This explicitly does not match strings which contain only
// digits, because digit strings like "#123" are used to reference tasks at
// Facebook and are somewhat conventional in general.
return '[^\s.!,:;]*[^\s\d.!,:;]+[^\s.!,:;]*';
}
protected function loadObjects(array $ids) {
$viewer = $this->getEngine()->getConfig('viewer');
// If the user types "#YoloSwag", we still want to match "#yoloswag", so
// we normalize, query, and then map back to the original inputs.
$map = array();
foreach ($ids as $key => $slug) {
$map[PhabricatorSlug::normalize($slug)][] = $slug;
}
$projects = id(new PhabricatorProjectQuery())
->setViewer($viewer)
->withPhrictionSlugs(array_keys($map))
->execute();
$result = array();
foreach ($projects as $project) {
$slugs = array($project->getPhrictionSlug());
foreach ($slugs as $slug) {
foreach ($map[$slug] as $original) {
$result[$original] = $project;
}
}
}
return $result;
}
}

View file

@ -99,11 +99,23 @@ abstract class PhabricatorRemarkupRuleObject
array($this, 'markupObjectEmbed'),
$text);
// If the prefix starts with a word character (like "D"), we want to
// require a word boundary so that we don't match "XD1" as "D1". If the
// prefix does not start with a word character, we want to require no word
// boundary for the same reasons. Test if the prefix starts with a word
// character.
if (preg_match('/^\w/', $prefix)) {
$boundary = '\\b';
} else {
$boundary = '\\B';
}
// NOTE: The "(?<!#)" prevents us from linking "#abcdef" or similar. The
// "\b" allows us to link "(abcdef)" or similar without linking things
// in the middle of words.
$text = preg_replace_callback(
'@(?<!#)\b'.$prefix.'('.$id.')(?:#([-\w\d]+))?\b@',
'((?<!#)'.$boundary.$prefix.'('.$id.')(?:#([-\w\d]+))?\b)',
array($this, 'markupObjectReference'),
$text);