CC-2166: Packaging Improvements. Moved the Zend app into airtime_mvc. It is now installed to /var/www/airtime. Storage is now set to /srv/airtime/stor. Utils are now installed to /usr/lib/airtime/utils/. Added install/airtime-dircheck.php as a simple test to see if everything is install/uninstalled correctly.

This commit is contained in:
Paul Baranowski 2011-04-14 18:55:04 -04:00
parent 514777e8d2
commit b11cbd8159
4546 changed files with 138 additions and 51 deletions

View file

@ -0,0 +1,336 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Queue
* @subpackage Adapter
* @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Activemq.php 20096 2010-01-06 02:05:09Z bkarwin $
*/
/**
* @see Zend_Queue_Adapter_AdapterAbstract
*/
require_once 'Zend/Queue/Adapter/AdapterAbstract.php';
/**
* @see Zend_Queue_Adapter_Stomp_Client
*/
require_once 'Zend/Queue/Stomp/Client.php';
/**
* @see Zend_Queue_Adapter_Stomp_Frame
*/
require_once 'Zend/Queue/Stomp/Frame.php';
/**
* Class for using Stomp to talk to an Stomp compliant server
*
* @category Zend
* @package Zend_Queue
* @subpackage Adapter
* @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Queue_Adapter_Activemq extends Zend_Queue_Adapter_AdapterAbstract
{
const DEFAULT_SCHEME = 'tcp';
const DEFAULT_HOST = '127.0.0.1';
const DEFAULT_PORT = 61613;
/**
* @var Zend_Queue_Adapter_Stomp_client
*/
private $_client = null;
/**
* Constructor
*
* @param array|Zend_Config $config An array having configuration data
* @param Zend_Queue The Zend_Queue object that created this class
* @return void
*/
public function __construct($options, Zend_Queue $queue = null)
{
parent::__construct($options);
$options = &$this->_options['driverOptions'];
if (!array_key_exists('scheme', $options)) {
$options['scheme'] = self::DEFAULT_SCHEME;
}
if (!array_key_exists('host', $options)) {
$options['host'] = self::DEFAULT_HOST;
}
if (!array_key_exists('port', $options)) {
$options['port'] = self::DEFAULT_PORT;
}
if (array_key_exists('stompClient', $options)) {
$this->_client = $options['stompClient'];
} else {
$this->_client = new Zend_Queue_Stomp_Client($options['scheme'], $options['host'], $options['port']);
}
$connect = $this->_client->createFrame();
// Username and password are optional on some messaging servers
// such as Apache's ActiveMQ
$connect->setCommand('CONNECT');
if (isset($options['username'])) {
$connect->setHeader('login', $options['username']);
$connect->setHeader('passcode', $options['password']);
}
$response = $this->_client->send($connect)->receive();
if ((false !== $response)
&& ($response->getCommand() != 'CONNECTED')
) {
require_once 'Zend/Queue/Exception.php';
throw new Zend_Queue_Exception("Unable to authenticate to '".$options['scheme'].'://'.$options['host'].':'.$options['port']."'");
}
}
/**
* Close the socket explicitly when destructed
*
* @return void
*/
public function __destruct()
{
// Gracefully disconnect
$frame = $this->_client->createFrame();
$frame->setCommand('DISCONNECT');
$this->_client->send($frame);
unset($this->_client);
}
/**
* Create a new queue
*
* @param string $name queue name
* @param integer $timeout default visibility timeout
* @return void
* @throws Zend_Queue_Exception
*/
public function create($name, $timeout=null)
{
require_once 'Zend/Queue/Exception.php';
throw new Zend_Queue_Exception('create() is not supported in ' . get_class($this));
}
/**
* Delete a queue and all of its messages
*
* @param string $name queue name
* @return void
* @throws Zend_Queue_Exception
*/
public function delete($name)
{
require_once 'Zend/Queue/Exception.php';
throw new Zend_Queue_Exception('delete() is not supported in ' . get_class($this));
}
/**
* Delete a message from the queue
*
* Returns true if the message is deleted, false if the deletion is
* unsuccessful.
*
* @param Zend_Queue_Message $message
* @return boolean
*/
public function deleteMessage(Zend_Queue_Message $message)
{
$frame = $this->_client->createFrame();
$frame->setCommand('ACK');
$frame->setHeader('message-id', $message->handle);
$this->_client->send($frame);
return true;
}
/**
* Get an array of all available queues
*
* @return void
* @throws Zend_Queue_Exception
*/
public function getQueues()
{
require_once 'Zend/Queue/Exception.php';
throw new Zend_Queue_Exception('getQueues() is not supported in this adapter');
}
/**
* Return the first element in the queue
*
* @param integer $maxMessages
* @param integer $timeout
* @param Zend_Queue $queue
* @return Zend_Queue_Message_Iterator
*/
public function receive($maxMessages=null, $timeout=null, Zend_Queue $queue=null)
{
if ($maxMessages === null) {
$maxMessages = 1;
}
if ($timeout === null) {
$timeout = self::RECEIVE_TIMEOUT_DEFAULT;
}
if ($queue === null) {
$queue = $this->_queue;
}
// read
$data = array();
// signal that we are reading
$frame = $this->_client->createFrame();
$frame->setCommand('SUBSCRIBE');
$frame->setHeader('destination', $queue->getName());
$frame->setHeader('ack','client');
$this->_client->send($frame);
if ($maxMessages > 0) {
if ($this->_client->canRead()) {
for ($i = 0; $i < $maxMessages; $i++) {
$response = $this->_client->receive();
switch ($response->getCommand()) {
case 'MESSAGE':
$datum = array(
'message_id' => $response->getHeader('message-id'),
'handle' => $response->getHeader('message-id'),
'body' => $response->getBody(),
'md5' => md5($response->getBody())
);
$data[] = $datum;
break;
default:
$block = print_r($response, true);
require_once 'Zend/Queue/Exception.php';
throw new Zend_Queue_Exception('Invalid response received: ' . $block);
}
}
}
}
$options = array(
'queue' => $queue,
'data' => $data,
'messageClass' => $queue->getMessageClass()
);
$classname = $queue->getMessageSetClass();
if (!class_exists($classname)) {
require_once 'Zend/Loader.php';
Zend_Loader::loadClass($classname);
}
return new $classname($options);
}
/**
* Push an element onto the end of the queue
*
* @param string $message message to send to the queue
* @param Zend_Queue $queue
* @return Zend_Queue_Message
*/
public function send($message, Zend_Queue $queue=null)
{
if ($queue === null) {
$queue = $this->_queue;
}
$frame = $this->_client->createFrame();
$frame->setCommand('SEND');
$frame->setHeader('destination', $queue->getName());
$frame->setHeader('content-length', strlen($message));
$frame->setBody((string) $message);
$this->_client->send($frame);
$data = array(
'message_id' => null,
'body' => $message,
'md5' => md5($message),
'handle' => null
);
$options = array(
'queue' => $queue,
'data' => $data
);
$classname = $queue->getMessageClass();
if (!class_exists($classname)) {
require_once 'Zend/Loader.php';
Zend_Loader::loadClass($classname);
}
return new $classname($options);
}
/**
* Returns the length of the queue
*
* @param Zend_Queue $queue
* @return integer
* @throws Zend_Queue_Exception (not supported)
*/
public function count(Zend_Queue $queue=null)
{
require_once 'Zend/Queue/Exception.php';
throw new Zend_Queue_Exception('count() is not supported in this adapter');
}
/**
* Does a queue already exist?
*
* @param string $name
* @return boolean
* @throws Zend_Queue_Exception (not supported)
*/
public function isExists($name)
{
require_once 'Zend/Queue/Exception.php';
throw new Zend_Queue_Exception('isExists() is not supported in this adapter');
}
/**
* Return a list of queue capabilities functions
*
* $array['function name'] = true or false
* true is supported, false is not supported.
*
* @param string $name
* @return array
*/
public function getCapabilities()
{
return array(
'create' => false,
'delete' => false,
'send' => true,
'receive' => true,
'deleteMessage' => true,
'getQueues' => false,
'count' => false,
'isExists' => false,
);
}
}

View file

@ -0,0 +1,191 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Queue
* @subpackage Adapter
* @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: AdapterAbstract.php 20096 2010-01-06 02:05:09Z bkarwin $
*/
/**
* @see Zend_Queue
*/
require_once 'Zend/Queue.php';
/**
* @see Zend_Queue_Adapter_AdapterInterface
*/
require_once 'Zend/Queue/Adapter/AdapterInterface.php';
/**
* Class for connecting to queues performing common operations.
*
* @category Zend
* @package Zend_Queue
* @subpackage Adapter
* @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
abstract class Zend_Queue_Adapter_AdapterAbstract
implements Zend_Queue_Adapter_AdapterInterface
{
/**
* Default timeout for createQueue() function
*/
const CREATE_TIMEOUT_DEFAULT = 30;
/**
* Default timeout for recieve() function
*/
const RECEIVE_TIMEOUT_DEFAULT = 30;
/**
* User-provided options
*
* @var array
*/
protected $_options = array();
/**
* Internal array of queues to save on lookups
*
* @var array
*/
protected $_queues = array();
/**
* Contains the Zend_Queue that this object
*
* @var Zend_Queue_Adapter_Abstract
*/
protected $_queue = null;
/**
* Constructor.
*
* $options is an array of key/value pairs or an instance of Zend_Config
* containing configuration options. These options are common to most adapters:
*
* See the Zend_Queue Adapter Notes documentation for example configurations.
*
* Some options are used on a case-by-case basis by adapters:
*
* access_key => (string) Amazon AWS Access Key
* secret_key => (string) Amazon AWS Secret Key
* dbname => (string) The name of the database to user
* username => (string) Connect to the database as this username.
* password => (string) Password associated with the username.
* host => (string) What host to connect to, defaults to localhost
* port => (string) The port of the database
*
* @param array|Zend_Config $config An array having configuration data
* @param Zend_Queue The Zend_Queue object that created this class
* @return void
* @throws Zend_Queue_Exception
*/
public function __construct($options, Zend_Queue $queue = null)
{
if ($options instanceof Zend_Config) {
$options = $options->toArray();
}
/*
* Verify that adapter parameters are in an array.
*/
if (!is_array($options)) {
require_once 'Zend/Queue/Exception.php';
throw new Zend_Queue_Exception('Adapter options must be an array or Zend_Config object');
}
// set the queue
if ($queue !== null) {
$this->setQueue($queue);
}
$adapterOptions = array();
$driverOptions = array();
// Normalize the options and merge with the defaults
if (array_key_exists('options', $options)) {
if (!is_array($options['options'])) {
require_once 'Zend/Queue/Exception.php';
throw new Zend_Queue_Exception("Configuration array 'options' must be an array");
}
// Can't use array_merge() because keys might be integers
foreach ($options['options'] as $key => $value) {
$adapterOptions[$key] = $value;
}
}
if (array_key_exists('driverOptions', $options)) {
// can't use array_merge() because keys might be integers
foreach ((array)$options['driverOptions'] as $key => $value) {
$driverOptions[$key] = $value;
}
}
$this->_options = array_merge($this->_options, $options);
$this->_options['options'] = $adapterOptions;
$this->_options['driverOptions'] = $driverOptions;
}
/********************************************************************
* Queue management functions
*********************************************************************/
/**
* get the Zend_Queue class that is attached to this object
*
* @return Zend_Queue|null
*/
public function getQueue()
{
return $this->_queue;
}
/**
* set the Zend_Queue class for this object
*
* @param Zend_Queue $queue
* @return Zend_Queue_Adapter_AdapterInterface
*/
public function setQueue(Zend_Queue $queue)
{
$this->_queue = $queue;
return $this;
}
/**
* Returns the configuration options in this adapter.
*
* @return array
*/
public function getOptions()
{
return $this->_options;
}
/**
* Indicates if a function is supported or not.
*
* @param string $name
* @return boolean
*/
public function isSupported($name)
{
$list = $this->getCapabilities();
return (isset($list[$name]) && $list[$name]);
}
}

