Changeset View
Changeset View
Standalone View
Standalone View
src/infrastructure/markup/rule/PhabricatorObjectRemarkupRule.php
<?php | <?php | ||||
abstract class PhabricatorObjectRemarkupRule extends PhutilRemarkupRule { | abstract class PhabricatorObjectRemarkupRule extends PhutilRemarkupRule { | ||||
private $referencePattern; | |||||
private $embedPattern; | |||||
const KEY_RULE_OBJECT = 'rule.object'; | const KEY_RULE_OBJECT = 'rule.object'; | ||||
const KEY_MENTIONED_OBJECTS = 'rule.object.mentioned'; | const KEY_MENTIONED_OBJECTS = 'rule.object.mentioned'; | ||||
abstract protected function getObjectNamePrefix(); | abstract protected function getObjectNamePrefix(); | ||||
abstract protected function loadObjects(array $ids); | abstract protected function loadObjects(array $ids); | ||||
public function getPriority() { | public function getPriority() { | ||||
return 450.0; | return 450.0; | ||||
▲ Show 20 Lines • Show All 174 Lines • ▼ Show 20 Lines | $text = preg_replace_callback( | ||||
$this->getObjectReferencePattern(), | $this->getObjectReferencePattern(), | ||||
array($this, 'markupObjectReference'), | array($this, 'markupObjectReference'), | ||||
$text); | $text); | ||||
return $text; | return $text; | ||||
} | } | ||||
private function getObjectEmbedPattern() { | private function getObjectEmbedPattern() { | ||||
if ($this->embedPattern === null) { | |||||
$prefix = $this->getObjectNamePrefix(); | $prefix = $this->getObjectNamePrefix(); | ||||
$prefix = preg_quote($prefix); | $prefix = preg_quote($prefix); | ||||
Lint: Misuse of `preg_quote`: If you use pattern delimiters that require escaping (such as `//`, but not `()`) then you… | |||||
$id = $this->getObjectIDPattern(); | $id = $this->getObjectIDPattern(); | ||||
return '(\B{'.$prefix.'('.$id.')([,\s](?:[^}\\\\]|\\\\.)*)?}\B)u'; | $this->embedPattern = | ||||
'(\B{'.$prefix.'('.$id.')([,\s](?:[^}\\\\]|\\\\.)*)?}\B)u'; | |||||
} | |||||
return $this->embedPattern; | |||||
} | } | ||||
private function getObjectReferencePattern() { | private function getObjectReferencePattern() { | ||||
if ($this->referencePattern === null) { | |||||
$prefix = $this->getObjectNamePrefix(); | $prefix = $this->getObjectNamePrefix(); | ||||
$prefix = preg_quote($prefix); | $prefix = preg_quote($prefix); | ||||
Lint: Misuse of `preg_quote` If you use pattern delimiters that require escaping (such as //, but not ()) then you should pass two arguments to preg_quote, so that preg_quote knows which delimiter to escape. Lint: Misuse of `preg_quote`: If you use pattern delimiters that require escaping (such as `//`, but not `()`) then you… | |||||
$id = $this->getObjectIDPattern(); | $id = $this->getObjectIDPattern(); | ||||
// If the prefix starts with a word character (like "D"), we want to | // 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 | // 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 | // 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 | // boundary for the same reasons. Test if the prefix starts with a word | ||||
// character. | // character. | ||||
if ($this->getObjectNamePrefixBeginsWithWordCharacter()) { | if ($this->getObjectNamePrefixBeginsWithWordCharacter()) { | ||||
$boundary = '\\b'; | $boundary = '\\b'; | ||||
} else { | } else { | ||||
$boundary = '\\B'; | $boundary = '\\B'; | ||||
} | } | ||||
// The "(?<![#@-])" prevents us from linking "#abcdef" or similar, and | // The "(?<![#@-])" prevents us from linking "#abcdef" or similar, and | ||||
// "ABC-T1" (see T5714), and from matching "@T1" as a task (it is a user) | // "ABC-T1" (see T5714), and from matching "@T1" as a task (it is a user) | ||||
// (see T9479). | // (see T9479). | ||||
// The "\b" allows us to link "(abcdef)" or similar without linking things | // The "\b" allows us to link "(abcdef)" or similar without linking things | ||||
// in the middle of words. | // in the middle of words. | ||||
return '((?<![#@-])'.$boundary.$prefix.'('.$id.')(?:#([-\w\d]+))?(?!\w))u'; | $this->referencePattern = | ||||
'((?<![#@-])'.$boundary.$prefix.'('.$id.')(?:#([-\w\d]+))?(?!\w))u'; | |||||
} | |||||
return $this->referencePattern; | |||||
} | } | ||||
/** | /** | ||||
* Extract matched object references from a block of text. | * Extract matched object references from a block of text. | ||||
* | * | ||||
* This is intended to make it easy to write unit tests for object remarkup | * This is intended to make it easy to write unit tests for object remarkup | ||||
* rules. Production code is not normally expected to call this method. | * rules. Production code is not normally expected to call this method. | ||||
▲ Show 20 Lines • Show All 171 Lines • Show Last 20 Lines |
If you use pattern delimiters that require escaping (such as //, but not ()) then you should pass two arguments to preg_quote, so that preg_quote knows which delimiter to escape.