Perforce Chronicle 2012.2/486814
API Documentation
|
This class facilitates the creation of categories, including storage of arbitrary metadata about the category, and associating arbitrary data with each category. More...
Public Member Functions | |
addEntries ($entries) | |
Add multiple entries to this category. | |
addEntry ($entry) | |
Add an entry to this category. | |
delete ($description=null) | |
Delete a category. | |
deleteEntries ($entries) | |
Delete multiple entries from this category. | |
deleteEntry ($entry) | |
Delete an entry from this category. | |
getAncestorIds () | |
Get the ids of this categories ancestors ordered from the top down (greatest ancestor to direct parent). | |
getAncestors () | |
Retrieves the ancestors for this category ordered from the top down (greatest ancestor to direct parent). | |
getBaseId () | |
Get the base id - the trailing portion (basename) of the id. | |
getChildren ($recursive=false) | |
Retrieves child categories within the specified path, if any. | |
getDepth () | |
Get the depth of this category in the hierarchy. | |
getDescription () | |
Get the current description or null if none set. | |
getEntries (array $options=array()) | |
Retrieve the entries within this category. | |
getParent () | |
Retrieves the parent category for this category. | |
getParentId () | |
Get the id of this category's parent category. | |
getTitle () | |
Get the category title or its base id if no title available. | |
hasChildren ($recursive=false) | |
Determines whether the specified category contains child categories. | |
hasEntries ($recursive=false) | |
Determines whether the current category has any entries. | |
hasEntry ($id) | |
Determines if the specified entry exists in this category. | |
hasParent () | |
Determines whether the current category has a parent category in storage. | |
save ($description=null) | |
Extend save to verify that category ancestry exists. | |
setDescription ($description) | |
Update the description with a new value. | |
setId ($id) | |
Set the id for this category category. | |
setTitle ($title) | |
Update the title with a new value. | |
Static Public Member Functions | |
static | decodeEntryId ($encoded) |
Decode an encoded entry id. | |
static | depotFileToId ($depotFile, P4Cms_Record_Adapter $adapter=null) |
Given a category filespec in depotFile syntax, determine the id. | |
static | encodeEntryId ($id) |
Encode an entry id so that it's safe to place in a filesystem. | |
static | fetchAll ($query=null, P4Cms_Record_Adapter $adapter=null) |
Extend parent to limit query to categories (excluding entries). | |
static | fetchAllByEntry ($item, P4Cms_Record_Adapter $adapter=null) |
Get all categories that contain the given entry. | |
static | fetchIdsByEntry ($item, P4Cms_Record_Adapter $adapter=null) |
Get the ids of all categories that contain the given entry. | |
static | idToFilespec ($id, P4Cms_Record_Adapter $adapter=null) |
Given a category id, determine the corresponding filespec. | |
static | isNestingAllowed () |
Reports whether the current category allows nesting of categories. | |
static | move ($sourceId, $targetId, P4Cms_Record_Adapter $adapter=null) |
Move/rename a category. | |
static | setEntryCategories ($item, $newCategoryIds, P4Cms_Record_Adapter $adapter=null) |
Set the categories that an entry resides in. | |
Public Attributes | |
const | CATEGORY_FILENAME = '.index' |
Defines the filename to contain category metadata. | |
const | ENTRY_PREFIX = '_' |
Defines the prefix for encoded category entry ids. | |
const | OPTION_RECURSIVE = 'recursive' |
Protected Member Functions | |
_acceptId ($item, $errorPrefix= '') | |
Accept ids passed as strings or objects with getId() method. | |
_adjustEntries ($action, $description, $entries) | |
Adjust the entries by performing the specified action (add or delete). | |
_canAcceptId ($item) | |
Determines whether an id can be extracted from the argument. | |
_checkIdSet ($action= '') | |
Checks whether the current instance has an id set. | |
_getEntryRecordId ($id) | |
Get the record id for the given entry id. | |
Static Protected Member Functions | |
static | _checkNestability () |
Check whether this category class permits nesting. | |
Static Protected Attributes | |
static | $_fields |
Specify the fields for category metadata. | |
static | $_nestingAllowed = false |
Specifies whether the concrete category allows nested categories. | |
static | $_storageSubPath = null |
Specifies the sub-path to use for storage of category data. |
This class facilitates the creation of categories, including storage of arbitrary metadata about the category, and associating arbitrary data with each category.
Categories can provide nesting, similar to folders in a filesystem, or can be flat, such as a list of tags.
Provides category associations/storage.
Typical usage:
$category = new ConcreteCategory; $category->setId('/') ->setLabel('My Directory') ->save(); $entries = $category->getEntries();
P4Cms_Categorization_CategoryAbstract::_acceptId | ( | $ | item, |
$ | errorPrefix = '' |
||
) | [protected] |
Accept ids passed as strings or objects with getId() method.
Override in a concrete class to implement the required id extraction. Note: ids passed as integers will be converted to strings.
string | object | $item | an id, or an object that has an id, |
string | $errorPrefix | a prefix to include in exceptions, if necessary. |
InvalidArgumentException | if $item is not a string or object with getId(). |
{ $id = ''; if (is_string($item) || is_int($item)) { $id = (string) $item; } else if (is_object($item)) { if (method_exists($item, 'getId')) { $id = $item->getId(); } else { throw new InvalidArgumentException( $errorPrefix .'the provided object does not have a getId() method.' ); } } else { throw new InvalidArgumentException( $errorPrefix .'the provided entry is not a string or object with a getId() method.' ); } return $id; }
P4Cms_Categorization_CategoryAbstract::_adjustEntries | ( | $ | action, |
$ | description, | ||
$ | entries | ||
) | [protected] |
Adjust the entries by performing the specified action (add or delete).
string | $action | the action to perform (add or delete). |
string | $description | the description to supply to perforce. |
array | $entries | an array of strings or entry objects to associate with the current category. |
P4Cms_Categorization_Exception | if category id not set. |
InvalidArgumentException | if $entries is not an array. |
{ // ensure action is valid. if (!in_array($action, array('add', 'delete'))) { throw new InvalidArgumentException( "Cannot '$action' entries. Action must be add or delete." ); } // ensure we have an id. $catId = $this->_checkIdSet("$action entries"); // validate entries if (!is_array($entries)) { throw new InvalidArgumentException( "Cannot $action entries; you must provide an array of entries." ); } foreach ($entries as $entry) { if (is_string($entry) || $this->_canAcceptId($entry)) { continue; } throw new InvalidArgumentException( "Cannot $action entries; all entries must either be strings or known entry types." ); } // begin a batch if we're not already in one. $adapter = $this->getAdapter(); $batch = !$adapter->inBatch() ? $adapter->beginBatch($description) : false; // add the entries foreach ($entries as $entry) { $id = $this->_acceptId($entry, "Cannot $action entry; "); // skip existing entries for add and // non-existant entries for delete. $shouldExist = ($action == 'add'); if ($shouldExist == $this->hasEntry($id)) { continue; } // adjust method call to add or delete as appropriate. $method = $action == 'add' ? 'save' : 'delete'; // setup entry record. $record = new P4Cms_Record; $record->setAdapter($this->getAdapter()) ->setId($this->_getEntryRecordId($id)) ->$method(); } // commit batch if we made it. if ($batch) { $adapter->commitBatch(); } return $this; }
P4Cms_Categorization_CategoryAbstract::_canAcceptId | ( | $ | item | ) | [protected] |
Determines whether an id can be extracted from the argument.
mixed | $item | an id, or other structure that has an id. |
{ try { $id = $this->_acceptId($item); return (isset($id) && strlen($id)) ? true : false; } catch (Exception $e) { return false; } }
P4Cms_Categorization_CategoryAbstract::_checkIdSet | ( | $ | action = '' | ) | [protected] |
Checks whether the current instance has an id set.
string | $action | Identifies the action in the exception, if required. |
P4Cms_Categorization_Exception | if the id is not set. |
{ if ($this->getId() === null) { if (strlen($action)) { $action = " $action"; } throw new P4Cms_Categorization_Exception( "Cannot$action; category id is not set." ); } return $this->getId(); }
static P4Cms_Categorization_CategoryAbstract::_checkNestability | ( | ) | [static, protected] |
Check whether this category class permits nesting.
P4Cms_Categorization_Exception | If nesting is not allowed. |
{ if (!static::isNestingAllowed()) { throw new P4Cms_Categorization_Exception( "This category does not permit nesting." ); } }
P4Cms_Categorization_CategoryAbstract::_getEntryRecordId | ( | $ | id | ) | [protected] |
Get the record id for the given entry id.
string | $id | the entry id to get the filespec for. |
{ // ensure we have a category id. $this->_checkIdSet('get entry record id'); return static::$_storageSubPath . '/' . $this->getId() . '/' . static::encodeEntryId($id); }
P4Cms_Categorization_CategoryAbstract::addEntries | ( | $ | entries | ) |
Add multiple entries to this category.
array | $entries | an array of strings or entry objects to associate with this category. |
P4Cms_Categorization_Exception | if category id not set. |
InvalidArgumentException | if $entries is not an array. |
{ return $this->_adjustEntries( 'add', 'Added entries to ' . $this->getId() . '.', $entries ); }
P4Cms_Categorization_CategoryAbstract::addEntry | ( | $ | entry | ) |
Add an entry to this category.
mixed | $entry | an entry id, or a known entry type, for association with the current category. |
InvalidArgumentException | if $entry is not a string or known entry type. |
{ return $this->addEntries(array($entry)); }
static P4Cms_Categorization_CategoryAbstract::decodeEntryId | ( | $ | encoded | ) | [static] |
Decode an encoded entry id.
string | $encoded | The encoded id to decode. |
InvalidArgumentException | if $encoded is not set, has 0 length, or cannot be successfully decoded. |
{ if (!isset($encoded) || strlen($encoded) == 0) { throw new InvalidArgumentException( 'Cannot decode entry id; encoded id not set or has no length.' ); } $id = null; try { $id = pack('H*', ltrim($encoded, static::ENTRY_PREFIX)); } catch (Exception $e) { throw new InvalidArgumentException( "Cannot decode entry id; encoded id contains invalid characters." ); } return $id; }
P4Cms_Categorization_CategoryAbstract::delete | ( | $ | description = null | ) |
Delete a category.
Extends parent to delete entries and sub-categories.
string | $description | optional - a description of the change. |
Reimplemented from P4Cms_Record.
{ $id = $this->_checkIdSet('delete category'); // ensure id exists. if (!static::exists($id)) { throw new P4Cms_Categorization_Exception( "Cannot delete category. Category does not exist." ); } $adapter = $this->getAdapter(); $connection = $adapter->getConnection(); $filespec = static::getStoragePath($adapter) . "/" . $id . "/..."; // revert and delete this entire category (-v deletes without syncing). $connection->run('revert', $filespec); $connection->run('delete', array('-v', $filespec)); // if we're in a batch, reopen in batch change, else submit. if ($adapter->inBatch()) { $connection->run('reopen', array('-c', $adapter->getBatchId(), $filespec)); } else { if (!$description) { $description = "Deleted '" . static::$_storageSubPath . "' record."; } $connection->run('submit', array('-d', $description, $filespec)); } return $this; }
P4Cms_Categorization_CategoryAbstract::deleteEntries | ( | $ | entries | ) |
Delete multiple entries from this category.
array | $entries | an array of strings or record objects to remove association from the current category. |
InvalidArgumentException | if $entries is not an array. |
{ return $this->_adjustEntries( 'delete', 'Deleted entries from ' . $this->getId() . '.', $entries ); }
P4Cms_Categorization_CategoryAbstract::deleteEntry | ( | $ | entry | ) |
Delete an entry from this category.
mixed | $entry | an entry id, or a known entry type, for removal from this category. |
InvalidArgumentException | if $entry is not a string or known entry type. |
{ return $this->deleteEntries(array($entry)); }
static P4Cms_Categorization_CategoryAbstract::depotFileToId | ( | $ | depotFile, |
P4Cms_Record_Adapter $ | adapter = null |
||
) | [static] |
Given a category filespec in depotFile syntax, determine the id.
string | $depotFile | a record depotFile. |
P4Cms_Record_Adapter | $adapter | optional - storage adapter to use. |
Reimplemented from P4Cms_Record.
{ // ensure depotFile is a category file. if (basename($depotFile) != static::CATEGORY_FILENAME) { throw new InvalidArgumentException( "Cannot get category id. Given depot file is not a valid category." ); } return dirname(parent::depotFileToId($depotFile, $adapter)); }
static P4Cms_Categorization_CategoryAbstract::encodeEntryId | ( | $ | id | ) | [static] |
Encode an entry id so that it's safe to place in a filesystem.
Encoded ids are modified base64 (replacing slashes '/' with dashes '-') with an ENTRY_PREFIX character.
string | $id | The id to encode. |
InvalidArgumentException | if $id is not set, or has 0 length. |
{ if (!isset($id) || strlen($id) == 0) { throw new InvalidArgumentException( 'Cannot encode entry id; id not set or has no length.' ); } return static::ENTRY_PREFIX . bin2hex($id); }
static P4Cms_Categorization_CategoryAbstract::fetchAll | ( | $ | query = null , |
P4Cms_Record_Adapter $ | adapter = null |
||
) | [static] |
Extend parent to limit query to categories (excluding entries).
See parent implementation for full description of options.
P4Cms_Record_Query | array | null | $query | optional - query options to augment result. |
P4Cms_Record_Adapter | $adapter | optional - storage adapter to use. |
Reimplemented from P4Cms_Record.
{ if (!$query instanceof P4Cms_Record_Query && !is_array($query) && !is_null($query)) { throw new InvalidArgumentException( 'Query must be a P4Cms_Record_Query, array or null' ); } // normalize array input to a query if (is_array($query)) { $query = new P4Cms_Record_Query($query); } // if null query given, make a new one. $query = $query ?: new P4Cms_Record_Query; // return all categories if we haven't been given any path/id limits. if ($query->getPaths() === null && !$query->getIds()) { $query->addPath('...'); } // manipulate the fetch-by-path so we search for the category file(s). $newPaths = array(); foreach ($query->getPaths() as $path) { $newPaths[] = $path .'/'. static::CATEGORY_FILENAME; } $query->setPaths($newPaths); // category files push depth down a level, adjust max depth if set. if ($query->getMaxDepth() !== null && $query->getMaxDepth() >= 0) { $query->setMaxDepth($query->getMaxDepth() + 1); } return parent::fetchAll($query, $adapter); }
static P4Cms_Categorization_CategoryAbstract::fetchAllByEntry | ( | $ | item, |
P4Cms_Record_Adapter $ | adapter = null |
||
) | [static] |
Get all categories that contain the given entry.
If you just want category ids (not objects), use fetchIdsByEntry.
mixed | $item | an id, or a known entry type to search for. |
P4Cms_Record_Adapter | $adapter | optional - storage adapter to use. |
{ $query = new P4Cms_Record_Query; $query->addPaths(static::fetchIdsByEntry($item, $adapter)); return static::fetchAll($query, $adapter); }
static P4Cms_Categorization_CategoryAbstract::fetchIdsByEntry | ( | $ | item, |
P4Cms_Record_Adapter $ | adapter = null |
||
) | [static] |
Get the ids of all categories that contain the given entry.
mixed | $item | an id, or a known entry type to search for. |
P4Cms_Record_Adapter | $adapter | optional - storage adapter to use. |
{ $tempCategory = new static; if (!isset($item) || !$tempCategory->_canAcceptId($item)) { throw new InvalidArgumentException( "Cannot get categories; the entry must either be a string or known entry type." ); } // if no adapter given, use default. $adapter = $adapter ?: static::getDefaultAdapter(); // determine set of categories containing entry using embedded wildcard. $filespec = static::getDepotStoragePath($adapter) . '/.../' . static::encodeEntryId($item); $query = P4_File_Query::create()->addFilespec($filespec)->setFilter('^headAction=...delete'); $files = P4_File::fetchAll($query, $adapter->getConnection()); // derive ids from file names. $categories = array(); foreach ($files as $file) { $categories[] = static::depotFileToId( dirname($file->getFilespec()) . '/' . static::CATEGORY_FILENAME, $adapter ); } return $categories; }
P4Cms_Categorization_CategoryAbstract::getAncestorIds | ( | ) |
Get the ids of this categories ancestors ordered from the top down (greatest ancestor to direct parent).
P4Cms_Categorization_Exception | if no id is set. |
{ $this->_checkIdSet('get ancestor ids'); // no ancestry if depth zero. if ($this->getDepth() === 0) { return array(); } // extract ancestors from parent id. $ancestors = array(); $segments = explode('/', $this->getParentId()); foreach ($segments as $segment) { $ancestorId = (isset($ancestorId) ? $ancestorId . '/' : '') . $segment; $ancestors[] = $ancestorId; } return $ancestors; }
P4Cms_Categorization_CategoryAbstract::getAncestors | ( | ) |
Retrieves the ancestors for this category ordered from the top down (greatest ancestor to direct parent).
{ $query = new P4Cms_Record_Query; $query->addPaths($this->getAncestorIds()); return static::fetchAll($query, $this->getAdapter()); }
P4Cms_Categorization_CategoryAbstract::getBaseId | ( | ) |
Get the base id - the trailing portion (basename) of the id.
{ return basename($this->getId()); }
P4Cms_Categorization_CategoryAbstract::getChildren | ( | $ | recursive = false | ) |
Retrieves child categories within the specified path, if any.
bool | $recursive | optional - collect children recursively if true; defaults to false. |
{ // perform validations static::_checkNestability(); $id = $this->_checkIdSet('get children'); // fetch all categories under this category. $selector = $recursive ? '...' : '*'; return static::fetchAll( P4Cms_Record_Query::create()->addPath($id . '/' . $selector), $this->getAdapter() ); }
P4Cms_Categorization_CategoryAbstract::getDepth | ( | ) |
Get the depth of this category in the hierarchy.
Categories at the root of the tree will have a depth of zero. The depth is equivalent to the number of ancestors a category has.
P4Cms_Category_Exception | if this category class does not permit nesting. |
{ // ensure nesting allowed. static::_checkNestability(); return substr_count($this->getId(), '/'); }
P4Cms_Categorization_CategoryAbstract::getDescription | ( | ) |
Get the current description or null if none set.
{ return $this->_getValue('description'); }
P4Cms_Categorization_CategoryAbstract::getEntries | ( | array $ | options = array() | ) |
Retrieve the entries within this category.
By default this will return a list of unique entry identifiers. If dereference is set to true, entry ids get resolved to their original form (e.g. objects).
array | $options | options to influence fetching entries, recognized keys are: OPTION_RECURSIVE - whether to include entries in sub-categories sort - if true then entries will be sorted |
Reimplemented in Category_Model_Category.
{ $id = $this->_checkIdSet('get entries'); $adapter = $this->getAdapter(); $recursive = isset($options[static::OPTION_RECURSIVE]) && $options[static::OPTION_RECURSIVE]; $sort = isset($options['sort']) && $options['sort']; // fetch entries in this category - exclude deleted and // category metadata files and adjust wildcard for recursive. $filespec = dirname(static::idToFilespec($id, $adapter)); $wildcard = $recursive ? '...' : '*'; $filter = '^headAction=...delete ^depotFile=...' . static::CATEGORY_FILENAME; $query = P4_File_Query::create() ->addFilespec($filespec .'/'. $wildcard) ->setFilter($filter); $files = P4_File::fetchAll($query, $adapter->getConnection()); // filenames are encoded entry ids. $entries = array(); foreach ($files as $file) { $entries[] = static::decodeEntryId($file->getBasename()); } // ensure entries are unique. $entries = array_unique($entries); // sort entries. if ($sort) { sort($entries); } return $entries; }
P4Cms_Categorization_CategoryAbstract::getParent | ( | ) |
Retrieves the parent category for this category.
P4Cms_Categorization_Exception | if has no parent or category id does not exist. |
{ if ($this->getDepth() === 0) { throw new P4Cms_Categorization_Exception( "Cannot get parent. This category has no parent." ); } return static::fetch($this->getParentId(), null, $this->getAdapter()); }
P4Cms_Categorization_CategoryAbstract::getParentId | ( | ) |
Get the id of this category's parent category.
Returns null for top-level categories.
P4Cms_Categorization_Exception | if no id is set. |
{ $this->_checkIdSet('get parent category'); if ($this->getDepth() > 0) { return dirname($this->getId()); } else { return null; } }
P4Cms_Categorization_CategoryAbstract::getTitle | ( | ) |
P4Cms_Categorization_CategoryAbstract::hasChildren | ( | $ | recursive = false | ) |
Determines whether the specified category contains child categories.
bool | $recursive | optional - collect children recursively if true; defaults to false. |
{ return (bool) count($this->getChildren($recursive)) > 0; }
P4Cms_Categorization_CategoryAbstract::hasEntries | ( | $ | recursive = false | ) |
Determines whether the current category has any entries.
bool | $recursive | optional - evaluate entries recursively if true; |
{ return (bool) count($this->getEntries(array(static::OPTION_RECURSIVE => $recursive))); }
P4Cms_Categorization_CategoryAbstract::hasEntry | ( | $ | id | ) |
Determines if the specified entry exists in this category.
string | $id | the id of the entry to check for. |
{ $this->_checkIdSet('check for entry'); return P4Cms_Record::exists( $this->_getEntryRecordId($id), null, $this->getAdapter() ); }
P4Cms_Categorization_CategoryAbstract::hasParent | ( | ) |
Determines whether the current category has a parent category in storage.
If you just want to check if the category looks like it should have a parent, use getDepth().
{ return ($this->getDepth()) ? static::exists($this->getParentId()) : false; }
static P4Cms_Categorization_CategoryAbstract::idToFilespec | ( | $ | id, |
P4Cms_Record_Adapter $ | adapter = null |
||
) | [static] |
Given a category id, determine the corresponding filespec.
This overrides P4Cms_Record's mapping to force the use of a particular filename.
string | $id | the category id to get the filespec for. |
P4Cms_Record_Adapter | $adapter | optional - storage adapter to use. |
Reimplemented from P4Cms_Record.
{ return parent::idToFilespec($id, $adapter) . '/' . static::CATEGORY_FILENAME; }
static P4Cms_Categorization_CategoryAbstract::isNestingAllowed | ( | ) | [static] |
Reports whether the current category allows nesting of categories.
{ return (bool) static::$_nestingAllowed; }
static P4Cms_Categorization_CategoryAbstract::move | ( | $ | sourceId, |
$ | targetId, | ||
P4Cms_Record_Adapter $ | adapter = null |
||
) | [static] |
Move/rename a category.
string | $sourceId | The category id to be moved/renamed |
string | $targetId | The category destination id. |
P4Cms_Record_Adapter | $adapter | optional - storage adapter to use. |
InvalidArgumentException | if $sourceId is null or does not exist. |
InvalidArgumentException | if $targetId is null or already exists. |
InvalidArgumentException | if $sourceId or $targetId == '' (aka root). |
InvalidArgumentException | if $targetId is a sub-category of $sourceId. |
P4Cms_Categorization_Exception | if the move is unsuccessful for some other reason. |
{ // if no adapter given, use default. $adapter = $adapter ?: static::getDefaultAdapter(); if (!isset($sourceId) || !isset($targetId)) { throw new InvalidArgumentException( 'Cannot move category; both the source and target category must be specified.' ); } if ($sourceId == '' || $targetId == '') { throw new InvalidArgumentException( 'Cannot move category; neither the source or target category can be "".' ); } if (!static::exists($sourceId, null, $adapter)) { throw new InvalidArgumentException( 'Cannot move category; source category does not exist.' ); } if (static::exists($targetId, null, $adapter)) { throw new InvalidArgumentException( 'Cannot move category; target category already exists.' ); } if (strpos($targetId, $sourceId . '/') === 0) { throw new InvalidArgumentException( 'Cannot move category; target category is within source category.' ); } // if we're not in a batch, setup a change to contain the moves if (!$adapter->inBatch()) { $change = new P4_Change; $change->setDescription("Preparing to move/rename category '$sourceId' to '$targetId'") ->save(); $changeId = $change->getId(); } else { $changeId = $adapter->getBatchId(); } // open the files to be moved for edit, and move them // move requires files to be opened for add or edit first $p4 = $adapter->getConnection(); $source = dirname(static::idToFilespec($sourceId, $adapter)) . '/...'; $target = dirname(static::idToFilespec($targetId, $adapter)) . '/...'; $p4->run('revert', $source); $p4->run('revert', $target); $p4->run('sync', $source); $p4->run('edit', $source); $p4->run('move', array($source, $target)); $p4->run('reopen', array('-c', $changeId, $source, $target)); // if we're not in a batch, submit the moves. if (!$adapter->inBatch()) { $change->setDescription("Move/rename category '$sourceId' to '$targetId'") ->submit(); } }
P4Cms_Categorization_CategoryAbstract::save | ( | $ | description = null | ) |
Extend save to verify that category ancestry exists.
string | $description | optional - a description of the change. |
{ $this->_checkIdSet('save'); // verify existence of parentage. $adapter = $this->getAdapter(); $parent = $this->getParentId(); while ($parent) { if (!static::exists($parent, null, $adapter)) { throw new InvalidArgumentException( 'Cannot create new category; category ancestry does not exist.' ); } $parent = strstr($parent, '/') ? dirname($parent) : null; } return parent::save($description); }
P4Cms_Categorization_CategoryAbstract::setDescription | ( | $ | description | ) |
Update the description with a new value.
string | $description | The new description |
{ return $this->_setValue('description', $description); }
static P4Cms_Categorization_CategoryAbstract::setEntryCategories | ( | $ | item, |
$ | newCategoryIds, | ||
P4Cms_Record_Adapter $ | adapter = null |
||
) | [static] |
Set the categories that an entry resides in.
mixed | $item | An id, or a known data structure, to associate with the list of categories. |
array | $newCategoryIds | A list of category ids to associate with the $item. |
P4Cms_Record_Adapter | $adapter | optional - storage adapter to use. |
InvalidArgumentException |
{ $tempCategory = new static; if (!is_string($item) || !$tempCategory->_canAcceptId($item)) { throw new InvalidArgumentException( 'Cannot set categories; the entry must either be a string or known data structure.' ); } if (!is_array($newCategoryIds)) { throw new InvalidArgumentException( 'Cannot set categories; categories must be an array.' ); } // if no adapter given, use default. $adapter = $adapter ?: static::getDefaultAdapter(); // ensure that the new categories exist foreach ($newCategoryIds as $id) { if (!static::exists($id)) { throw new P4Cms_Categorization_Exception( "Cannot add entry to a non-existant category." ); } } // now fetch the current categories $categoryIds = static::fetchIdsByEntry($item, $adapter); // compute the difference between the two lists. list($adds, $deletes) = P4Cms_ArrayUtility::computeDiff($categoryIds, $newCategoryIds); // add $item to these categories foreach ($adds as $id) { $category = new static; $category->setId($id)->addEntry($item); } // remove $item from these categories foreach ($deletes as $id) { $category = new static; $category->setId($id)->deleteEntry($item); } }
P4Cms_Categorization_CategoryAbstract::setId | ( | $ | id | ) |
Set the id for this category category.
null | string | $id | the id for this record - null to clear. |
InvalidArgumentException | if $id contains '/' when nesting is not allowed. |
InvalidArgumentException | if $id contains invalid characters. |
Reimplemented from P4Cms_Record.
{ $validator = new P4Cms_Validate_CategoryId; if ($id !== null && !$validator->isValid($id, static::CATEGORY_FILENAME)) { $messages = array_values($validator->getMessages()); throw new InvalidArgumentException( "Cannot set id: ". $messages[0] ); } if (strpos($id, '/') !== false) { static::_checkNestability(); } return parent::setId($id); }
P4Cms_Categorization_CategoryAbstract::setTitle | ( | $ | title | ) |
Update the title with a new value.
string | $title | The new title |
{ return $this->_setValue('title', $title); }
P4Cms_Categorization_CategoryAbstract::$_fields [static, protected] |
array( 'title' => array( 'accessor' => 'getTitle', 'mutator' => 'setTitle' ), 'description' => array( 'accessor' => 'getDescription', 'mutator' => 'setDescription' ) )
Specify the fields for category metadata.
Reimplemented from P4Cms_Record.
Reimplemented in Category_Model_Category.
P4Cms_Categorization_CategoryAbstract::$_nestingAllowed = false [static, protected] |
Specifies whether the concrete category allows nested categories.
Reimplemented in Category_Model_Category.
P4Cms_Categorization_CategoryAbstract::$_storageSubPath = null [static, protected] |
Specifies the sub-path to use for storage of category data.
This is used in combination with the records path to construct the full storage path. The implementing class MUST set this property.
Reimplemented from P4Cms_Record.
Reimplemented in Category_Model_Category.
const P4Cms_Categorization_CategoryAbstract::CATEGORY_FILENAME = '.index' |
Defines the filename to contain category metadata.
Defines the prefix for encoded category entry ids.
const P4Cms_Categorization_CategoryAbstract::OPTION_RECURSIVE = 'recursive' |