View file

@ -0,0 +1,174 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Queue
* @subpackage Adapter
* @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: AdapterInterface.php 20096 2010-01-06 02:05:09Z bkarwin $
*/
/**
* Interface for common queue operations
*
* @category Zend
* @package Zend_Queue
* @subpackage Adapter
* @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
interface Zend_Queue_Adapter_AdapterInterface
{
/**
* Constructor
*
* @param array|Zend_Config $options
* @param Zend_Queue $queue
* @return void
*/
public function __construct($options, Zend_Queue $queue = null);
/**
* Retrieve queue instance
*
* @return Zend_Queue
*/
public function getQueue();
/**
* Set queue instnace
*
* @param Zend_Queue $queue
* @return Zend_Queue_Adapter_AdapterInterface
*/
public function setQueue(Zend_Queue $queue);
/**
* Does a queue already exist?
*
* Use isSupported('isExists') to determine if an adapter can test for
* queue existance.
*
* @param string $name Queue name
* @return boolean
*/
public function isExists($name);
/**
* Create a new queue
*
* Visibility timeout is how long a message is left in the queue
* "invisible" to other readers. If the message is acknowleged (deleted)
* before the timeout, then the message is deleted. However, if the
* timeout expires then the message will be made available to other queue
* readers.
*
* @param string $name Queue name
* @param integer $timeout Default visibility timeout
* @return boolean
*/
public function create($name, $timeout=null);
/**
* Delete a queue and all of its messages
*
* Return false if the queue is not found, true if the queue exists.
*
* @param string $name Queue name
* @return boolean
*/
public function delete($name);
/**
* Get an array of all available queues
*
* Not all adapters support getQueues(); use isSupported('getQueues')
* to determine if the adapter supports this feature.
*
* @return array
*/
public function getQueues();
/**
* Return the approximate number of messages in the queue
*
* @param Zend_Queue|null $queue
* @return integer
*/
public function count(Zend_Queue $queue = null);
/********************************************************************
* Messsage management functions
*********************************************************************/
/**
* Send a message to the queue
*
* @param mixed $message Message to send to the active queue
* @param Zend_Queue|null $queue
* @return Zend_Queue_Message
*/
public function send($message, Zend_Queue $queue = null);
/**
* Get messages in the queue
*
* @param integer|null $maxMessages Maximum number of messages to return
* @param integer|null $timeout Visibility timeout for these messages
* @param Zend_Queue|null $queue
* @return Zend_Queue_Message_Iterator
*/
public function receive($maxMessages = null, $timeout = null, Zend_Queue $queue = null);
/**
* Delete a message from the queue
*
* Return true if the message is deleted, false if the deletion is
* unsuccessful.
*
* @param Zend_Queue_Message $message
* @return boolean
*/
public function deleteMessage(Zend_Queue_Message $message);
/********************************************************************
* Supporting functions
*********************************************************************/
/**
* Returns the configuration options in this adapter.
*
* @return array
*/
public function getOptions();
/**
* Return a list of queue capabilities functions
*
* $array['function name'] = true or false
* true is supported, false is not supported.
*
* @return array
*/
public function getCapabilities();
/**
* Indicates if a function is supported or not.
*
* @param string $name Function name
* @return boolean
*/
public function isSupported($name);
}

View file

@ -0,0 +1,355 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Queue
* @subpackage Adapter
* @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Array.php 20096 2010-01-06 02:05:09Z bkarwin $
*/
/**
* @see Zend_Queue_Adapter_AdapterAbstract
*/
require_once 'Zend/Queue/Adapter/AdapterAbstract.php';
/**
* Class for using a standard PHP array as a queue
*
* @category Zend
* @package Zend_Queue
* @subpackage Adapter
* @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Queue_Adapter_Array extends Zend_Queue_Adapter_AdapterAbstract
{
/**
* @var array
*/
protected $_data = array();
/**
* Constructor
*
* @param array|Zend_Config $options
* @param Zend_Queue|null $queue
* @return void
*/
public function __construct($options, Zend_Queue $queue = null)
{
parent::__construct($options, $queue);
}
/********************************************************************
* Queue management functions
*********************************************************************/
/**
* Does a queue already exist?
*
* Throws an exception if the adapter cannot determine if a queue exists.
* use isSupported('isExists') to determine if an adapter can test for
* queue existance.
*
* @param string $name
* @return boolean
*/
public function isExists($name)
{
return array_key_exists($name, $this->_data);
}
/**
* Create a new queue
*
* Visibility timeout is how long a message is left in the queue "invisible"
* to other readers. If the message is acknowleged (deleted) before the
* timeout, then the message is deleted. However, if the timeout expires
* then the message will be made available to other queue readers.
*
* @param string $name queue name
* @param integer $timeout default visibility timeout
* @return boolean
*/
public function create($name, $timeout=null)
{
if ($this->isExists($name)) {
return false;
}
if ($timeout === null) {
$timeout = self::CREATE_TIMEOUT_DEFAULT;
}
$this->_data[$name] = array();
return true;
}
/**
* Delete a queue and all of it's messages
*
* Returns false if the queue is not found, true if the queue exists
*
* @param string $name queue name
* @return boolean
*/
public function delete($name)
{
$found = isset($this->_data[$name]);
if ($found) {
unset($this->_data[$name]);
}
return $found;
}
/**
* Get an array of all available queues
*
* Not all adapters support getQueues(), use isSupported('getQueues')
* to determine if the adapter supports this feature.
*
* @return array
*/
public function getQueues()
{
return array_keys($this->_data);
}
/**
* Return the approximate number of messages in the queue
*
* @param Zend_Queue $queue
* @return integer
* @throws Zend_Queue_Exception
*/
public function count(Zend_Queue $queue=null)
{
if ($queue === null) {
$queue = $this->_queue;
}
if (!isset($this->_data[$queue->getName()])) {
/**
* @see Zend_Queue_Exception
*/
require_once 'Zend/Queue/Exception.php';
throw new Zend_Queue_Exception('Queue does not exist');
}
return count($this->_data[$queue->getName()]);
}
/********************************************************************
* Messsage management functions
*********************************************************************/
/**
* Send a message to the queue
*
* @param string $message Message to send to the active queue
* @param Zend_Queue $queue
* @return Zend_Queue_Message
* @throws Zend_Queue_Exception
*/
public function send($message, Zend_Queue $queue=null)
{
if ($queue === null) {
$queue = $this->_queue;
}
if (!$this->isExists($queue->getName())) {
require_once 'Zend/Queue/Exception.php';
throw new Zend_Queue_Exception('Queue does not exist:' . $queue->getName());
}
// create the message
$data = array(
'message_id' => md5(uniqid(rand(), true)),
'body' => $message,
'md5' => md5($message),
'handle' => null,
'created' => time(),
'queue_name' => $queue->getName(),
);
// add $data to the "queue"
$this->_data[$queue->getName()][] = $data;
$options = array(
'queue' => $queue,
'data' => $data,
);
$classname = $queue->getMessageClass();
if (!class_exists($classname)) {
require_once 'Zend/Loader.php';
Zend_Loader::loadClass($classname);
}
return new $classname($options);
}
/**
* Get messages in the queue
*
* @param integer $maxMessages Maximum number of messages to return
* @param integer $timeout Visibility timeout for these messages
* @param Zend_Queue $queue
* @return Zend_Queue_Message_Iterator
*/
public function receive($maxMessages = null, $timeout = null, Zend_Queue $queue = null)
{
if ($maxMessages === null) {
$maxMessages = 1;
}
if ($timeout === null) {
$timeout = self::RECEIVE_TIMEOUT_DEFAULT;
}
if ($queue === null) {
$queue = $this->_queue;
}
$data = array();
if ($maxMessages > 0) {
$start_time = microtime(true);
$count = 0;
$temp = &$this->_data[$queue->getName()];
foreach ($temp as $key=>&$msg) {
// count check has to be first, as someone can ask for 0 messages
// ZF-7650
if ($count >= $maxMessages) {
break;
}
if (($msg['handle'] === null)
|| ($msg['timeout'] + $timeout < $start_time)
) {
$msg['handle'] = md5(uniqid(rand(), true));
$msg['timeout'] = microtime(true);
$data[] = $msg;
$count++;
}
}
}
$options = array(
'queue' => $queue,
'data' => $data,
'messageClass' => $queue->getMessageClass(),
);
$classname = $queue->getMessageSetClass();
if (!class_exists($classname)) {
require_once 'Zend/Loader.php';
Zend_Loader::loadClass($classname);
}
return new $classname($options);
}
/**
* Delete a message from the queue
*
* Returns true if the message is deleted, false if the deletion is
* unsuccessful.
*
* @param Zend_Queue_Message $message
* @return boolean
* @throws Zend_Queue_Exception
*/
public function deleteMessage(Zend_Queue_Message $message)
{
// load the queue
$queue = &$this->_data[$message->queue_name];
foreach ($queue as $key => &$msg) {
if ($msg['handle'] == $message->handle) {
unset($queue[$key]);
return true;
}
}
return false;
}
/********************************************************************
* Supporting functions
*********************************************************************/
/**
* Return a list of queue capabilities functions
*
* $array['function name'] = true or false
* true is supported, false is not supported.
*
* @param string $name
* @return array
*/
public function getCapabilities()
{
return array(
'create' => true,
'delete' => true,
'send' => true,
'receive' => true,
'deleteMessage' => true,
'getQueues' => true,
'count' => true,
'isExists' => true,
);
}
/********************************************************************
* Functions that are not part of the Zend_Queue_Adapter_Abstract
*********************************************************************/
/**
* serialize
*/
public function __sleep()
{
return array('_data');
}
/*
* These functions are debug helpers.
*/
/**
* returns underlying _data array
* $queue->getAdapter()->getData();
*
* @return $this;
*/
public function getData()
{
return $this->_data;
}
/**
* sets the underlying _data array
* $queue->getAdapter()->setData($data);
*
* @param $data array
* @return $this;
*/
public function setData($data)
{
$this->_data = $data;
return $this;
}
}

View file

