diff --git a/resources/sql/20230427.semistructured.0.edge.sql b/resources/sql/20230427.semistructured.0.edge.sql new file mode 100644 index 0000000..f6c647b --- /dev/null +++ b/resources/sql/20230427.semistructured.0.edge.sql @@ -0,0 +1,3 @@ +CREATE TABLE {$NAMESPACE}_semistructured.edge LIKE {$NAMESPACE}_file.edge; +CREATE TABLE {$NAMESPACE}_semistructured.edgedata + LIKE {$NAMESPACE}_file.edgedata; diff --git a/resources/sql/20230427.semistructured.1.objecttype.sql b/resources/sql/20230427.semistructured.1.objecttype.sql index 6e9fbc0..d1f757c 100644 --- a/resources/sql/20230427.semistructured.1.objecttype.sql +++ b/resources/sql/20230427.semistructured.1.objecttype.sql @@ -1,24 +1,26 @@ CREATE TABLE {$NAMESPACE}_semistructured.semistructured_objecttype ( id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, phid VARBINARY(64) NOT NULL, + viewPolicy varbinary(64) NOT NULL, + editPolicy varbinary(64) NOT NULL, dateCreated INT UNSIGNED NOT NULL, dateModified INT UNSIGNED NOT NULL, name VARCHAR(255) NOT NULL COLLATE {$COLLATE_SORT}, description LONGTEXT NOT NULL COLLATE {$COLLATE_TEXT}, status VARCHAR(32) NOT NULL COLLATE {$COLLATE_TEXT}, UNIQUE KEY `key_phid` (phid) ) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT}; --- CREATE TABLE {$NAMESPACE}_semistructured.semistructured_objecttypetransaction --- LIKE {$NAMESPACE}_file.file_transaction; +CREATE TABLE {$NAMESPACE}_semistructured.semistructured_objecttypetransaction + LIKE {$NAMESPACE}_file.file_transaction; CREATE TABLE {$NAMESPACE}_semistructured.semistructured_objecttype_ffield LIKE {$NAMESPACE}_dashboard.dashboard_dashboard_ffield; CREATE TABLE {$NAMESPACE}_semistructured.semistructured_objecttype_fdocument LIKE {$NAMESPACE}_dashboard.dashboard_dashboard_fdocument; CREATE TABLE {$NAMESPACE}_semistructured.semistructured_objecttype_fngrams LIKE {$NAMESPACE}_dashboard.dashboard_dashboard_fngrams; CREATE TABLE {$NAMESPACE}_semistructured.semistructured_objecttype_fngrams_common LIKE {$NAMESPACE}_dashboard.dashboard_dashboard_fngrams_common; diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index 872b200..6b71c24 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -1,55 +1,69 @@ <?php /** * This file is automatically generated. Use 'arc liberate' to rebuild it. * * @generated * @phutil-library-version 2 */ phutil_register_library_map(array( '__library_version__' => 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', 'SemiStructuredObjectInstancePHIDType' => 'applications/semistruct/phid/SemiStructuredObjectInstancePHIDType.php', 'SemiStructuredObjectInstanceQuery' => 'applications/semistruct/query/SemiStructuredObjectInstanceQuery.php', 'SemiStructuredObjectType' => 'applications/semistruct/storage/SemiStructuredObjectType.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/SemiStructuredObjectTypeListController.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', 'SemiStructuredPatchList' => 'applications/semistruct/storage/SemiStructuredPatchList.php', ), 'function' => array(), 'xmap' => array( 'SemiStructuredBaseController' => 'PhabricatorController', 'SemiStructuredDAO' => 'PhabricatorLiskDAO', 'SemiStructuredDataApplication' => 'PhabricatorApplication', 'SemiStructuredObjectInstance' => array( 'SemiStructuredDAO', 'PhabricatorPolicyInterface', 'PhabricatorApplicationTransactionInterface', 'PhabricatorFlaggableInterface', 'PhabricatorDestructibleInterface', ), 'SemiStructuredObjectInstancePHIDType' => 'PhabricatorPHIDType', 'SemiStructuredObjectInstanceQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 'SemiStructuredObjectType' => array( 'SemiStructuredDAO', 'PhabricatorPolicyInterface', 'PhabricatorApplicationTransactionInterface', 'PhabricatorFlaggableInterface', 'PhabricatorDestructibleInterface', 'PhabricatorFerretInterface', ), + 'SemiStructuredObjectTypeDescriptionTransaction' => 'SemiStructuredObjectTypeTransactionType', + 'SemiStructuredObjectTypeEditController' => 'PhabricatorDashboardController', + 'SemiStructuredObjectTypeEditEngine' => 'PhabricatorEditEngine', 'SemiStructuredObjectTypeFerretEngine' => 'PhabricatorFerretEngine', 'SemiStructuredObjectTypeListController' => 'SemiStructuredBaseController', + 'SemiStructuredObjectTypeNameTransaction' => 'SemiStructuredObjectTypeTransactionType', 'SemiStructuredObjectTypePHIDType' => 'PhabricatorPHIDType', 'SemiStructuredObjectTypeQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 'SemiStructuredObjectTypeSearchEngine' => 'PhabricatorApplicationSearchEngine', + 'SemiStructuredObjectTypeTransaction' => 'PhabricatorModularTransaction', + 'SemiStructuredObjectTypeTransactionEditor' => 'PhabricatorApplicationTransactionEditor', + 'SemiStructuredObjectTypeTransactionType' => 'PhabricatorModularTransactionType', 'SemiStructuredPatchList' => 'PhabricatorSQLPatchList', ), )); diff --git a/src/application/SemiStructuredDataApplication.php b/src/application/SemiStructuredDataApplication.php index 4c0022f..4639307 100644 --- a/src/application/SemiStructuredDataApplication.php +++ b/src/application/SemiStructuredDataApplication.php @@ -1,25 +1,27 @@ <?php final class SemiStructuredDataApplication extends PhabricatorApplication { public function getName() { return pht('Semi-Structured'); } public function getShortDescription() { return pht('Work with evolving data sets.'); } public function getBaseURI() { return '/semistruct/'; } public function getRoutes() { return array( '/semistruct/' => array( '(?:query/(?P<queryKey>[^/]+)/)?' => 'SemiStructuredObjectTypeListController', + $this->getEditRoutePattern('editclass/') => + 'SemiStructuredObjectTypeEditController', ), ); } } diff --git a/src/controller/class/SemiStructuredObjectTypeEditController.php b/src/controller/class/SemiStructuredObjectTypeEditController.php new file mode 100644 index 0000000..7cb0880 --- /dev/null +++ b/src/controller/class/SemiStructuredObjectTypeEditController.php @@ -0,0 +1,12 @@ +<?php + +final class SemiStructuredObjectTypeEditController + extends PhabricatorDashboardController { + + public function handleRequest(AphrontRequest $request) { + return id(new SemiStructuredObjectTypeEditEngine()) + ->setController($this) + ->buildResponse(); + } + +} diff --git a/src/controller/SemiStructuredObjectTypeListController.php b/src/controller/class/SemiStructuredObjectTypeListController.php similarity index 88% rename from src/controller/SemiStructuredObjectTypeListController.php rename to src/controller/class/SemiStructuredObjectTypeListController.php index f9d30fa..9640b2a 100644 --- a/src/controller/SemiStructuredObjectTypeListController.php +++ b/src/controller/class/SemiStructuredObjectTypeListController.php @@ -1,41 +1,41 @@ <?php final class SemiStructuredObjectTypeListController extends SemiStructuredBaseController { public function handleRequest(AphrontRequest $request) { $viewer = $request->getViewer(); $query_key = $request->getURIData('queryKey'); $controller = id(new PhabricatorApplicationSearchController()) ->setQueryKey($query_key) ->setSearchEngine(new SemiStructuredObjectTypeSearchEngine()) ->setNavigation($this->buildSideNavView()); return $this->delegateToController($controller); } public function buildSideNavView() { $user = $this->getRequest()->getUser(); $nav = new AphrontSideNavFilterView(); $nav->setBaseURI(new PhutilURI($this->getApplicationURI())); id(new SemiStructuredObjectTypeSearchEngine()) ->setViewer($user) ->addNavigationItems($nav->getMenu()); $nav->selectFilter(null); return $nav; } protected function buildApplicationCrumbs() { $crumbs = parent::buildApplicationCrumbs(); -// id(new SemiStructuredObjectTypeEditEngine()) // TODO - // ->setViewer($this->getViewer()) - // ->addActionToCrumbs($crumbs); + id(new SemiStructuredObjectTypeEditEngine()) + ->setViewer($this->getViewer()) + ->addActionToCrumbs($crumbs); return $crumbs; } } diff --git a/src/editor/SemiStructuredObjectTypeEditEngine.php b/src/editor/SemiStructuredObjectTypeEditEngine.php new file mode 100644 index 0000000..5a1ff18 --- /dev/null +++ b/src/editor/SemiStructuredObjectTypeEditEngine.php @@ -0,0 +1,99 @@ +<?php + +final class SemiStructuredObjectTypeEditEngine + extends PhabricatorEditEngine { + + const ENGINECONST = 'sst:objecttype'; + + public function isEngineConfigurable() { + return false; + } + + public function getEngineName() { + return pht('Object Type'); + } + + public function getSummaryHeader() { + return pht('Edit Object Type'); + } + + public function getSummaryText() { + return pht('This engine is used to modify object types.'); + } + + public function getEngineApplicationClass() { + return 'SemiStructuredDataApplication'; + } + + protected function newEditableObject() { + $viewer = $this->getViewer(); + return SemiStructuredObjectType::initializeNewObjectType($viewer); + } + + protected function newObjectQuery() { + return new SemiStructuredObjectTypeQuery(); + } + + protected function getObjectCreateTitleText($object) { + return pht('Create Object Type'); + } + + protected function getObjectCreateButtonText($object) { + return pht('Create Object Type'); + } + + protected function getObjectCreateCancelURI($object) { + return '/semistructured/'; + } + + protected function getEditorURI() { + return $this->getApplication()->getApplicationURI('editclass/'); + } + + protected function getObjectEditTitleText($object) { + return pht('Edit Object Type: %s', $object->getName()); + } + + protected function getObjectEditShortText($object) { + return pht('Edit Object Type'); + } + + protected function getObjectCreateShortText() { + return pht('Create Object Type'); + } + + protected function getObjectName() { + return pht('Object Type'); + } + + protected function getObjectViewURI($object) { + return $object->getURI(); + } + + protected function buildCustomEditFields($object) { + + $fields = array( + id(new PhabricatorTextEditField()) + ->setKey('name') + ->setLabel(pht('Name')) + ->setDescription(pht('Name of the object type.')) + ->setConduitDescription(pht('Rename the type.')) + ->setConduitTypeDescription(pht('New type name.')) + ->setTransactionType( + SemiStructuredObjectTypeNameTransaction::TRANSACTIONTYPE) + ->setIsRequired(true) + ->setValue($object->getName()), + id(new PhabricatorRemarkupEditField()) + ->setKey('description') + ->setLabel(pht('Description')) + ->setDescription(pht('Object Type long description.')) + ->setConduitTypeDescription(pht('New type description.')) + ->setTransactionType( + SemiStructuredObjectTypeDescriptionTransaction::TRANSACTIONTYPE) + ->setValue($object->getDescription()), + ); + + return $fields; + } + +} diff --git a/src/editor/SemiStructuredObjectTypeTransactionEditor.php b/src/editor/SemiStructuredObjectTypeTransactionEditor.php new file mode 100644 index 0000000..6d9dc24 --- /dev/null +++ b/src/editor/SemiStructuredObjectTypeTransactionEditor.php @@ -0,0 +1,28 @@ +<?php + +final class SemiStructuredObjectTypeTransactionEditor + extends PhabricatorApplicationTransactionEditor { + + public function getEditorApplicationClass() { + return 'PhabricatorDashboardApplication'; + } + + public function getEditorObjectsDescription() { + return pht('Dashboard Panels'); + } + + public function getTransactionTypes() { + $types = parent::getTransactionTypes(); + + $types[] = PhabricatorTransactions::TYPE_VIEW_POLICY; + $types[] = PhabricatorTransactions::TYPE_EDIT_POLICY; + $types[] = PhabricatorTransactions::TYPE_EDGE; + + return $types; + } + + protected function supportsSearch() { + return true; + } + +} diff --git a/src/query/SemiStructuredObjectTypeSearchEngine.php b/src/query/SemiStructuredObjectTypeSearchEngine.php index 82b09a9..af9f8bf 100644 --- a/src/query/SemiStructuredObjectTypeSearchEngine.php +++ b/src/query/SemiStructuredObjectTypeSearchEngine.php @@ -1,153 +1,153 @@ <?php final class SemiStructuredObjectTypeSearchEngine extends PhabricatorApplicationSearchEngine { public function getResultTypeDescription() { return pht('Object Types'); } public function getApplicationClassName() { return 'SemiStructuredDataApplication'; } public function newQuery() { return id(new SemiStructuredObjectTypeQuery()); } protected function buildCustomSearchFields() { return array( id(new PhabricatorSearchCheckboxesField()) ->setKey('statuses') ->setLabel(pht('Status')) - ->setOptions(PhabricatorDashboard::getStatusNameMap()), + ->setOptions(SemiStructuredObjectType::getStatusNameMap()), id(new PhabricatorSearchCheckboxesField()) ->setKey('editable') ->setLabel(pht('Editable')) ->setOptions(array('editable' => null)), ); } protected function getURI($path) { return '/semistruct/'.$path; } protected function getBuiltinQueryNames() { $names = array(); $names['all'] = pht('All Types'); $names['open'] = pht('Active Types'); return $names; } public function buildSavedQueryFromBuiltin($query_key) { $query = $this->newSavedQuery(); $query->setQueryKey($query_key); $viewer = $this->requireViewer(); switch ($query_key) { case 'all': return $query; case 'open': return $query->setParameter( 'statuses', array( SemiStructuredObjectType::STATUS_ACTIVE, )); } return parent::buildSavedQueryFromBuiltin($query_key); } protected function buildQueryFromParameters(array $map) { $query = $this->newQuery(); if ($map['statuses']) { $query->withStatuses($map['statuses']); } if ($map['editable'] !== null) { $query->withCanEdit($map['editable']); } return $query; } protected function renderResultList( array $items, PhabricatorSavedQuery $query, array $handles) { $viewer = $this->requireViewer(); $phids = array(); foreach ($items as $item) { // $author_phid = $dashboard->getAuthorPHID(); // if ($author_phid) { // $phids[] = $author_phid; // } } $handles = $viewer->loadHandles($phids); if ($items) { $edge_query = id(new PhabricatorEdgeQuery()) ->withSourcePHIDs(mpull($items, 'getPHID')) ->withEdgeTypes( array( PhabricatorProjectObjectHasProjectEdgeType::EDGECONST, )); $edge_query->execute(); } $list = id(new PHUIObjectItemListView()) ->setViewer($viewer); - foreach ($items as $item) { + foreach ($items as $class) { $item = id(new PHUIObjectItemView()) ->setViewer($viewer) ->setObjectName($item->getObjectName()) ->setHeader($item->getName()) ->setHref($item->getURI()) ->setObject($item); - if ($item->isArchived()) { + if ($class->isArchived()) { $item->setDisabled(true); $bg_color = 'bg-grey'; } else { $bg_color = 'bg-dark'; } $icon = id(new PHUIIconView()) - ->setIcon($item->getIcon()) + ->setIcon($class->getIcon()) ->setBackground($bg_color); $item->setImageIcon($icon); - $item->setEpoch($item->getDateModified()); + $item->setEpoch($class->getDateModified()); - $phid = $item->getPHID(); + $phid = $class->getPHID(); $project_phids = $edge_query->getDestinationPHIDs(array($phid)); $project_handles = $viewer->loadHandles($project_phids); $item->addAttribute( id(new PHUIHandleTagListView()) ->setLimit(4) ->setNoDataString(pht('No Tags')) ->setSlim(true) ->setHandles($project_handles)); $list->addItem($item); } $result = new PhabricatorApplicationSearchResultView(); $result->setObjectList($list); $result->setNoDataString(pht('No object types found.')); return $result; } } diff --git a/src/storage/SemiStructuredObjectInstance.php b/src/storage/SemiStructuredObjectInstance.php index c8dc301..ec37143 100644 --- a/src/storage/SemiStructuredObjectInstance.php +++ b/src/storage/SemiStructuredObjectInstance.php @@ -1,107 +1,111 @@ <?php final class SemiStructuredObjectInstance extends SemiStructuredDAO implements PhabricatorPolicyInterface, PhabricatorApplicationTransactionInterface, // PhabricatorSubscribableInterface, PhabricatorFlaggableInterface, PhabricatorDestructibleInterface // PhabricatorConduitResultInterface { protected $classPHID; protected $status; protected $rawData; const STATUS_ACTIVE = 'active'; const STATUS_ARCHIVED = 'archived'; public static function initializeNewObjectInstance( PhabricatorUser $actor, SemiStructuredObjectType $object_class) { return id(new self()) ->setClassPHID($object_class->getPHID()) ->setViewPolicy(PhabricatorPolicies::getMostOpenPolicy()) // TODO take policies from class? ->setEditPolicy($actor->getPHID()) ->setStatus(self::STATUS_ACTIVE); } 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', 'classPHID' => 'phid', 'rawData' => 'text', ), self::CONFIG_KEY_SCHEMA => array( 'classPHID' => array( 'columns' => array('classPHID'), ), ), ) + parent::getConfiguration(); } + public function getPHIDType() { + return SemiStructuredObjectInstancePHIDType::TYPECONST; + } + /* -( PhabricatorApplicationTransactionInterface )------------------------- */ public function getApplicationTransactionEditor() { - return new PhabricatorDashboardPanelTransactionEditor(); + // return new PhabricatorDashboardPanelTransactionEditor(); TODO } public function getApplicationTransactionTemplate() { - return new PhabricatorDashboardPanelTransaction(); + // return new PhabricatorDashboardPanelTransaction(); TODO } /* -( PhabricatorPolicyInterface )----------------------------------------- */ public function getCapabilities() { return array( PhabricatorPolicyCapability::CAN_VIEW, PhabricatorPolicyCapability::CAN_EDIT, ); } public function getPolicy($capability) { switch ($capability) { case PhabricatorPolicyCapability::CAN_VIEW: return $this->getViewPolicy(); case PhabricatorPolicyCapability::CAN_EDIT: return $this->getEditPolicy(); } } public function hasAutomaticCapability($capability, PhabricatorUser $viewer) { return false; } /* -( PhabricatorDestructibleInterface )----------------------------------- */ public function destroyObjectPermanently( PhabricatorDestructionEngine $engine) { $this->openTransaction(); $this->delete(); $this->saveTransaction(); } } diff --git a/src/storage/SemiStructuredObjectType.php b/src/storage/SemiStructuredObjectType.php index fcf849d..642f611 100644 --- a/src/storage/SemiStructuredObjectType.php +++ b/src/storage/SemiStructuredObjectType.php @@ -1,106 +1,132 @@ <?php final class SemiStructuredObjectType extends SemiStructuredDAO implements PhabricatorPolicyInterface, PhabricatorApplicationTransactionInterface, // PhabricatorSubscribableInterface, PhabricatorFlaggableInterface, PhabricatorDestructibleInterface, PhabricatorFerretInterface // PhabricatorConduitResultInterface { protected $name; protected $status; protected $description; + protected $viewPolicy; + protected $editPolicy; + +// custom fields +// icon/logo const STATUS_ACTIVE = 'active'; const STATUS_ARCHIVED = 'archived'; public static function initializeNewObjectType(PhabricatorUser $actor) { return id(new self()) ->setName('') ->setViewPolicy(PhabricatorPolicies::getMostOpenPolicy()) - ->setEditPolicy($actor->getPHID()) // TODO config for deflt + ->setEditPolicy($actor->getPHID()) ->setStatus(self::STATUS_ACTIVE); } 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', 'description' => 'text', ), ) + parent::getConfiguration(); } + public function getPHIDType() { + return SemiStructuredObjectTypePHIDType::TYPECONST; + } + + public function isArchived() { + return ($this->getStatus() == self::STATUS_ARCHIVED); + } + + public function getURI() { + return urisprintf('/semistruct/type/%d/', $this->getID()); + } + + public function getObjectName() { + return pht('Object Type %d', $this->getID()); + } + + public function getIcon() { + // TODO + return 'fa-bear'; + } /* -( PhabricatorApplicationTransactionInterface )------------------------- */ public function getApplicationTransactionEditor() { - return new PhabricatorDashboardPanelTransactionEditor(); + return new SemiStructuredObjectTypeTransactionEditor(); } public function getApplicationTransactionTemplate() { - return new PhabricatorDashboardPanelTransaction(); + return new SemiStructuredObjectTypeTransaction(); } /* -( PhabricatorPolicyInterface )----------------------------------------- */ public function getCapabilities() { return array( PhabricatorPolicyCapability::CAN_VIEW, PhabricatorPolicyCapability::CAN_EDIT, + // TODO can-create-instances ); } public function getPolicy($capability) { switch ($capability) { case PhabricatorPolicyCapability::CAN_VIEW: return $this->getViewPolicy(); case PhabricatorPolicyCapability::CAN_EDIT: return $this->getEditPolicy(); } } public function hasAutomaticCapability($capability, PhabricatorUser $viewer) { return false; } /* -( PhabricatorDestructibleInterface )----------------------------------- */ public function destroyObjectPermanently( PhabricatorDestructionEngine $engine) { $this->openTransaction(); $this->delete(); $this->saveTransaction(); } /* -( PhabricatorFerretInterface )----------------------------------------- */ public function newFerretEngine() { return new SemiStructuredObjectTypeFerretEngine(); } } diff --git a/src/storage/SemiStructuredObjectTypeTransaction.php b/src/storage/SemiStructuredObjectTypeTransaction.php new file mode 100644 index 0000000..eea9346 --- /dev/null +++ b/src/storage/SemiStructuredObjectTypeTransaction.php @@ -0,0 +1,18 @@ +<?php + +final class SemiStructuredObjectTypeTransaction + extends PhabricatorModularTransaction { + + public function getApplicationName() { + return 'semistructured'; + } + + public function getApplicationTransactionType() { + return SemiStructuredObjectTypePHIDType::TYPECONST; + } + + public function getBaseTransactionClass() { + return 'SemiStructuredObjectTypeTransactionType'; + } + +} diff --git a/src/xaction/class/SemiStructuredObjectTypeDescriptionTransaction.php b/src/xaction/class/SemiStructuredObjectTypeDescriptionTransaction.php new file mode 100644 index 0000000..e6ae6fa --- /dev/null +++ b/src/xaction/class/SemiStructuredObjectTypeDescriptionTransaction.php @@ -0,0 +1,57 @@ +<?php + +final class SemiStructuredObjectTypeDescriptionTransaction + extends SemiStructuredObjectTypeTransactionType { + + const TRANSACTIONTYPE = 'semist:class:description'; + + public function generateOldValue($object) { + return $object->getDescription(); + } + + public function applyInternalEffects($object, $value) { + $object->setDescription($value); + } + + public function getTitle() { + return pht( + '%s updated the object type description.', + $this->renderAuthor()); + } + + public function getTitleForFeed() { + return pht( + '%s updated the description for object type %s.', + $this->renderAuthor(), + $this->renderObject()); + } + + public function hasChangeDetailView() { + return true; + } + + public function getMailDiffSectionHeader() { + return pht('CHANGES TO OBJECT TYPE DESCRIPTION'); + } + + public function newChangeDetailView() { + $viewer = $this->getViewer(); + + return id(new PhabricatorApplicationTransactionTextDiffDetailView()) + ->setViewer($viewer) + ->setOldText($this->getOldValue()) + ->setNewText($this->getNewValue()); + } + + public function newRemarkupChanges() { + $changes = array(); + + $changes[] = $this->newRemarkupChange() + ->setOldValue($this->getOldValue()) + ->setNewValue($this->getNewValue()); + + return $changes; + } + + +} diff --git a/src/xaction/class/SemiStructuredObjectTypeNameTransaction.php b/src/xaction/class/SemiStructuredObjectTypeNameTransaction.php new file mode 100644 index 0000000..111239b --- /dev/null +++ b/src/xaction/class/SemiStructuredObjectTypeNameTransaction.php @@ -0,0 +1,55 @@ +<?php + +final class SemiStructuredObjectTypeNameTransaction + extends SemiStructuredObjectTypeTransactionType { + + const TRANSACTIONTYPE = 'semist:class:name'; + + public function generateOldValue($object) { + return $object->getName(); + } + + public function applyInternalEffects($object, $value) { + $object->setName($value); + } + + public function getTitle() { + return pht( + '%s renamed this object type from %s to %s.', + $this->renderAuthor(), + $this->renderOldValue(), + $this->renderNewValue()); + } + + public function getTitleForFeed() { + return pht( + '%s renamed %s object type %s to %s.', + $this->renderAuthor(), + $this->renderObject(), + $this->renderOldValue(), + $this->renderNewValue()); + } + + public function validateTransactions($object, array $xactions) { + $errors = array(); + + if ($this->isEmptyTextTransaction($object->getName(), $xactions)) { + $errors[] = $this->newRequiredError( + pht('Object type must have a name.')); + } + + $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; + } + +} diff --git a/src/xaction/class/SemiStructuredObjectTypeTransactionType.php b/src/xaction/class/SemiStructuredObjectTypeTransactionType.php new file mode 100644 index 0000000..e6f6f48 --- /dev/null +++ b/src/xaction/class/SemiStructuredObjectTypeTransactionType.php @@ -0,0 +1,4 @@ +<?php + +abstract class SemiStructuredObjectTypeTransactionType + extends PhabricatorModularTransactionType {}