Perforce Chronicle 2012.2/486814
API Documentation

P4Cms_Record_Query Class Reference

Provides a container for query options suitable for passing to fetchAll. More...

List of all members.

Public Member Functions

 __construct ($options=array())
 Constructor that accepts an array of query options.
 addFilter (P4Cms_Record_Filter $filter)
 Add a filter to this query.
 addId ($id)
 Add a single ID to the list of IDs to be used to fetch records.
 addIds ($ids)
 Add IDs to the list of IDs to be used to fetch records.
 addPath ($path, $intersect=false)
 Add a single path to the list of paths to be used to fetch records.
 addPaths ($paths=array(), $intersect=false)
 Add paths to the list of paths to be used to fetch records.
 getFilter ()
 Retrieve the current filter expression.
 getIds ()
 Retrieve the IDs to be used to fetch records.
 getIncludeDeleted ()
 Retrieve the flag indicating whether deleted files will be included in results.
 getLimitFields ()
 Retrieve the list of record fields to return in server responses.
 getMaxDepth ()
 Retrieve the maximum path depth of records to include in results.
 getMaxRows ()
 Retrieve the maximum number of records to include in results.
 getPaths ()
 Retrieve the paths to be used to fetch records.
 getRecordClass ()
 Get the record class to use when preparing the query.
 getReverseOrder ()
 Retrieve the current reverse order flag setting.
 getSortBy ()
 Get the current sort field.
 getStartRow ()
 Return the starting row for matching records.
 removeId ($id)
 Remove a single ID from the list to be used to fetch records.
 removeIds ($ids=array())
 Remove IDs from the list to be used to fetch records.
 removePath ($path)
 Remove a single path from the list to be used to fetch records.
 removePaths ($paths=array())
 Remove paths from the list to be used to fetch records.
 reset ()
 Reset the current query object to its default state.
 setFilter ($filter=null)
 Set the "filter expression" to limit the returned set of records.
 setIds ($ids=null)
 Set the list of IDs to be used to fetch records.
 setIncludeDeleted ($include=false)
 Set the flag indicating whether deleted files will be included in results.
 setLimitFields ($fields=array())
 Set the list of fields to include in the response from the server.
 setMaxDepth ($depth=null)
 Set the maximum path depth for records to be included in results.
 setMaxRows ($max=null)
 Set to limit the number of matching records returned, or null to return all matching records.
 setPaths ($paths=null)
 Set the list of paths to be used to fetch records.
 setRecordClass ($class)
 Set the record class to use when preparing the query for execution.
 setReverseOrder ($reverse=false)
 Set the flag indicating whether the results will be returned in reverse order.
 setSortBy ($sortBy=null, $options=null)
 Set the record field which will be used to sort results.
 setStartRow ($row=null)
 Set the starting row to return from matching records, or null to return all matching records.
 toArray ()
 Provide all of the current options as an array.
 toFileQuery ($recordClass=null, P4Cms_Record_Adapter $adapter=null)
 Compose a P4_File_Query to be used in P4_File::fetchAll() calls.

Static Public Member Functions

static create ($options=array())
 Creates and returns a new Query class.

Public Attributes

const QUERY_IDS = 'ids'
const QUERY_INCLUDE_DELETED = 'includeDeleted'
const QUERY_LIMIT_FIELDS = 'limitFields'
const QUERY_MAX_DEPTH = 'maxDepth'
const QUERY_MAX_ROWS = 'maxRows'
const QUERY_PATHS = 'paths'
const QUERY_RECORD_CLASS = 'recordClass'
const RECORD_BASE_CLASS = 'P4Cms_Record'
const SORT_ASCENDING = 'a'
const SORT_DATE = '#REdate'
const SORT_DESCENDING = 'd'
const SORT_FILE_SIZE = '#REsize'
const SORT_FILE_TYPE = '#NEtype'
const SORT_HAVE_REV = '#NEhrev'
const SORT_HEAD_REV = '#RErev'

Protected Member Functions

 _validateRecordClass ($class)
 Verify that the given class name is a valid record class.

