diff --git a/resources/sql/20230427.semistructured.2.objectinstance.sql b/resources/sql/20230427.semistructured.2.objectinstance.sql index 8d6bbd3..dec0fff 100644 --- a/resources/sql/20230427.semistructured.2.objectinstance.sql +++ b/resources/sql/20230427.semistructured.2.objectinstance.sql @@ -1,16 +1,17 @@ CREATE TABLE {$NAMESPACE}_semistructured.semistructured_objectinstance ( id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, phid VARBINARY(64) NOT NULL, dateCreated INT UNSIGNED NOT NULL, dateModified INT UNSIGNED NOT NULL, classID INT UNSIGNED NOT NULL, + name VARCHAR(255) NOT NULL COLLATE {$COLLATE_SORT}, status VARCHAR(32) NOT NULL COLLATE {$COLLATE_TEXT}, rawData LONGTEXT NOT NULL COLLATE {$COLLATE_TEXT}, UNIQUE KEY `key_phid` (phid), KEY `classID` (classID) ) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT}; CREATE TABLE {$NAMESPACE}_semistructured.semistructured_objectinstancetransaction LIKE {$NAMESPACE}_file.file_transaction; diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index ccd04bd..4f79c9b 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -1,91 +1,95 @@ 2, 'class' => array( 'SemiStructuredBaseController' => 'applications/semistruct/controller/SemiStructuredBaseController.php', 'SemiStructuredDAO' => 'applications/semistruct/storage/SemiStructuredDAO.php', 'SemiStructuredDataApplication' => 'applications/semistruct/application/SemiStructuredDataApplication.php', 'SemiStructuredObjectInstance' => 'applications/semistruct/storage/SemiStructuredObjectInstance.php', 'SemiStructuredObjectInstanceClassTransaction' => 'applications/semistruct/xaction/instance/SemiStructuredObjectInstanceClassTransaction.php', 'SemiStructuredObjectInstanceController' => 'applications/semistruct/controller/instance/SemiStructuredObjectInstanceController.php', + 'SemiStructuredObjectInstanceEditController' => 'applications/semistruct/controller/instance/SemiStructuredObjectInstanceEditController.php', 'SemiStructuredObjectInstanceEditEngine' => 'applications/semistruct/editor/SemiStructuredObjectInstanceEditEngine.php', + 'SemiStructuredObjectInstanceNameTransaction' => 'applications/semistruct/xaction/instance/SemiStructuredObjectInstanceNameTransaction.php', 'SemiStructuredObjectInstancePHIDType' => 'applications/semistruct/phid/SemiStructuredObjectInstancePHIDType.php', 'SemiStructuredObjectInstanceQuery' => 'applications/semistruct/query/SemiStructuredObjectInstanceQuery.php', 'SemiStructuredObjectInstanceRawDataTransaction' => 'applications/semistruct/xaction/instance/SemiStructuredObjectInstanceRawDataTransaction.php', 'SemiStructuredObjectInstanceTransaction' => 'applications/semistruct/storage/SemiStructuredObjectInstanceTransaction.php', 'SemiStructuredObjectInstanceTransactionEditor' => 'applications/semistruct/editor/SemiStructuredObjectInstanceTransactionEditor.php', 'SemiStructuredObjectInstanceTransactionType' => 'applications/semistruct/xaction/instance/SemiStructuredObjectInstanceTransactionType.php', 'SemiStructuredObjectInstanceViewController' => 'applications/semistruct/controller/instance/SemiStructuredObjectInstanceViewController.php', 'SemiStructuredObjectNewInstanceController' => 'applications/semistruct/controller/class/SemiStructuredObjectNewInstanceController.php', 'SemiStructuredObjectType' => 'applications/semistruct/storage/SemiStructuredObjectType.php', 'SemiStructuredObjectTypeController' => 'applications/semistruct/controller/class/SemiStructuredObjectTypeController.php', 'SemiStructuredObjectTypeDescriptionTransaction' => 'applications/semistruct/xaction/class/SemiStructuredObjectTypeDescriptionTransaction.php', 'SemiStructuredObjectTypeEditController' => 'applications/semistruct/controller/class/SemiStructuredObjectTypeEditController.php', 'SemiStructuredObjectTypeEditEngine' => 'applications/semistruct/editor/SemiStructuredObjectTypeEditEngine.php', 'SemiStructuredObjectTypeFerretEngine' => 'applications/semistruct/engine/SemiStructuredObjectTypeFerretEngine.php', 'SemiStructuredObjectTypeListController' => 'applications/semistruct/controller/class/SemiStructuredObjectTypeListController.php', 'SemiStructuredObjectTypeNameTransaction' => 'applications/semistruct/xaction/class/SemiStructuredObjectTypeNameTransaction.php', 'SemiStructuredObjectTypePHIDType' => 'applications/semistruct/phid/SemiStructuredObjectTypePHIDType.php', 'SemiStructuredObjectTypeQuery' => 'applications/semistruct/query/SemiStructuredObjectTypeQuery.php', 'SemiStructuredObjectTypeSearchEngine' => 'applications/semistruct/query/SemiStructuredObjectTypeSearchEngine.php', 'SemiStructuredObjectTypeTransaction' => 'applications/semistruct/storage/SemiStructuredObjectTypeTransaction.php', 'SemiStructuredObjectTypeTransactionEditor' => 'applications/semistruct/editor/SemiStructuredObjectTypeTransactionEditor.php', 'SemiStructuredObjectTypeTransactionType' => 'applications/semistruct/xaction/class/SemiStructuredObjectTypeTransactionType.php', 'SemiStructuredObjectTypeViewController' => 'applications/semistruct/controller/class/SemiStructuredObjectTypeViewController.php', 'SemiStructuredPatchList' => 'applications/semistruct/storage/SemiStructuredPatchList.php', ), 'function' => array(), 'xmap' => array( 'SemiStructuredBaseController' => 'PhabricatorController', 'SemiStructuredDAO' => 'PhabricatorLiskDAO', 'SemiStructuredDataApplication' => 'PhabricatorApplication', 'SemiStructuredObjectInstance' => array( 'SemiStructuredDAO', 'PhabricatorPolicyInterface', 'PhabricatorApplicationTransactionInterface', 'PhabricatorFlaggableInterface', 'PhabricatorDestructibleInterface', ), 'SemiStructuredObjectInstanceClassTransaction' => 'SemiStructuredObjectInstanceTransactionType', 'SemiStructuredObjectInstanceController' => 'SemiStructuredBaseController', + 'SemiStructuredObjectInstanceEditController' => 'SemiStructuredBaseController', 'SemiStructuredObjectInstanceEditEngine' => 'PhabricatorEditEngine', + 'SemiStructuredObjectInstanceNameTransaction' => 'SemiStructuredObjectInstanceTransactionType', 'SemiStructuredObjectInstancePHIDType' => 'PhabricatorPHIDType', 'SemiStructuredObjectInstanceQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 'SemiStructuredObjectInstanceRawDataTransaction' => 'SemiStructuredObjectInstanceTransactionType', 'SemiStructuredObjectInstanceTransaction' => 'PhabricatorModularTransaction', 'SemiStructuredObjectInstanceTransactionEditor' => 'PhabricatorApplicationTransactionEditor', 'SemiStructuredObjectInstanceTransactionType' => 'PhabricatorModularTransactionType', 'SemiStructuredObjectInstanceViewController' => 'SemiStructuredObjectInstanceController', 'SemiStructuredObjectNewInstanceController' => 'SemiStructuredObjectTypeController', 'SemiStructuredObjectType' => array( 'SemiStructuredDAO', 'PhabricatorPolicyInterface', 'PhabricatorApplicationTransactionInterface', 'PhabricatorFlaggableInterface', 'PhabricatorDestructibleInterface', 'PhabricatorFerretInterface', ), 'SemiStructuredObjectTypeController' => 'SemiStructuredBaseController', 'SemiStructuredObjectTypeDescriptionTransaction' => 'SemiStructuredObjectTypeTransactionType', - 'SemiStructuredObjectTypeEditController' => 'PhabricatorDashboardController', + 'SemiStructuredObjectTypeEditController' => 'SemiStructuredBaseController', 'SemiStructuredObjectTypeEditEngine' => 'PhabricatorEditEngine', 'SemiStructuredObjectTypeFerretEngine' => 'PhabricatorFerretEngine', 'SemiStructuredObjectTypeListController' => 'SemiStructuredBaseController', 'SemiStructuredObjectTypeNameTransaction' => 'SemiStructuredObjectTypeTransactionType', 'SemiStructuredObjectTypePHIDType' => 'PhabricatorPHIDType', 'SemiStructuredObjectTypeQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 'SemiStructuredObjectTypeSearchEngine' => 'PhabricatorApplicationSearchEngine', 'SemiStructuredObjectTypeTransaction' => 'PhabricatorModularTransaction', 'SemiStructuredObjectTypeTransactionEditor' => 'PhabricatorApplicationTransactionEditor', 'SemiStructuredObjectTypeTransactionType' => 'PhabricatorModularTransactionType', 'SemiStructuredObjectTypeViewController' => 'SemiStructuredObjectTypeController', 'SemiStructuredPatchList' => 'PhabricatorSQLPatchList', ), )); diff --git a/src/application/SemiStructuredDataApplication.php b/src/application/SemiStructuredDataApplication.php index 6ec3103..a22528f 100644 --- a/src/application/SemiStructuredDataApplication.php +++ b/src/application/SemiStructuredDataApplication.php @@ -1,38 +1,38 @@ array( '(?:query/(?P[^/]+)/)?' => 'SemiStructuredObjectTypeListController', $this->getEditRoutePattern('editclass/') => 'SemiStructuredObjectTypeEditController', 'type/(?:(?P\d+)/)?' => array( '' => 'SemiStructuredObjectTypeViewController', 'new/' => 'SemiStructuredObjectNewInstanceController', ), - $this->getEditRoutePattern('editobject/') => + $this->getEditRoutePattern('editinstance/') => 'SemiStructuredObjectInstanceEditController', 'instance/(?:(?P\d+)/)?' => 'SemiStructuredObjectInstanceViewController', ), ); } } diff --git a/src/controller/class/SemiStructuredObjectTypeEditController.php b/src/controller/class/SemiStructuredObjectTypeEditController.php index 7cb0880..c2a1bdc 100644 --- a/src/controller/class/SemiStructuredObjectTypeEditController.php +++ b/src/controller/class/SemiStructuredObjectTypeEditController.php @@ -1,12 +1,12 @@ setController($this) ->buildResponse(); } } diff --git a/src/controller/instance/SemiStructuredObjectInstanceController.php b/src/controller/instance/SemiStructuredObjectInstanceController.php index 781049c..f046d57 100644 --- a/src/controller/instance/SemiStructuredObjectInstanceController.php +++ b/src/controller/instance/SemiStructuredObjectInstanceController.php @@ -1,89 +1,88 @@ objectType = $object_type; + public function setObject(SemiStructuredObjectInstance $object) { + $this->object = $object; return $this; } - public function getObjectType() { - return $this->objectType; + public function getObject() { + return $this->object; } // TODO ??? public function buildApplicationMenu() { return $this->buildSideNavView()->getMenu(); } protected function buildHeaderView() { $viewer = $this->getViewer(); - $object_type = $this->getObjectType(); + $object = $this->getObject(); + $object_type = $object->getClass(); if ($object_type->isArchived()) { $status_icon = 'fa-ban'; $status_color = 'dark'; } else { $status_icon = 'fa-check'; $status_color = 'bluegrey'; } $status_name = idx( SemiStructuredObjectType::getStatusNameMap(), $object_type->getStatus()); return id(new PHUIHeaderView()) - ->setHeader($object_type->getName()) + ->setHeader(pht("%s: %d %s", $object_type->getName(), $object->getID(), $object->getName())) ->setUser($viewer) ->setPolicyObject($object_type) ->setStatus($status_icon, $status_color, $status_name) ->setHeaderIcon('fa-trophy'); } protected function buildApplicationCrumbs() { - $object_type = $this->getObjectType(); - $uri = $object_type->getURI(); + $object = $this->getObject(); + $object_type = $object->getClass(); $crumbs = parent::buildApplicationCrumbs(); - $crumbs->addTextCrumb($object_type->getName(), $uri); + $crumbs->addTextCrumb($object_type->getName(), $object_type->getURI()); + $crumbs->addTextCrumb(pht("%d %s", $object->getID(), $object->getName(),), $object->getURI()); $crumbs->setBorder(true); return $crumbs; } protected function buildSideNavView($filter = null) { $viewer = $this->getViewer(); - $object_type = $this->getObjectType(); - $id = $object_type->getID(); - - $can_edit = PhabricatorPolicyFilter::hasCapability( - $viewer, - $object_type, - PhabricatorPolicyCapability::CAN_EDIT); + $object = $this->getObject(); + $object_type = $object->getClass(); + $id = $object->getID(); $nav = id(new AphrontSideNavFilterView()) ->setBaseURI(new PhutilURI($this->getApplicationURI())); - $nav->addLabel(pht('Object Type')); - + $nav->addLabel(pht('Instance of %s', $object_type->getName())); + // TODO figure out menu $nav->addFilter( 'view', pht('View Object Type'), $object_type->getURI(), 'fa-trophy'); $nav->addFilter( 'instances', pht('View Instances'), $this->getApplicationURI("/recipients/{$id}/"), 'fa-group'); $nav->selectFilter($filter); return $nav; } } diff --git a/src/controller/instance/SemiStructuredObjectInstanceEditController.php b/src/controller/instance/SemiStructuredObjectInstanceEditController.php new file mode 100644 index 0000000..a1a3502 --- /dev/null +++ b/src/controller/instance/SemiStructuredObjectInstanceEditController.php @@ -0,0 +1,12 @@ +setController($this) + ->buildResponse(); + } + +} diff --git a/src/controller/instance/SemiStructuredObjectInstanceViewController.php b/src/controller/instance/SemiStructuredObjectInstanceViewController.php index 5b30eae..1663420 100644 --- a/src/controller/instance/SemiStructuredObjectInstanceViewController.php +++ b/src/controller/instance/SemiStructuredObjectInstanceViewController.php @@ -1,114 +1,96 @@ getViewer(); $id = $request->getURIData('id'); - $object_type = id(new SemiStructuredObjectInstanceQuery()) + $object = id(new SemiStructuredObjectInstanceQuery()) ->setViewer($viewer) ->withIDs(array($id)) ->executeOne(); - if (!$object_type) { + if (!$object) { return new Aphront404Response(); } - $this->setObjectType($object_type); + $this->setObject($object); $crumbs = $this->buildApplicationCrumbs(); - $title = $object_type->getName(); + $title = "AN OBJ";// $object_type->getName(); $header = $this->buildHeaderView(); $curtain = $this->buildCurtain(); $details = $this->buildDetailsView(); // $timeline = $this->buildTransactionTimeline( // $object_type, // new PhabricatorBadgesTransactionQuery()); /// TODO $timeline = null; - $comment_view = id(new SemiStructuredObjectTypeEditEngine()) + $comment_view = id(new SemiStructuredObjectInstanceEditEngine()) ->setViewer($viewer) - ->buildEditEngineCommentView($object_type); + ->buildEditEngineCommentView($object); $view = id(new PHUITwoColumnView()) ->setHeader($header) ->setCurtain($curtain) ->setMainColumn(array( $timeline, $comment_view, )) ->addPropertySection(pht('Description'), $details); $navigation = $this->buildSideNavView('view'); return $this->newPage() ->setTitle($title) ->setCrumbs($crumbs) - ->setPageObjectPHIDs(array($object_type->getPHID())) + ->setPageObjectPHIDs(array($object->getPHID())) ->setNavigation($navigation) ->appendChild($view); } private function buildDetailsView() { $viewer = $this->getViewer(); - $object_type = $this->getObjectType(); + $object = $this->getObject(); $view = id(new PHUIPropertyListView()) ->setUser($viewer); - $description = $object_type->getDescription(); +/* $description = $object_type->getDescription(); if (strlen($description)) { $view->addTextContent( new PHUIRemarkupView($viewer, $description)); } - +*/ return $view; } private function buildCurtain() { $viewer = $this->getViewer(); - $object_type = $this->getObjectType(); + $object = $this->getObject(); $can_edit = PhabricatorPolicyFilter::hasCapability( $viewer, - $object_type, + $object, PhabricatorPolicyCapability::CAN_EDIT); - $id = $object_type->getID(); - $edit_uri = $this->getApplicationURI("/editclass/{$id}/"); - $archive_uri = $this->getApplicationURI("/archive/{$id}/"); + $id = $object->getID(); + $edit_uri = $this->getApplicationURI("/editinstance/{$id}/"); - $curtain = $this->newCurtainView($object_type); + $curtain = $this->newCurtainView($object); $curtain->addAction( id(new PhabricatorActionView()) - ->setName(pht('Edit Object Type')) + ->setName(pht('Edit Instance')) ->setIcon('fa-pencil') ->setDisabled(!$can_edit) ->setHref($edit_uri)); - if ($object_type->isArchived()) { - $curtain->addAction( - id(new PhabricatorActionView()) - ->setName(pht('Activate Object Type')) - ->setIcon('fa-check') - ->setDisabled(!$can_edit) - ->setWorkflow($can_edit) - ->setHref($archive_uri)); - } else { - $curtain->addAction( - id(new PhabricatorActionView()) - ->setName(pht('Archive Object Type')) - ->setIcon('fa-ban') - ->setDisabled(!$can_edit) - ->setWorkflow($can_edit) - ->setHref($archive_uri)); - } return $curtain; } } diff --git a/src/editor/SemiStructuredObjectInstanceEditEngine.php b/src/editor/SemiStructuredObjectInstanceEditEngine.php index 44bbf78..7997473 100644 --- a/src/editor/SemiStructuredObjectInstanceEditEngine.php +++ b/src/editor/SemiStructuredObjectInstanceEditEngine.php @@ -1,111 +1,120 @@ objectType = $object_type; return $this; } protected function newEditableObject() { $viewer = $this->getViewer(); return SemiStructuredObjectInstance::initializeNewObjectInstance( $viewer, $this->objectType); } protected function newObjectQuery() { return new SemiStructuredObjectInstanceQuery(); } protected function getObjectCreateTitleText($object) { return pht('Create Object Instance'); } protected function getObjectCreateButtonText($object) { return pht('Create Object Instance'); } protected function getObjectCreateCancelURI($object) { // TODO if objjec has link to class - go to that class return '/semistructured/'; } protected function getEditorURI() { return $this->getApplication()->getApplicationURI('editobject/'); } protected function getObjectEditTitleText($object) { return pht('Edit Object: %d', $object->getID()); } protected function getObjectEditShortText($object) { return pht('Edit Object'); } protected function getObjectCreateShortText() { return pht('Create Object Instance'); } protected function getObjectName() { return pht('Object Instance'); } protected function getObjectViewURI($object) { return $object->getURI(); } protected function buildCustomEditFields($object) { $fields = array( // TODO is this the best edit field? id(new PhabricatorIntEditField()) ->setKey('classID') ->setLabel(pht('Object Type')) ->setDescription(pht('Type of the object.')) ->setConduitDescription(pht('Set type of object.')) ->setIsHidden(true) ->setTransactionType( SemiStructuredObjectInstanceClassTransaction::TRANSACTIONTYPE) ->setIsRequired(true) ->setValue($object->getClassID()), + id(new PhabricatorTextEditField()) + ->setKey('name') + ->setLabel(pht('Name')) + ->setDescription(pht('Name of the object.')) + ->setConduitDescription(pht('Rename the object.')) + ->setConduitTypeDescription(pht('New object name.')) + ->setTransactionType( + SemiStructuredObjectInstanceNameTransaction::TRANSACTIONTYPE) + ->setValue($object->getName()), id(new PhabricatorTextAreaEditField()) ->setKey('rawdata') ->setLabel(pht('Raw data')) ->setDescription(pht('Object unstructured data (JSON).')) ->setConduitTypeDescription(pht('Object body (JSON).')) ->setMonospaced(true) ->setTransactionType( SemiStructuredObjectInstanceRawDataTransaction::TRANSACTIONTYPE) ->setValue($object->getRawData()), ); return $fields; } } diff --git a/src/phid/SemiStructuredObjectInstancePHIDType.php b/src/phid/SemiStructuredObjectInstancePHIDType.php index 2ed055c..02fa5b8 100644 --- a/src/phid/SemiStructuredObjectInstancePHIDType.php +++ b/src/phid/SemiStructuredObjectInstancePHIDType.php @@ -1,42 +1,44 @@ withPHIDs($phids); } public function loadHandles( PhabricatorHandleQuery $query, array $handles, array $objects) { foreach ($handles as $phid => $handle) { $item = $objects[$phid]; $id = $item->getID(); - $handle->setName($item->getName()); - // TODO $handle->setURI("/semistruct/object/view/{$id}/"); + $class = $item->getClass(); + + $handle->setName(pht("%s %d", $class->getName(), $id)); + $handle->setURI("/semistruct/instance/{$id}/"); } } } diff --git a/src/query/SemiStructuredObjectInstanceQuery.php b/src/query/SemiStructuredObjectInstanceQuery.php index 2778c4c..be4edde 100644 --- a/src/query/SemiStructuredObjectInstanceQuery.php +++ b/src/query/SemiStructuredObjectInstanceQuery.php @@ -1,100 +1,119 @@ ids = $ids; return $this; } public function withPHIDs(array $phids) { $this->phids = $phids; return $this; } public function withClassPHIDs(array $class_phids) { $this->classPHIDs = $class_phids; return $this; } public function withStatuses(array $statuses) { $this->statuses = $statuses; return $this; } public function withCanEdit($can_edit) { $this->canEdit = $can_edit; return $this; } public function newResultObject() { return new SemiStructuredObjectInstance(); } protected function didFilterPage(array $items) { $phids = mpull($items, 'getPHID'); if ($this->canEdit) { $items = id(new PhabricatorPolicyFilter()) ->setViewer($this->getViewer()) ->requireCapabilities(array( PhabricatorPolicyCapability::CAN_EDIT, )) ->apply($items); } return $items; } protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) { $where = parent::buildWhereClauseParts($conn); if ($this->ids !== null) { $where[] = qsprintf( $conn, 'instances.id IN (%Ld)', $this->ids); } if ($this->phids !== null) { $where[] = qsprintf( $conn, 'instances.phid IN (%Ls)', $this->phids); } if ($this->classPHIDs !== null) { $where[] = qsprintf( $conn, 'instances.classPHID IN (%Ls)', $this->phids); } if ($this->statuses !== null) { $where[] = qsprintf( $conn, 'instances.status IN (%Ls)', $this->statuses); } return $where; } + protected function willFilterPage(array $objects) { + $classes = id(new SemiStructuredObjectTypeQuery()) + ->setViewer($this->getViewer()) + ->withIDs(mpull($objects, 'getClassID')) + ->execute(); + + foreach ($objects as $key => $object) { + $class = idx($classes, $object->getClassID()); + if (!$class) { + unset($objects[$key]); + continue; + } + $object->attachClass($class); + } + + return $objects; + } + + public function getQueryApplicationClass() { return 'SemiStructuredDataApplication'; } protected function getPrimaryTableAlias() { return 'instances'; } } diff --git a/src/storage/SemiStructuredObjectInstance.php b/src/storage/SemiStructuredObjectInstance.php index f5e06fc..762dedb 100644 --- a/src/storage/SemiStructuredObjectInstance.php +++ b/src/storage/SemiStructuredObjectInstance.php @@ -1,136 +1,137 @@ setViewPolicy(PhabricatorPolicies::getMostOpenPolicy()) // TODO take policies from class? // ->setEditPolicy($actor->getPHID()) ->setStatus(self::STATUS_ACTIVE); if ($object_class !== null) { $object ->setClassID($object_class->getID()) ->attachClass($object_class); } return $object; } public function attachClass( SemiStructuredObjectType $object_class = null) { $this->class = $object_class; return $this; } public function getClass() { return $this->assertAttached($this->class); } public function getURI() { return urisprintf('/semistruct/instance/%d/', $this->getID()); } public static function getStatusNameMap() { return array( self::STATUS_ACTIVE => pht('Active'), self::STATUS_ARCHIVED => pht('Archived'), ); } protected function getConfiguration() { return array( self::CONFIG_AUX_PHID => true, self::CONFIG_COLUMN_SCHEMA => array( 'name' => 'sort255', 'status' => 'text32', 'rawData' => 'text', ), self::CONFIG_KEY_SCHEMA => array( 'classID' => array( 'columns' => array('classID'), ), ), ) + parent::getConfiguration(); } public function getPHIDType() { return SemiStructuredObjectInstancePHIDType::TYPECONST; } /* -( PhabricatorApplicationTransactionInterface )------------------------- */ public function getApplicationTransactionEditor() { return new SemiStructuredObjectInstanceTransactionEditor(); } public function getApplicationTransactionTemplate() { return new SemiStructuredObjectInstanceTransaction(); } /* -( PhabricatorPolicyInterface )----------------------------------------- */ public function getCapabilities() { return array( PhabricatorPolicyCapability::CAN_VIEW, PhabricatorPolicyCapability::CAN_EDIT, ); } public function getPolicy($capability) { return; switch ($capability) { // TODO case PhabricatorPolicyCapability::CAN_VIEW: return $this->getViewPolicy(); case PhabricatorPolicyCapability::CAN_EDIT: return $this->getEditPolicy(); } } public function hasAutomaticCapability($capability, PhabricatorUser $viewer) { return true; } /* -( PhabricatorDestructibleInterface )----------------------------------- */ public function destroyObjectPermanently( PhabricatorDestructionEngine $engine) { $this->openTransaction(); $this->delete(); $this->saveTransaction(); } } diff --git a/src/xaction/instance/SemiStructuredObjectInstanceNameTransaction.php b/src/xaction/instance/SemiStructuredObjectInstanceNameTransaction.php new file mode 100644 index 0000000..c5d5562 --- /dev/null +++ b/src/xaction/instance/SemiStructuredObjectInstanceNameTransaction.php @@ -0,0 +1,50 @@ +getName(); + } + + public function applyInternalEffects($object, $value) { + $object->setName($value); + } + + public function getTitle() { + return pht( + '%s renamed this object from %s to %s.', + $this->renderAuthor(), + $this->renderOldValue(), + $this->renderNewValue()); + } + + public function getTitleForFeed() { + return pht( + '%s renamed %s object %s to %s.', + $this->renderAuthor(), + $this->renderObject(), + $this->renderOldValue(), + $this->renderNewValue()); + } + + public function validateTransactions($object, array $xactions) { + $errors = array(); + + $max_length = $object->getColumnMaximumByteLength('name'); + foreach ($xactions as $xaction) { + $new_value = $xaction->getNewValue(); + $new_length = strlen($new_value); + if ($new_length > $max_length) { + $errors[] = $this->newInvalidError( + pht('The name can be no longer than %s characters.', + new PhutilNumber($max_length))); + } + } + + return $errors; + } + +}