/ */ class P4_Counter extends P4_ConnectedAbstract { const FETCH_MAXIMUM = 'maximum'; protected $_id = null; /** * Get the id of this counter. * * @return null|string the id of this entry. */ public function getId() { return $this->_id; } /** * Set the id of this counter. Id must be in a valid format or null. * * @param null|string $id the id of this entry - pass null to clear. * @return P4_Counter provides a fluent interface * @throws InvalidArgumentException if id does not pass validation. */ public function setId($id) { if ($id !== null && !static::_isValidId($id)) { throw new InvalidArgumentException("Cannot set id. Id is invalid."); } $this->_id = $id; return $this; } /** * Determine if the given counter id exists. * * @param string $id the id to check for. * @param P4_Connection_Interface $connection optional - a specific connection to use. * @return bool true if the given id matches an existing counter. */ public static function exists($id, P4_Connection_Interface $connection = null) { // check id for valid format if (!static::_isValidId($id)) { return false; } $counters = static::fetchAll(array(), $connection); return in_array($id, $counters->invoke('getId')); } /** * Get the requested counter from Perforce. * * @param string $id the id of the counter to fetch. * @param P4_Connection_Interface $connection optional - a specific connection to use. * @return P4_Counter instace of the requested counter. * @throws InvalidArgumentException if invalid id is given. */ public static function fetch($id, P4_Connection_Interface $connection = null) { // ensure a valid id is provided. if (!static::_isValidId($id)) { throw new InvalidArgumentException("Must supply a valid id to fetch."); } // if no connection given, use default. $connection = $connection ?: static::getDefaultConnection(); // ensure id exists. if (!static::exists($id, $connection)) { throw new P4_Exception( "Cannot fetch counter. Counter does not exist." ); } // construct counter instance. $counter = new static($connection); $counter->setId($id); return $counter; } /** * Get all Counters from Perforce. * * @param array $options optional - array of options to augment fetch behavior. * supported options are: * FETCH_MAXIMUM - set to integer value to limit to the first * 'max' number of entries. * *Note: Limits imposed client side. * * @param P4_Connection_Interface $connection optional - a specific connection to use. * @return P4_Iterator all counters matching passed option(s). */ public static function fetchAll($options = array(), P4_Connection_Interface $connection = null) { // if no connection given, use default. $connection = $connection ?: static::getDefaultConnection(); // fetch all counters. $result = $connection->run('counters'); // convert result data to counter objects. $counters = new P4_Iterator; $max = array_key_exists(static::FETCH_MAXIMUM, $options) ? (int)$options[static::FETCH_MAXIMUM] : 0; foreach ($result->getData() as $data) { // populate a counter and add it to the iterator $counter = new static($connection); $counter->setId($data['counter']); $counters[] = $counter; // stop looping if we reach 'FETCH_MAXIMUM' if ($max > 0 && count($counters) == $max) { break; } } return $counters; } /** * Delete this counter entry. * * @param bool $force optional - force delete the counter. * @return P4_Counter provides a fluent interface * @throws P4_Exception if no id has been set. */ public function delete($force = false) { $id = $this->getId(); if ($id === null) { throw new P4_Exception("Cannot delete. No id has been set."); } // ensure id exists. $connection = $this->getConnection(); if (!static::exists($id, $connection)) { throw new P4_Exception( "Cannot delete counter. Counter does not exist." ); } // setup counter command args. $params = $force ? array('-f') : array(); $params[] = "-d"; $params[] = $id; $result = $connection->run('counter', $params); return $this; } /** * Get counter's value. There is no caching, the value is always read from * perforce. * * @return mixed the value of the counter. */ public function getValue() { $id = $this->getId(); $connection = $this->getConnection(); // if the ID is not set or the ID doesn't exist in perforce, return null if ($id === null || !static::exists($id, $connection)) { return null; } $result = $connection->run('counter', $id); $data = $result->getData(); return $data[0]['value']; } /** * Set counters value. The value will be immediately written to perforce. * * @param mixed $value the value to set in the counter. * @param bool $force optional - force set the counter. * @return P4_Counter provides a fluent interface * @throws P4_Exception if no Id has been set */ public function setValue($value, $force = false) { $id = $this->getId(); if ($id === null) { throw new P4_Exception("Cannot set value. No id has been set."); } // setup counter command args. $params = $force ? array('-f') : array(); $params[] = $id; $params[] = $value; $this->getConnection()->run('counter', $params); return $this; } /** * Increment counters value by 1. If the counter doesn't exist it will be * created and assigned the value 1. * The update is carried out atomically by the server. * * @return string The counters new value * @throws P4_Exception If the current value is non-numeric */ public function increment() { $id = $this->getId(); if ($id === null) { throw new P4_Exception("Cannot increment value. No id has been set."); } $result = $this->getConnection()->run('counter', array('-i', $id)); $data = $result->getData(); return $data[0]['value']; } /** * Check if the given id is in a valid format. * * @param string $id the id to check * @return bool true if id is valid, false otherwise */ protected static function _isValidId($id) { $validator = new P4_Validate_CounterName; return $validator->isValid($id); } }