Protected Attributes

 $_options = null
 $_query = null
 $_recordClass = null

Detailed Description

Provides a container for query options suitable for passing to fetchAll.

Copyright:
2011-2012 Perforce Software. All rights reserved
License:
Please see LICENSE.txt in top-level folder of this distribution.
Version:
2012.2/486814

Constructor & Destructor Documentation

P4Cms_Record_Query::__construct ( options = array())

Constructor that accepts an array of query options.

Parameters:
array$optionsOptional array of options to populate
    {
        $this->reset();

        // some options that are valid for both this and file query as well,
        // may not be directly passed to the file query constructor
        $fileQueryOptions = array_diff($options, array(static::QUERY_LIMIT_FIELDS));
        $this->_query     = new P4_File_Query($fileQueryOptions);

        if (isset($options) and is_array($options)) {
            foreach ($options as $key => $value) {
                if (array_key_exists($key, $this->_options)) {
                    $method = 'set'. ucfirst($key);
                    $this->$method($value);
                }
            }
        }
    }

Member Function Documentation

P4Cms_Record_Query::_validateRecordClass ( class) [protected]

Verify that the given class name is a valid record class.

Parameters:
string$classthe class name to verify.
Exceptions:
InvalidArgumentExceptionif the class does not exist or is not a record.
    {
        $base = static::RECORD_BASE_CLASS;
        
        // ensure class exists and is a valid record class.
        if (!class_exists($class) 
            || (!is_subclass_of($class, $base) && $class !== $base)
        ) {
            throw new InvalidArgumentException("Invalid record class given.");
        }
    }
P4Cms_Record_Query::addFilter ( P4Cms_Record_Filter filter)

Add a filter to this query.

Parameters:
P4Cms_Record_Filter$filterthe filter to add.
Returns:
P4Cms_Record_Query provides fluent interface.
    {
        $currentFilter = $this->getFilter();
        if (!$currentFilter) {
            return $this->setFilter($filter);
        }

        $currentFilter->addSubFilter($filter);
        return $this;
    }
P4Cms_Record_Query::addId ( id)

Add a single ID to the list of IDs to be used to fetch records.

Parameters:
string | int$idAn ID to be added.
Returns:
P4Cms_Record_Query provide a fluent interface.
    {
        if (!is_string($id) && !is_int($id)) {
            throw new InvalidArgumentException('Cannot add ID; argument must be a string or int.');
        }

        return $this->addIds(array($id));
    }
P4Cms_Record_Query::addIds ( ids)

Add IDs to the list of IDs to be used to fetch records.

Parameters:
array$idsset of string or int IDs to be added.
Returns:
P4Cms_Record_Query provide a fluent interface.
    {
        if (!is_array($ids)) {
            throw new InvalidArgumentException('Cannot add IDs; argument must be an array.');
        }

        $this->setIds(array_merge($this->getIds() ?: array(), $ids));
        
        return $this;
    }
P4Cms_Record_Query::addPath ( path,
intersect = false 
)

Add a single path to the list of paths to be used to fetch records.

Parameters:
string$pathA path to be added.
bool$intersectoptional - defaults to false - intersect with existing paths.
Returns:
P4Cms_Record_Query provide a fluent interface.
    {
        if (!isset($path) or !is_string($path)) {
            throw new InvalidArgumentException('Cannot add path; argument must be a string.');
        }

        return $this->addPaths(array($path), $intersect);
    }
P4Cms_Record_Query::addPaths ( paths = array(),
intersect = false 
)

Add paths to the list of paths to be used to fetch records.

Parameters:
array$pathsset of paths to be added.
bool$intersectoptional - defaults to false - intersect with existing paths.
Returns:
P4Cms_Record_Query provide a fluent interface.
    {
        if (!isset($paths) or !is_array($paths)) {
            throw new InvalidArgumentException('Cannot add paths; argument must be an array.');
        }

        // if paths are currently null, no need to combine.
        if ($this->getPaths() === null) {
            $this->setPaths($paths);
            return $this;
        }

        // combine arrays appropriately
        if ($intersect) {
            $this->setPaths(array_intersect($this->getPaths(), $paths));
        } else {
            $this->setPaths(array_merge($this->getPaths(), $paths));
        }

        return $this;
    }