@ -0,0 +1,536 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Queue
* @subpackage Adapter
* @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Db.php 20096 2010-01-06 02:05:09Z bkarwin $
*/
/**
* @see Zend_Queue_Adapter_AdapterAbstract
*/
require_once 'Zend/Queue/Adapter/AdapterAbstract.php';
/**
* @see Zend_Db_Select
*/
require_once 'Zend/Db/Select.php';
/**
* @see Zend_Db
*/
require_once 'Zend/Db.php';
/**
* @see Zend_Queue_Adapter_Db_Queue
*/
require_once 'Zend/Queue/Adapter/Db/Queue.php';
/**
* @see Zend_Queue_Adapter_Db_Message
*/
require_once 'Zend/Queue/Adapter/Db/Message.php';
/**
* Class for using connecting to a Zend_Db-based queuing system
*
* @category Zend
* @package Zend_Queue
* @subpackage Adapter
* @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Queue_Adapter_Db extends Zend_Queue_Adapter_AdapterAbstract
{
/**
* @var Zend_Queue_Adapter_Db_Queue
*/
protected $_queueTable = null;
/**
* @var Zend_Queue_Adapter_Db_Message
*/
protected $_messageTable = null;
/**
* @var Zend_Db_Table_Row_Abstract
*/
protected $_messageRow = null;
/**
* Constructor
*
* @param array|Zend_Config $options
* @param Zend_Queue|null $queue
* @return void
*/
public function __construct($options, Zend_Queue $queue = null)
{
parent::__construct($options, $queue);
if (!isset($this->_options['options'][Zend_Db_Select::FOR_UPDATE])) {
// turn off auto update by default
$this->_options['options'][Zend_Db_Select::FOR_UPDATE] = false;
}
if (!is_bool($this->_options['options'][Zend_Db_Select::FOR_UPDATE])) {
require_once 'Zend/Queue/Exception.php';
throw new Zend_Queue_Exception('Options array item: Zend_Db_Select::FOR_UPDATE must be boolean');
}
if (isset($this->_options['dbAdapter'])
&& $this->_options['dbAdapter'] instanceof Zend_Db_Adapter_Abstract) {
$db = $this->_options['dbAdapter'];
} else {
$db = $this->_initDbAdapter();
}
$this->_queueTable = new Zend_Queue_Adapter_Db_Queue(array(
'db' => $db,
));
$this->_messageTable = new Zend_Queue_Adapter_Db_Message(array(
'db' => $db,
));
}
/**
* Initialize Db adapter using 'driverOptions' section of the _options array
*
* Throws an exception if the adapter cannot connect to DB.
*
* @return Zend_Db_Adapter_Abstract
* @throws Zend_Queue_Exception
*/
protected function _initDbAdapter()
{
$options = &$this->_options['driverOptions'];
if (!array_key_exists('type', $options)) {
require_once 'Zend/Queue/Exception.php';
throw new Zend_Queue_Exception("Configuration array must have a key for 'type' for the database type to use");
}
if (!array_key_exists('host', $options)) {
require_once 'Zend/Queue/Exception.php';
throw new Zend_Queue_Exception("Configuration array must have a key for 'host' for the host to use");
}
if (!array_key_exists('username', $options)) {
require_once 'Zend/Queue/Exception.php';
throw new Zend_Queue_Exception("Configuration array must have a key for 'username' for the username to use");
}
if (!array_key_exists('password', $options)) {
require_once 'Zend/Queue/Exception.php';
throw new Zend_Queue_Exception("Configuration array must have a key for 'password' for the password to use");
}
if (!array_key_exists('dbname', $options)) {
require_once 'Zend/Queue/Exception.php';
throw new Zend_Queue_Exception("Configuration array must have a key for 'dbname' for the database to use");
}
$type = $options['type'];
unset($options['type']);
try {
$db = Zend_Db::factory($type, $options);
} catch (Zend_Db_Exception $e) {
require_once 'Zend/Queue/Exception.php';
throw new Zend_Queue_Exception('Error connecting to database: ' . $e->getMessage(), $e->getCode(), $e);
}
return $db;
}
/********************************************************************
* Queue management functions
*********************************************************************/
/**
* Does a queue already exist?
*
* Throws an exception if the adapter cannot determine if a queue exists.
* use isSupported('isExists') to determine if an adapter can test for
* queue existance.
*
* @param string $name
* @return boolean
* @throws Zend_Queue_Exception
*/
public function isExists($name)
{
$id = 0;
try {
$id = $this->getQueueId($name);
} catch (Zend_Queue_Exception $e) {
return false;
}
return ($id > 0);
}
/**
* Create a new queue
*
* Visibility timeout is how long a message is left in the queue "invisible"
* to other readers. If the message is acknowleged (deleted) before the
* timeout, then the message is deleted. However, if the timeout expires
* then the message will be made available to other queue readers.
*
* @param string $name queue name
* @param integer $timeout default visibility timeout
* @return boolean
* @throws Zend_Queue_Exception - database error
*/
public function create($name, $timeout = null)
{
if ($this->isExists($name)) {
return false;
}
$queue = $this->_queueTable->createRow();
$queue->queue_name = $name;
$queue->timeout = ($timeout === null) ? self::CREATE_TIMEOUT_DEFAULT : (int)$timeout;
try {
if ($queue->save()) {
return true;
}
} catch (Exception $e) {
require_once 'Zend/Queue/Exception.php';
throw new Zend_Queue_Exception($e->getMessage(), $e->getCode(), $e);
}
return false;
}
/**
* Delete a queue and all of it's messages
*
* Returns false if the queue is not found, true if the queue exists
*
* @param string $name queue name
* @return boolean
* @throws Zend_Queue_Exception - database error
*/
public function delete($name)
{
$id = $this->getQueueId($name); // get primary key
// if the queue does not exist then it must already be deleted.
$list = $this->_queueTable->find($id);
if (count($list) === 0) {
return false;
}
$queue = $list->current();
if ($queue instanceof Zend_Db_Table_Row_Abstract) {
try {
$queue->delete();
} catch (Exception $e) {
require_once 'Zend/Queue/Exception.php';
throw new Zend_Queue_Exception($e->getMessage(), $e->getCode(), $e);
}
}
if (array_key_exists($name, $this->_queues)) {
unset($this->_queues[$name]);
}
return true;
}
/*
* Get an array of all available queues
*
* Not all adapters support getQueues(), use isSupported('getQueues')
* to determine if the adapter supports this feature.
*
* @return array
* @throws Zend_Queue_Exception - database error
*/
public function getQueues()
{
$query = $this->_queueTable->select();
$query->from($this->_queueTable, array('queue_id', 'queue_name'));
$this->_queues = array();
foreach ($this->_queueTable->fetchAll($query) as $queue) {
$this->_queues[$queue->queue_name] = (int)$queue->queue_id;
}
$list = array_keys($this->_queues);
return $list;
}
/**
* Return the approximate number of messages in the queue
*
* @param Zend_Queue $queue
* @return integer
* @throws Zend_Queue_Exception
*/
public function count(Zend_Queue $queue = null)
{
if ($queue === null) {
$queue = $this->_queue;
}
$info = $this->_messageTable->info();
$db = $this->_messageTable->getAdapter();
$query = $db->select();
$query->from($info['name'], array(new Zend_Db_Expr('COUNT(1)')))
->where('queue_id=?', $this->getQueueId($queue->getName()));
// return count results
return (int) $db->fetchOne($query);
}
/********************************************************************
* Messsage management functions
*********************************************************************/
/**
* Send a message to the queue
*
* @param string $message Message to send to the active queue
* @param Zend_Queue $queue
* @return Zend_Queue_Message
* @throws Zend_Queue_Exception - database error
*/
public function send($message, Zend_Queue $queue = null)
{
if ($this->_messageRow === null) {
$this->_messageRow = $this->_messageTable->createRow();
}
if ($queue === null) {
$queue = $this->_queue;
}
if (is_scalar($message)) {
$message = (string) $message;
}
if (is_string($message)) {
$message = trim($message);
}
if (!$this->isExists($queue->getName())) {
require_once 'Zend/Queue/Exception.php';
throw new Zend_Queue_Exception('Queue does not exist:' . $queue->getName());
}
$msg = clone $this->_messageRow;
$msg->queue_id = $this->getQueueId($queue->getName());
$msg->created = time();
$msg->body = $message;
$msg->md5 = md5($message);
// $msg->timeout = ??? @TODO
try {
$msg->save();
} catch (Exception $e) {
require_once 'Zend/Queue/Exception.php';
throw new Zend_Queue_Exception($e->getMessage(), $e->getCode(), $e);
}
$options = array(
'queue' => $queue,
'data' => $msg->toArray(),
);
$classname = $queue->getMessageClass();
if (!class_exists($classname)) {
require_once 'Zend/Loader.php';
Zend_Loader::loadClass($classname);
}
return new $classname($options);
}
/**
* Get messages in the queue
*
* @param integer $maxMessages Maximum number of messages to return
* @param integer $timeout Visibility timeout for these messages
* @param Zend_Queue $queue
* @return Zend_Queue_Message_Iterator
* @throws Zend_Queue_Exception - database error
*/
public function receive($maxMessages = null, $timeout = null, Zend_Queue $queue = null)
{
if ($maxMessages === null) {
$maxMessages = 1;
}
if ($timeout === null) {
$timeout = self::RECEIVE_TIMEOUT_DEFAULT;
}
if ($queue === null) {
$queue = $this->_queue;
}
$msgs = array();
$info = $this->_messageTable->info();
$microtime = microtime(true); // cache microtime
$db = $this->_messageTable->getAdapter();
// start transaction handling
try {
if ( $maxMessages > 0 ) { // ZF-7666 LIMIT 0 clause not included.
$db->beginTransaction();
$query = $db->select();
if ($this->_options['options'][Zend_Db_Select::FOR_UPDATE]) {
// turn on forUpdate
$query->forUpdate();
}
$query->from($info['name'], array('*'))
->where('queue_id=?', $this->getQueueId($queue->getName()))
->where('handle IS NULL OR timeout+' . (int)$timeout . ' < ' . (int)$microtime)
->limit($maxMessages);
foreach ($db->fetchAll($query) as $data) {
// setup our changes to the message
$data['handle'] = md5(uniqid(rand(), true));
$update = array(
'handle' => $data['handle'],
'timeout' => $microtime,
);
// update the database
$where = array();
$where[] = $db->quoteInto('message_id=?', $data['message_id']);
$where[] = 'handle IS NULL OR timeout+' . (int)$timeout . ' < ' . (int)$microtime;
$count = $db->update($info['name'], $update, $where);
// we check count to make sure no other thread has gotten
// the rows after our select, but before our update.
if ($count > 0) {
$msgs[] = $data;
}
}
$db->commit();
}
} catch (Exception $e) {
$db->rollBack();
require_once 'Zend/Queue/Exception.php';
throw new Zend_Queue_Exception($e->getMessage(), $e->getCode(), $e);
}
$options = array(
'queue' => $queue,
'data' => $msgs,
'messageClass' => $queue->getMessageClass(),
);
$classname = $queue->getMessageSetClass();
if (!class_exists($classname)) {
require_once 'Zend/Loader.php';
Zend_Loader::loadClass($classname);
}
return new $classname($options);
}
/**
* Delete a message from the queue
*
* Returns true if the message is deleted, false if the deletion is
* unsuccessful.
*
* @param Zend_Queue_Message $message
* @return boolean
* @throws Zend_Queue_Exception - database error
*/
public function deleteMessage(Zend_Queue_Message $message)
{
$db = $this->_messageTable->getAdapter();
$where = $db->quoteInto('handle=?', $message->handle);
if ($this->_messageTable->delete($where)) {
return true;
}
return false;
}
/********************************************************************
* Supporting functions
*********************************************************************/
/**
* Return a list of queue capabilities functions
*
* $array['function name'] = true or false
* true is supported, false is not supported.
*
* @param string $name
* @return array
*/
public function getCapabilities()
{
return array(
'create' => true,
'delete' => true,
'send' => true,
'receive' => true,
'deleteMessage' => true,
'getQueues' => true,
'count' => true,
'isExists' => true,
);
}
/********************************************************************
* Functions that are not part of the Zend_Queue_Adapter_Abstract
*********************************************************************/
/**
* Get the queue ID
*
* Returns the queue's row identifier.
*
* @param string $name
* @return integer|null
* @throws Zend_Queue_Exception
*/
protected function getQueueId($name)
{
if (array_key_exists($name, $this->_queues)) {
return $this->_queues[$name];
}
$query = $this->_queueTable->select();
$query->from($this->_queueTable, array('queue_id'))
->where('queue_name=?', $name);
$queue = $this->_queueTable->fetchRow($query);
if ($queue === null) {
require_once 'Zend/Queue/Exception.php';
throw new Zend_Queue_Exception('Queue does not exist: ' . $name);
}
$this->_queues[$name] = (int)$queue->queue_id;
return $this->_queues[$name];
}
}

View file

@ -0,0 +1,51 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Queue
* @subpackage Adapter
* @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Message.php 20096 2010-01-06 02:05:09Z bkarwin $
*/
/**
* @see Zend_Db_Table_Abstract
*/
require_once 'Zend/Db/Table/Abstract.php';
/**
* @category Zend
* @package Zend_Queue
* @subpackage Adapter
* @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Queue_Adapter_Db_Message extends Zend_Db_Table_Abstract
{
/**
* @var string
*/
protected $_name = 'message';
/**
* @var string
*/
protected $_primary = 'message_id';
/**
* @var mixed
*/
protected $_sequence = true;
}

View file

