Perforce Chronicle 2012.2/486814
API Documentation
|
This class models hierarchical groupings of paths. More...
Public Member Functions | |
addBasePath ($basePath) | |
Add the specified base path to this path group. | |
addBasePaths (array $basePaths) | |
Add the passed array of base paths to this path group. | |
addPath ($path) | |
Add a path to this path group. | |
addSubGroup ($group) | |
Add a sub-group to this path group. | |
findById ($id, $group=null) | |
Find a group under this group (includes this group) with the given id. | |
getBasePaths () | |
Get the base paths for this path group. | |
getConflictCount () | |
A convienence method that calls through to getCount returning a shallow count (non-recursive) of conflicts. | |
getCount ($options=null) | |
Get the count of paths in this path group. | |
getCountCallback () | |
Returns the count callback without actually executing it. | |
getDetails ($options=null) | |
Provides details about the paths held in this group. | |
getDetailsCallback () | |
Returns the details callback without actually executing it. | |
getId () | |
Get an identifier for this group. | |
getIncludePaths () | |
Get a list of paths in this group to use in a pull operation. | |
getLabel () | |
Get the label for this path group. | |
getParent () | |
Get the parent group for this path group (if one is set) | |
getPaths ($options=null) | |
Get the paths in this path group (not recursive). | |
getSubGroup ($label) | |
Try to find a sub-group with the given label under this group. | |
getSubGroups () | |
Get the immediate child groups of this group (not recursive). | |
inheritPaths ($paths) | |
Scans up through parent objects and brings over any paths matching the passed filespec(s). | |
setBasePaths ($basePaths) | |
Set the base path(s) for this path group. | |
setCount ($count) | |
Control the count of paths in this path group. | |
setDetails ($callback) | |
Set a callback which will provide details about the paths held in this group. | |
setLabel ($label) | |
Set the label for this path group. | |
setParent (Site_Model_PullPathGroup $parent=null) | |
Set the parent group for this path group. | |
setPaths (P4Cms_Model_Iterator $paths=null) | |
Set the paths in this path group. | |
setSubGroups (P4Cms_Model_Iterator $groups=null) | |
Set the sub-groups in this path group. | |
Static Public Member Functions | |
static | fetchRecords (array $ids, $class, P4Cms_Site $source, P4Cms_Site $target) |
Helper function to fetch records from either the source or the target branch as necessary. | |
static | pathsByRecordId (P4Cms_Model_Iterator $paths, $class, P4Cms_Record_Adapter $adapter=null) |
Helper function to re-index a given paths iterator by record id. | |
Public Attributes | |
const | ONLY_CONFLICTS = 'onlyConflicts' |
const | RECURSIVE = 'recursive' |
Static Protected Attributes | |
static | $_fields |
This class models hierarchical groupings of paths.
The paths are files affected by merge or copy pull operations. It is desirable to group these files under friendly labels to assist users in selecting which files to include in a pull operation (or to see which files are affected).
One of the other features of this model is to provide control over how files in each path group are counted. In some cases multiple files are stored to represent one logical entry. This allows us to adjust the count to better match the user's expectations.
Site_Model_PullPathGroup::addBasePath | ( | $ | basePath | ) |
Add the specified base path to this path group.
Base path(s) can be set to optimize pull operations (as they will be used instead of paths).
string | $basePath | the basepath to add |
{ $basePaths = $this->getBasePaths(); $basePaths[] = $basePath; return $this->_setValue('basePaths', $basePaths); }
Site_Model_PullPathGroup::addBasePaths | ( | array $ | basePaths | ) |
Add the passed array of base paths to this path group.
Base path(s) can be set to optimize pull operations (as they will be used instead of paths).
array | $basePaths | the basepaths to add |
{ foreach ($basePaths as $path) { $this->addBasePath($path); } return $this; }
Site_Model_PullPathGroup::addPath | ( | $ | path | ) |
Add a path to this path group.
The path must be an array of information about the path (containing at least a depotFile) or a model. If an array is given it will be normalized to a model.
array | P4Cms_Model | $path | the path array or model to add. |
{ if (!is_array($path) && !$path instanceof P4Cms_Model) { throw new InvalidArgumentArgument("Cannot set path. Path must be an array or model"); } if (is_array($path)) { $path = new P4Cms_Model($path); } $paths = $this->getPaths(); $paths[] = $path; return $this; }
Site_Model_PullPathGroup::addSubGroup | ( | $ | group | ) |
Add a sub-group to this path group.
The sub-group must be an array of information about the group or pull path group model. If an array is given it will be normalized to a model.
This method will set the parent of the given sub-group to be this group.
If the sub-group is passed as an array with a 'inheritPaths' property any matching paths will automatically move from this group (or its parents) to the new sub-group.
array | Site_Model_PullPathGroup | $group | the group array or model to add. |
{ if (!is_array($group) && !$group instanceof Site_Model_PullPathGroup) { throw new InvalidArgumentException( "Cannot add sub-group. Group must be a array or path group object." ); } $inheritPaths = array(); if (is_array($group)) { if (isset($group['inheritPaths'])) { $inheritPaths = $group['inheritPaths']; unset($group['inheritPaths']); } $group = new Site_Model_PullPathGroup($group); } // ensure the sub-group has a link back to this (its parent) $group->setParent($this); $group->inheritPaths($inheritPaths); $groups = $this->getSubGroups(); $groups[] = $group; return $this; }
static Site_Model_PullPathGroup::fetchRecords | ( | array $ | ids, |
$ | class, | ||
P4Cms_Site $ | source, | ||
P4Cms_Site $ | target | ||
) | [static] |
Helper function to fetch records from either the source or the target branch as necessary.
First attempts to fetch from the source branch and falls back to the target branch if any of the identified records could not be found in the source.
When doing a 'copy' style of pull, we can get into a situation where items that only exist in the target are opened for delete. Naturally, these records can't be fetched from the source, so we fetch them from the target branch instead.
If a given id cannot be found in either the source or the target branch it will not be included in the result.
array | $ids | a list of ids to fetch |
string | $class | the type of record to fetch. |
P4Cms_Site | $source | the source site/branch to fetch from. |
P4Cms_Site | $target | the target site/branch to fallback to. |
{ if (!class_exists($class) || (!is_subclass_of($class, 'P4Cms_Record') && $class !== 'P4Cms_Record')) { throw new InvalidArgumentException("Cannot fetch entries. Invalid class type specified."); } // nothing to do if no ids given. if (empty($ids)) { return new P4Cms_Model_Iterator; } // first attempt to fetch from the source branch. $entries = $class::fetchAll( array( 'ids' => $ids, 'includeDeleted' => true ), $source->getStorageAdapter() ); // if we got everything, all done! $missing = array_diff($ids, $entries->invoke('getId')); if (!$missing) { return $entries; } // try to fetch missing records from the target branch. return $entries->merge( $class::fetchAll( array( 'ids' => $missing, 'includeDeleted' => true ), $target->getStorageAdapter() ) ); }
Site_Model_PullPathGroup::findById | ( | $ | id, |
$ | group = null |
||
) |
Find a group under this group (includes this group) with the given id.
If no matching group can be found, returns false.
string | $id | the id of the group to look for. |
Site_Model_PullPathGroup | null | $group | used for recursion. |
{ $group = $group ?: $this; // check for immediate match. if ($group->getId() === $id) { return $group; } // check for recursive (sub-group) match. foreach ($group->getSubGroups() as $subGroup) { $found = $this->findById($id, $subGroup); if ($found) { return $found; } } return false; }
Site_Model_PullPathGroup::getBasePaths | ( | ) |
Get the base paths for this path group.
{ return $this->_getValue('basePaths'); }
Site_Model_PullPathGroup::getConflictCount | ( | ) |
A convienence method that calls through to getCount returning a shallow count (non-recursive) of conflicts.
{ return $this->getCount(Site_Model_PullPathGroup::ONLY_CONFLICTS); }
Site_Model_PullPathGroup::getCount | ( | $ | options = null | ) |
Get the count of paths in this path group.
This will execute the count callback and use its result if one is set.
string | array | null | $options | options to influence the result: ONLY_CONFLICTS - if passed, only conflicting paths are counted RECURSIVE - if passed, count of all sub groups will be included |
{ $options = (array) $options; $onlyConflicts = in_array(static::ONLY_CONFLICTS, $options) ? static::ONLY_CONFLICTS : null; $computed = $this->getPaths($onlyConflicts)->count(); // if a count callback has been set, use it, // passing this and the count we computed above $count = $this->_getValue('count'); if (is_callable($count)) { // just pass the 'conflictsOnly' option to the callback. // we handle recursion ourselves. $computed = call_user_func($count, $this, $computed, (array) $onlyConflicts); } // compute the number of paths recursively if needed. if (in_array(static::RECURSIVE, $options)) { foreach ($this->getSubGroups() as $group) { $computed += $group->getCount($options); } } return $computed; }
Site_Model_PullPathGroup::getCountCallback | ( | ) |
Returns the count callback without actually executing it.
{ return $this->_getValue('count'); }
Site_Model_PullPathGroup::getDetails | ( | $ | options = null | ) |
Provides details about the paths held in this group.
Details are provided as an iterator of Models. The keys/values in the models are intended to represent columns of data. At a minimum a 'label', 'conflict' and 'action' value should be present on each model.
The returned iterator may optionally use a 'columns' property to provide column id's (e.g. label) with custom titles. If no columns property is present the default columns of Label and Action will be used.
If a details callback is present it will be utilized to generate the details. Otherwise, each path will get default details using the depotFile as a label and existing branch action and conflict status.
string | array | null | $options | options to influence the result: ONLY_CONFLICTS - if passed, only conflicting path details are returned RECURSIVE - if passed, details of all sub groups paths will be included |
{ $options = (array) $options; $onlyConflicts = in_array(static::ONLY_CONFLICTS, $options) ? static::ONLY_CONFLICTS : null; $paths = $this->getPaths($onlyConflicts); $callback = $this->_getValue('details'); $details = new P4Cms_Model_Iterator; if (is_callable($callback) && $paths->count()) { $details = $callback($paths) ?: new P4Cms_Model_Iterator; foreach ($details as $detail) { if (!$detail->hasField("type")) { $detail->setValue('type', $this->getLabel()); } } } else if ($paths->count()) { foreach ($paths as $path) { $details[] = new P4Cms_Model( array( 'action' => $path->action, 'conflict' => $path->conflict, 'type' => $this->getLabel(), 'label' => preg_replace('#^//[^/]+/[^/]+/#', '', $path->depotFile) ) ); } $details->setProperty('columns', array('label' => 'File', 'action' => 'Action')); } $columns = $details->hasProperty('columns') ? $details->getProperty('columns') : array(); if (in_array(static::RECURSIVE, (array) $options)) { foreach ($this->getSubGroups() as $group) { $subDetails = $group->getDetails($options); if ($subDetails->count()) { if ($subDetails->hasProperty('columns')) { $columns += $subDetails->getProperty('columns'); } $details->merge($subDetails); } } } // ensure our details iterator has the aggregated columns // fall back to defaults of Label and Action if none found. $details->setProperty( 'columns', $columns ?: array('label' => 'Label', 'action' => 'Action') ); return $details; }
Site_Model_PullPathGroup::getDetailsCallback | ( | ) |
Returns the details callback without actually executing it.
{ return $this->_getValue('details'); }
Site_Model_PullPathGroup::getId | ( | ) |
Get an identifier for this group.
If an explicit id is set, it will be returned. Otherwise, we generate an identifier for this path group based on its label and the labels of its parents (e.g. 'configuration/permissions')
Note: this identifier is not guaranteed to be unique!
Reimplemented from P4Cms_Model.
{ // if an explicit id was set, use it. if (parent::getId()) { return parent::getId(); } $ids = array(); $filter = new P4Cms_Filter_TitleToId; $parent = $this; while ($parent) { $ids[] = $filter->filter($parent->getLabel()); $parent = $parent->getParent(); } return trim(implode('/', array_reverse($ids)), '/'); }
Site_Model_PullPathGroup::getIncludePaths | ( | ) |
Get a list of paths in this group to use in a pull operation.
If base path(s) are set, these will be returned (as an optimization). Otherwise, a list of depotFiles will be taken from getPaths and returned.
{ return $this->getBasePaths() ?: $this->getPaths()->invoke('getValue', array('depotFile')); }
Site_Model_PullPathGroup::getLabel | ( | ) |
Get the label for this path group.
{ return $this->_getValue('label'); }
Site_Model_PullPathGroup::getParent | ( | ) |
Get the parent group for this path group (if one is set)
{ return $this->_getValue('parent'); }
Site_Model_PullPathGroup::getPaths | ( | $ | options = null | ) |
Get the paths in this path group (not recursive).
string | array | null | $options | options to influence the result: ONLY_CONFLICTS - if passed, only conflicting paths are returned RECURSIVE - if passed, paths of all sub groups will be included |
{ // initialize paths to an iterator if necessary. $paths = $this->_getValue('paths') ?: new P4Cms_Model_Iterator; $this->_setValue('paths', $paths); if (in_array(static::ONLY_CONFLICTS, (array) $options)) { $paths = $paths->filter('conflict', true, array(P4Cms_Model_Iterator::FILTER_COPY)); } if (in_array(static::RECURSIVE, (array) $options)) { foreach ($this->getSubGroups() as $group) { $paths->merge($group->getPaths($options)); } } return $paths; }
Site_Model_PullPathGroup::getSubGroup | ( | $ | label | ) |
Try to find a sub-group with the given label under this group.
string | $label | the name of the sub-group to look for. |
{ return $this->getSubGroups() ->filter('label', $label, array(P4Cms_Model_Iterator::FILTER_COPY)) ->first(); }
Site_Model_PullPathGroup::getSubGroups | ( | ) |
Get the immediate child groups of this group (not recursive).
{ // initialize sub-groups to an iterator if necessary. $groups = $this->_getValue('subGroups') ?: new P4Cms_Model_Iterator; $this->_setValue('subGroups', $groups); return $groups; }
Site_Model_PullPathGroup::inheritPaths | ( | $ | paths | ) |
Scans up through parent objects and brings over any paths matching the passed filespec(s).
If the passed filespec ends in the wildcard '...' anything starting with the value will be considered a match.
If a path model is passed its 'depotFile' value will be used as the search value and any matching paths brought over.
array | Iterator | string | P4Cms_Model | $paths | one or more paths to inherit |
{ // we need to selectively 'arrayize' input if only a single // path was passed. blindly casting to array would 'toArray' // P4Cms_Model's causing a later invalid argument exception. if (!$paths instanceof Iterator && !is_array($paths)) { $paths = array($paths); } // if paths are in an iterator the cursor may become corrupt // if we take a path from a parent with a shared reference. // swap it over to being an array of paths for safety. if ($paths instanceof Iterator) { $paths = iterator_to_array($paths); } foreach ($paths as $path) { // normalize to a string if ($path instanceof P4Cms_Model && $path->depotFile) { $path = $path->depotFile; } if (!$path || !is_string($path)) { throw new InvalidArgumentException( 'Inherit path must be a non empty string or path model.' ); } // our 'needle' starts out as the full path value requiring // an exact match. if the path ends in '...' we switch to a // starts with match and strip the trailing wildcard. $needle = $path; $mode = 'exact'; if (substr($needle, -3) == '...') { $mode = 'starts'; $needle = substr($needle, 0, -3); } $parent = $this->getParent(); while ($parent) { $paths = $parent->getPaths(); foreach ($paths->toArray(true) as $key => $path) { // if we have an acceptable match, add the path to our group // and remove it from the parent that originally had it. if (($mode == 'exact' && $needle === $path->getValue('depotFile')) || ($mode == 'starts' && strpos($path->getValue('depotFile'), $needle) === 0) ) { $this->addPath($path); unset($paths[$key]); } } // up the tree. $parent = $parent->getParent(); } } }
static Site_Model_PullPathGroup::pathsByRecordId | ( | P4Cms_Model_Iterator $ | paths, |
$ | class, | ||
P4Cms_Record_Adapter $ | adapter = null |
||
) | [static] |
Helper function to re-index a given paths iterator by record id.
Any paths that are not of the given record class type (ie. not under the appropriate storage path) will be excluded.
P4Cms_Model_Iterator | $paths | an iterator of paths to re-index. |
string | $class | the type of record to use to convert paths to ids. |
P4Cms_Record_Adapter | null | $adapter | optional - a specific storage adapter to use. |
{ $byId = new P4Cms_Model_Iterator; foreach ($paths as $path) { try { $id = $class::depotFileToId($path->depotFile, $adapter); $byId[$id] = $path; } catch (P4Cms_Record_Exception $e) { // skip entries whose id can't be determined (assumed to be of a different type). } } return $byId; }
Site_Model_PullPathGroup::setBasePaths | ( | $ | basePaths | ) |
Set the base path(s) for this path group.
Base path(s) can be set to optimize pull operations (as they will be used instead of paths).
array | string | null | $basePaths | the base-path(s) for files in this group. |
{ $this->_setValue('basePaths', array()); $basePaths = (array) $basePaths; foreach ($basePaths as $basePath) { $this->addBasePath($basePath); } return $this; }
Site_Model_PullPathGroup::setCount | ( | $ | count | ) |
Control the count of paths in this path group.
By default simply returns a count of all paths and paths in sub-groups (recursively). Can be set to null for the default behaviour or a callback that may use whatever logic is desired to return a count.
null | callable | $count | null to clear the count (fallback to default), or a callback that returns the count (passed $this, the computed count, $recursive and $onlyConflicts) |
{ if (!is_null($count) && !is_callable($count)) { throw InvalidArgumentException( "Cannot set count. Given count is not a valid type." ); } return $this->_setValue('count', $count); }
Site_Model_PullPathGroup::setDetails | ( | $ | callback | ) |
Set a callback which will provide details about the paths held in this group.
The callback will be passed an iterator of Paths (output of getPaths) and is expected to return an iterator of Models. The keys/values in the models will inform the columns used to display your data. At a minimum a 'label', 'conflict' and 'action' value should be present.
If no callback is set the default details will be returned. See getDetails for more information.
callable | null | $callback | the callback to use |
InvalidArgumentException | if an invalid type is passed |
{ if (!is_callable($callback) && !is_null($callback)) { throw new InvalidArgumentException( 'Details Callback must be callable or null' ); } return $this->_setValue('details', $callback); }
Site_Model_PullPathGroup::setLabel | ( | $ | label | ) |
Set the label for this path group.
string | null | $label | the human-friendly label for this group. |
{ return $this->_setValue('label', $label); }
Site_Model_PullPathGroup::setParent | ( | Site_Model_PullPathGroup $ | parent = null | ) |
Set the parent group for this path group.
This gives sub-groups access to their parent. If this group has basepaths set on it, specifiying a parent will trigger moving any matching paths from parent group(s).
Site_Model_PullPathGroup | null | $parent | parent group or null. |
{ $this->_setValue('parent', $parent); if ($parent) { $this->setBasePaths($this->getBasePaths()); } return $this; }
Site_Model_PullPathGroup::setPaths | ( | P4Cms_Model_Iterator $ | paths = null | ) |
Set the paths in this path group.
P4Cms_Model_Iterator | null | $paths | the list of paths to put in this group (null to clear). |
{ $paths = $paths ?: new P4Cms_Model_Iterator; return $this->_setValue('paths', $paths); }
Site_Model_PullPathGroup::setSubGroups | ( | P4Cms_Model_Iterator $ | groups = null | ) |
Set the sub-groups in this path group.
P4Cms_Model_Iterator | null | $groups | the sub-groups to put in this group (null to clear). |
{ $groups = $groups ?: new P4Cms_Model_Iterator; foreach ($groups as $group) { $this->addSubGroup($group); } return $this->_setValue('subGroups', $groups); }
Site_Model_PullPathGroup::$_fields [static, protected] |
Reimplemented from P4Cms_Model.
const Site_Model_PullPathGroup::ONLY_CONFLICTS = 'onlyConflicts' |
const Site_Model_PullPathGroup::RECURSIVE = 'recursive' |