static P4Cms_Record_Query::create ( options = array()) [static]

Creates and returns a new Query class.

Useful for working around PHP's lack of new chaining.

Parameters:
array$optionsOptional array of options to populate for new Query class
Returns:
P4Cms_Record_Query
    {
        return new static($options);
    }
P4Cms_Record_Query::getFilter ( )

Retrieve the current filter expression.

Null means no filtering will take place.

Returns:
P4Cms_Record_Filter|null The current filter object or null.
    {
        return $this->_query->getFilter();
    }
P4Cms_Record_Query::getIds ( )

Retrieve the IDs to be used to fetch records.

Returns:
array|null The list of ids to be used to fetch records.
    {
        return $this->_options[static::QUERY_IDS];
    }
P4Cms_Record_Query::getIncludeDeleted ( )

Retrieve the flag indicating whether deleted files will be included in results.

True means deleted files will be included.

Returns:
boolean True indicates deleted files included.
    {
        return $this->_options[static::QUERY_INCLUDE_DELETED];
    }
P4Cms_Record_Query::getLimitFields ( )

Retrieve the list of record fields to return in server responses.

Null means all fields will be returned.

Returns:
array|null The current list of record fields.
    {
        return $this->_options[static::QUERY_LIMIT_FIELDS];
    }
P4Cms_Record_Query::getMaxDepth ( )

Retrieve the maximum path depth of records to include in results.

0 means include records only at the current depth. Null means unlimited.

Returns:
integer The maximum depth of records to include in results.
    {
        return $this->_options[static::QUERY_MAX_DEPTH];
    }
P4Cms_Record_Query::getMaxRows ( )

Retrieve the maximum number of records to include in results.

0 or null means unlimited.

Returns:
integer The maximum number of records to include in results.
    {
        return $this->_query->getMaxFiles();
    }
P4Cms_Record_Query::getPaths ( )

Retrieve the paths to be used to fetch records.

Returns:
array|null The list of paths to be used to fetch records.
    {
        return $this->_query->getFilespecs();
    }
P4Cms_Record_Query::getRecordClass ( )

Get the record class to use when preparing the query.

If no record class has been set, returns the base record class.

Returns:
string the name of the record class to use.
    {
        return $this->_recordClass ?: static::RECORD_BASE_CLASS;
    }
P4Cms_Record_Query::getReverseOrder ( )

Retrieve the current reverse order flag setting.

True means that the sort order will be reversed.

Returns:
boolean true if the sort order will be reversed.
    {
        return $this->_query->getReverseOrder();
    }
P4Cms_Record_Query::getSortBy ( )

Get the current sort field.

Null means default sorting will take place.

Returns:
string The current sort field, or null if not set.
    {
        return $this->_query->getSortBy();
    }
P4Cms_Record_Query::getStartRow ( )

Return the starting row for matching records.

Null means all matching records will be returned.

Returns:
int|null The starting row.
    {
        return $this->_query->getStartRow();
    }
P4Cms_Record_Query::removeId ( id)

Remove a single ID from the list to be used to fetch records.

Parameters:
string | int$idID to remove from list
Returns:
P4Cms_Record_Query provide a fluent interface.
    {
        if (!is_string($id) && !is_int($id)) {
            throw new InvalidArgumentException('Cannot remove id; argument must be a string or int.');
        }

        return $this->removeIds(array($id));
    }
P4Cms_Record_Query::removeIds ( ids = array())

Remove IDs from the list to be used to fetch records.

Parameters:
array$idsThe IDs to be removed.
Returns:
P4Cms_Record_Query provide a fluent interface.
    {
        if (!is_array($ids)) {
            throw new InvalidArgumentException('Cannot remove IDs; argument must be an array.');
        }

        $currentIds = $this->getIds() ?: array();
        foreach ($ids as $id) {
            $index = array_search($id, $currentIds);
            if ($index !== false) {
                unset($currentIds[$index]);
            }
        }
        $this->setIds($currentIds);

        return $this;
    }
