mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-10 00:42:41 +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:
parent
0ade49fbe4
commit
79fa8e40cb
4 changed files with 71 additions and 1 deletions
|
@ -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',
|
||||
|
|
|
@ -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(
|
||||
|
|
50
src/applications/project/remarkup/ProjectRemarkupRule.php
Normal file
50
src/applications/project/remarkup/ProjectRemarkupRule.php
Normal 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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in a new issue