diff --git a/README.md b/README.md index 3489e0f..7861b22 100644 --- a/README.md +++ b/README.md @@ -7,4 +7,28 @@ Build statuses: - master: [![Build Status](https://travis-ci.org/dcarbone/ugly-queue.svg?branch=master)](https://travis-ci.org/dcarbone/ugly-queue) - 0.3.1: [![Build Status](https://travis-ci.org/dcarbone/ugly-queue.svg?branch=0.3.1)](https://travis-ci.org/dcarbone/ugly-queue) -Documentation and Test suites forthcoming. +## Installation +This library is designed to be installed into your app using [https://getcomposer.org/](Composer). +Simply copy-paste the following line into your `"requires:"` hash: + +```json +"dcarbone/ugly-queue": "0.3.*" +``` + +## Basic Usage +Once installed, you must first initialize an instance of [src/UglyQueueManager.php](UglyQueueManager). +This is done as such: + +```php +$config = array( + 'queue-base-dir' => 'path to where you would like queue files and directories to be stored' +); + +$manager = new UglyQueueManager($config); +``` + +Once initialized, you can start adding queues! + +```php +$manager +``` \ No newline at end of file diff --git a/src/UglyQueue.php b/src/UglyQueue.php index 0337b99..9040803 100644 --- a/src/UglyQueue.php +++ b/src/UglyQueue.php @@ -5,80 +5,82 @@ use DCarbone\Helpers\FileHelper; /** * Class UglyQueue * @package DCarbone - * - * @property string name - * @property string path - * @property bool locked */ class UglyQueue implements \Serializable, \SplSubject, \Countable { - /** @var int */ - public $notifyStatus; - const QUEUE_READONLY = 0; const QUEUE_READWRITE = 1; - /** @var array */ - private $observers = array(); + /** @var int */ + private $_notifyStatus; + + /** @var \SplObserver[] */ + private $_observers = array(); /** @var int */ protected $mode = null; /** @var string */ - protected $_name; + protected $baseDir; /** @var string */ - protected $_path; + protected $name; + + /** @var string */ + protected $path; /** @var bool */ - protected $_locked = false; + protected $locked = false; /** @var resource */ - protected $_tmpHandle; + protected $tmpHandle; + + /** @var string */ + protected $queueFile; + + /** @var string */ + protected $queueTmpFile; + + /** @var string */ + protected $lockFile; /** - * @param string $directoryPath - * @param array $observers - * @throws \RuntimeException - * @throws \InvalidArgumentException - * @return UglyQueue + * @param string $baseDir + * @param string $queueName + * @param \SplObserver[] $observers */ - public static function queueWithDirectoryPathAndObservers($directoryPath, array $observers = array()) + public function __construct($baseDir, $queueName, array $observers = array()) { - if (!is_string($directoryPath)) - throw new \InvalidArgumentException('Argument 1 expected to be string, '.gettype($directoryPath).' seen'); + $this->baseDir = trim($baseDir, "/\\"); + $this->name = $queueName; + $this->_observers = $observers; - if (($directoryPath = trim($directoryPath)) === '') - throw new \InvalidArgumentException('Empty string passed for argument 1'); + $path = sprintf('%s/%s', $baseDir, $queueName); + if (!file_exists($path) && !@mkdir($path)) + throw new \RuntimeException('Unable to initialize queue directory "'.$path.'". Please check permissions.'); - if (file_exists($directoryPath)) + $this->path = $path; + $this->lockFile = sprintf('%s/queue.lock', $this->path); + $this->queueFile = sprintf('%s/queue.txt', $this->path); + $this->queueTmpFile = sprintf('%s/queue.tmp', $this->path); + + $this->_initialize(); + } + + /** + * Initialize queue if needed. + */ + private function _initialize() + { + if (is_readable($this->path) && is_writable($this->path)) + $this->mode = self::QUEUE_READWRITE; + else if (is_readable($this->path)) + $this->mode = self::QUEUE_READONLY; + + if (!file_exists($this->path.'index.html')) { - if (!is_dir($directoryPath)) - throw new \RuntimeException('Argument 1 expected to be path to directory, path to non-directory seen'); - } - else if (!@mkdir($directoryPath)) - { - throw new \RuntimeException('Unable to create queue directory at path: "'.$directoryPath.'".'); - } - - $uglyQueue = new UglyQueue(); - $uglyQueue->observers = $observers; - - $split = preg_split('#[/\\\]+#', $directoryPath); - - $uglyQueue->_name = end($split); - $uglyQueue->_path = rtrim(realpath(implode(DIRECTORY_SEPARATOR, $split)), "/\\").DIRECTORY_SEPARATOR; - - if (is_writable($uglyQueue->_path)) - $uglyQueue->mode = self::QUEUE_READWRITE; - else if (is_readable($uglyQueue->_path)) - $uglyQueue->mode = self::QUEUE_READONLY; - - // Insert "don't look here" index.html file - if (!file_exists($uglyQueue->_path.'index.html')) - { - if ($uglyQueue->mode === self::QUEUE_READONLY) - throw new \RuntimeException('Cannot initialize queue with name "'.$uglyQueue->_name.'", the user lacks permission to create files.'); + if ($this->mode === self::QUEUE_READONLY) + throw new \RuntimeException('Cannot initialize queue with name "'.$this->name.'", the user lacks permission to create files.'); $html = << @@ -90,44 +92,19 @@ class UglyQueue implements \Serializable, \SplSubject, \Countable HTML; - file_put_contents($uglyQueue->_path.'index.html', $html); + file_put_contents($this->path.'index.html', $html); } - if (!file_exists($uglyQueue->_path.'queue.txt')) + if (!file_exists($this->queueFile)) { - if ($uglyQueue->mode === self::QUEUE_READONLY) - throw new \RuntimeException('Cannot initialize queue with name "'.$uglyQueue->_name.'", the user lacks permission to create files.'); + if ($this->mode === self::QUEUE_READONLY) + throw new \RuntimeException('Cannot initialize queue with name "'.$this->name.'", the user lacks permission to create files.'); - file_put_contents($uglyQueue->_path.'queue.txt', ''); + file_put_contents($this->queueFile, ''); } - $uglyQueue->notifyStatus = UglyQueueEnum::QUEUE_INITIALIZED; - $uglyQueue->notify(); - - return $uglyQueue; - } - - /** - * @param string $param - * @return string - * @throws \OutOfBoundsException - */ - public function __get($param) - { - switch($param) - { - case 'name' : - return $this->_name; - - case 'path': - return $this->_path; - - case 'locked': - return $this->_locked; - - default: - throw new \OutOfBoundsException(get_class($this).' does not have a property named "'.$param.'".'); - } + $this->_notifyStatus = UglyQueueEnum::QUEUE_INITIALIZED; + $this->notify(); } /** @@ -137,7 +114,63 @@ HTML; { $this->_populateQueue(); $this->unlock(); - file_put_contents($this->_path.UglyQueueManager::UGLY_QUEUE_SERIALIZED_NAME, serialize($this)); + file_put_contents($this->path.'/ugly-queue.obj', serialize($this)); + } + + /** + * @return string + */ + public function getName() + { + return $this->name; + } + + /** + * @return int + */ + public function getMode() + { + return $this->mode; + } + + /** + * @return string + */ + public function getPath() + { + return $this->path; + } + + /** + * @return string + */ + public function getBaseDir() + { + return $this->baseDir; + } + + /** + * @return string + */ + public function getQueueFile() + { + return $this->queueFile; + } + + /** + * @return string + */ + public function getQueueTmpFile() + { + return $this->queueTmpFile; + } + + /** + * @return string + */ + public function getLockFile() + { + return $this->lockFile; } /** @@ -150,8 +183,8 @@ HTML; if (!is_int($ttl)) throw new \InvalidArgumentException('Argument 1 expected to be integer, "'.gettype($ttl).'" seen'); - if ($ttl < 0) - throw new \InvalidArgumentException('Argument 1 expected to be positive integer, "'.$ttl.'" seen'); + if ($ttl < 1) + throw new \InvalidArgumentException('Argument 1 expected to be greater than 0 "'.$ttl.'" seen'); $alreadyLocked = $this->isLocked(); @@ -160,8 +193,8 @@ HTML; return $this->createLockFile($ttl); // If we make it this far, there is already a lock in place. - $this->_locked = false; - $this->notifyStatus = UglyQueueEnum::QUEUE_LOCKED_BY_OTHER_PROCESS; + $this->locked = false; + $this->_notifyStatus = UglyQueueEnum::QUEUE_LOCKED_BY_OTHER_PROCESS; $this->notify(); return false; @@ -174,19 +207,19 @@ HTML; protected function createLockFile($ttl) { $ok = (bool)@file_put_contents( - $this->_path.'queue.lock', + $this->lockFile, json_encode(array('ttl' => $ttl, 'born' => time()))); if ($ok !== true) { - $this->notifyStatus = UglyQueueEnum::QUEUE_FAILED_TO_LOCK; + $this->_notifyStatus = UglyQueueEnum::QUEUE_FAILED_TO_LOCK; $this->notify(); - return $this->_locked = false; + return $this->locked = false; } - $this->_locked = true; + $this->locked = true; - $this->notifyStatus = UglyQueueEnum::QUEUE_LOCKED; + $this->_notifyStatus = UglyQueueEnum::QUEUE_LOCKED; $this->notify(); return true; @@ -197,12 +230,12 @@ HTML; */ public function unlock() { - if ($this->_locked === true) + if ($this->locked === true) { - unlink($this->_path.'queue.lock'); - $this->_locked = false; + unlink($this->lockFile); + $this->locked = false; - $this->notifyStatus = UglyQueueEnum::QUEUE_UNLOCKED; + $this->_notifyStatus = UglyQueueEnum::QUEUE_UNLOCKED; $this->notify(); } } @@ -214,24 +247,23 @@ HTML; public function isLocked() { // First check for lock file - if (is_file($this->_path.'queue.lock')) + if (is_file($this->lockFile)) { - $lock = json_decode(file_get_contents($this->_path.'queue.lock'), true); + $lock = json_decode(file_get_contents($this->lockFile), true); - // If we have an invalid lock structure. - if (!isset($lock['ttl']) || !isset($lock['born'])) - throw new \RuntimeException('Invalid "queue.lock" file structure seen at "'.$this->_path.'queue.lock".'); + // If the decoded lock file contains a ttl and born value... + if (isset($lock['ttl']) && isset($lock['born'])) + { + $lock_ttl = ((int)$lock['born'] + (int)$lock['ttl']); - // Otherwise... - $lock_ttl = ((int)$lock['born'] + (int)$lock['ttl']); - - // If we're within the TTL of the lock, assume another thread is already processing. - // We'll pick it up on the next go around. - if ($lock_ttl > time()) - return true; + // If we're within the TTL of the lock, assume another thread is already processing. + // We'll pick it up on the next go around. + if ($lock_ttl > time()) + return true; + } // Else, remove lock file and assume we're good to go! - unlink($this->_path.'queue.lock'); + unlink($this->lockFile); return false; } @@ -245,14 +277,14 @@ HTML; * @throws \InvalidArgumentException * @return bool|array */ - public function processQueue($count = 1) + public function retrieveItems($count = 1) { if ($this->mode === self::QUEUE_READONLY) - throw new \RuntimeException('Queue "'.$this->_name.'" cannot be processed. It was started in Read-Only mode (the user running this process does not have permission to write to the queue directory).'); + throw new \RuntimeException('Queue "'.$this->name.'" cannot be processed. It was started in Read-Only mode (the user running this process does not have permission to write to the queue directory).'); // If we don't have a lock, assume issue and move on. - if ($this->_locked === false) - throw new \RuntimeException('Cannot process queue named "'.$this->_name.'". It is locked by another process.'); + if ($this->isLocked() === false) + throw new \RuntimeException('Cannot process queue named "'.$this->name.'". It is locked by another process.'); // If non-int valid is passed if (!is_int($count)) @@ -262,21 +294,21 @@ HTML; if ($count <= 0) throw new \InvalidArgumentException('Argument 1 expected to be integer greater than 0, "'.$count.'" seen'); - if ($this->notifyStatus !== UglyQueueEnum::QUEUE_PROCESSING) + if ($this->_notifyStatus !== UglyQueueEnum::QUEUE_PROCESSING) { - $this->notifyStatus = UglyQueueEnum::QUEUE_PROCESSING; + $this->_notifyStatus = UglyQueueEnum::QUEUE_PROCESSING; $this->notify(); } // Find number of lines in the queue file - $lineCount = FileHelper::getLineCount($this->_path.'queue.txt'); + $lineCount = FileHelper::getLineCount($this->queueFile); // If queue line count is 0, assume empty if ($lineCount === 0) return false; // Try to open the file for reading / writing. - $queueFileHandle = fopen($this->_path.'queue.txt', 'r+'); + $queueFileHandle = fopen($this->queueFile, 'r+'); if ($queueFileHandle === false) $this->unlock(); @@ -300,13 +332,13 @@ HTML; ftruncate($queueFileHandle, 0); fclose($queueFileHandle); - $this->notifyStatus = UglyQueueEnum::QUEUE_REACHED_END; + $this->_notifyStatus = UglyQueueEnum::QUEUE_REACHED_END; $this->notify(); } // Otherwise, create new queue file minus the processed lines. else { - $tmp = fopen($this->_path.'queue.tmp', 'w+'); + $tmp = fopen($this->queueTmpFile, 'w+'); rewind($queueFileHandle); $i = 0; while (($line = fgets($queueFileHandle)) !== false && $i < $start_line) @@ -319,8 +351,8 @@ HTML; fclose($queueFileHandle); fclose($tmp); - unlink($this->_path.'queue.txt'); - rename($this->_path.'queue.tmp', $this->_path.'queue.txt'); + unlink($this->queueFile); + rename($this->queueTmpFile, $this->queueFile); } return $data; @@ -332,19 +364,19 @@ HTML; * @return bool * @throws \RuntimeException */ - public function addToQueue($key, $value) + public function addItem($key, $value) { if ($this->mode === self::QUEUE_READONLY) - throw new \RuntimeException('Cannot add items to queue "'.$this->_name.'" as it is in read-only mode'); + throw new \RuntimeException('Cannot add item to queue "'.$this->name.'" as it is in read-only mode'); // If we don't have a lock, assume issue and move on. - if ($this->_locked === false) - throw new \RuntimeException('Cannot add items to queue "'.$this->_name.'". Queue is already locked by another process'); + if ($this->locked === false) + throw new \RuntimeException('Cannot add item to queue "'.$this->name.'". Queue is already locked by another process'); - if (!is_resource($this->_tmpHandle)) + if (!is_resource($this->tmpHandle)) { - $this->_tmpHandle = fopen($this->_path.'queue.tmp', 'w+'); - if ($this->_tmpHandle === false) + $this->tmpHandle = fopen($this->queueTmpFile, 'w+'); + if ($this->tmpHandle === false) throw new \RuntimeException('Unable to create "queue.tmp" file.'); } @@ -352,7 +384,7 @@ HTML; $value = json_encode($value); return (bool)fwrite( - $this->_tmpHandle, + $this->tmpHandle, $key."\t".str_replace(array("\r\n", "\n"), ' ', $value) ."\n"); } @@ -364,35 +396,26 @@ HTML; */ public function _populateQueue() { - if (is_resource($this->_tmpHandle)) + if (is_resource($this->tmpHandle)) { - if (file_exists($this->_path.'queue.txt')) + if (file_exists($this->queueFile)) { - $queueFileHandle = fopen($this->_path.'queue.txt', 'r+'); + $queueFileHandle = fopen($this->queueFile, 'r+'); while (($line = fgets($queueFileHandle)) !== false) { if ($line !== "\n" && $line !== "") - fwrite($this->_tmpHandle, $line); + fwrite($this->tmpHandle, $line); } fclose($queueFileHandle); - unlink($this->_path.'queue.txt'); + unlink($this->queueFile); } - fclose($this->_tmpHandle); - rename($this->_path.'queue.tmp', $this->_path.'queue.txt'); + fclose($this->tmpHandle); + rename($this->queueTmpFile, $this->queueFile); } } - /** - * @return int - * @throws \RuntimeException - */ - public function getQueueItemCount() - { - return FileHelper::getLineCount($this->_path.'queue.txt'); - } - /** * @param string $key * @return bool @@ -403,13 +426,11 @@ HTML; $key = (string)$key; // Try to open the file for reading / writing. - $queueFileHandle = fopen($this->_path.'queue.txt', 'r'); + $queueFileHandle = fopen($this->queueFile, 'r'); while(($line = fscanf($queueFileHandle, "%s\t%s\n")) !== false) { - list ($lineKey, $lineValue) = $line; - - if ($key === $lineKey) + if ($key === $line[0]) { fclose($queueFileHandle); return true; @@ -429,7 +450,7 @@ HTML; */ public function count() { - return $this->getQueueItemCount(); + return (int)FileHelper::getLineCount($this->queueFile); } /** @@ -441,7 +462,7 @@ HTML; */ public function serialize() { - return serialize(array($this->_name, $this->_path)); + return serialize(array($this->name, $this->path)); } /** @@ -456,8 +477,8 @@ HTML; { /** @var \DCarbone\UglyQueue $uglyQueue */ $data = unserialize($serialized); - $this->_name = $data[0]; - $this->_path = $data[1]; + $this->name = $data[0]; + $this->path = $data[1]; } /** @@ -470,8 +491,8 @@ HTML; */ public function attach(\SplObserver $observer) { - if (!in_array($observer, $this->observers)) - $this->observers[] = $observer; + if (!in_array($observer, $this->_observers)) + $this->_observers[] = $observer; } /** @@ -484,9 +505,9 @@ HTML; */ public function detach(\SplObserver $observer) { - $idx = array_search($observer, $this->observers, true); + $idx = array_search($observer, $this->_observers, true); if ($idx !== false) - unset($this->observers[$idx]); + unset($this->_observers[$idx]); } /** @@ -498,9 +519,9 @@ HTML; */ public function notify() { - for ($i = 0, $count = count($this->observers); $i < $count; $i++) + foreach($this->_observers as $observer) { - $this->observers[$i]->notify($this); + $observer->update($this); } } } \ No newline at end of file diff --git a/src/UglyQueueManager.php b/src/UglyQueueManager.php index b23a204..df23d78 100644 --- a/src/UglyQueueManager.php +++ b/src/UglyQueueManager.php @@ -4,77 +4,38 @@ * Class UglyQueueManager * @package DCarbone */ -class UglyQueueManager implements \SplObserver, \SplSubject, \Countable +class UglyQueueManager implements \SplObserver, \Countable { - /** @var int */ - public $notifyStatus; - - const UGLY_QUEUE_SERIALIZED_NAME = 'ugly-queue.obj'; - - /** @var array */ - private $observers = array(); - - /** @var array */ + /** @var UglyQueue[] */ protected $queues = array(); - /** @var array */ - protected $config = array(); - /** @var string */ - protected $queueBaseDir; + protected $baseDir; /** * Constructor * - * @param array $config - * @param array $observers + * @param string $baseDir * @throws \RuntimeException * @throws \InvalidArgumentException */ - protected function __construct(array $config, array $observers = array()) + public function __construct($baseDir) { - if (!isset($config['queue-base-dir'])) - throw new \InvalidArgumentException('"$config" parameter "queue-base-dir" not seen.'); + if (false === is_string($baseDir)) + throw new \InvalidArgumentException('Argument 1 expected to be string, "'.gettype($baseDir).'" seen.'); - if (!is_dir($config['queue-base-dir'])) - throw new \RuntimeException('"queue-base-dir" points to a directory that does not exist.'); + if (false === is_dir($baseDir)) + throw new \RuntimeException('"'.$baseDir.'" points to a directory that does not exist.'); - $this->config = $config; - $this->queueBaseDir = rtrim(realpath($this->config['queue-base-dir']), "/\\").DIRECTORY_SEPARATOR; - $this->observers = $observers; - } + if (false === is_readable($baseDir)) + throw new \RuntimeException('"'.$baseDir.'" is not readable and/or writable .'); - /** - * @param array $config - * @param array $observers - * @return UglyQueueManager - */ - public static function init(array $config, array $observers = array()) - { - /** @var \DCarbone\UglyQueueManager $manager */ - $manager = new static($config, $observers); + $this->baseDir = rtrim($baseDir, "/\\"); - /** @var \DCarbone\UglyQueue $uglyQueue */ - - foreach(glob($manager->queueBaseDir.DIRECTORY_SEPARATOR.'*', GLOB_ONLYDIR) as $queueDir) + foreach(glob(sprintf('%s/*', $this->baseDir), GLOB_ONLYDIR) as $queueDir) { - // Try to avoid looking at hidden directories or magic dirs such as '.' and '..' - $split = preg_split('#[/\\\]+#', $queueDir); - if (strpos(end($split), '.') === 0) - continue; - - if (file_exists($queueDir.DIRECTORY_SEPARATOR.self::UGLY_QUEUE_SERIALIZED_NAME)) - $uglyQueue = unserialize(file_get_contents($queueDir.DIRECTORY_SEPARATOR.self::UGLY_QUEUE_SERIALIZED_NAME)); - else - $uglyQueue = UglyQueue::queueWithDirectoryPathAndObservers($queueDir, $manager->observers); - - $manager->addQueue($uglyQueue); + $this->addQueueAtPath($queueDir); } - - $manager->notifyStatus = UglyQueueEnum::MANAGER_INITIALIZED; - $manager->notify(); - - return $manager; } /** @@ -84,24 +45,45 @@ class UglyQueueManager implements \SplObserver, \SplSubject, \Countable */ public function addQueue(UglyQueue $uglyQueue) { - if ($this->containsQueueWithName($uglyQueue->name)) - throw new \RuntimeException('Queue named "'.$uglyQueue->name.'" already exists in this manager.'); + $name = $uglyQueue->getName(); - $this->queues[$uglyQueue->name] = $uglyQueue; + if ($this->containsQueueWithName($name)) + throw new \RuntimeException('Queue named "'.$name.'" already exists in this manager.'); - $this->notifyStatus = UglyQueueEnum::QUEUE_ADDED; - $this->notify(); + $this->queues[$name] = $uglyQueue; return $this; } /** - * @param $path + * @param string $name + * @return UglyQueue + */ + public function createQueue($name) + { + $this->addQueue(new UglyQueue($this->baseDir, $name, array($this))); + return end($this->queues); + } + + /** + * @param string $path * @return \DCarbone\UglyQueueManager */ public function addQueueAtPath($path) { - $uglyQueue = UglyQueue::queueWithDirectoryPathAndObservers($path, $this->observers); + // Try to avoid looking at hidden directories or magic dirs such as '.' and '..' + $split = preg_split('#[/\\\]+#', $path); + + $queueName = end($split); + + if (0 === strpos($queueName, '.')) + return null; + + $serializedFile = sprintf('%s/%s/ugly-queue.obj', $this->baseDir, $queueName); + if (file_exists($serializedFile)) + $uglyQueue = unserialize(file_get_contents($serializedFile)); + else + $uglyQueue = new UglyQueue($this->baseDir, $queueName, array($this)); return $this->addQueue($uglyQueue); } @@ -112,8 +94,9 @@ class UglyQueueManager implements \SplObserver, \SplSubject, \Countable */ public function removeQueue(UglyQueue $uglyQueue) { - if ($this->containsQueueWithName($uglyQueue->name)) - unset($this->queues[$uglyQueue->name]); + $name = $uglyQueue->getName(); + if ($this->containsQueueWithName($name)) + unset($this->queues[$name]); return $this; } @@ -125,11 +108,7 @@ class UglyQueueManager implements \SplObserver, \SplSubject, \Countable public function removeQueueByName($name) { if ($this->containsQueueWithName($name)) - { unset($this->queues[$name]); - $this->notifyStatus = UglyQueueEnum::QUEUE_REMOVED; - $this->notify(); - } return $this; } @@ -139,7 +118,7 @@ class UglyQueueManager implements \SplObserver, \SplSubject, \Countable * @return \DCarbone\UglyQueue * @throws \InvalidArgumentException */ - public function &getQueueWithName($name) + public function getQueueWithName($name) { if (isset($this->queues[$name])) return $this->queues[$name]; @@ -186,53 +165,6 @@ class UglyQueueManager implements \SplObserver, \SplSubject, \Countable */ public function update(\SplSubject $subject) { - for ($i = 0, $count = count($this->observers); $i < $count; $i++) - { - $this->observers[$i]->notify($subject); - } - } - - /** - * (PHP 5 >= 5.1.0) - * Attach an SplObserver - * @link http://php.net/manual/en/splsubject.attach.php - * - * @param \SplObserver $observer The SplObserver to attach. - * @return void - */ - public function attach(\SplObserver $observer) - { - if (!in_array($observer, $this->observers, true)) - $this->observers[] = $observer; - } - - /** - * (PHP 5 >= 5.1.0) - * Detach an observer - * @link http://php.net/manual/en/splsubject.detach.php - * - * @param \SplObserver $observer The SplObserver to detach. - * @return void - */ - public function detach(\SplObserver $observer) - { - $idx = array_search($observer, $this->observers, true); - if ($idx !== false) - unset($this->observers[$idx]); - } - - /** - * (PHP 5 >= 5.1.0) - * Notify an observer - * @link http://php.net/manual/en/splsubject.notify.php - * - * @return void - */ - public function notify() - { - for ($i = 0, $count = count($this->observers); $i < $count; $i++) - { - $this->observers[$i]->notify($this); - } + // Nothing for now... } } \ No newline at end of file diff --git a/tests/UglyQueue/UglyQueueTest.php b/tests/UglyQueue/UglyQueueTest.php index b221e17..e47d33e 100644 --- a/tests/UglyQueue/UglyQueueTest.php +++ b/tests/UglyQueue/UglyQueueTest.php @@ -9,6 +9,8 @@ require_once __DIR__.'/../misc/cleanup.php'; */ class UglyQueueTest extends PHPUnit_Framework_TestCase { + protected $baseDir; + /** * @var array */ @@ -26,14 +28,19 @@ class UglyQueueTest extends PHPUnit_Framework_TestCase '10' => 'Virginia baked ham, sliced', ); + protected function setUp() + { + $this->baseDir = __DIR__.'/../misc/queues'; + } + /** - * @covers \DCarbone\UglyQueue::queueWithDirectoryPathAndObservers + * @covers \DCarbone\UglyQueue::__construct * @uses \DCarbone\UglyQueue * @return \DCarbone\UglyQueue */ - public function testCanInitializeUglyQueueWithValidConfigArrayAndNoObservers() + public function testCanInitializeObjectWithValidParameters() { - $uglyQueue = \DCarbone\UglyQueue::queueWithDirectoryPathAndObservers(dirname(__DIR__).'/misc/queues/tasty-sandwich'); + $uglyQueue = new \DCarbone\UglyQueue($this->baseDir, 'tasty-sandwich'); $this->assertInstanceOf('\\DCarbone\\UglyQueue', $uglyQueue); @@ -41,31 +48,21 @@ class UglyQueueTest extends PHPUnit_Framework_TestCase } /** - * @covers \DCarbone\UglyQueue::queueWithDirectoryPathAndObservers + * @covers \DCarbone\UglyQueue::retrieveItems * @uses \DCarbone\UglyQueue - * @expectedException \InvalidArgumentException - */ - public function testExceptionThrownWhenInitializingUglyQueueWithEmptyOrInvalidConf() - { - $uglyQueue = \DCarbone\UglyQueue::queueWithDirectoryPathAndObservers(array()); - } - - /** - * @covers \DCarbone\UglyQueue::processQueue - * @uses \DCarbone\UglyQueue - * @depends testCanInitializeUglyQueueWithValidConfigArrayAndNoObservers + * @depends testCanInitializeObjectWithValidParameters * @expectedException \RuntimeException * @param \DCarbone\UglyQueue $uglyQueue */ public function testExceptionThrownWhenTryingToProcessQueueAfterInitializationBeforeLock(\DCarbone\UglyQueue $uglyQueue) { - $process = $uglyQueue->processQueue(); + $uglyQueue->retrieveItems(); } /** * @covers \DCarbone\UglyQueue::keyExistsInQueue * @uses \DCarbone\UglyQueue - * @depends testCanInitializeUglyQueueWithValidConfigArrayAndNoObservers + * @depends testCanInitializeObjectWithValidParameters * @param \DCarbone\UglyQueue $uglyQueue */ public function testKeyExistsInQueueReturnsFalseWithEmptyQueueAfterInitialization(\DCarbone\UglyQueue $uglyQueue) @@ -76,101 +73,76 @@ class UglyQueueTest extends PHPUnit_Framework_TestCase } /** - * @covers \DCarbone\UglyQueue::addToQueue + * @covers \DCarbone\UglyQueue::addItem * @uses \DCarbone\UglyQueue - * @depends testCanInitializeUglyQueueWithValidConfigArrayAndNoObservers + * @depends testCanInitializeObjectWithValidParameters * @expectedException \RuntimeException * @param \DCarbone\UglyQueue $uglyQueue */ public function testExceptionThrownWhenTryingToAddItemsToQueueWithoutLock(\DCarbone\UglyQueue $uglyQueue) { - $addToQueue = $uglyQueue->addToQueue('test', 'value'); + $uglyQueue->addItem('test', 'value'); } /** - * @covers \DCarbone\UglyQueue::__get + * @covers \DCarbone\UglyQueue::getPath * @uses \DCarbone\UglyQueue - * @depends testCanInitializeUglyQueueWithValidConfigArrayAndNoObservers + * @depends testCanInitializeObjectWithValidParameters * @param \DCarbone\UglyQueue $uglyQueue */ public function testCanGetQueueDirectory(\DCarbone\UglyQueue $uglyQueue) { - $queuePath = $uglyQueue->path; + $queuePath = $uglyQueue->getPath(); $this->assertFileExists($queuePath); } /** - * @covers \DCarbone\UglyQueue::__get + * @covers \DCarbone\UglyQueue::getName * @uses \DCarbone\UglyQueue - * @depends testCanInitializeUglyQueueWithValidConfigArrayAndNoObservers + * @depends testCanInitializeObjectWithValidParameters * @param \DCarbone\UglyQueue $uglyQueue */ public function testCanGetQueueName(\DCarbone\UglyQueue $uglyQueue) { - $queueName = $uglyQueue->name; + $queueName = $uglyQueue->getName(); $this->assertEquals('tasty-sandwich', $queueName); } /** - * @covers \DCarbone\UglyQueue::__get + * @covers \DCarbone\UglyQueue::isLocked * @uses \DCarbone\UglyQueue - * @depends testCanInitializeUglyQueueWithValidConfigArrayAndNoObservers + * @depends testCanInitializeObjectWithValidParameters * @param \DCarbone\UglyQueue $uglyQueue */ public function testCanGetQueueLockedStatus(\DCarbone\UglyQueue $uglyQueue) { - $locked = $uglyQueue->locked; + $locked = $uglyQueue->isLocked(); $this->assertFalse($locked); } /** - * @covers \DCarbone\UglyQueue::__get + * @covers \DCarbone\UglyQueue::count * @uses \DCarbone\UglyQueue - * @expectedException \OutOfBoundsException - * @depends testCanInitializeUglyQueueWithValidConfigArrayAndNoObservers - * @param \DCarbone\UglyQueue $uglyQueue - */ - public function testExceptionThrownWhenAttemptingToGetInvalidProperty(\DCarbone\UglyQueue $uglyQueue) - { - $sandwich = $uglyQueue->sandwich; - } - - /** - * @covers \DCarbone\UglyQueue::isLocked - * @uses \DCarbone\UglyQueue - * @depends testCanInitializeUglyQueueWithValidConfigArrayAndNoObservers - * @param \DCarbone\UglyQueue $uglyQueue - */ - public function testIsLockedReturnsFalseBeforeLocking(\DCarbone\UglyQueue $uglyQueue) - { - $isLocked = $uglyQueue->isLocked(); - - $this->assertFalse($isLocked); - } - - /** - * @covers \DCarbone\UglyQueue::getQueueItemCount - * @uses \DCarbone\UglyQueue - * @depends testCanInitializeUglyQueueWithValidConfigArrayAndNoObservers + * @depends testCanInitializeObjectWithValidParameters * @param \DCarbone\UglyQueue $uglyQueue */ public function testGetQueueItemCountReturnsZeroWithEmptyQueue(\DCarbone\UglyQueue $uglyQueue) { - $itemCount = $uglyQueue->getQueueItemCount(); + $itemCount = count($uglyQueue); $this->assertEquals(0, $itemCount); } /** - * @covers \DCarbone\UglyQueue::queueWithDirectoryPathAndObservers + * @covers \DCarbone\UglyQueue::__construct * @uses \DCarbone\UglyQueue * @return \DCarbone\UglyQueue */ public function testCanInitializeExistingQueue() { - $uglyQueue = \DCarbone\UglyQueue::queueWithDirectoryPathAndObservers(dirname(__DIR__).'/misc/queues/tasty-sandwich'); + $uglyQueue = new \DCarbone\UglyQueue($this->baseDir, 'tasty-sandwich'); $this->assertInstanceOf('\\DCarbone\\UglyQueue', $uglyQueue); @@ -180,7 +152,7 @@ class UglyQueueTest extends PHPUnit_Framework_TestCase /** * @covers \DCarbone\UglyQueue::lock * @uses \DCarbone\UglyQueue - * @depends testCanInitializeUglyQueueWithValidConfigArrayAndNoObservers + * @depends testCanInitializeObjectWithValidParameters * @expectedException \InvalidArgumentException * @param \DCarbone\UglyQueue $uglyQueue */ @@ -192,7 +164,7 @@ class UglyQueueTest extends PHPUnit_Framework_TestCase /** * @covers \DCarbone\UglyQueue::lock * @uses \DCarbone\UglyQueue - * @depends testCanInitializeUglyQueueWithValidConfigArrayAndNoObservers + * @depends testCanInitializeObjectWithValidParameters * @expectedException \InvalidArgumentException * @param \DCarbone\UglyQueue $uglyQueue */ @@ -206,7 +178,7 @@ class UglyQueueTest extends PHPUnit_Framework_TestCase * @covers \DCarbone\UglyQueue::isLocked * @covers \DCarbone\UglyQueue::createLockFile * @uses \DCarbone\UglyQueue - * @depends testCanInitializeUglyQueueWithValidConfigArrayAndNoObservers + * @depends testCanInitializeObjectWithValidParameters * @param \DCarbone\UglyQueue $uglyQueue * @return \DCarbone\UglyQueue */ @@ -216,11 +188,9 @@ class UglyQueueTest extends PHPUnit_Framework_TestCase $this->assertTrue($locked); - $queueDir = $uglyQueue->path; + $this->assertFileExists($uglyQueue->getLockFile()); - $this->assertFileExists($queueDir.'queue.lock'); - - $decode = @json_decode(file_get_contents($queueDir.'queue.lock')); + $decode = @json_decode(file_get_contents($uglyQueue->getLockFile())); $this->assertTrue((json_last_error() === JSON_ERROR_NONE)); $this->assertObjectHasAttribute('ttl', $decode); @@ -268,9 +238,7 @@ class UglyQueueTest extends PHPUnit_Framework_TestCase { $uglyQueue->unlock(); - $queueGroupDir = $uglyQueue->path; - - $this->assertFileNotExists($queueGroupDir.'queue.lock'); + $this->assertFileNotExists($uglyQueue->getLockFile()); return $uglyQueue; } @@ -323,11 +291,9 @@ class UglyQueueTest extends PHPUnit_Framework_TestCase $this->assertTrue($locked); - $queueDir = $uglyQueue->path; + $this->assertFileExists($uglyQueue->getLockFile()); - $this->assertFileExists($queueDir.'queue.lock'); - - $decode = @json_decode(file_get_contents($queueDir.'queue.lock')); + $decode = @json_decode(file_get_contents($uglyQueue->getLockFile())); $this->assertTrue((json_last_error() === JSON_ERROR_NONE)); $this->assertObjectHasAttribute('ttl', $decode); @@ -338,7 +304,7 @@ class UglyQueueTest extends PHPUnit_Framework_TestCase } /** - * @covers \DCarbone\UglyQueue::addToQueue + * @covers \DCarbone\UglyQueue::addItem * @uses \DCarbone\UglyQueue * @uses \DCarbone\Helpers\FileHelper * @depends testCanLockQueueWithValidIntegerValue @@ -349,17 +315,15 @@ class UglyQueueTest extends PHPUnit_Framework_TestCase { foreach(array_reverse($this->tastySandwich, true) as $k=>$v) { - $added = $uglyQueue->addToQueue($k, $v); + $added = $uglyQueue->addItem($k, $v); $this->assertTrue($added); } - $groupDir = $uglyQueue->path; - $this->assertFileExists( - $groupDir.'queue.tmp', + $uglyQueue->getQueueTmpFile(), 'queue.tmp file was not created!'); - $lineCount = \DCarbone\Helpers\FileHelper::getLineCount($groupDir.'queue.tmp'); + $lineCount = \DCarbone\Helpers\FileHelper::getLineCount($uglyQueue->getQueueTmpFile()); $this->assertEquals(11, $lineCount); @@ -377,9 +341,7 @@ class UglyQueueTest extends PHPUnit_Framework_TestCase { $uglyQueue->_populateQueue(); - $groupDir = $uglyQueue->path; - - $this->assertFileNotExists($groupDir.'queue.tmp'); + $this->assertFileNotExists($uglyQueue->getQueueTmpFile()); $uglyQueue->_populateQueue(); @@ -395,7 +357,7 @@ class UglyQueueTest extends PHPUnit_Framework_TestCase */ public function testCanGetCountOfItemsInPopulatedQueue(\DCarbone\UglyQueue $uglyQueue) { - $itemCount = $uglyQueue->getQueueItemCount(); + $itemCount = count($uglyQueue); $this->assertEquals(11, $itemCount); } @@ -414,7 +376,7 @@ class UglyQueueTest extends PHPUnit_Framework_TestCase } /** - * @covers \DCarbone\UglyQueue::processQueue + * @covers \DCarbone\UglyQueue::retrieveItems * @uses \DCarbone\UglyQueue * @depends testCanPopulateQueueTempFileAfterInitializationAndAcquiringLock * @expectedException \InvalidArgumentException @@ -422,11 +384,11 @@ class UglyQueueTest extends PHPUnit_Framework_TestCase */ public function testExceptionThrownWhenTryingToProcessLockedQueueWithNonInteger(\DCarbone\UglyQueue $uglyQueue) { - $process = $uglyQueue->processQueue('Eleventy Billion'); + $uglyQueue->retrieveItems('Eleventy Billion'); } /** - * @covers \DCarbone\UglyQueue::processQueue + * @covers \DCarbone\UglyQueue::retrieveItems * @uses \DCarbone\UglyQueue * @depends testCanPopulateQueueTempFileAfterInitializationAndAcquiringLock * @expectedException \InvalidArgumentException @@ -434,11 +396,11 @@ class UglyQueueTest extends PHPUnit_Framework_TestCase */ public function testExceptionThrownWhenTryingToProcessLockedQueueWithIntegerLessThan1(\DCarbone\UglyQueue $uglyQueue) { - $process = $uglyQueue->processQueue(0); + $uglyQueue->retrieveItems(0); } /** - * @covers \DCarbone\UglyQueue::processQueue + * @covers \DCarbone\UglyQueue::retrieveItems * @covers \DCarbone\UglyQueue::getQueueItemCount * @uses \DCarbone\UglyQueue * @uses \DCarbone\Helpers\FileHelper @@ -448,20 +410,20 @@ class UglyQueueTest extends PHPUnit_Framework_TestCase */ public function testCanGetPartialQueueContents(\DCarbone\UglyQueue $uglyQueue) { - $process = $uglyQueue->processQueue(5); + $process = $uglyQueue->retrieveItems(5); $this->assertEquals(5, count($process)); $this->assertArrayHasKey('0', $process); $this->assertArrayHasKey('4', $process); - $this->assertEquals(6, $uglyQueue->getQueueItemCount()); + $this->assertEquals(6, count($uglyQueue)); return $uglyQueue; } /** - * @covers \DCarbone\UglyQueue::processQueue + * @covers \DCarbone\UglyQueue::retrieveItems * @covers \DCarbone\UglyQueue::getQueueItemCount * @uses \DCarbone\UglyQueue * @uses \DCarbone\Helpers\FileHelper @@ -471,14 +433,14 @@ class UglyQueueTest extends PHPUnit_Framework_TestCase */ public function testCanGetFullQueueContents(\DCarbone\UglyQueue $uglyQueue) { - $process = $uglyQueue->processQueue(6); + $process = $uglyQueue->retrieveItems(6); $this->assertEquals(6, count($process)); $this->assertArrayHasKey('10', $process); $this->assertArrayHasKey('5', $process); - $this->assertEquals(0, $uglyQueue->getQueueItemCount()); + $this->assertEquals(0, count($uglyQueue)); return $uglyQueue; } diff --git a/tests/UglyQueueManager/UglyQueueManagerTest.php b/tests/UglyQueueManager/UglyQueueManagerTest.php index 824adeb..789ae19 100644 --- a/tests/UglyQueueManager/UglyQueueManagerTest.php +++ b/tests/UglyQueueManager/UglyQueueManagerTest.php @@ -5,30 +5,31 @@ */ class UglyQueueManagerTest extends PHPUnit_Framework_TestCase { + protected $baseDir; + protected $reallyTastySandwich = array( '0' => 'beef broth', '1' => 'barbeque sauce', '2' => 'boneless pork ribs', ); + protected function setUp() + { + $this->baseDir = __DIR__.'/../misc/queues'; + } + /** * @covers \DCarbone\UglyQueueManager::__construct - * @covers \DCarbone\UglyQueueManager::init * @covers \DCarbone\UglyQueue::unserialize - * @covers \DCarbone\UglyQueue::__get * @covers \DCarbone\UglyQueueManager::addQueue * @covers \DCarbone\UglyQueueManager::containsQueueWithName * @uses \DCarbone\UglyQueueManager * @uses \DCarbone\UglyQueue * @return \DCarbone\UglyQueueManager */ - public function testCanInitializeManagerWithConfigAndNoObservers() + public function testCanInitializeObjectWithValidPath() { - $config = array( - 'queue-base-dir' => __DIR__.'/../misc/queues' - ); - - $manager = \DCarbone\UglyQueueManager::init($config); + $manager = new \DCarbone\UglyQueueManager($this->baseDir); $this->assertInstanceOf('\\DCarbone\\UglyQueueManager', $manager); @@ -36,39 +37,20 @@ class UglyQueueManagerTest extends PHPUnit_Framework_TestCase } /** - * @covers \DCarbone\UglyQueueManager::init * @covers \DCarbone\UglyQueueManager::__construct * @uses \DCarbone\UglyQueueManager * @expectedException \RuntimeException */ public function testExceptionThrownDuringConstructionWithInvalidBasePathValue() { - $config = array( - 'queue-base-dir' => 'i do not exist!' - ); - - $manager = \DCarbone\UglyQueueManager::init($config); + new \DCarbone\UglyQueueManager('i do not exist!'); } - /** - * @covers \DCarbone\UglyQueueManager::init - * @covers \DCarbone\UglyQueueManager::__construct - * @uses \DCarbone\UglyQueueManager - * @expectedException \InvalidArgumentException - */ - public function testExceptionThrownDuringConstructionWithInvalidConfArray() - { - $config = array( - 'wrong-key' => 'wrong value' - ); - - $manager = \DCarbone\UglyQueueManager::init($config); - } /** * @covers \DCarbone\UglyQueueManager::containsQueueWithName * @uses \DCarbone\UglyQueueManager - * @depends testCanInitializeManagerWithConfigAndNoObservers + * @depends testCanInitializeObjectWithValidPath * @param \DCarbone\UglyQueueManager $manager */ public function testCanDetermineIfValidQueueExistsInManager(\DCarbone\UglyQueueManager $manager) @@ -81,7 +63,7 @@ class UglyQueueManagerTest extends PHPUnit_Framework_TestCase /** * @covers \DCarbone\UglyQueueManager::containsQueueWithName * @uses \DCarbone\UglyQueueManager - * @depends testCanInitializeManagerWithConfigAndNoObservers + * @depends testCanInitializeObjectWithValidPath * @param \DCarbone\UglyQueueManager $manager */ public function testCanDetermineQueueDoesNotExistInManager(\DCarbone\UglyQueueManager $manager) @@ -93,10 +75,9 @@ class UglyQueueManagerTest extends PHPUnit_Framework_TestCase /** * @covers \DCarbone\UglyQueueManager::getQueueWithName - * @covers \DCarbone\UglyQueue::__get * @uses \DCarbone\UglyQueueManager * @uses \DCarbone\UglyQueue - * @depends testCanInitializeManagerWithConfigAndNoObservers + * @depends testCanInitializeObjectWithValidPath * @param \DCarbone\UglyQueueManager $manager */ public function testCanGetUglyQueueObjectFromManager(\DCarbone\UglyQueueManager $manager) @@ -104,25 +85,25 @@ class UglyQueueManagerTest extends PHPUnit_Framework_TestCase $uglyQueue = $manager->getQueueWithName('tasty-sandwich'); $this->assertInstanceOf('\\DCarbone\\UglyQueue', $uglyQueue); - $this->assertEquals('tasty-sandwich', $uglyQueue->name); + $this->assertEquals('tasty-sandwich', $uglyQueue->getName()); } /** * @covers \DCarbone\UglyQueueManager::getQueueWithName * @uses \DCarbone\UglyQueueManager * @expectedException \InvalidArgumentException - * @depends testCanInitializeManagerWithConfigAndNoObservers + * @depends testCanInitializeObjectWithValidPath * @param \DCarbone\UglyQueueManager $manager */ public function testExceptionThrownWhenTryingToGetNonExistentQueueFromManager(\DCarbone\UglyQueueManager $manager) { - $shouldNotExist = $manager->getQueueWithName('sandwiches'); + $manager->getQueueWithName('sandwiches'); } /** * @covers \DCarbone\UglyQueueManager::getQueueList * @uses \DCarbone\UglyQueueManager - * @depends testCanInitializeManagerWithConfigAndNoObservers + * @depends testCanInitializeObjectWithValidPath * @param \DCarbone\UglyQueueManager $manager */ public function testCanGetListOfQueuesInManager(\DCarbone\UglyQueueManager $manager) @@ -140,7 +121,7 @@ class UglyQueueManagerTest extends PHPUnit_Framework_TestCase * @uses \DCarbone\UglyQueueManager * @uses \DCarbone\UglyQueue * @expectedException \RuntimeException - * @depends testCanInitializeManagerWithConfigAndNoObservers + * @depends testCanInitializeObjectWithValidPath * @param \DCarbone\UglyQueueManager $manager */ public function testExceptionThrownWhenReAddingQueueToManager(\DCarbone\UglyQueueManager $manager) @@ -156,7 +137,7 @@ class UglyQueueManagerTest extends PHPUnit_Framework_TestCase * @covers \DCarbone\UglyQueueManager::getQueueWithName * @uses \DCarbone\UglyQueueManager * @uses \DCarbone\UglyQueue - * @depends testCanInitializeManagerWithConfigAndNoObservers + * @depends testCanInitializeObjectWithValidPath * @param \DCarbone\UglyQueueManager $manager */ public function testCanInitializeNewQueueAndAddToManager(\DCarbone\UglyQueueManager $manager) @@ -166,7 +147,7 @@ class UglyQueueManagerTest extends PHPUnit_Framework_TestCase $uglyQueue = $manager->getQueueWithName('really-tasty-sandwich'); $this->assertInstanceOf('\\DCarbone\\UglyQueue', $uglyQueue); - $this->assertEquals('really-tasty-sandwich', $uglyQueue->name); + $this->assertEquals('really-tasty-sandwich', $uglyQueue->getName()); $queueList = $manager->getQueueList(); @@ -178,7 +159,7 @@ class UglyQueueManagerTest extends PHPUnit_Framework_TestCase /** * @covers \DCarbone\UglyQueueManager::removeQueueByName * @uses \DCarbone\UglyQueueManager - * @depends testCanInitializeManagerWithConfigAndNoObservers + * @depends testCanInitializeObjectWithValidPath * @param \DCarbone\UglyQueueManager $manager */ public function testCanRemoveQueueFromManagerByName(\DCarbone\UglyQueueManager $manager)