P4Cms_Record_Query::removePath ( path)

Remove a single path from the list to be used to fetch records.

Parameters:
string$pathpath to remove from list
Returns:
P4Cms_Record_Query provide a fluent interface.
    {
        if (!is_string($path)) {
            throw new InvalidArgumentException('Cannot remove path; argument must be a string.');
        }

        return $this->removePaths(array($path));
    }
P4Cms_Record_Query::removePaths ( paths = array())

Remove paths from the list to be used to fetch records.

Parameters:
array$pathsThe paths to be removed.
Returns:
P4Cms_Record_Query provide a fluent interface.
    {
        if (!isset($paths) or !is_array($paths)) {
            throw new InvalidArgumentException('Cannot remove paths; argument must be an array.');
        }

        $currentPaths = $this->getPaths() ?: array();
        foreach ($paths as $path) {
            $index = array_search($path, $currentPaths);
            if ($index !== false) {
                array_splice($currentPaths, $index, 1);
            }
        }
        $this->setPaths($currentPaths);

        return $this;
    }
P4Cms_Record_Query::reset ( )

Reset the current query object to its default state.

Returns:
P4Cms_Record_Query provide a fluent interface.
    {
        $this->_options = array(
            static::QUERY_INCLUDE_DELETED   => false,
            static::QUERY_RECORD_CLASS      => null,
            static::QUERY_LIMIT_FIELDS      => null,
            static::QUERY_MAX_DEPTH         => null,
            static::QUERY_MAX_ROWS          => null,
            static::QUERY_PATHS             => null,
            static::QUERY_IDS               => null
        );
        $this->_query = new P4_File_Query;
        return $this;
    }
P4Cms_Record_Query::setFilter ( filter = null)

Set the "filter expression" to limit the returned set of records.

See 'p4 help fstat' and 'p4 help jobview' for more information on the filter format. Accepts a P4Cms_Record_Filter or string for input, or null to remove any filter.

Parameters:
string | array | P4Cms_Record_Filter | null$filterThe desired filter expression.
Returns:
P4Cms_Record_Query provide a fluent interface.
    {
        if (is_string($filter) || is_array($filter)) {
            $filter = new P4Cms_Record_Filter($filter);
        }
        
        if (!$filter instanceof P4Cms_Record_Filter && !is_null($filter)) {
            throw new InvalidArgumentException(
                'Cannot set filter; argument must be a P4Cms_Record_Filter, an array, a string, or null.'
            );
        }
        $this->_query->setFilter($filter);
        return $this;
    }
P4Cms_Record_Query::setIds ( ids = null)

Set the list of IDs to be used to fetch records.

Parameters:
array | null$idsThe IDs to be used to fetch records.
Returns:
P4Cms_Record_Query provide a fluent interface.
    {
        if (!is_array($ids) && !is_null($ids)) {
            throw new InvalidArgumentException("IDs should be an array or null");
        }

        $this->_options[static::QUERY_IDS] = $ids;
        return $this;
    }
P4Cms_Record_Query::setIncludeDeleted ( include = false)

Set the flag indicating whether deleted files will be included in results.

True means deleted files should be included.

Parameters:
boolean$includeFlag to include deleted files.
Returns:
P4Cms_Record_Query provide a fluent interface.
    {
        $this->_options[static::QUERY_INCLUDE_DELETED] = (bool) $include;
        return $this;
    }
P4Cms_Record_Query::setLimitFields ( fields = array())

Set the list of fields to include in the response from the server.

Record limitFields are converted to the file fields (i.e. file attributes) when this query is converted to the file query as we need to know the record class to determine id and file content fields that have to be skipped.

Parameters:
string | array | null$fieldsThe list of desired fields. Supply a string to specify one field, or supply a null to retrieve all fields.
Returns:
P4Cms_Record_Query provide a fluent interface.
    {
        $this->_options[static::QUERY_LIMIT_FIELDS] = $fields;
        return $this;
    }