@ -0,0 +1,51 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Queue
* @subpackage Adapter
* @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Queue.php 20096 2010-01-06 02:05:09Z bkarwin $
*/
/**
* @see Zend_Db_Table_Abstract
*/
require_once 'Zend/Db/Table/Abstract.php';
/**
* @category Zend
* @package Zend_Queue
* @subpackage Adapter
* @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Queue_Adapter_Db_Queue extends Zend_Db_Table_Abstract
{
/**
* @var string
*/
protected $_name = 'queue';
/**
* @var string
*/
protected $_primary = 'queue_id';
/**
* @var mixed
*/
protected $_sequence = true;
}

View file

@ -0,0 +1,75 @@
-- phpMyAdmin SQL Dump
-- version 2.11.6
-- http://www.phpmyadmin.net
--
-- Host: localhost:3306
-- Generation Time: Jun 19, 2008 at 08:09 PM
-- Server version: 5.0.51
-- PHP Version: 5.2.3
SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";
/*
Sample grant for MySQL
GRANT DELETE, INSERT, SELECT, UPDATE ON queue.* TO 'queue'@'127.0.0.1' IDENTIFIED BY '[CHANGE ME]';
mysql -u queue -h 127.0.0.1 -p queue
mysqlaccess queue queue --superuser=root -H 127.0.0.1
*/
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
--
-- Database: `queue`
--
-- --------------------------------------------------------
--
-- Table structure for table `message`
--
DROP TABLE IF EXISTS `message`;
CREATE TABLE IF NOT EXISTS `message` (
`message_id` bigint(20) unsigned NOT NULL auto_increment,
`queue_id` int(10) unsigned NOT NULL,
`handle` char(32) default NULL,
`body` varchar(8192) NOT NULL,
`md5` char(32) NOT NULL,
`timeout` decimal(14,4) unsigned default NULL,
`created` int(10) unsigned NOT NULL,
PRIMARY KEY (`message_id`),
UNIQUE KEY `message_handle` (`handle`),
KEY `message_queueid` (`queue_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Table structure for table `queue`
--
DROP TABLE IF EXISTS `queue`;
CREATE TABLE IF NOT EXISTS `queue` (
`queue_id` int(10) unsigned NOT NULL auto_increment,
`queue_name` varchar(100) NOT NULL,
`timeout` smallint(5) unsigned NOT NULL default '30',
PRIMARY KEY (`queue_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
-- Constraints for dumped tables
--
--
-- Constraints for table `message`
--
ALTER TABLE `message`
ADD CONSTRAINT `message_ibfk_1` FOREIGN KEY (`queue_id`) REFERENCES `queue` (`queue_id`) ON DELETE CASCADE ON UPDATE CASCADE;

View file

@ -0,0 +1,49 @@
/*
Sample grant for PostgreSQL
CREATE ROLE queue LOGIN
PASSWORD '[CHANGE ME]'
NOSUPERUSER NOINHERIT NOCREATEDB NOCREATEROLE;
*/
--
-- Table structure for table `queue`
--
DROP TABLE IF EXISTS queue;
CREATE TABLE queue
(
queue_id serial NOT NULL,
queue_name character varying(100) NOT NULL,
timeout smallint NOT NULL DEFAULT 30,
CONSTRAINT queue_pk PRIMARY KEY (queue_id)
)
WITH (OIDS=FALSE);
ALTER TABLE queue OWNER TO queue;
-- --------------------------------------------------------
--
-- Table structure for table `message`
--
DROP TABLE IF EXISTS message;
CREATE TABLE message
(
message_id bigserial NOT NULL,
queue_id integer,
handle character(32),
body character varying(8192) NOT NULL,
md5 character(32) NOT NULL,
timeout real,
created integer,
CONSTRAINT message_pk PRIMARY KEY (message_id),
CONSTRAINT message_ibfk_1 FOREIGN KEY (queue_id)
REFERENCES queue (queue_id) MATCH SIMPLE
ON UPDATE CASCADE ON DELETE CASCADE
)
WITH (OIDS=FALSE);
ALTER TABLE message OWNER TO queue;

View file

@ -0,0 +1,40 @@
/*
Sample grant for SQLite
CREATE ROLE queue LOGIN
PASSWORD '[CHANGE ME]'
NOSUPERUSER NOINHERIT NOCREATEDB NOCREATEROLE;
*/
--
-- Table structure for table `queue`
--
CREATE TABLE queue
(
queue_id INTEGER PRIMARY KEY AUTOINCREMENT,
queue_name VARCHAR(100) NOT NULL,
timeout INTEGER NOT NULL DEFAULT 30
);
-- --------------------------------------------------------
--
-- Table structure for table `message`
--
CREATE TABLE message
(
message_id INTEGER PRIMARY KEY AUTOINCREMENT,
queue_id INTEGER PRIMARY KEY,
handle CHAR(32),
body VARCHAR(8192) NOT NULL,
md5 CHAR(32) NOT NULL,
timeout REAL,
created INTEGER,
FOREIGN KEY (queue_id) REFERENCES queue(queue_id)
);

View file

@ -0,0 +1,428 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Queue
* @subpackage Adapter
* @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Memcacheq.php 20096 2010-01-06 02:05:09Z bkarwin $
*/
/**
* @see Zend_Queue_Adapter_AdapterAbstract
*/
require_once 'Zend/Queue/Adapter/AdapterAbstract.php';
/**
* Class for using connecting to a Zend_Cache-based queuing system
*
* @category Zend
* @package Zend_Queue
* @subpackage Adapter
* @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Queue_Adapter_Memcacheq extends Zend_Queue_Adapter_AdapterAbstract
{
const DEFAULT_HOST = '127.0.0.1';
const DEFAULT_PORT = 22201;
const EOL = "\r\n";
/**
* @var Memcache
*/
protected $_cache = null;
/**
* @var string
*/
protected $_host = null;
/**
* @var integer
*/
protected $_port = null;
/**
* @var resource
*/
protected $_socket = null;
/********************************************************************
* Constructor / Destructor
*********************************************************************/
/**
* Constructor
*
* @param array|Zend_Config $options
* @param null|Zend_Queue $queue
* @return void
*/
public function __construct($options, Zend_Queue $queue = null)
{
if (!extension_loaded('memcache')) {
require_once 'Zend/Queue/Exception.php';
throw new Zend_Queue_Exception('Memcache extension does not appear to be loaded');
}
parent::__construct($options, $queue);
$options = &$this->_options['driverOptions'];
if (!array_key_exists('host', $options)) {
$options['host'] = self::DEFAULT_HOST;
}
if (!array_key_exists('port', $options)) {
$options['port'] = self::DEFAULT_PORT;
}
$this->_cache = new Memcache();
$result = $this->_cache->connect($options['host'], $options['port']);
if ($result === false) {
require_once 'Zend/Queue/Exception.php';
throw new Zend_Queue_Exception('Could not connect to MemcacheQ');
}
$this->_host = $options['host'];
$this->_port = (int)$options['port'];
}
/**
* Destructor
*
* @return void
*/
public function __destruct()
{
if ($this->_cache instanceof Memcache) {
$this->_cache->close();
}
if (is_resource($this->_socket)) {
$cmd = 'quit' . self::EOL;
fwrite($this->_socket, $cmd);
fclose($this->_socket);
}
}
/********************************************************************
* Queue management functions
*********************************************************************/
/**
* Does a queue already exist?
*
* Throws an exception if the adapter cannot determine if a queue exists.
* use isSupported('isExists') to determine if an adapter can test for
* queue existance.
*
* @param string $name
* @return boolean
* @throws Zend_Queue_Exception
*/
public function isExists($name)
{
if (empty($this->_queues)) {
$this->getQueues();
}
return in_array($name, $this->_queues);
}
/**
* Create a new queue
*
* Visibility timeout is how long a message is left in the queue "invisible"
* to other readers. If the message is acknowleged (deleted) before the
* timeout, then the message is deleted. However, if the timeout expires
* then the message will be made available to other queue readers.
*
* @param string $name queue name
* @param integer $timeout default visibility timeout
* @return boolean
* @throws Zend_Queue_Exception
*/
public function create($name, $timeout=null)
{
if ($this->isExists($name)) {
return false;
}
if ($timeout === null) {
$timeout = self::CREATE_TIMEOUT_DEFAULT;
}
// MemcacheQ does not have a method to "create" a queue
// queues are created upon sending a packet.
// We cannot use the send() and receive() functions because those
// depend on the current name.
$result = $this->_cache->set($name, 'creating queue', 0, 15);
$result = $this->_cache->get($name);
$this->_queues[] = $name;
return true;
}
/**
* Delete a queue and all of it's messages
*
* Returns false if the queue is not found, true if the queue exists
*
* @param string $name queue name
* @return boolean
* @throws Zend_Queue_Exception
*/
public function delete($name)
{
$response = $this->_sendCommand('delete ' . $name, array('DELETED', 'NOT_FOUND'), true);
if (in_array('DELETED', $response)) {
$key = array_search($name, $this->_queues);
if ($key !== false) {
unset($this->_queues[$key]);
}
return true;
}
return false;
}
/**
* Get an array of all available queues
*
* Not all adapters support getQueues(), use isSupported('getQueues')
* to determine if the adapter supports this feature.
*
* @return array
* @throws Zend_Queue_Exception
*/
public function getQueues()
{
$this->_queues = array();
$response = $this->_sendCommand('stats queue', array('END'));
foreach ($response as $i => $line) {
$this->_queues[] = str_replace('STAT ', '', $line);
}
return $this->_queues;
}
/**
* Return the approximate number of messages in the queue
*
* @param Zend_Queue $queue
* @return integer
* @throws Zend_Queue_Exception (not supported)
*/
public function count(Zend_Queue $queue=null)
{
require_once 'Zend/Queue/Exception.php';
throw new Zend_Queue_Exception('count() is not supported in this adapter');
}
/********************************************************************
* Messsage management functions
*********************************************************************/
/**
* Send a message to the queue
*
* @param string $message Message to send to the active queue
* @param Zend_Queue $queue
* @return Zend_Queue_Message
* @throws Zend_Queue_Exception
*/
public function send($message, Zend_Queue $queue=null)
{
if ($queue === null) {
$queue = $this->_queue;
}
if (!$this->isExists($queue->getName())) {
require_once 'Zend/Queue/Exception.php';
throw new Zend_Queue_Exception('Queue does not exist:' . $queue->getName());
}
$message = (string) $message;
$data = array(
'message_id' => md5(uniqid(rand(), true)),
'handle' => null,
'body' => $message,
'md5' => md5($message),
);
$result = $this->_cache->set($queue->getName(), $message, 0, 0);
if ($result === false) {
require_once 'Zend/Queue/Exception.php';
throw new Zend_Queue_Exception('failed to insert message into queue:' . $queue->getName());
}
$options = array(
'queue' => $queue,
'data' => $data,
);
$classname = $queue->getMessageClass();
if (!class_exists($classname)) {
require_once 'Zend/Loader.php';
Zend_Loader::loadClass($classname);
}
return new $classname($options);
}
/**
* Get messages in the queue
*
* @param integer $maxMessages Maximum number of messages to return
* @param integer $timeout Visibility timeout for these messages
* @param Zend_Queue $queue
* @return Zend_Queue_Message_Iterator
* @throws Zend_Queue_Exception
*/
public function receive($maxMessages=null, $timeout=null, Zend_Queue $queue=null)
{
if ($maxMessages === null) {
$maxMessages = 1;
}
if ($timeout === null) {
$timeout = self::RECEIVE_TIMEOUT_DEFAULT;
}
if ($queue === null) {
$queue = $this->_queue;
}
$msgs = array();
if ($maxMessages > 0 ) {
for ($i = 0; $i < $maxMessages; $i++) {
$data = array(
'handle' => md5(uniqid(rand(), true)),
'body' => $this->_cache->get($queue->getName()),
);
$msgs[] = $data;
}
}
$options = array(
'queue' => $queue,
'data' => $msgs,
'messageClass' => $queue->getMessageClass(),
);
$classname = $queue->getMessageSetClass();
if (!class_exists($classname)) {
require_once 'Zend/Loader.php';
Zend_Loader::loadClass($classname);
}
return new $classname($options);
}
/**
* Delete a message from the queue
*
* Returns true if the message is deleted, false if the deletion is
* unsuccessful.
*
* @param Zend_Queue_Message $message
* @return boolean
* @throws Zend_Queue_Exception (unsupported)
*/
public function deleteMessage(Zend_Queue_Message $message)
{
require_once 'Zend/Queue/Exception.php';
throw new Zend_Queue_Exception('deleteMessage() is not supported in ' . get_class($this));
}
/********************************************************************
* Supporting functions
*********************************************************************/
/**
* Return a list of queue capabilities functions
*
* $array['function name'] = true or false
* true is supported, false is not supported.
*
* @param string $name
* @return array
*/
public function getCapabilities()
{
return array(
'create' => true,
'delete' => true,
'send' => true,
'receive' => true,
'deleteMessage' => false,
'getQueues' => true,
'count' => false,
'isExists' => true,
);
}
/********************************************************************
* Functions that are not part of the Zend_Queue_Adapter_Abstract
*********************************************************************/
/**
* sends a command to MemcacheQ
*
* The memcache functions by php cannot handle all types of requests
* supported by MemcacheQ
* Non-standard requests are handled by this function.
*
* @param string $command - command to send to memcacheQ
* @param array $terminator - strings to indicate end of memcacheQ response
* @param boolean $include_term - include terminator in response
* @return array
* @throws Zend_Queue_Exception if connection cannot be opened
*/
protected function _sendCommand($command, array $terminator, $include_term=false)
{
if (!is_resource($this->_socket)) {
$this->_socket = fsockopen($this->_host, $this->_port, $errno, $errstr, 10);
}
if ($this->_socket === false) {
require_once 'Zend/Queue/Exception.php';
throw new Zend_Queue_Exception("Could not open a connection to $this->_host:$this->_port errno=$errno : $errstr");
}
$response = array();
$cmd = $command . self::EOL;
fwrite($this->_socket, $cmd);
$continue_reading = true;
while (!feof($this->_socket) && $continue_reading) {
$resp = trim(fgets($this->_socket, 1024));
if (in_array($resp, $terminator)) {
if ($include_term) {
$response[] = $resp;
}
$continue_reading = false;
} else {
$response[] = $resp;
}
}
return $response;
}
}

View file

@ -0,0 +1,174 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Queue
* @subpackage Adapter
* @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Null.php 20096 2010-01-06 02:05:09Z bkarwin $
*/
/**
* @see Zend_Queue_Adapter_AdapterAbstract
*/
require_once 'Zend/Queue/Adapter/AdapterAbstract.php';
/**
* Class testing. No supported functions. Also used to disable a Zend_Queue.
*
* @category Zend
* @package Zend_Queue
* @subpackage Adapter
* @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Queue_Adapter_Null extends Zend_Queue_Adapter_AdapterAbstract
{
/**
* Constructor
*
* @param array|Zend_Config $options
* @param null|Zend_Queue $queue
* @return void
*/
public function __construct($options, Zend_Queue $queue = null)
{
parent::__construct($options, $queue);
}
/********************************************************************
* Queue management functions
*********************************************************************/
/**
* Does a queue already exist?
*
* @throws Zend_Queue_Exception - not supported.
*/
public function isExists($name)
{
require_once 'Zend/Queue/Exception.php';
throw new Zend_Queue_Exception(__FUNCTION__ . '() is not supported by ' . get_class($this));
}
/**
* Create a new queue
*
* @throws Zend_Queue_Exception - not supported.
*/
public function create($name, $timeout=null)
{
require_once 'Zend/Queue/Exception.php';
throw new Zend_Queue_Exception(__FUNCTION__ . '() is not supported by ' . get_class($this));
}
/**
* Delete a queue and all of it's messages
*
* @throws Zend_Queue_Exception - not supported.
*/
public function delete($name)
{
require_once 'Zend/Queue/Exception.php';
throw new Zend_Queue_Exception(__FUNCTION__ . '() is not supported by ' . get_class($this));
}
/**
* Get an array of all available queues
*
* @throws Zend_Queue_Exception - not supported.
*/
public function getQueues()
{
require_once 'Zend/Queue/Exception.php';
throw new Zend_Queue_Exception(__FUNCTION__ . '() is not supported by ' . get_class($this));
}
/**
* Return the approximate number of messages in the queue
*
* @throws Zend_Queue_Exception - not supported.
*/
public function count(Zend_Queue $queue=null)
{
require_once 'Zend/Queue/Exception.php';
throw new Zend_Queue_Exception(__FUNCTION__ . '() is not supported by ' . get_class($this));
}
/********************************************************************
* Messsage management functions
*********************************************************************/
/**
* Send a message to the queue
*
* @throws Zend_Queue_Exception - not supported.
*/
public function send($message, Zend_Queue $queue=null)
{
require_once 'Zend/Queue/Exception.php';
throw new Zend_Queue_Exception(__FUNCTION__ . '() is not supported by ' . get_class($this));
}
/**
* Get messages in the queue
*
* @throws Zend_Queue_Exception - not supported.
*/
public function receive($maxMessages=null, $timeout=null, Zend_Queue $queue=null)
{
require_once 'Zend/Queue/Exception.php';
throw new Zend_Queue_Exception(__FUNCTION__ . '() is not supported by ' . get_class($this));
}
/**
* Delete a message from the queue
*
* @throws Zend_Queue_Exception - not supported.
*/
public function deleteMessage(Zend_Queue_Message $message)
{
require_once 'Zend/Queue/Exception.php';
throw new Zend_Queue_Exception(__FUNCTION__ . '() is not supported by ' . get_class($this));
}
/********************************************************************
* Supporting functions
*********************************************************************/
/**
* Return a list of queue capabilities functions
*
* $array['function name'] = true or false
* true is supported, false is not supported.
*
* @param string $name
* @return array
*/
public function getCapabilities()
{
return array(
'create' => false,
'delete' => false,
'send' => false,
'receive' => false,
'deleteMessage' => false,
'getQueues' => false,
'count' => false,
'isExists' => false,
);
}
}

