Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F15426365
D9837.id23625.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
13 KB
Referenced Files
None
Subscribers
None
D9837.id23625.diff
View Options
diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -1554,6 +1554,7 @@
'PhabricatorEdgeGraph' => 'infrastructure/edges/util/PhabricatorEdgeGraph.php',
'PhabricatorEdgeQuery' => 'infrastructure/edges/query/PhabricatorEdgeQuery.php',
'PhabricatorEdgeTestCase' => 'infrastructure/edges/__tests__/PhabricatorEdgeTestCase.php',
+ 'PhabricatorEdgeType' => 'infrastructure/edges/type/PhabricatorEdgeType.php',
'PhabricatorEditor' => 'infrastructure/PhabricatorEditor.php',
'PhabricatorEmailLoginController' => 'applications/auth/controller/PhabricatorEmailLoginController.php',
'PhabricatorEmailVerificationController' => 'applications/auth/controller/PhabricatorEmailVerificationController.php',
@@ -1704,6 +1705,7 @@
'PhabricatorJavelinLinter' => 'infrastructure/lint/linter/PhabricatorJavelinLinter.php',
'PhabricatorJumpNavHandler' => 'applications/search/engine/PhabricatorJumpNavHandler.php',
'PhabricatorKeyValueDatabaseCache' => 'applications/cache/PhabricatorKeyValueDatabaseCache.php',
+ 'PhabricatorLegacyEdgeType' => 'infrastructure/edges/type/PhabricatorLegacyEdgeType.php',
'PhabricatorLegalpadConfigOptions' => 'applications/legalpad/config/PhabricatorLegalpadConfigOptions.php',
'PhabricatorLegalpadPHIDTypeDocument' => 'applications/legalpad/phid/PhabricatorLegalpadPHIDTypeDocument.php',
'PhabricatorLipsumArtist' => 'applications/lipsum/image/PhabricatorLipsumArtist.php',
@@ -4393,6 +4395,7 @@
'PhabricatorEdgeGraph' => 'AbstractDirectedGraph',
'PhabricatorEdgeQuery' => 'PhabricatorQuery',
'PhabricatorEdgeTestCase' => 'PhabricatorTestCase',
+ 'PhabricatorEdgeType' => 'Phobject',
'PhabricatorEditor' => 'Phobject',
'PhabricatorEmailLoginController' => 'PhabricatorAuthController',
'PhabricatorEmailVerificationController' => 'PhabricatorAuthController',
@@ -4550,6 +4553,7 @@
'PhabricatorIteratedMD5PasswordHasher' => 'PhabricatorPasswordHasher',
'PhabricatorJavelinLinter' => 'ArcanistLinter',
'PhabricatorKeyValueDatabaseCache' => 'PhutilKeyValueCache',
+ 'PhabricatorLegacyEdgeType' => 'PhabricatorEdgeType',
'PhabricatorLegalpadConfigOptions' => 'PhabricatorApplicationConfigOptions',
'PhabricatorLegalpadPHIDTypeDocument' => 'PhabricatorPHIDType',
'PhabricatorLipsumGenerateWorkflow' => 'PhabricatorLipsumManagementWorkflow',
diff --git a/src/infrastructure/edges/constants/PhabricatorEdgeConfig.php b/src/infrastructure/edges/constants/PhabricatorEdgeConfig.php
--- a/src/infrastructure/edges/constants/PhabricatorEdgeConfig.php
+++ b/src/infrastructure/edges/constants/PhabricatorEdgeConfig.php
@@ -78,6 +78,13 @@
const TYPE_OBJECT_NEEDS_SIGNATURE = 49;
const TYPE_SIGNATURE_NEEDED_BY_OBJECT = 50;
+/* !!!! STOP !!!! STOP !!!! STOP !!!! STOP !!!! STOP !!!! STOP !!!! STOP !!!! */
+
+ // HEY! DO NOT ADD NEW CONSTANTS HERE!
+ // Instead, subclass PhabricatorEdgeType.
+
+/* !!!! STOP !!!! STOP !!!! STOP !!!! STOP !!!! STOP !!!! STOP !!!! STOP !!!! */
+
const TYPE_TEST_NO_CYCLE = 9000;
const TYPE_PHOB_HAS_ASANATASK = 80001;
@@ -89,6 +96,47 @@
const TYPE_PHOB_HAS_JIRAISSUE = 80004;
const TYPE_JIRAISSUE_HAS_PHOB = 80005;
+
+ /**
+ * Build @{class:PhabricatorLegacyEdgeType} objects for edge which have not
+ * yet been modernized. This allows code to act as though we've completed
+ * the edge type migration before we actually do all the work, by building
+ * these fake type objects.
+ *
+ * @param list<const> List of edge types that objects that objects should
+ * not be built for. This is used to avoid constructing duplicate objects
+ * for edge constants which have migrated and already have a real object.
+ * @return list<PhabricatorLegacyEdgeType> Real-looking edge type objects for
+ * unmigrated edge types.
+ */
+ public static function getLegacyTypes(array $exclude) {
+ $consts = array_merge(
+ range(1, 50),
+ array(9000),
+ range(80000, 80005));
+ $consts = array_diff($consts, $exclude);
+
+ $map = array();
+ foreach ($consts as $const) {
+ $prevent_cycles = self::shouldPreventCycles($const);
+ $inverse_constant = self::getInverse($const);
+
+ $map[$const] = id(new PhabricatorLegacyEdgeType())
+ ->setEdgeConstant($const)
+ ->setShouldPreventCycles($prevent_cycles)
+ ->setInverseEdgeConstant($inverse_constant)
+ ->setStrings(
+ array(
+ self::getAddStringForEdgeType($const),
+ self::getRemoveStringForEdgeType($const),
+ self::getEditStringForEdgeType($const),
+ self::getFeedStringForEdgeType($const),
+ ));
+ }
+
+ return $map;
+ }
+
public static function getInverse($edge_type) {
static $map = array(
self::TYPE_TASK_HAS_COMMIT => self::TYPE_COMMIT_HAS_TASK,
@@ -136,7 +184,7 @@
self::TYPE_DREV_HAS_COMMIT => self::TYPE_COMMIT_HAS_DREV,
self::TYPE_COMMIT_HAS_DREV => self::TYPE_DREV_HAS_COMMIT,
- self::TYPE_OBJECT_HAS_CONTRIBUTOR => self::TYPE_SUBSCRIBED_TO_OBJECT,
+ self::TYPE_OBJECT_HAS_CONTRIBUTOR => self::TYPE_CONTRIBUTED_TO_OBJECT,
self::TYPE_CONTRIBUTED_TO_OBJECT => self::TYPE_OBJECT_HAS_CONTRIBUTOR,
self::TYPE_TASK_HAS_MOCK => self::TYPE_MOCK_HAS_TASK,
diff --git a/src/infrastructure/edges/type/PhabricatorEdgeType.php b/src/infrastructure/edges/type/PhabricatorEdgeType.php
new file mode 100644
--- /dev/null
+++ b/src/infrastructure/edges/type/PhabricatorEdgeType.php
@@ -0,0 +1,217 @@
+<?php
+
+/**
+ * Defines an edge type.
+ *
+ * Edges are typed, directed connections between two objects. They are used to
+ * represent most simple relationships, like when a user is subscribed to an
+ * object or an object is a member of a project.
+ *
+ * @task load Loading Types
+ */
+abstract class PhabricatorEdgeType extends Phobject {
+
+ abstract public function getEdgeConstant();
+
+ public function getInverseEdgeConstant() {
+ return null;
+ }
+
+ public function shouldPreventCycles() {
+ return false;
+ }
+
+ public function getTransactionAddString(
+ $actor,
+ $add_count,
+ $add_edges) {
+
+ return pht(
+ '%s added %s edge(s): %s.',
+ $actor,
+ $add_count,
+ $add_edges);
+ }
+
+ public function getTransactionRemoveString(
+ $actor,
+ $rem_count,
+ $rem_edges) {
+
+ return pht(
+ '%s removed %s edge(s): %s.',
+ $actor,
+ $rem_count,
+ $rem_edges);
+ }
+
+ public function getTransactionEditString(
+ $actor,
+ $total_count,
+ $add_count,
+ $add_edges,
+ $rem_count,
+ $rem_edges) {
+
+ return pht(
+ '%s edited %s edges, added %s: %s; removed %s: %s.',
+ $actor,
+ $total_count,
+ $add_count,
+ $add_edges,
+ $rem_count,
+ $rem_edges);
+ }
+
+ public function getFeedAddString(
+ $actor,
+ $object,
+ $add_count,
+ $add_edges) {
+
+ return pht(
+ '%s added %s edge(s) to %s: %s.',
+ $actor,
+ $add_count,
+ $object,
+ $add_edges);
+ }
+
+ public function getFeedRemoveString(
+ $actor,
+ $object,
+ $rem_count,
+ $rem_edges) {
+
+ return pht(
+ '%s removed %s edge(s) from %s: %s.',
+ $actor,
+ $rem_count,
+ $object,
+ $rem_edges);
+ }
+
+ public function getFeedEditString(
+ $actor,
+ $object,
+ $total_count,
+ $add_count,
+ $add_edges,
+ $rem_count,
+ $rem_edges) {
+
+ return pht(
+ '%s edited %s edges for %s, added %s: %s; removed %s: %s.',
+ $actor,
+ $total_count,
+ $object,
+ $add_count,
+ $add_edges,
+ $rem_count,
+ $rem_edges);
+ }
+
+
+/* -( Loading Types )------------------------------------------------------ */
+
+
+ /**
+ * @task load
+ */
+ public static function getAllTypes() {
+ static $type_map;
+
+ if ($type_map === null) {
+ $types = id(new PhutilSymbolLoader())
+ ->setAncestorClass(__CLASS__)
+ ->loadObjects();
+
+ $map = array();
+
+
+ // TODO: Remove this once everything is migrated.
+ $exclude = mpull($types, 'getEdgeConstant');
+ $map = PhabricatorEdgeConfig::getLegacyTypes($exclude);
+ unset($types['PhabricatorLegacyEdgeType']);
+
+
+ foreach ($types as $class => $type) {
+ $const = $type->getEdgeConstant();
+
+ if (!is_int($const) || ($const <= 0)) {
+ throw new Exception(
+ pht(
+ 'Edge type "%s" has an invalid edge constant. Edge constants '.
+ 'must be positive integers.',
+ $class));
+ }
+
+ if (isset($map[$const])) {
+ throw new Exception(
+ pht(
+ 'Two edge types ("%s", "%s") share the same edge constant '.
+ '(%d). Each edge type must have a unique constant.',
+ $class,
+ get_class($map[$const]),
+ $const));
+ }
+
+ $map[$const] = $type;
+ }
+
+ // Check that all the inverse edge definitions actually make sense. If
+ // edge type A says B is its inverse, B must exist and say that A is its
+ // inverse.
+
+ foreach ($map as $const => $type) {
+ $inverse = $type->getInverseEdgeConstant();
+ if ($inverse === null) {
+ continue;
+ }
+
+ if (empty($map[$inverse])) {
+ throw new Exception(
+ pht(
+ 'Edge type "%s" ("%d") defines an inverse type ("%d") which '.
+ 'does not exist.',
+ get_class($type),
+ $const,
+ $inverse));
+ }
+
+ $inverse_inverse = $map[$inverse]->getInverseEdgeConstant();
+ if ($inverse_inverse !== $const) {
+ throw new Exception(
+ pht(
+ 'Edge type "%s" ("%d") defines an inverse type ("%d"), but that '.
+ 'inverse type defines a different type ("%d") as its '.
+ 'inverse.',
+ get_class($type),
+ $const,
+ $inverse,
+ $inverse_inverse));
+ }
+ }
+
+ $type_map = $map;
+ }
+
+ return $type_map;
+ }
+
+
+ /**
+ * @task load
+ */
+ public static function getByConst($const) {
+ $type = idx(self::getAllTypes(), $const);
+
+ if (!$type) {
+ throw new Exception(
+ pht('Unknown edge constant "%s"!', $const));
+ }
+
+ return $type;
+ }
+
+}
diff --git a/src/infrastructure/edges/type/PhabricatorLegacyEdgeType.php b/src/infrastructure/edges/type/PhabricatorLegacyEdgeType.php
new file mode 100644
--- /dev/null
+++ b/src/infrastructure/edges/type/PhabricatorLegacyEdgeType.php
@@ -0,0 +1,119 @@
+<?php
+
+/**
+ * Supports legacy edges. Do not use or extend this class!
+ *
+ * TODO: Move all edge constants out of @{class:PhabricatorEdgeConfig}, then
+ * throw this away.
+ */
+final class PhabricatorLegacyEdgeType extends PhabricatorEdgeType {
+
+ private $edgeConstant;
+ private $inverseEdgeConstant;
+ private $shouldPreventCycles;
+ private $strings;
+
+ public function getEdgeConstant() {
+ return $this->edgeConstant;
+ }
+
+ public function getInverseEdgeConstant() {
+ return $this->inverseEdgeConstant;
+ }
+
+ public function getShouldPreventCycles() {
+ return $this->shouldPreventCycles;
+ }
+
+ public function setEdgeConstant($edge_constant) {
+ $this->edgeConstant = $edge_constant;
+ return $this;
+ }
+
+ public function setInverseEdgeConstant($inverse_edge_constant) {
+ $this->inverseEdgeConstant = $inverse_edge_constant;
+ return $this;
+ }
+
+ public function setShouldPreventCycles($should_prevent_cycles) {
+ $this->shouldPreventCycles = $should_prevent_cycles;
+ return $this;
+ }
+
+ public function setStrings(array $strings) {
+ $this->strings = $strings;
+ return $this;
+ }
+
+ private function getString($idx, array $argv) {
+ array_unshift($argv, idx($this->strings, $idx, ''));
+
+ // TODO: Burn this class in a fire. Just hiding this from lint for now.
+ $pht_func = 'pht';
+ return call_user_func_array($pht_func, $argv);
+ }
+
+ public function getTransactionAddString(
+ $actor,
+ $add_count,
+ $add_edges) {
+
+ $args = func_get_args();
+ return $this->getString(0, $args);
+ }
+
+ public function getTransactionRemoveString(
+ $actor,
+ $rem_count,
+ $rem_edges) {
+
+ $args = func_get_args();
+ return $this->getString(1, $args);
+ }
+
+ public function getTransactionEditString(
+ $actor,
+ $total_count,
+ $add_count,
+ $add_edges,
+ $rem_count,
+ $rem_edges) {
+
+ $args = func_get_args();
+ return $this->getString(2, $args);
+ }
+
+ public function getFeedAddString(
+ $actor,
+ $object,
+ $add_count,
+ $add_edges) {
+
+ $args = func_get_args();
+ return $this->getString(3, $args);
+ }
+
+ public function getFeedRemoveString(
+ $actor,
+ $object,
+ $rem_count,
+ $rem_edges) {
+
+ $args = func_get_args();
+ return $this->getString(3, $args);
+ }
+
+ public function getFeedEditString(
+ $actor,
+ $object,
+ $total_count,
+ $add_count,
+ $add_edges,
+ $rem_count,
+ $rem_edges) {
+
+ $args = func_get_args();
+ return $this->getString(3, $args);
+ }
+
+}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, Mar 24, 8:16 AM (4 d, 12 h ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7703646
Default Alt Text
D9837.id23625.diff (13 KB)
Attached To
Mode
D9837: Make edge types modular
Attached
Detach File
Event Timeline
Log In to Comment