P4Cms_Record_Query::setMaxDepth ( depth = null)

Set the maximum path depth for records to be included in results.

0 means include records only at the current depth. Null means unlimited.

Parameters:
integer$depthThe maximum depth of records to include in results.
Returns:
P4Cms_Record_Query provide a fluent interface.
    {
        // accept numeric string values, for convenience.
        if (is_string($depth)) {
            $depth = (int) $depth;
        }
        if (isset($depth) and (!is_integer($depth) or $depth < 0)) {
            throw new InvalidArgumentException(
                'Cannot set maximum depth; argument must be a non-negative integer or null.'
            );
        }

        $this->_options[static::QUERY_MAX_DEPTH] = $depth;
        return $this;
    }
P4Cms_Record_Query::setMaxRows ( max = null)

Set to limit the number of matching records returned, or null to return all matching records.

Parameters:
int | null$maxThe maximum number of records to return.
Returns:
P4_File_Query provide a fluent interface.
    {
        $this->_options[static::QUERY_MAX_ROWS] = $max;
        $this->_query->setMaxFiles($max);
        return $this;
    }
P4Cms_Record_Query::setPaths ( paths = null)

Set the list of paths to be used to fetch records.

Parameters:
array | null$pathsThe paths to be used to fetch records.
Returns:
P4Cms_Record_Query provide a fluent interface.
    {
        $this->_query->setFilespecs($paths);
        $this->_options[static::QUERY_PATHS] = $paths;
        return $this;
    }
P4Cms_Record_Query::setRecordClass ( class)

Set the record class to use when preparing the query for execution.

If no record class is set uses the base record class.

Parameters:
object | string | null$classinstance or name of a record class - null to clear.
Returns:
P4Cms_Record_Query provides fluent interface.
Exceptions:
InvalidArgumentExceptionif the given class is not a valid record class.
    {
        $class = is_object($class) ? get_class($object) : $class;
        
        // only validate if class is not null.
        if ($class) {
            $this->_validateRecordClass($class);
        }

        $this->_recordClass = $class;

        return $this;
    }
P4Cms_Record_Query::setReverseOrder ( reverse = false)

Set the flag indicating whether the results will be returned in reverse order.

Parameters:
boolean$reverseSet to true to reverse sort order.
Returns:
P4Cms_Record_Query provide a fluent interface.
    {
        $this->_query->setReverseOrder($reverse);
        return $this;
    }
P4Cms_Record_Query::setSortBy ( sortBy = null,
options = null 
)

Set the record field which will be used to sort results.

Valid sort fields are: SORT_DATE, SORT_HEAD_REV, SORT_HAVE_REV, SORT_FILE_TYPE, SORT_FILE_SIZE. Specify null to receive records in the default order.

Parameters:
array | string | null$sortByAn array of fields or field => options, a string field, or default null.
array | null$optionsSorting options, only used when sortBy is a string.
Returns:
P4Cms_Record_Query provide a fluent interface.
See also:
P4_File_Query
    {
        $this->_query->setSortBy($sortBy, $options);
        return $this;
    }
P4Cms_Record_Query::setStartRow ( row = null)

Set the starting row to return from matching records, or null to return all matching records.

Parameters:
int | null$rowThe starting row.
Returns:
P4Cms_Record_Query provide a fluent interface.
    {
        $this->_query->setStartRow($row);
        return $this;
    }
P4Cms_Record_Query::toArray ( )

Provide all of the current options as an array.

Returns:
array The current query options as an array.
    {
        $array = $this->_query->toArray();

        // hide filespecs option (superseded by paths)
        unset($array[P4_File_Query::QUERY_FILESPECS]);
        
        // hide max-files option (superseded by max-rows)
        unset($array[P4_File_Query::QUERY_MAX_FILES]);

        return array_merge($array, $this->_options);
    }
P4Cms_Record_Query::toFileQuery ( recordClass = null,
P4Cms_Record_Adapter adapter = null 
)