View file

@ -0,0 +1,343 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Queue
* @subpackage Adapter
* @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: PlatformJobQueue.php 20096 2010-01-06 02:05:09Z bkarwin $
*/
/**
* @see Zend_Queue_Adapter_AdapterAbstract
*/
require_once 'Zend/Queue/Adapter/AdapterAbstract.php';
/**
* Zend Platform JobQueue adapter
*
* @category Zend
* @package Zend_Queue
* @subpackage Adapter
* @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Queue_Adapter_PlatformJobQueue extends Zend_Queue_Adapter_AdapterAbstract
{
/**
* @var ZendApi_JobQueue
*/
protected $_zendQueue;
/**
* Constructor
*
* @param array|Zend_Config $options
* @param Zend_Queue|null $queue
* @return void
*/
public function __construct($options, Zend_Queue $queue = null)
{
parent::__construct($options, $queue);
if (!extension_loaded("jobqueue_client")) {
require_once 'Zend/Queue/Exception.php';
throw new Zend_Queue_Exception('Platform Job Queue extension does not appear to be loaded');
}
if (! isset($this->_options['daemonOptions'])) {
require_once 'Zend/Queue/Exception.php';
throw new Zend_Queue_Exception('Job Queue host and password should be provided');
}
$options = $this->_options['daemonOptions'];
if (!array_key_exists('host', $options)) {
require_once 'Zend/Queue/Exception.php';
throw new Zend_Queue_Exception('Platform Job Queue host should be provided');
}
if (!array_key_exists('password', $options)) {
require_once 'Zend/Queue/Exception.php';
throw new Zend_Queue_Exception('Platform Job Queue password should be provided');
}
$this->_zendQueue = new ZendApi_Queue($options['host']);
if (!$this->_zendQueue) {
require_once 'Zend/Queue/Exception.php';
throw new Zend_Queue_Exception('Platform Job Queue connection failed');
}
if (!$this->_zendQueue->login($options['password'])) {
require_once 'Zend/Queue/Exception.php';
throw new Zend_Queue_Exception('Job Queue login failed');
}
if ($this->_queue) {
$this->_queue->setMessageClass('Zend_Queue_Message_PlatformJob');
}
}
/********************************************************************
* Queue management functions
********************************************************************/
/**
* Does a queue already exist?
*
* @param string $name
* @return boolean
* @throws Zend_Queue_Exception (not supported)
*/
public function isExists($name)
{
require_once 'Zend/Queue/Exception.php';
throw new Zend_Queue_Exception('isExists() is not supported in this adapter');
}
/**
* Create a new queue
*
* @param string $name queue name
* @param integer $timeout default visibility timeout
* @return void
* @throws Zend_Queue_Exception
*/
public function create($name, $timeout=null)
{
require_once 'Zend/Queue/Exception.php';
throw new Zend_Queue_Exception('create() is not supported in ' . get_class($this));
}
/**
* Delete a queue and all of its messages
*
* @param string $name queue name
* @return void
* @throws Zend_Queue_Exception
*/
public function delete($name)
{
require_once 'Zend/Queue/Exception.php';
throw new Zend_Queue_Exception('delete() is not supported in ' . get_class($this));
}
/**
* Get an array of all available queues
*
* @return void
* @throws Zend_Queue_Exception
*/
public function getQueues()
{
require_once 'Zend/Queue/Exception.php';
throw new Zend_Queue_Exception('getQueues() is not supported in this adapter');
}
/**
* Return the approximate number of messages in the queue
*
* @param Zend_Queue|null $queue
* @return integer
*/
public function count(Zend_Queue $queue = null)
{
if ($queue !== null) {
require_once 'Zend/Queue/Exception.php';
throw new Zend_Queue_Exception('Queue parameter is not supported');
}
return $this->_zendQueue->getNumOfJobsInQueue();
}
/********************************************************************
* Messsage management functions
********************************************************************/
/**
* Send a message to the queue
*
* @param array | ZendAPI_job $message Message to send to the active queue
* @param Zend_Queue $queue Not supported
* @return Zend_Queue_Message
* @throws Zend_Queue_Exception
*/
public function send($message, Zend_Queue $queue = null)
{
if ($queue !== null) {
require_once 'Zend/Queue/Exception.php';
throw new Zend_Queue_Exception('Queue parameter is not supported');
}
// This adapter can work only for this message type
$classname = $this->_queue->getMessageClass();
if (!class_exists($classname)) {
require_once 'Zend/Loader.php';
Zend_Loader::loadClass($classname);
}
if ($message instanceof ZendAPI_Job) {
$message = array('data' => $message);
}
$zendApiJob = new $classname($message);
// Unfortunately, the Platform JQ API is PHP4-style...
$platformJob = $zendApiJob->getJob();
$jobId = $this->_zendQueue->addJob($platformJob);
if (!$jobId) {
require_once 'Zend/Queue/Exception.php';
throw new Zend_Queue_Exception('Failed to add a job to queue: '
. $this->_zendQueue->getLastError());
}
$zendApiJob->setJobId($jobId);
return $zendApiJob;
}
/**
* Get messages in the queue
*
* @param integer $maxMessages Maximum number of messages to return
* @param integer $timeout Ignored
* @param Zend_Queue $queue Not supported
* @throws Zend_Queue_Exception
* @return ArrayIterator
*/
public function receive($maxMessages = null, $timeout = null, Zend_Queue $queue = null)
{
if ($maxMessages === null) {
$maxMessages = 1;
}
if ($queue !== null) {
require_once 'Zend/Queue/Exception.php';
throw new Zend_Queue_Exception('Queue shouldn\'t be set');
}
$jobs = $this->_zendQueue->getJobsInQueue(null, $maxMessages, true);
$classname = $this->_queue->getMessageClass();
if (!class_exists($classname)) {
require_once 'Zend/Loader.php';
Zend_Loader::loadClass($classname);
}
$options = array(
'queue' => $this->_queue,
'data' => $jobs,
'messageClass' => $this->_queue->getMessageClass(),
);
$classname = $this->_queue->getMessageSetClass();
if (!class_exists($classname)) {
require_once 'Zend/Loader.php';
Zend_Loader::loadClass($classname);
}
return new $classname($options);
}
/**
* Delete a message from the queue
*
* Returns true if the message is deleted, false if the deletion is
* unsuccessful.
*
* @param Zend_Queue_Message $message
* @return boolean
* @throws Zend_Queue_Exception
*/
public function deleteMessage(Zend_Queue_Message $message)
{
if (get_class($message) != $this->_queue->getMessageClass()) {
require_once 'Zend/Queue/Exception.php';
throw new Zend_Queue_Exception(
'Failed to remove job from the queue; only messages of type '
. 'Zend_Queue_Message_PlatformJob may be used'
);
}
return $this->_zendQueue->removeJob($message->getJobId());
}
public function isJobIdExist($id)
{
return (($this->_zendQueue->getJob($id))? true : false);
}
/********************************************************************
* Supporting functions
********************************************************************/
/**
* Return a list of queue capabilities functions
*
* $array['function name'] = true or false
* true is supported, false is not supported.
*
* @param string $name
* @return array
*/
public function getCapabilities()
{
return array(
'create' => false,
'delete' => false,
'getQueues' => false,
'isExists' => false,
'count' => true,
'send' => true,
'receive' => true,
'deleteMessage' => true,
);
}
/********************************************************************
* Functions that are not part of the Zend_Queue_Adapter_AdapterAbstract
********************************************************************/
/**
* Serialize
*
* @return array
*/
public function __sleep()
{
return array('_options');
}
/**
* Unserialize
*
* @return void
*/
public function __wakeup()
{
$options = $this->_options['daemonOptions'];
$this->_zendQueue = new ZendApi_Queue($options['host']);
if (!$this->_zendQueue) {
require_once 'Zend/Queue/Exception.php';
throw new Zend_Queue_Exception('Platform Job Queue connection failed');
}
if (!$this->_zendQueue->login($options['password'])) {
require_once 'Zend/Queue/Exception.php';
throw new Zend_Queue_Exception('Job Queue login failed');
}
}
}

View file

@ -0,0 +1,35 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Queue
* @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Exception.php 20096 2010-01-06 02:05:09Z bkarwin $
*/
/**
* @see Zend_Exception
*/
require_once 'Zend/Exception.php';
/**
* @category Zend
* @package Zend_Queue
* @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Queue_Exception extends Zend_Exception
{
}

View file

@ -0,0 +1,230 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Queue
* @subpackage Message
* @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Message.php 20096 2010-01-06 02:05:09Z bkarwin $
*/
/**
* Class for managing queue messages
*
* @category Zend
* @package Zend_Queue
* @subpackage Message
* @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Queue_Message
{
/**
* The data for the queue message
*
* @var array
*/
protected $_data = array();
/**
* Connected is true if we have a reference to a live
* Zend_Queue_Adapter_Abstract object.
* This is false after the Message has been deserialized.
*
* @var boolean
*/
protected $_connected = true;
/**
* Zend_Queue parent class or instance
*
* @var Zend_Queue
*/
protected $_queue = null;
/**
* Name of the class of the Zend_Queue
*
* @var string
*/
protected $_queueClass = null;
/**
* Constructor
*
* @param array $options
* @throws Zend_Queue_Exception
*/
public function __construct(array $options = array())
{
if (isset($options['queue'])) {
if ($options['queue'] instanceof Zend_Queue) {
$this->_queue = $options['queue'];
$this->_queueClass = get_class($this->_queue);
} else {
$result = gettype($options['queue']);
if ($result === 'object') {
$result = get_class($options['queue']);
}
require_once 'Zend/Queue/Exception.php';
throw new Zend_Queue_Exception(
'$options[\'queue\'] = '
. $result
. ': must be instanceof Zend_Queue'
);
}
}
if (isset($options['data'])) {
if (!is_array($options['data'])) {
require_once 'Zend/Queue/Exception.php';
throw new Zend_Queue_Exception('Data must be an array');
}
$this->_data = $options['data'];
}
}
/**
* Retrieve message field value
*
* @param string $key The user-specified key name.
* @return string The corresponding key value.
* @throws Zend_Queue_Exception if the $key is not a column in the message.
*/
public function __get($key)
{
if (!array_key_exists($key, $this->_data)) {
require_once 'Zend/Queue/Exception.php';
throw new Zend_Queue_Exception("Specified field \"$key\" is not in the message");
}
return $this->_data[$key];
}
/**
* Set message field value
*
* @param string $key The message key.
* @param mixed $value The value for the property.
* @return void
* @throws Zend_Queue_Exception
*/
public function __set($key, $value)
{
if (!array_key_exists($key, $this->_data)) {
require_once 'Zend/Queue/Exception.php';
throw new Zend_Queue_Exception("Specified field \"$key\" is not in the message");
}
$this->_data[$key] = $value;
}
/**
* Test existence of message field
*
* @param string $key The column key.
* @return boolean
*/
public function __isset($key)
{
return array_key_exists($key, $this->_data);
}
/*
* Serialize
*/
/**
* Store queue and data in serialized object
*
* @return array
*/
public function __sleep()
{
return array('_queueClass', '_data');
}
/**
* Setup to do on wakeup.
* A de-serialized Message should not be assumed to have access to a live
* queue connection, so set _connected = false.
*
* @return void
*/
public function __wakeup()
{
$this->_connected = false;
}
/**
* Returns the queue object, or null if this is disconnected message
*
* @return Zend_Queue|null
*/
public function getQueue()
{
return $this->_queue;
}
/**
* Set the queue object, to re-establish a live connection
* to the queue for a Message that has been de-serialized.
*
* @param Zend_Queue $queue
* @return boolean
*/
public function setQueue(Zend_Queue $queue)
{
$queueClass = get_class($queue);
$this->_queue = $queue;
$this->_queueClass = $queueClass;
$this->_connected = true;
return true;
}
/**
* Query the class name of the Queue object for which this
* Message was created.
*
* @return string
*/
public function getQueueClass()
{
return $this->_queueClass;
}
/**
* Returns the column/value data as an array.
*
* @return array
*/
public function toArray()
{
return $this->_data;
}
/**
* Sets all data in the row from an array.
*
* @param array $data
* @return Zend_Queue_Message Provides a fluent interface
*/
public function setFromArray(array $data)
{
foreach ($data as $columnName => $value) {
$this->$columnName = $value;
}
return $this;
}
}

View file

@ -0,0 +1,285 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Queue
* @subpackage Message
* @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Iterator.php 20096 2010-01-06 02:05:09Z bkarwin $
*/
/**
* @category Zend
* @package Zend_Queue
* @subpackage Message
* @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Queue_Message_Iterator implements Iterator, Countable
{
/**
* The data for the queue message
*
* @var array
*/
protected $_data = array();
/**
* Connected is true if we have a reference to a live
* Zend_Queue_Adapter_AdapterInterface object.
* This is false after the Message has been deserialized.
*
* @var boolean
*/
protected $_connected = true;
/**
* Zend_Queue_Adapter_AdapterInterface parent class or instance
*
* @var Zend_Queue_Adapter_AdapterInterface
*/
protected $_queue = null;
/**
* Name of the class of the Zend_Queue_Adapter_AdapterInterface object.
*
* @var string
*/
protected $_queueClass = null;
/**
* Zend_Queue_Message class name
*
* @var string
*/
protected $_messageClass = 'Zend_Queue_Message';
/**
* Iterator pointer.
*
* @var integer
*/
protected $_pointer = 0;
/**
* Constructor
*
* @param array $options ('queue', 'messageClass', 'data'=>array());
* @return void
*/
public function __construct(array $options = array())
{
if (isset($options['queue'])) {
$this->_queue = $options['queue'];
$this->_queueClass = get_class($this->_queue);
$this->_connected = true;
} else {
$this->_connected = false;
}
if (isset($options['messageClass'])) {
$this->_messageClass = $options['messageClass'];
}
if (!is_array($options['data'])) {
require_once 'Zend/Queue/Exception.php';
throw new Zend_Queue_Exception('array optionsuration must have $options[\'data\'] = array');
}
// load the message class
$classname = $this->_messageClass;
if (!class_exists($classname)) {
require_once 'Zend/Loader.php';
Zend_Loader::loadClass($classname);
}
// for each of the messages
foreach ($options['data'] as $data) {
// construct the message parameters
$message = array('data' => $data);
// If queue has not been set, then use the default.
if (empty($message['queue'])) {
$message['queue'] = $this->_queue;
}
// construct the message and add it to _data[];
$this->_data[] = new $classname($message);
}
}
/**
* Store queue and data in serialized object
*
* @return array
*/
public function __sleep()
{
return array('_data', '_queueClass', '_messageClass', '_pointer');
}
/**
* Setup to do on wakeup.
* A de-serialized Message should not be assumed to have access to a live
* queue connection, so set _connected = false.
*
* @return void
*/
public function __wakeup()
{
$this->_connected = false;
}
/**
* Returns all data as an array.
*
* Used for debugging.
*
* @return array
*/
public function toArray()
{
// @todo This works only if we have iterated through
// the result set once to instantiate the messages.
foreach ($this->_data as $i => $message) {
$this->_data[$i] = $message->toArray();
}
return $this->_data;
}
/**
* Returns the queue object, or null if this is disconnected message set
*
* @return Zend_Queue|null
*/
public function getQueue()
{
return $this->_queue;
}
/**
* Set the queue object, to re-establish a live connection
* to the queue for a Message that has been de-serialized.
*
* @param Zend_Queue_Adapter_AdapterInterface $queue
* @return boolean
* @throws Zend_Queue_Exception
*/
public function setQueue(Zend_Queue $queue)
{
$this->_queue = $queue;
$this->_connected = false;
// @todo This works only if we have iterated through
// the result set once to instantiate the rows.
foreach ($this->_data as $i => $message) {
$this->_connected = $this->_connected || $message->setQueue($queue);
}
return $this->_connected;
}
/**
* Query the class name of the Queue object for which this
* Message was created.
*
* @return string
*/
public function getQueueClass()
{
return $this->_queueClass;
}
/*
* Iterator implementation
*/
/**
* Rewind the Iterator to the first element.
* Similar to the reset() function for arrays in PHP.
* Required by interface Iterator.
*
* @return void
*/
public function rewind()
{
$this->_pointer = 0;
}
/**
* Return the current element.
* Similar to the current() function for arrays in PHP
* Required by interface Iterator.
*
* @return Zend_Queue_Message current element from the collection
*/
public function current()
{
return (($this->valid() === false)
? null
: $this->_data[$this->_pointer]); // return the messages object
}
/**
* Return the identifying key of the current element.
* Similar to the key() function for arrays in PHP.
* Required by interface Iterator.
*
* @return integer
*/
public function key()
{
return $this->_pointer;
}
/**
* Move forward to next element.
* Similar to the next() function for arrays in PHP.
* Required by interface Iterator.
*
* @return void
*/
public function next()
{
++$this->_pointer;
}
/**
* Check if there is a current element after calls to rewind() or next().
* Used to check if we've iterated to the end of the collection.
* Required by interface Iterator.
*
* @return bool False if there's nothing more to iterate over
*/
public function valid()
{
return $this->_pointer < count($this);
}
/*
* Countable Implementation
*/
/**
* Returns the number of elements in the collection.
*
* Implements Countable::count()
*
* @return integer
*/
public function count()
{
return count($this->_data);
}
}

View file

@ -0,0 +1,194 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Queue
* @subpackage Message
* @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: PlatformJob.php 20096 2010-01-06 02:05:09Z bkarwin $
*/
/**
* @see Zend_Queue_Message
*/
require_once 'Zend/Queue/Message.php';
/**
* Class for managing Zend Platform JobQueue jobs via Zend_Queue
*
* @category Zend
* @package Zend_Queue
* @subpackage Message
* @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Queue_Message_PlatformJob extends Zend_Queue_Message
{
/**
* @var ZendApi_Job
*/
protected $_job;
/**
* Job identifier
* @var string
*/
protected $_id = null;
/**
* Constructor
*
* The constructor should be an array of options.
*
* If the option 'data' is provided, and is an instance of ZendApi_Job,
* that object will be used as the internal job; if that option is not a
* ZendApi_Job instance, an exception will be thrown.
*
* Alternately, you may specify the 'script' parameter, which should be a
* JobQueue script the job will request. A new ZendApi_Job object will then
* be created using that script and any options you provide.
*
* @param array $options
* @return void
* @throws Zend_Queue_Exception
*/
public function __construct(array $options = array())
{
if (isset($options['data'])) {
if (!($options['data'] instanceof ZendApi_Job)) {
require_once 'Zend/Queue/Exception.php';
throw new Zend_Queue_Exception('Data must be an instance of ZendApi_Job');
}
$this->_job = $options['data'];
parent::__construct($this->_job->getProperties());
} else {
parent::__construct($options);
if (!isset($options['script'])) {
require_once 'Zend/Queue/Exception.php';
throw new Zend_Queue_Exception('The script is mandatory data');
}
$this->_job = new ZendApi_Job($options['script']);
$this->_setJobProperties();
}
}
/**
* Set the job identifier
*
* Used within Zend_Queue only.
*
* @param string $id
* @return Zend_Queue_Message_PlatformJob
*/
public function setJobId($id)
{
$this->_id = $id;
return $this;
}
/**
* Retrieve the job identifier
*
* @return string
*/
public function getJobId()
{
return (($this->_id) ? $this->_id : $this->_job->getID());
}
/**
* Retrieve the internal ZendApi_Job instance
*
* @return ZendApi_Job
*/
public function getJob()
{
return $this->_job;
}
/**
* Store queue and data in serialized object
*
* @return array
*/
public function __sleep()
{
return serialize('_job', '_id', '_data');
}
/**
* Query the class name of the Queue object for which this
* Message was created.
*
* @return string
*/
public function getQueueClass()
{
return 'Zend_Queue_Adapter_Platform_JQ';
}
/**
* Sets properties on the ZendApi_Job instance
*
* Any options in the {@link $_data} array will be checked. Those matching
* options in ZendApi_Job will be used to set those options in that
* instance.
*
* @return void
*/
protected function _setJobProperties() {
if (isset($this->_data['script'])) {
$this->_job->setScript($this->_data['script']);
}
if (isset($this->_data['priority'])) {
$this->_job->setJobPriority($this->_data['priority']);
}
if (isset($this->_data['name'])) {
$this->_job->setJobName($this->_data['name']);
}
if (isset($this->_data['predecessor'])) {
$this->_job->setJobDependency($this->_data['predecessor']);
}
if (isset($this->_data['preserved'])) {
$this->_job->setPreserved($this->_data['preserved']);
}
if (isset($this->_data['user_variables'])) {
$this->_job->setUserVariables($this->_data['user_variables']);
}
if (!empty($this->_data['interval'])) {
$endTime = isset($this->_data['end_time']) ? $this->_data['end_time'] : null;
$this->_job->setRecurrenceData($this->_data['interval'], $endTime);
} elseif (isset($this->_data['interval']) && ($this->_data['interval'] === '')) {
$this->_job->setRecurrenceData(0,0);
}
if (isset($this->_data['scheduled_time'])) {
$this->_job->setScheduledTime($this->_data['scheduled_time']);
}
if (isset($this->_data['application_id'])) {
$this->_job->setApplicationID($this->_data['application_id']);
}
}
}

View file

@ -0,0 +1,173 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Queue
* @subpackage Stomp
* @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Client.php 20096 2010-01-06 02:05:09Z bkarwin $
*/
/**
* The Stomp client interacts with a Stomp server.
*
* @category Zend
* @package Zend_Queue
* @subpackage Stomp
* @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Queue_Stomp_Client
{
/**
* Array of $client Zend_Queue_Stomp_Client_Interface
*
* @var array
*/
protected $_connection;
/**
* Add a server to connections
*
* @param string scheme
* @param string host
* @param integer port
*/
public function __construct(
$scheme = null, $host = null, $port = null,
$connectionClass = 'Zend_Queue_Stomp_Client_Connection',
$frameClass = 'Zend_Queue_Stomp_Frame'
) {
if (($scheme !== null)
&& ($host !== null)
&& ($port !== null)
) {
$this->addConnection($scheme, $host, $port, $connectionClass);
$this->getConnection()->setFrameClass($frameClass);
}
}
/**
* Shutdown
*
* @return void
*/
public function __destruct()
{
if ($this->getConnection()) {
$this->getConnection()->close(true);
}
}
/**
* Add a connection to this client.
*
* Attempts to add this class to the client. Returns a boolean value
* indicating success of operation.
*
* You cannot add more than 1 connection to the client at this time.
*
* @param string $scheme ['tcp', 'udp']
* @param string host
* @param integer port
* @param string class - create a connection with this class; class must support Zend_Queue_Stomp_Client_ConnectionInterface
* @return boolean
*/
public function addConnection($scheme, $host, $port, $class = 'Zend_Queue_Stomp_Client_Connection')
{
if (!class_exists($class)) {
require_once 'Zend/Loader.php';
Zend_Loader::loadClass($class);
}
$connection = new $class();
if ($connection->open($scheme, $host, $port)) {
$this->setConnection($connection);
return true;
}
$connection->close();
return false;
}
/**
* Set client connection
*
* @param Zend_Queue_Stomp_Client_ConnectionInterface $connection
* @return void
*/
public function setConnection(Zend_Queue_Stomp_Client_ConnectionInterface $connection)
{
$this->_connection = $connection;
return $this;
}
/**
* Get client connection
*
* @return Zend_Queue_Stomp_Client_ConnectionInterface|null
*/
public function getConnection()
{
return $this->_connection;
}
/**
* Send a stomp frame
*
* Returns true if the frame was successfully sent.
*
* @param Zend_Queue_Stomp_FrameInterface $frame
* @return boolean
*/
public function send(Zend_Queue_Stomp_FrameInterface $frame)
{
$this->getConnection()->write($frame);
return $this;
}
/**
* Receive a frame
*
* Returns a frame or false if none were to be read.
*
* @return Zend_Queue_Stomp_FrameInterface|boolean
*/
public function receive()
{
return $this->getConnection()->read();
}
/**
* canRead()
*
* @return boolean
*/
public function canRead()
{
return $this->getConnection()->canRead();
}
/**
* creates a frame class
*
* @return Zend_Queue_Stomp_FrameInterface
*/
public function createFrame()
{
return $this->getConnection()->createFrame();
}
}

View file

@ -0,0 +1,280 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Queue
* @subpackage Stomp
* @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Connection.php 20096 2010-01-06 02:05:09Z bkarwin $
*/
/**
* @see Zend_Queue_Stomp_Client_ConnectionInterface
*/
require_once 'Zend/Queue/Stomp/Client/ConnectionInterface.php';
/**
* The Stomp client interacts with a Stomp server.
*
* @category Zend
* @package Zend_Queue
* @subpackage Stomp
* @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Queue_Stomp_Client_Connection
implements Zend_Queue_Stomp_Client_ConnectionInterface
{
const READ_TIMEOUT_DEFAULT_USEC = 0; // 0 microseconds
const READ_TIMEOUT_DEFAULT_SEC = 5; // 5 seconds
/**
* Connection options
* @var array
*/
protected $_options;
/**
* tcp/udp socket
*
* @var resource
*/
protected $_socket = false;
/**
* open() opens a socket to the Stomp server
*
* @param array $options ('scheme', 'host', 'port')
* @param string $scheme
* @param string $host
* @param int $port
* @param array $options Accepts "timeout_sec" and "timeout_usec" keys
* @return true;
* @throws Zend_Queue_Exception
*/
public function open($scheme, $host, $port, array $options = array())
{
$str = $scheme . '://' . $host;
$this->_socket = fsockopen($str, $port, $errno, $errstr);
if ($this->_socket === false) {
// aparently there is some reason that fsockopen will return false
// but it normally throws an error.
require_once 'Zend/Queue/Exception.php';
throw new Zend_Queue_Exception("Unable to connect to $str; error = $errstr ( errno = $errno )");
}
stream_set_blocking($this->_socket, 0); // non blocking
if (!isset($options['timeout_sec'])) {
$options['timeout_sec'] = self::READ_TIMEOUT_DEFAULT_SEC;
}
if (! isset($options['timeout_usec'])) {
$options['timeout_usec'] = self::READ_TIMEOUT_DEFAULT_USEC;
}
$this->_options = $options;
return true;
}
/**
* Close the socket explicitly when destructed
*
* @return void
*/
public function __destruct()
{
}
/**
* Close connection
*
* @param boolean $destructor
* @return void
*/
public function close($destructor = false)
{
// Gracefully disconnect
if (!$destructor) {
$frame = $this->createFrame();
$frame->setCommand('DISCONNECT');
$this->write($frame);
}
// @todo: Should be fixed.
// When the socket is "closed", it will trigger the below error when php exits
// Fatal error: Exception thrown without a stack frame in Unknown on line 0
// Danlo: I suspect this is because this has already been claimed by the interpeter
// thus trying to shutdown this resources, which is already shutdown is a problem.
if (is_resource($this->_socket)) {
// fclose($this->_socket);
}
// $this->_socket = null;
}
/**
* Check whether we are connected to the server
*
* @return true
* @throws Zend_Queue_Exception
*/
public function ping()
{
if (!is_resource($this->_socket)) {
require_once 'Zend/Queue/Exception.php';
throw new Zend_Queue_Exception('Not connected to Stomp server');
}
return true;
}
/**
* Write a frame to the stomp server
*
* example: $response = $client->write($frame)->read();
*
* @param Zend_Queue_Stom_FrameInterface $frame
* @return $this
*/
public function write(Zend_Queue_Stomp_FrameInterface $frame)
{
$this->ping();
$output = $frame->toFrame();
$bytes = fwrite($this->_socket, $output, strlen($output));
if ($bytes === false || $bytes == 0) {
require_once 'Zend/Queue/Exception.php';
throw new Zend_Queue_Exception('No bytes written');
}
return $this;
}
/**
* Tests the socket to see if there is data for us
*
* @return boolean
*/
public function canRead()
{
$read = array($this->_socket);
$write = null;
$except = null;
return stream_select(
$read,
$write,
$except,
$this->_options['timeout_sec'],
$this->_options['timeout_usec']
) == 1;
// see http://us.php.net/manual/en/function.stream-select.php
}
/**
* Reads in a frame from the socket or returns false.
*
* @return Zend_Queue_Stomp_FrameInterface|false
* @throws Zend_Queue_Exception
*/
public function read()
{
$this->ping();
$response = '';
$prev = '';
// while not end of file.
while (!feof($this->_socket)) {
// read in one character until "\0\n" is found
$data = fread($this->_socket, 1);
// check to make sure that the connection is not lost.
if ($data === false) {
require_once 'Zend/Queue/Exception.php';
throw new Zend_Queue_Exception('Connection lost');
}
// append last character read to $response
$response .= $data;
// is this \0 (prev) \n (data)? END_OF_FRAME
if (ord($data) == 10 && ord($prev) == 0) {
break;
}
$prev = $data;
}
if ($response === '') {
return false;
}
$frame = $this->createFrame();
$frame->fromFrame($response);
return $frame;
}
/**
* Set the frameClass to be used
*
* This must be a Zend_Queue_Stomp_FrameInterface.
*
* @param string $classname - class is an instance of Zend_Queue_Stomp_FrameInterface
* @return $this;
*/
public function setFrameClass($classname)
{
$this->_options['frameClass'] = $classname;
return $this;
}
/**
* Get the frameClass
*
* @return string
*/
public function getFrameClass()
{
return isset($this->_options['frameClass'])
? $this->_options['frameClass']
: 'Zend_Queue_Stomp_Frame';
}
/**
* Create an empty frame
*
* @return Zend_Queue_Stomp_FrameInterface
*/
public function createFrame()
{
$class = $this->getFrameClass();
if (!class_exists($class)) {
require_once 'Zend/Loader.php';
Zend_Loader::loadClass($class);
}
$frame = new $class();
if (!$frame instanceof Zend_Queue_Stomp_FrameInterface) {
require_once 'Zend/Queue/Exception.php';
throw new Zend_Queue_Exception('Invalid Frame class provided; must implement Zend_Queue_Stomp_FrameInterface');
}
return $frame;
}
}

View file

@ -0,0 +1,103 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Queue
* @subpackage Stomp
* @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: ConnectionInterface.php 20096 2010-01-06 02:05:09Z bkarwin $
*/
/**
* The Stomp client interacts with a Stomp server.
*
* @category Zend
* @package Zend_Queue
* @subpackage Stomp
* @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
interface Zend_Queue_Stomp_Client_ConnectionInterface
{
/**
* @param string $scheme ['tcp', 'udp']
* @param string host
* @param integer port
* @param string class - create a connection with this class; class must support Zend_Queue_Stomp_Client_Connection_Interface
* @return boolean
*/
public function open($scheme, $host, $port);
/**
* @param boolean $destructor
* @return void
*/
public function close($destructor = false);
/**
* Check whether we are connected to the server
*
* @return true
* @throws Zend_Queue_Exception
*/
public function ping();
/**
* write a frame to the stomp server
*
* example: $response = $client->write($frame)->read();
*
* @param Zend_Queue_Stomp_FrameInterface $frame
* @return $this
*/
public function write(Zend_Queue_Stomp_FrameInterface $frame);
/**
* tests the socket to see if there is data for us
*/
public function canRead();
/**
* reads in a frame from the socket or returns false.
*
* @return Zend_Queue_Stomp_Frame|false
* @throws Zend_Queue_Exception
*/
public function read();
/**
* Set the frame class to be used
*
* This must be a Zend_Queue_Stomp_FrameInterface.
*
* @param string $class
* @return Zend_Queue_Stomp_Client_ConnectionInterface;
*/
public function setFrameClass($class);
/**
* Get the frameClass
*
* @return string
*/
public function getFrameClass();
/**
* create an empty frame
*
* @return Zend_Queue_Stomp_FrameInterface class
*/
public function createFrame();
}

View file

@ -0,0 +1,363 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Queue
* @subpackage Stomp
* @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Frame.php 20096 2010-01-06 02:05:09Z bkarwin $
*/
/**
* @see Zend_Queue_Stomp_FrameInterface
*/
require_once 'Zend/Queue/Stomp/FrameInterface.php';
/**
* This class represents a Stomp Frame
*
* @category Zend
* @package Zend_Queue
* @subpackage Stomp
* @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Queue_Stomp_Frame
implements Zend_Queue_Stomp_FrameInterface
{
const END_OF_FRAME = "\x00\n";
const CONTENT_LENGTH = 'content-length';
const EOL = "\n";
/**
* Headers for the frame
*
* @var array
*/
protected $_headers = array();
/**
* The command for the frame
*
* @var string
*/
protected $_command = null;
/**
* The body of the frame
*
* @var string
*/
protected $_body = null;
/**
* Do the content-length automatically?
*/
protected $_autoContentLength = null;
/**
* Constructor
*/
public function __construct()
{
$this->setHeaders(array());
$this->setBody(null);
$this->setCommand(null);
$this->setAutoContentLength(true);
}
/**
* get the status of the auto content length
*
* If AutoContentLength is true this code will automatically put the
* content-length header in, even if it is already set by the user.
*
* This is done to make the message sending more reliable.
*
* @return boolean
*/
public function getAutoContentLength()
{
return $this->_autoContentLength;
}
/**
* setAutoContentLength()
*
* Set the value on or off.
*
* @param boolean $auto
* @return $this;
* @throws Zend_Queue_Exception
*/
public function setAutoContentLength($auto)
{
if (!is_bool($auto)) {
require_once 'Zend/Queue/Exception.php';
throw new Zend_Queue_Exception('$auto is not a boolean');
}
$this->_autoContentLength = $auto;
return $this;
}
/**
* Get the headers
*
* @return array
*/
public function getHeaders()
{
return $this->_headers;
}
/**
* Set the headers
*
* Throws an exception if the array values are not strings.
*
* @param array $headers
* @return $this
* @throws Zend_Queue_Exception
*/
public function setHeaders(array $headers)
{
foreach ($headers as $header => $value) {
$this->setHeader($header, $value);
}
return $this;
}
/**
* Sets a value for a header
*
* @param string $header
* @param string $value
* @return Zend_Queue_Stomp_Frame
* @throws Zend_Queue_Exception
*/
public function setHeader($header, $value) {
if (!is_string($header)) {
require_once 'Zend/Queue/Exception.php';
throw new Zend_Queue_Exception('$header is not a string: ' . print_r($header, true));
}
if (!is_scalar($value)) {
require_once 'Zend/Queue/Exception.php';
throw new Zend_Queue_Exception('$value is not a string: ' . print_r($value, true));
}
$this->_headers[$header] = $value;
return $this;
}
/**
* Returns a value for a header
*
* Returns false if the header does not exist.
*
* @param string $header
* @return string|false
* @throws Zend_Queue_Exception
*/
public function getHeader($header)
{
if (!is_string($header)) {
require_once 'Zend/Queue/Exception.php';
throw new Zend_Queue_Exception('$header is not a string');
}
return isset($this->_headers[$header])
? $this->_headers[$header]
: false;
}
/**
* Return the body for this frame
*
* Returns false if the body does not exist
*
* @return false|string
*/
public function getBody()
{
return is_null($this->_body)
? false
: $this->_body;
}
/**
* Set the body for this frame
*
* Set to null for no body.
*
* @param string|null $body
* @return Zend_Queue_Stomp_Frame
* @throws Zend_Queue_Exception
*/
public function setBody($body)
{
if (!is_string($body) && !is_null($body)) {
require_once 'Zend/Queue/Exception.php';
throw new Zend_Queue_Exception('$body is not a string or null');
}
$this->_body = $body;
return $this;
}
/**
* Return the command for this frame
*
* Return false if the command does not exist
*
* @return string|false
*/
public function getCommand()
{
return is_null($this->_command)
? false
: $this->_command;
}
/**
* Set the body for this frame
*
* @param string|null
* @return Zend_Queue_Stomp_Frame
* @throws Zend_Queue_Exception
*/
public function setCommand($command)
{
if (!is_string($command) && !is_null($command)) {
require_once 'Zend/Queue/Exception.php';
throw new Zend_Queue_Exception('$command is not a string or null');
}
$this->_command = $command;
return $this;
}
/**
* Takes the current parameters and returns a Stomp Frame
*
* @return string
* @throws Zend_Queue_Exception
*/
public function toFrame()
{
if ($this->getCommand() === false) {
require_once 'Zend/Queue/Exception.php';
throw new Zend_Queue_Exception('You must set the command');
}
$command = $this->getCommand();
$headers = $this->getHeaders();
$body = $this->getBody();
$frame = '';
// add a content-length to the SEND command.
// @see http://stomp.codehaus.org/Protocol
if ($this->getAutoContentLength()) {
$headers[self::CONTENT_LENGTH] = strlen($this->getBody());
}
// Command
$frame = $command . self::EOL;
// Headers
foreach ($headers as $key=>$value) {
$frame .= $key . ': ' . $value . self::EOL;
}
// Seperator
$frame .= self::EOL; // blank line required by protocol
// add the body if any
if ($body !== false) {
$frame .= $body;
}
$frame .= self::END_OF_FRAME;
return $frame;
}
/**
* @see toFrame()
* @return string
*/
public function __toString()
{
try {
$return = $this->toFrame();
} catch (Zend_Queue_Exception $e) {
$return = '';
}
return $return;
}
/**
* Accepts a frame and deconstructs the frame into its component parts
*
* @param string $frame - a stomp frame
* @return $this
*/
public function fromFrame($frame)
{
if (!is_string($frame)) {
require_once 'Zend/Queue/Exception.php';
throw new Zend_Queue_Exception('$frame is not a string');
}
$headers = array();
$body = null;
$command = false;
$header = '';
// separate the headers and the body
$match = self::EOL . self::EOL;
if (preg_match('/' . $match . '/', $frame)) {
list ($header, $body) = explode($match, $frame, 2);
} else {
$header = $frame;
}
// blow up headers
$headers = explode(self::EOL, $header);
unset($header);
// get the command (first line)
$this->setCommand(array_shift($headers));
// set each of the headers.
foreach ($headers as $header) {
if (strpos($header, ':') > 0) {
list($name, $value) = explode(':', $header, 2);
$this->setHeader($name, $value);
}
}
// crop the body if content-length is present
if ($this->getHeader(self::CONTENT_LENGTH) !== false ) {
$length = (int) $this->getHeader(self::CONTENT_LENGTH);
$body = substr($body, 0, $length);
}
$this->setBody($body);
return $this;
}
}

View file

@ -0,0 +1,154 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Queue
* @subpackage Stomp
* @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: FrameInterface.php 20096 2010-01-06 02:05:09Z bkarwin $
*/
/**
* This class represents a Stomp Frame Interface
*
* @category Zend
* @package Zend_Queue
* @subpackage Stomp
* @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
interface Zend_Queue_Stomp_FrameInterface
{
/**
* Get the status of the auto content length
*
* If AutoContentLength is true this code will automatically put the
* content-length header in, even if it is already set by the user.
*
* This is done to make the message sending more reliable.
*
* @return boolean
*/
public function getAutoContentLength();
/**
* setAutoContentLength()
*
* Set the value on or off.
*
* @param boolean $auto
* @return $this;
* @throws Zend_Queue_Exception
*/
public function setAutoContentLength($auto);
/**
* Get the headers
*
* @return array
*/
public function getHeaders();
/**
* Set the headers
*
* Throws an exception if the array values are not strings.
*
* @param array $headers
* @return $this
* @throws Zend_Queue_Exception
*/
public function setHeaders(array $headers);
/**
* Returns a value for a header
* returns false if the header does not exist
*
* @param string $header
* @return $string
* @throws Zend_Queue_Exception
*/
public function getHeader($header);
/**
* Returns a value for a header
* returns false if the header does not exist
*
* @param string $header
* @param string $value
* @return $this
* @throws Zend_Queue_Exception
*/
public function setHeader($header, $value);
/**
* Return the body for this frame
* returns false if the body does not exist
*
* @return $this
*/
public function getBody();
/**
* Set the body for this frame
* returns false if the body does not exist
*
* Set to null for no body.
*
* @param string|null $body
* @return $this
* @throws Zend_Queue_Exception
*/
public function setBody($body);
/**
* Return the command for this frame
* return false if the command does not exist
*
* @return $this
*/
public function getCommand();
/**
* Set the body for this frame
* returns false if the body does not exist
*
* @return $this
* @throws Zend_Queue_Exception
*/
public function setCommand($command);
/**
* Takes the current parameters and returns a Stomp Frame
*
* @throws Zend_Queue_Exception
* @return string
*/
public function toFrame();
/**
* @see toFrame()
*/
public function __toString();
/**
* Accepts a frame and deconstructs the frame into its' component parts
*
* @param string $frame - a stomp frame
* @return $this
*/
public function fromFrame($frame);
}