Compose a P4_File_Query to be used in P4_File::fetchAll() calls.

Parameters:
string$recordClassoptional - a specific record class to influence storage paths.
P4Cms_Record_Adapter$adapteroptional - storage adapter to use.
Returns:
P4_File_Query A query object for use with P4_File::fetchAll()
    {
        // validate record class.
        $recordClass = $recordClass ?: $this->getRecordClass();
        $this->_validateRecordClass($recordClass);

        // if no adapter given, use default.
        $adapter = $adapter ?: $recordClass::getDefaultAdapter();

        // determine location of records in depot.
        $depotStoragePath = $recordClass::getDepotStoragePath($adapter);
        $storagePath      = $recordClass::getStoragePath($adapter);

        // clone the current query options, so that later on we
        // don't have to undo the modifications below.
        $query = clone $this->_query;

        // update the filter to remove deleted records, unless include deleted is true
        if (!$this->getIncludeDeleted()) {
            $filter = "^headAction=...delete";
            $filter = $query->getFilter() !== null && (string) $query->getFilter() !== ''
                ? '('. $query->getFilter() .') & '. $filter
                : $filter;

            $query->setFilter($filter);
        }

        // set limit fields - we have to do it here as we need to know recordClass
        // to ignore id and file content fields
        if ($this->_options[static::QUERY_LIMIT_FIELDS]) {
            // always include depotFile field
            $limitFields = array('depotFile');

            $fields = (array) $this->_options[static::QUERY_LIMIT_FIELDS];
            foreach ($fields as $field) {
                // ignore id and file content fields
                if ($field === $recordClass::getIdField() 
                    || ($recordClass::hasFileContentField() && $field === $recordClass::getFileContentField())
                ) {
                    continue;
                }

                $limitFields[] = 'attr-' . $field;
            }

            $query->setLimitFields($limitFields);
        }

        // modify the filter to limit results by depth, if required
        if ($this->getMaxDepth() !== null) {
            // restrict depth by filtering depot paths deeper than max depth.
            $filter = '^depotFile=' . $depotStoragePath
                    . str_repeat('/*', $this->getMaxDepth() + 1) .'/...';
            $filter = $query->getFilter() !== null
                ? '('. $query->getFilter() . ') & '. $filter
                : $filter;

            $query->setFilter($filter);
        }

        $filespecs = array();

        // collect all paths, prepending storage path
        foreach ($this->getPaths() ?: array() as $path) {
            $filespecs[] = $storagePath . "/" . $path;
        }

        // collect all IDs, translating to filespec
        foreach ($this->getIds() ?: array() as $id) {
            $filespecs[] = $recordClass::idToFilespec($id, $adapter);
        }

        // do any required global touchup
        foreach ($filespecs as &$filespec) {
            if (!P4_File::hasRevspec($filespec)) {
                $filespec .= '#head';
            }
        }

        // four cases for handling path filters:
        //            null - set to entire storage path and append #head to hide pending adds.
        //     empty array - leave empty (no results desired).
        //        one path - simply set the one filespec directly.
        //  multiple paths - put paths in a temp label to limit results.
        if ($this->getPaths() === null && $this->getIds() === null) {
            $query->setFilespecs($storagePath . "/...#head");
        } else {
            switch (count($filespecs)) {
                case 0:
                case 1:
                    $query->setFilespecs($filespecs);
                    break;
                default:
                    $label = P4_Label::makeTemp(
                        array('View' => array($depotStoragePath . '/...')),
                        null,
                        $adapter->getConnection()
                    );
                    $label->tag($filespecs);
                    $query->setFilespecs($storagePath . '/...@' . $label->getId());
            }
        }

        return $query;
    }

Member Data Documentation

P4Cms_Record_Query::$_options = null [protected]
P4Cms_Record_Query::$_query = null [protected]
P4Cms_Record_Query::$_recordClass = null [protected]
const P4Cms_Record_Query::SORT_DATE = '#REdate'

The documentation for this class was generated from the following file: