adding zend project folders into old campcaster.

This commit is contained in:
naomiaro 2010-12-07 14:19:27 -05:00
parent 56abfaf28e
commit 7ef0c18b26
4045 changed files with 1054952 additions and 0 deletions

View file

@ -0,0 +1,197 @@
<?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_Service_WindowsAzure
* @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: SharedKeyCredentials.php 14561 2009-05-07 08:05:12Z unknown $
*/
/**
* @see Zend_Http_Client
*/
require_once 'Zend/Http/Client.php';
/**
* @category Zend
* @package Zend_Service_WindowsAzure
* @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_Service_WindowsAzure_Credentials_CredentialsAbstract
{
/**
* Development storage account and key
*/
const DEVSTORE_ACCOUNT = "devstoreaccount1";
const DEVSTORE_KEY = "Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==";
/**
* HTTP header prefixes
*/
const PREFIX_PROPERTIES = "x-ms-prop-";
const PREFIX_METADATA = "x-ms-meta-";
const PREFIX_STORAGE_HEADER = "x-ms-";
/**
* Permissions
*/
const PERMISSION_READ = "r";
const PERMISSION_WRITE = "w";
const PERMISSION_DELETE = "d";
const PERMISSION_LIST = "l";
/**
* Account name for Windows Azure
*
* @var string
*/
protected $_accountName = '';
/**
* Account key for Windows Azure
*
* @var string
*/
protected $_accountKey = '';
/**
* Use path-style URI's
*
* @var boolean
*/
protected $_usePathStyleUri = false;
/**
* Creates a new Zend_Service_WindowsAzure_Credentials_CredentialsAbstract instance
*
* @param string $accountName Account name for Windows Azure
* @param string $accountKey Account key for Windows Azure
* @param boolean $usePathStyleUri Use path-style URI's
*/
public function __construct(
$accountName = Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::DEVSTORE_ACCOUNT,
$accountKey = Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::DEVSTORE_KEY,
$usePathStyleUri = false
) {
$this->_accountName = $accountName;
$this->_accountKey = base64_decode($accountKey);
$this->_usePathStyleUri = $usePathStyleUri;
}
/**
* Set account name for Windows Azure
*
* @param string $value
* @return Zend_Service_WindowsAzure_Credentials_CredentialsAbstract
*/
public function setAccountName($value = Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::DEVSTORE_ACCOUNT)
{
$this->_accountName = $value;
return $this;
}
/**
* Set account key for Windows Azure
*
* @param string $value
* @return Zend_Service_WindowsAzure_Credentials_CredentialsAbstract
*/
public function setAccountkey($value = Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::DEVSTORE_KEY)
{
$this->_accountKey = base64_decode($value);
return $this;
}
/**
* Set use path-style URI's
*
* @param boolean $value
* @return Zend_Service_WindowsAzure_Credentials_CredentialsAbstract
*/
public function setUsePathStyleUri($value = false)
{
$this->_usePathStyleUri = $value;
return $this;
}
/**
* Sign request URL with credentials
*
* @param string $requestUrl Request URL
* @param string $resourceType Resource type
* @param string $requiredPermission Required permission
* @return string Signed request URL
*/
abstract public function signRequestUrl(
$requestUrl = '',
$resourceType = Zend_Service_WindowsAzure_Storage::RESOURCE_UNKNOWN,
$requiredPermission = Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_READ
);
/**
* Sign request headers with credentials
*
* @param string $httpVerb HTTP verb the request will use
* @param string $path Path for the request
* @param string $queryString Query string for the request
* @param array $headers x-ms headers to add
* @param boolean $forTableStorage Is the request for table storage?
* @param string $resourceType Resource type
* @param string $requiredPermission Required permission
* @return array Array of headers
*/
abstract public function signRequestHeaders(
$httpVerb = Zend_Http_Client::GET,
$path = '/',
$queryString = '',
$headers = null,
$forTableStorage = false,
$resourceType = Zend_Service_WindowsAzure_Storage::RESOURCE_UNKNOWN,
$requiredPermission = Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_READ
);
/**
* Prepare query string for signing
*
* @param string $value Original query string
* @return string Query string for signing
*/
protected function _prepareQueryStringForSigning($value)
{
// Check for 'comp='
if (strpos($value, 'comp=') === false) {
// If not found, no query string needed
return '';
} else {
// If found, make sure it is the only parameter being used
if (strlen($value) > 0 && strpos($value, '?') === 0) {
$value = substr($value, 1);
}
// Split parts
$queryParts = explode('&', $value);
foreach ($queryParts as $queryPart) {
if (strpos($queryPart, 'comp=') !== false) {
return '?' . $queryPart;
}
}
// Should never happen...
return '';
}
}
}

View file

@ -0,0 +1,305 @@
<?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_Service_WindowsAzure
* @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: SharedKeyCredentials.php 24305 2009-07-23 06:30:04Z unknown $
*/
/**
* @see Zend_Service_WindowsAzure_Credentials_CredentialsAbstract
*/
require_once 'Zend/Service/WindowsAzure/Credentials/CredentialsAbstract.php';
/**
* @see Zend_Service_WindowsAzure_Storage
*/
require_once 'Zend/Service/WindowsAzure/Storage.php';
/**
* @see Zend_Http_Client
*/
require_once 'Zend/Http/Client.php';
/**
* @category Zend
* @package Zend_Service_WindowsAzure
* @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_Service_WindowsAzure_Credentials_SharedAccessSignature
extends Zend_Service_WindowsAzure_Credentials_CredentialsAbstract
{
/**
* Permission set
*
* @var array
*/
protected $_permissionSet = array();
/**
* Creates a new Zend_Service_WindowsAzure_Credentials_SharedAccessSignature instance
*
* @param string $accountName Account name for Windows Azure
* @param string $accountKey Account key for Windows Azure
* @param boolean $usePathStyleUri Use path-style URI's
* @param array $permissionSet Permission set
*/
public function __construct(
$accountName = Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::DEVSTORE_ACCOUNT,
$accountKey = Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::DEVSTORE_KEY,
$usePathStyleUri = false, $permissionSet = array()
) {
parent::__construct($accountName, $accountKey, $usePathStyleUri);
$this->_permissionSet = $permissionSet;
}
/**
* Get permission set
*
* @return array
*/
public function getPermissionSet()
{
return $this->_permissionSet;
}
/**
* Set permisison set
*
* Warning: fine-grained permissions should be added prior to coarse-grained permissions.
* For example: first add blob permissions, end with container-wide permissions.
*
* Warning: the signed access signature URL must match the account name of the
* Zend_Service_WindowsAzure_Credentials_Zend_Service_WindowsAzure_Credentials_SharedAccessSignature instance
*
* @param array $value Permission set
* @return void
*/
public function setPermissionSet($value = array())
{
foreach ($value as $url) {
if (strpos($url, $this->_accountName) === false) {
throw new Zend_Service_WindowsAzure_Exception('The permission set can only contain URLs for the account name specified in the Zend_Service_WindowsAzure_Credentials_SharedAccessSignature instance.');
}
}
$this->_permissionSet = $value;
}
/**
* Create signature
*
* @param string $path Path for the request
* @param string $resource Signed resource - container (c) - blob (b)
* @param string $permissions Signed permissions - read (r), write (w), delete (d) and list (l)
* @param string $start The time at which the Shared Access Signature becomes valid.
* @param string $expiry The time at which the Shared Access Signature becomes invalid.
* @param string $identifier Signed identifier
* @return string
*/
public function createSignature(
$path = '/',
$resource = 'b',
$permissions = 'r',
$start = '',
$expiry = '',
$identifier = ''
) {
// Determine path
if ($this->_usePathStyleUri) {
$path = substr($path, strpos($path, '/'));
}
// Add trailing slash to $path
if (substr($path, 0, 1) !== '/') {
$path = '/' . $path;
}
// Build canonicalized resource string
$canonicalizedResource = '/' . $this->_accountName;
/*if ($this->_usePathStyleUri) {
$canonicalizedResource .= '/' . $this->_accountName;
}*/
$canonicalizedResource .= $path;
// Create string to sign
$stringToSign = array();
$stringToSign[] = $permissions;
$stringToSign[] = $start;
$stringToSign[] = $expiry;
$stringToSign[] = $canonicalizedResource;
$stringToSign[] = $identifier;
$stringToSign = implode("\n", $stringToSign);
$signature = base64_encode(hash_hmac('sha256', $stringToSign, $this->_accountKey, true));
return $signature;
}
/**
* Create signed query string
*
* @param string $path Path for the request
* @param string $queryString Query string for the request
* @param string $resource Signed resource - container (c) - blob (b)
* @param string $permissions Signed permissions - read (r), write (w), delete (d) and list (l)
* @param string $start The time at which the Shared Access Signature becomes valid.
* @param string $expiry The time at which the Shared Access Signature becomes invalid.
* @param string $identifier Signed identifier
* @return string
*/
public function createSignedQueryString(
$path = '/',
$queryString = '',
$resource = 'b',
$permissions = 'r',
$start = '',
$expiry = '',
$identifier = ''
) {
// Parts
$parts = array();
if ($start !== '') {
$parts[] = 'st=' . urlencode($start);
}
$parts[] = 'se=' . urlencode($expiry);
$parts[] = 'sr=' . $resource;
$parts[] = 'sp=' . $permissions;
if ($identifier !== '') {
$parts[] = 'si=' . urlencode($identifier);
}
$parts[] = 'sig=' . urlencode($this->createSignature($path, $resource, $permissions, $start, $expiry, $identifier));
// Assemble parts and query string
if ($queryString != '') {
$queryString .= '&';
}
$queryString .= implode('&', $parts);
return $queryString;
}
/**
* Permission matches request?
*
* @param string $permissionUrl Permission URL
* @param string $requestUrl Request URL
* @param string $resourceType Resource type
* @param string $requiredPermission Required permission
* @return string Signed request URL
*/
public function permissionMatchesRequest(
$permissionUrl = '',
$requestUrl = '',
$resourceType = Zend_Service_WindowsAzure_Storage::RESOURCE_UNKNOWN,
$requiredPermission = Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_READ
) {
// Build requirements
$requiredResourceType = $resourceType;
if ($requiredResourceType == Zend_Service_WindowsAzure_Storage::RESOURCE_BLOB) {
$requiredResourceType .= Zend_Service_WindowsAzure_Storage::RESOURCE_CONTAINER;
}
// Parse permission url
$parsedPermissionUrl = parse_url($permissionUrl);
// Parse permission properties
$permissionParts = explode('&', $parsedPermissionUrl['query']);
// Parse request url
$parsedRequestUrl = parse_url($requestUrl);
// Check if permission matches request
$matches = true;
foreach ($permissionParts as $part) {
list($property, $value) = explode('=', $part, 2);
if ($property == 'sr') {
$matches = $matches && (strpbrk($value, $requiredResourceType) !== false);
}
if ($property == 'sp') {
$matches = $matches && (strpbrk($value, $requiredPermission) !== false);
}
}
// Ok, but... does the resource match?
$matches = $matches && (strpos($parsedRequestUrl['path'], $parsedPermissionUrl['path']) !== false);
// Return
return $matches;
}
/**
* Sign request URL with credentials
*
* @param string $requestUrl Request URL
* @param string $resourceType Resource type
* @param string $requiredPermission Required permission
* @return string Signed request URL
*/
public function signRequestUrl(
$requestUrl = '',
$resourceType = Zend_Service_WindowsAzure_Storage::RESOURCE_UNKNOWN,
$requiredPermission = Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_READ
) {
// Look for a matching permission
foreach ($this->getPermissionSet() as $permittedUrl) {
if ($this->permissionMatchesRequest($permittedUrl, $requestUrl, $resourceType, $requiredPermission)) {
// This matches, append signature data
$parsedPermittedUrl = parse_url($permittedUrl);
if (strpos($requestUrl, '?') === false) {
$requestUrl .= '?';
} else {
$requestUrl .= '&';
}
$requestUrl .= $parsedPermittedUrl['query'];
// Return url
return $requestUrl;
}
}
// Return url, will be unsigned...
return $requestUrl;
}
/**
* Sign request with credentials
*
* @param string $httpVerb HTTP verb the request will use
* @param string $path Path for the request
* @param string $queryString Query string for the request
* @param array $headers x-ms headers to add
* @param boolean $forTableStorage Is the request for table storage?
* @param string $resourceType Resource type
* @param string $requiredPermission Required permission
* @return array Array of headers
*/
public function signRequestHeaders(
$httpVerb = Zend_Http_Client::GET,
$path = '/',
$queryString = '',
$headers = null,
$forTableStorage = false,
$resourceType = Zend_Service_WindowsAzure_Storage::RESOURCE_UNKNOWN,
$requiredPermission = Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_READ
) {
return $headers;
}
}

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_Service_WindowsAzure
* @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: SharedKey.php 35999 2009-12-21 07:56:42Z unknown $
*/
/**
* @see Zend_Service_WindowsAzure_Credentials_CredentialsAbstract
*/
require_once 'Zend/Service/WindowsAzure/Credentials/CredentialsAbstract.php';
/**
* @see Zend_Service_WindowsAzure_Storage
*/
require_once 'Zend/Service/WindowsAzure/Storage.php';
/**
* @see Zend_Http_Client
*/
require_once 'Zend/Http/Client.php';
/**
* @category Zend
* @package Zend_Service_WindowsAzure
* @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_Service_WindowsAzure_Credentials_SharedKey
extends Zend_Service_WindowsAzure_Credentials_CredentialsAbstract
{
/**
* Sign request URL with credentials
*
* @param string $requestUrl Request URL
* @param string $resourceType Resource type
* @param string $requiredPermission Required permission
* @return string Signed request URL
*/
public function signRequestUrl(
$requestUrl = '',
$resourceType = Zend_Service_WindowsAzure_Storage::RESOURCE_UNKNOWN,
$requiredPermission = Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_READ
) {
return $requestUrl;
}
/**
* Sign request headers with credentials
*
* @param string $httpVerb HTTP verb the request will use
* @param string $path Path for the request
* @param string $queryString Query string for the request
* @param array $headers x-ms headers to add
* @param boolean $forTableStorage Is the request for table storage?
* @param string $resourceType Resource type
* @param string $requiredPermission Required permission
* @return array Array of headers
*/
public function signRequestHeaders(
$httpVerb = Zend_Http_Client::GET,
$path = '/',
$queryString = '',
$headers = null,
$forTableStorage = false,
$resourceType = Zend_Service_WindowsAzure_Storage::RESOURCE_UNKNOWN,
$requiredPermission = Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_READ
) {
// http://github.com/sriramk/winazurestorage/blob/214010a2f8931bac9c96dfeb337d56fe084ca63b/winazurestorage.py
// Determine path
if ($this->_usePathStyleUri) {
$path = substr($path, strpos($path, '/'));
}
// Determine query
$queryString = $this->_prepareQueryStringForSigning($queryString);
// Canonicalized headers
$canonicalizedHeaders = array();
// Request date
$requestDate = '';
if (isset($headers[Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PREFIX_STORAGE_HEADER . 'date'])) {
$requestDate = $headers[Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PREFIX_STORAGE_HEADER . 'date'];
} else {
$requestDate = gmdate('D, d M Y H:i:s', time()) . ' GMT'; // RFC 1123
$canonicalizedHeaders[] = Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PREFIX_STORAGE_HEADER . 'date:' . $requestDate;
}
// Build canonicalized headers
if (!is_null($headers)) {
foreach ($headers as $header => $value) {
if (is_bool($value)) {
$value = $value === true ? 'True' : 'False';
}
$headers[$header] = $value;
if (substr($header, 0, strlen(Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PREFIX_STORAGE_HEADER)) == Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PREFIX_STORAGE_HEADER) {
$canonicalizedHeaders[] = strtolower($header) . ':' . $value;
}
}
}
sort($canonicalizedHeaders);
// Build canonicalized resource string
$canonicalizedResource = '/' . $this->_accountName;
if ($this->_usePathStyleUri) {
$canonicalizedResource .= '/' . $this->_accountName;
}
$canonicalizedResource .= $path;
if ($queryString !== '') {
$canonicalizedResource .= $queryString;
}
// Create string to sign
$stringToSign = array();
$stringToSign[] = strtoupper($httpVerb); // VERB
$stringToSign[] = ""; // Content-MD5
$stringToSign[] = ""; // Content-Type
$stringToSign[] = "";
// Date already in $canonicalizedHeaders
// $stringToSign[] = self::PREFIX_STORAGE_HEADER . 'date:' . $requestDate; // Date
if (!$forTableStorage && count($canonicalizedHeaders) > 0) {
$stringToSign[] = implode("\n", $canonicalizedHeaders); // Canonicalized headers
}
$stringToSign[] = $canonicalizedResource; // Canonicalized resource
$stringToSign = implode("\n", $stringToSign);
$signString = base64_encode(hash_hmac('sha256', $stringToSign, $this->_accountKey, true));
// Sign request
$headers[Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PREFIX_STORAGE_HEADER . 'date'] = $requestDate;
$headers['Authorization'] = 'SharedKey ' . $this->_accountName . ':' . $signString;
// Return headers
return $headers;
}
}

View file

@ -0,0 +1,123 @@
<?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_Service_WindowsAzure
* @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: SharedKeyCredentials.php 14561 2009-05-07 08:05:12Z unknown $
*/
/**
* @see Zend_Service_WindowsAzure_Credentials_CredentialsAbstract
*/
require_once 'Zend/Service/WindowsAzure/Credentials/CredentialsAbstract.php';
/**
* @see Zend_Service_WindowsAzure_Storage
*/
require_once 'Zend/Service/WindowsAzure/Storage.php';
/**
* @see Zend_Service_WindowsAzure_Credentials_SharedKey
*/
require_once 'Zend/Service/WindowsAzure/Credentials/SharedKey.php';
/**
* @category Zend
* @package Zend_Service_WindowsAzure
* @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_Service_WindowsAzure_Credentials_SharedKeyLite
extends Zend_Service_WindowsAzure_Credentials_CredentialsAbstract
{
/**
* Sign request URL with credentials
*
* @param string $requestUrl Request URL
* @param string $resourceType Resource type
* @param string $requiredPermission Required permission
* @return string Signed request URL
*/
public function signRequestUrl(
$requestUrl = '',
$resourceType = Zend_Service_WindowsAzure_Storage::RESOURCE_UNKNOWN,
$requiredPermission = Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_READ
) {
return $requestUrl;
}
/**
* Sign request headers with credentials
*
* @param string $httpVerb HTTP verb the request will use
* @param string $path Path for the request
* @param string $queryString Query string for the request
* @param array $headers x-ms headers to add
* @param boolean $forTableStorage Is the request for table storage?
* @param string $resourceType Resource type
* @param string $requiredPermission Required permission
* @return array Array of headers
*/
public function signRequestHeaders(
$httpVerb = Zend_Http_Client::GET,
$path = '/',
$queryString = '',
$headers = null,
$forTableStorage = false,
$resourceType = Zend_Service_WindowsAzure_Storage::RESOURCE_UNKNOWN,
$requiredPermission = Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_READ
) {
// Determine path
if ($this->_usePathStyleUri) {
$path = substr($path, strpos($path, '/'));
}
// Determine query
$queryString = $this->_prepareQueryStringForSigning($queryString);
// Build canonicalized resource string
$canonicalizedResource = '/' . $this->_accountName;
if ($this->_usePathStyleUri) {
$canonicalizedResource .= '/' . $this->_accountName;
}
$canonicalizedResource .= $path;
if ($queryString !== '') {
$canonicalizedResource .= $queryString;
}
// Request date
$requestDate = '';
if (isset($headers[Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PREFIX_STORAGE_HEADER . 'date'])) {
$requestDate = $headers[Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PREFIX_STORAGE_HEADER . 'date'];
} else {
$requestDate = gmdate('D, d M Y H:i:s', time()) . ' GMT'; // RFC 1123
}
// Create string to sign
$stringToSign = array();
$stringToSign[] = $requestDate; // Date
$stringToSign[] = $canonicalizedResource; // Canonicalized resource
$stringToSign = implode("\n", $stringToSign);
$signString = base64_encode(hash_hmac('sha256', $stringToSign, $this->_accountKey, true));
// Sign request
$headers[Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PREFIX_STORAGE_HEADER . 'date'] = $requestDate;
$headers['Authorization'] = 'SharedKeyLite ' . $this->_accountName . ':' . $signString;
// Return headers
return $headers;
}
}

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_Service_WindowsAzure
* @subpackage Exception
* @version $Id: Exception.php 28585 2009-09-07 12:12:56Z unknown $
* @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
/**
* @see Zend_Service_Exception
*/
require_once 'Zend/Service/Exception.php';
/**
* @category Zend
* @package Zend_Service_WindowsAzure
* @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_Service_WindowsAzure_Exception extends Zend_Service_Exception
{}

View file

@ -0,0 +1,36 @@
<?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_Service_WindowsAzure
* @subpackage Exception
* @version $Id: Exception.php 28585 2009-09-07 12:12:56Z unknown $
* @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
/**
* @see Zend_Service_WindowsAzure_Exception
*/
require_once 'Zend/Service/WindowsAzure/Exception.php';
/**
* @category Zend
* @package Zend_Service_WindowsAzure
* @subpackage RetryPolicy
* @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_Service_WindowsAzure_RetryPolicy_Exception extends Zend_Service_WindowsAzure_Exception
{}

View file

@ -0,0 +1,58 @@
<?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_Service_WindowsAzure
* @subpackage RetryPolicy
* @version $Id: NoRetry.php 35709 2009-12-14 14:14:14Z unknown $
* @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
/**
* @see Zend_Service_WindowsAzure_RetryPolicy_RetryPolicyAbstract
*/
require_once 'Zend/Service/WindowsAzure/RetryPolicy/RetryPolicyAbstract.php';
/**
* @category Zend
* @package Zend_Service_WindowsAzure
* @subpackage RetryPolicy
* @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_Service_WindowsAzure_RetryPolicy_NoRetry extends Zend_Service_WindowsAzure_RetryPolicy_RetryPolicyAbstract
{
/**
* Execute function under retry policy
*
* @param string|array $function Function to execute
* @param array $parameters Parameters for function call
* @return mixed
*/
public function execute($function, $parameters = array())
{
$returnValue = null;
try
{
$returnValue = call_user_func_array($function, $parameters);
return $returnValue;
}
catch (Exception $ex)
{
throw $ex;
}
}
}

View file

@ -0,0 +1,92 @@
<?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_Service_WindowsAzure
* @subpackage RetryPolicy
* @version $Id: RetryN.php 35709 2009-12-14 14:14:14Z unknown $
* @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
/**
* @see Zend_Service_WindowsAzure_RetryPolicy_RetryPolicyAbstract
*/
require_once 'Zend/Service/WindowsAzure/RetryPolicy/RetryPolicyAbstract.php';
/**
* @see Zend_Service_WindowsAzure_RetryPolicy_Exception
*/
require_once 'Zend/Service/WindowsAzure/RetryPolicy/Exception.php';
/**
* @category Zend
* @package Zend_Service_WindowsAzure
* @subpackage RetryPolicy
* @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_Service_WindowsAzure_RetryPolicy_RetryN extends Zend_Service_WindowsAzure_RetryPolicy_RetryPolicyAbstract
{
/**
* Number of retries
*
* @var int
*/
protected $_retryCount = 1;
/**
* Interval between retries (in milliseconds)
*
* @var int
*/
protected $_retryInterval = 0;
/**
* Constructor
*
* @param int $count Number of retries
* @param int $intervalBetweenRetries Interval between retries (in milliseconds)
*/
public function __construct($count = 1, $intervalBetweenRetries = 0)
{
$this->_retryCount = $count;
$this->_retryInterval = $intervalBetweenRetries;
}
/**
* Execute function under retry policy
*
* @param string|array $function Function to execute
* @param array $parameters Parameters for function call
* @return mixed
*/
public function execute($function, $parameters = array())
{
$returnValue = null;
for ($retriesLeft = $this->_retryCount; $retriesLeft >= 0; --$retriesLeft) {
try {
$returnValue = call_user_func_array($function, $parameters);
return $returnValue;
} catch (Exception $ex) {
if ($retriesLeft == 1) {
throw new Zend_Service_WindowsAzure_RetryPolicy_Exception("Exceeded retry count of " . $this->_retryCount . ". " . $ex->getMessage());
}
usleep($this->_retryInterval * 1000);
}
}
}
}

View file

@ -0,0 +1,77 @@
<?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_Service_WindowsAzure
* @subpackage RetryPolicy
* @version $Id: RetryPolicy.php 28585 2009-09-07 12:12:56Z unknown $
* @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
/**
* @see Zend_Service_WindowsAzure_Exception
*/
require_once 'Zend/Service/WindowsAzure/Exception.php';
/**
* @see Zend_Service_WindowsAzure_RetryPolicy_NoRetry
*/
require_once 'Zend/Service/WindowsAzure/RetryPolicy/NoRetry.php';
/**
* @see Zend_Service_WindowsAzure_RetryPolicy_RetryN
*/
require_once 'Zend/Service/WindowsAzure/RetryPolicy/RetryN.php';
/**
* @category Zend
* @package Zend_Service_WindowsAzure
* @subpackage RetryPolicy
* @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_Service_WindowsAzure_RetryPolicy_RetryPolicyAbstract
{
/**
* Execute function under retry policy
*
* @param string|array $function Function to execute
* @param array $parameters Parameters for function call
* @return mixed
*/
public abstract function execute($function, $parameters = array());
/**
* Create a Zend_Service_WindowsAzure_RetryPolicy_NoRetry instance
*
* @return Zend_Service_WindowsAzure_RetryPolicy_NoRetry
*/
public static function noRetry()
{
return new Zend_Service_WindowsAzure_RetryPolicy_NoRetry();
}
/**
* Create a Zend_Service_WindowsAzure_RetryPolicy_RetryN instance
*
* @param int $count Number of retries
* @param int $intervalBetweenRetries Interval between retries (in milliseconds)
* @return Zend_Service_WindowsAzure_RetryPolicy_RetryN
*/
public static function retryN($count = 1, $intervalBetweenRetries = 0)
{
return new Zend_Service_WindowsAzure_RetryPolicy_RetryN($count, $intervalBetweenRetries);
}
}

View file

@ -0,0 +1,217 @@
<?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_Service_WindowsAzure
* @subpackage Session
* @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: Storage.php 21617 2009-06-12 10:46:31Z unknown $
*/
/** Zend_Service_WindowsAzure_Storage_Table */
require_once 'Zend/Service/WindowsAzure/Storage/Table.php';
/**
* @see Zend_Service_WindowsAzure_Exception
*/
require_once 'Zend/Service/WindowsAzure/Exception.php';
/**
* @category Zend
* @package Zend_Service_WindowsAzure
* @subpackage Session
* @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_Service_WindowsAzure_SessionHandler
{
/**
* Table storage
*
* @var Zend_Service_WindowsAzure_Storage_Table
*/
protected $_tableStorage;
/**
* Session table name
*
* @var string
*/
protected $_sessionTable;
/**
* Session table partition
*
* @var string
*/
protected $_sessionTablePartition;
/**
* Creates a new Zend_Service_WindowsAzure_SessionHandler instance
*
* @param Zend_Service_WindowsAzure_Storage_Table $tableStorage Table storage
* @param string $sessionTable Session table name
* @param string $sessionTablePartition Session table partition
*/
public function __construct(Zend_Service_WindowsAzure_Storage_Table $tableStorage, $sessionTable = 'phpsessions', $sessionTablePartition = 'sessions')
{
// Set properties
$this->_tableStorage = $tableStorage;
$this->_sessionTable = $sessionTable;
$this->_sessionTablePartition = $sessionTablePartition;
}
/**
* Registers the current session handler as PHP's session handler
*
* @return boolean
*/
public function register()
{
return session_set_save_handler(array($this, 'open'),
array($this, 'close'),
array($this, 'read'),
array($this, 'write'),
array($this, 'destroy'),
array($this, 'gc')
);
}
/**
* Open the session store
*
* @return bool
*/
public function open()
{
// Make sure table exists
$tableExists = $this->_tableStorage->tableExists($this->_sessionTable);
if (!$tableExists) {
$this->_tableStorage->createTable($this->_sessionTable);
}
// Ok!
return true;
}
/**
* Close the session store
*
* @return bool
*/
public function close()
{
return true;
}
/**
* Read a specific session
*
* @param int $id Session Id
* @return string
*/
public function read($id)
{
try
{
$sessionRecord = $this->_tableStorage->retrieveEntityById(
$this->_sessionTable,
$this->_sessionTablePartition,
$id
);
return base64_decode($sessionRecord->serializedData);
}
catch (Zend_Service_WindowsAzure_Exception $ex)
{
return '';
}
}
/**
* Write a specific session
*
* @param int $id Session Id
* @param string $serializedData Serialized PHP object
*/
public function write($id, $serializedData)
{
$sessionRecord = new Zend_Service_WindowsAzure_Storage_DynamicTableEntity($this->_sessionTablePartition, $id);
$sessionRecord->sessionExpires = time();
$sessionRecord->serializedData = base64_encode($serializedData);
$sessionRecord->setAzurePropertyType('sessionExpires', 'Edm.Int32');
try
{
$this->_tableStorage->updateEntity($this->_sessionTable, $sessionRecord);
}
catch (Zend_Service_WindowsAzure_Exception $unknownRecord)
{
$this->_tableStorage->insertEntity($this->_sessionTable, $sessionRecord);
}
}
/**
* Destroy a specific session
*
* @param int $id Session Id
* @return boolean
*/
public function destroy($id)
{
try
{
$sessionRecord = $this->_tableStorage->retrieveEntityById(
$this->_sessionTable,
$this->_sessionTablePartition,
$id
);
$this->_tableStorage->deleteEntity($this->_sessionTable, $sessionRecord);
return true;
}
catch (Zend_Service_WindowsAzure_Exception $ex)
{
return false;
}
}
/**
* Garbage collector
*
* @param int $lifeTime Session maximal lifetime
* @see session.gc_divisor 100
* @see session.gc_maxlifetime 1440
* @see session.gc_probability 1
* @usage Execution rate 1/100 (session.gc_probability/session.gc_divisor)
* @return boolean
*/
public function gc($lifeTime)
{
try
{
$result = $this->_tableStorage->retrieveEntities($this->_sessionTable, 'PartitionKey eq \'' . $this->_sessionTablePartition . '\' and sessionExpires lt ' . (time() - $lifeTime));
foreach ($result as $sessionRecord)
{
$this->_tableStorage->deleteEntity($this->_sessionTable, $sessionRecord);
}
return true;
}
catch (Zend_Service_WindowsAzure_exception $ex)
{
return false;
}
}
}

View file

@ -0,0 +1,504 @@
<?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_Service_WindowsAzure
* @subpackage Storage
* @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: Storage.php 36457 2010-01-04 07:36:33Z unknown $
*/
/**
* @see Zend_Service_WindowsAzure_Credentials_CredentialsAbstract
*/
require_once 'Zend/Service/WindowsAzure/Credentials/CredentialsAbstract.php';
/**
* @see Zend_Service_WindowsAzure_Credentials_SharedKey
*/
require_once 'Zend/Service/WindowsAzure/Credentials/SharedKey.php';
/**
* @see Zend_Service_WindowsAzure_RetryPolicy_RetryPolicyAbstract
*/
require_once 'Zend/Service/WindowsAzure/RetryPolicy/RetryPolicyAbstract.php';
/**
* @see Zend_Service_WindowsAzure_Exception
*/
require_once 'Zend/Service/WindowsAzure/Exception.php';
/**
* @see Zend_Http_Client
*/
require_once 'Zend/Http/Client.php';
/**
* @see Zend_Http_Response
*/
require_once 'Zend/Http/Response.php';
/**
* @category Zend
* @package Zend_Service_WindowsAzure
* @subpackage Storage
* @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_Service_WindowsAzure_Storage
{
/**
* Development storage URLS
*/
const URL_DEV_BLOB = "127.0.0.1:10000";
const URL_DEV_QUEUE = "127.0.0.1:10001";
const URL_DEV_TABLE = "127.0.0.1:10002";
/**
* Live storage URLS
*/
const URL_CLOUD_BLOB = "blob.core.windows.net";
const URL_CLOUD_QUEUE = "queue.core.windows.net";
const URL_CLOUD_TABLE = "table.core.windows.net";
/**
* Resource types
*/
const RESOURCE_UNKNOWN = "unknown";
const RESOURCE_CONTAINER = "c";
const RESOURCE_BLOB = "b";
const RESOURCE_TABLE = "t";
const RESOURCE_ENTITY = "e";
const RESOURCE_QUEUE = "q";
/**
* Current API version
*
* @var string
*/
protected $_apiVersion = '2009-04-14';
/**
* Storage host name
*
* @var string
*/
protected $_host = '';
/**
* Account name for Windows Azure
*
* @var string
*/
protected $_accountName = '';
/**
* Account key for Windows Azure
*
* @var string
*/
protected $_accountKey = '';
/**
* Use path-style URI's
*
* @var boolean
*/
protected $_usePathStyleUri = false;
/**
* Zend_Service_WindowsAzure_Credentials_CredentialsAbstract instance
*
* @var Zend_Service_WindowsAzure_Credentials_CredentialsAbstract
*/
protected $_credentials = null;
/**
* Zend_Service_WindowsAzure_RetryPolicy_RetryPolicyAbstract instance
*
* @var Zend_Service_WindowsAzure_RetryPolicy_RetryPolicyAbstract
*/
protected $_retryPolicy = null;
/**
* Zend_Http_Client channel used for communication with REST services
*
* @var Zend_Http_Client
*/
protected $_httpClientChannel = null;
/**
* Use proxy?
*
* @var boolean
*/
protected $_useProxy = false;
/**
* Proxy url
*
* @var string
*/
protected $_proxyUrl = '';
/**
* Proxy port
*
* @var int
*/
protected $_proxyPort = 80;
/**
* Proxy credentials
*
* @var string
*/
protected $_proxyCredentials = '';
/**
* Creates a new Zend_Service_WindowsAzure_Storage instance
*
* @param string $host Storage host name
* @param string $accountName Account name for Windows Azure
* @param string $accountKey Account key for Windows Azure
* @param boolean $usePathStyleUri Use path-style URI's
* @param Zend_Service_WindowsAzure_RetryPolicy_RetryPolicyAbstract $retryPolicy Retry policy to use when making requests
*/
public function __construct(
$host = self::URL_DEV_BLOB,
$accountName = Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::DEVSTORE_ACCOUNT,
$accountKey = Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::DEVSTORE_KEY,
$usePathStyleUri = false,
Zend_Service_WindowsAzure_RetryPolicy_RetryPolicyAbstract $retryPolicy = null
) {
$this->_host = $host;
$this->_accountName = $accountName;
$this->_accountKey = $accountKey;
$this->_usePathStyleUri = $usePathStyleUri;
// Using local storage?
if (!$this->_usePathStyleUri
&& ($this->_host == self::URL_DEV_BLOB
|| $this->_host == self::URL_DEV_QUEUE
|| $this->_host == self::URL_DEV_TABLE)
) {
// Local storage
$this->_usePathStyleUri = true;
}
if (is_null($this->_credentials)) {
$this->_credentials = new Zend_Service_WindowsAzure_Credentials_SharedKey(
$this->_accountName, $this->_accountKey, $this->_usePathStyleUri);
}
$this->_retryPolicy = $retryPolicy;
if (is_null($this->_retryPolicy)) {
$this->_retryPolicy = Zend_Service_WindowsAzure_RetryPolicy_RetryPolicyAbstract::noRetry();
}
// Setup default Zend_Http_Client channel
$this->_httpClientChannel = new Zend_Http_Client(
null,
array(
'adapter' => 'Zend_Http_Client_Adapter_Proxy',
'curloptions' => array(
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_TIMEOUT => 120,
)
)
);
}
/**
* Set the HTTP client channel to use
*
* @param Zend_Http_Client_Adapter_Interface|string $adapterInstance Adapter instance or adapter class name.
*/
public function setHttpClientChannel($adapterInstance = 'Zend_Http_Client_Adapter_Proxy')
{
$this->_httpClientChannel->setAdapter($adapterInstance);
}
/**
* Set retry policy to use when making requests
*
* @param Zend_Service_WindowsAzure_RetryPolicy_RetryPolicyAbstract $retryPolicy Retry policy to use when making requests
*/
public function setRetryPolicy(Zend_Service_WindowsAzure_RetryPolicy_RetryPolicyAbstract $retryPolicy = null)
{
$this->_retryPolicy = $retryPolicy;
if (is_null($this->_retryPolicy)) {
$this->_retryPolicy = Zend_Service_WindowsAzure_RetryPolicy_RetryPolicyAbstract::noRetry();
}
}
/**
* Set proxy
*
* @param boolean $useProxy Use proxy?
* @param string $proxyUrl Proxy URL
* @param int $proxyPort Proxy port
* @param string $proxyCredentials Proxy credentials
*/
public function setProxy($useProxy = false, $proxyUrl = '', $proxyPort = 80, $proxyCredentials = '')
{
$this->_useProxy = $useProxy;
$this->_proxyUrl = $proxyUrl;
$this->_proxyPort = $proxyPort;
$this->_proxyCredentials = $proxyCredentials;
if ($this->_useProxy) {
$credentials = explode(':', $this->_proxyCredentials);
$this->_httpClientChannel->setConfig(array(
'proxy_host' => $this->_proxyUrl,
'proxy_port' => $this->_proxyPort,
'proxy_user' => $credentials[0],
'proxy_pass' => $credentials[1],
));
} else {
$this->_httpClientChannel->setConfig(array(
'proxy_host' => '',
'proxy_port' => 8080,
'proxy_user' => '',
'proxy_pass' => '',
));
}
}
/**
* Returns the Windows Azure account name
*
* @return string
*/
public function getAccountName()
{
return $this->_accountName;
}
/**
* Get base URL for creating requests
*
* @return string
*/
public function getBaseUrl()
{
if ($this->_usePathStyleUri) {
return 'http://' . $this->_host . '/' . $this->_accountName;
} else {
return 'http://' . $this->_accountName . '.' . $this->_host;
}
}
/**
* Set Zend_Service_WindowsAzure_Credentials_CredentialsAbstract instance
*
* @param Zend_Service_WindowsAzure_Credentials_CredentialsAbstract $credentials Zend_Service_WindowsAzure_Credentials_CredentialsAbstract instance to use for request signing.
*/
public function setCredentials(Zend_Service_WindowsAzure_Credentials_CredentialsAbstract $credentials)
{
$this->_credentials = $credentials;
$this->_credentials->setAccountName($this->_accountName);
$this->_credentials->setAccountkey($this->_accountKey);
$this->_credentials->setUsePathStyleUri($this->_usePathStyleUri);
}
/**
* Get Zend_Service_WindowsAzure_Credentials_CredentialsAbstract instance
*
* @return Zend_Service_WindowsAzure_Credentials_CredentialsAbstract
*/
public function getCredentials()
{
return $this->_credentials;
}
/**
* Perform request using Zend_Http_Client channel
*
* @param string $path Path
* @param string $queryString Query string
* @param string $httpVerb HTTP verb the request will use
* @param array $headers x-ms headers to add
* @param boolean $forTableStorage Is the request for table storage?
* @param mixed $rawData Optional RAW HTTP data to be sent over the wire
* @param string $resourceType Resource type
* @param string $requiredPermission Required permission
* @return Zend_Http_Response
*/
protected function _performRequest(
$path = '/',
$queryString = '',
$httpVerb = Zend_Http_Client::GET,
$headers = array(),
$forTableStorage = false,
$rawData = null,
$resourceType = Zend_Service_WindowsAzure_Storage::RESOURCE_UNKNOWN,
$requiredPermission = Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_READ
) {
// Clean path
if (strpos($path, '/') !== 0) {
$path = '/' . $path;
}
// Clean headers
if (is_null($headers)) {
$headers = array();
}
// Ensure cUrl will also work correctly:
// - disable Content-Type if required
// - disable Expect: 100 Continue
if (!isset($headers["Content-Type"])) {
$headers["Content-Type"] = '';
}
$headers["Expect"]= '';
// Add version header
$headers['x-ms-version'] = $this->_apiVersion;
// URL encoding
$path = self::urlencode($path);
$queryString = self::urlencode($queryString);
// Generate URL and sign request
$requestUrl = $this->_credentials
->signRequestUrl($this->getBaseUrl() . $path . $queryString, $resourceType, $requiredPermission);
$requestHeaders = $this->_credentials
->signRequestHeaders($httpVerb, $path, $queryString, $headers, $forTableStorage, $resourceType, $requiredPermission);
// Prepare request
$this->_httpClientChannel->resetParameters(true);
$this->_httpClientChannel->setUri($requestUrl);
$this->_httpClientChannel->setHeaders($requestHeaders);
$this->_httpClientChannel->setRawData($rawData);
// Execute request
$response = $this->_retryPolicy->execute(
array($this->_httpClientChannel, 'request'),
array($httpVerb)
);
return $response;
}
/**
* Parse result from Zend_Http_Response
*
* @param Zend_Http_Response $response Response from HTTP call
* @return object
* @throws Zend_Service_WindowsAzure_Exception
*/
protected function _parseResponse(Zend_Http_Response $response = null)
{
if (is_null($response)) {
throw new Zend_Service_WindowsAzure_Exception('Response should not be null.');
}
$xml = @simplexml_load_string($response->getBody());
if ($xml !== false) {
// Fetch all namespaces
$namespaces = array_merge($xml->getNamespaces(true), $xml->getDocNamespaces(true));
// Register all namespace prefixes
foreach ($namespaces as $prefix => $ns) {
if ($prefix != '') {
$xml->registerXPathNamespace($prefix, $ns);
}
}
}
return $xml;
}
/**
* Generate metadata headers
*
* @param array $metadata
* @return HTTP headers containing metadata
*/
protected function _generateMetadataHeaders($metadata = array())
{
// Validate
if (!is_array($metadata)) {
return array();
}
// Return headers
$headers = array();
foreach ($metadata as $key => $value) {
if (strpos($value, "\r") !== false || strpos($value, "\n") !== false) {
throw new Zend_Service_WindowsAzure_Exception('Metadata cannot contain newline characters.');
}
$headers["x-ms-meta-" . strtolower($key)] = $value;
}
return $headers;
}
/**
* Parse metadata errors
*
* @param array $headers HTTP headers containing metadata
* @return array
*/
protected function _parseMetadataHeaders($headers = array())
{
// Validate
if (!is_array($headers)) {
return array();
}
// Return metadata
$metadata = array();
foreach ($headers as $key => $value) {
if (substr(strtolower($key), 0, 10) == "x-ms-meta-") {
$metadata[str_replace("x-ms-meta-", '', strtolower($key))] = $value;
}
}
return $metadata;
}
/**
* Generate ISO 8601 compliant date string in UTC time zone
*
* @param int $timestamp
* @return string
*/
public function isoDate($timestamp = null)
{
$tz = @date_default_timezone_get();
@date_default_timezone_set('UTC');
if (is_null($timestamp)) {
$timestamp = time();
}
$returnValue = str_replace('+00:00', '.0000000Z', @date('c', $timestamp));
@date_default_timezone_set($tz);
return $returnValue;
}
/**
* URL encode function
*
* @param string $value Value to encode
* @return string Encoded value
*/
public static function urlencode($value)
{
return str_replace(' ', '%20', $value);
}
}

View file

@ -0,0 +1,248 @@
<?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_Service_WindowsAzure
* @subpackage Storage
* @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: Storage.php 21617 2009-06-12 10:46:31Z unknown $
*/
/**
* @see Zend_Service_WindowsAzure_Exception
*/
require_once 'Zend/Service/WindowsAzure/Exception.php';
/**
* @see Zend_Service_WindowsAzure_Storage_BatchStorageAbstract
*/
require_once 'Zend/Service/WindowsAzure/Storage/BatchStorageAbstract.php';
/**
* @category Zend
* @package Zend_Service_WindowsAzure
* @subpackage Storage
* @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_Service_WindowsAzure_Storage_Batch
{
/**
* Storage client the batch is defined on
*
* @var Zend_Service_WindowsAzure_Storage_BatchStorageAbstract
*/
protected $_storageClient = null;
/**
* For table storage?
*
* @var boolean
*/
protected $_forTableStorage = false;
/**
* Base URL
*
* @var string
*/
protected $_baseUrl;
/**
* Pending operations
*
* @var unknown_type
*/
protected $_operations = array();
/**
* Does the batch contain a single select?
*
* @var boolean
*/
protected $_isSingleSelect = false;
/**
* Creates a new Zend_Service_WindowsAzure_Storage_Batch
*
* @param Zend_Service_WindowsAzure_Storage_BatchStorageAbstract $storageClient Storage client the batch is defined on
*/
public function __construct(Zend_Service_WindowsAzure_Storage_BatchStorageAbstract $storageClient = null, $baseUrl = '')
{
$this->_storageClient = $storageClient;
$this->_baseUrl = $baseUrl;
$this->_beginBatch();
}
/**
* Get base URL for creating requests
*
* @return string
*/
public function getBaseUrl()
{
return $this->_baseUrl;
}
/**
* Starts a new batch operation set
*
* @throws Zend_Service_WindowsAzure_Exception
*/
protected function _beginBatch()
{
$this->_storageClient->setCurrentBatch($this);
}
/**
* Cleanup current batch
*/
protected function _clean()
{
unset($this->_operations);
$this->_storageClient->setCurrentBatch(null);
$this->_storageClient = null;
unset($this);
}
/**
* Enlist operation in current batch
*
* @param string $path Path
* @param string $queryString Query string
* @param string $httpVerb HTTP verb the request will use
* @param array $headers x-ms headers to add
* @param boolean $forTableStorage Is the request for table storage?
* @param mixed $rawData Optional RAW HTTP data to be sent over the wire
* @throws Zend_Service_WindowsAzure_Exception
*/
public function enlistOperation($path = '/', $queryString = '', $httpVerb = Zend_Http_Client::GET, $headers = array(), $forTableStorage = false, $rawData = null)
{
// Set _forTableStorage
if ($forTableStorage) {
$this->_forTableStorage = true;
}
// Set _isSingleSelect
if ($httpVerb == Zend_Http_Client::GET) {
if (count($this->_operations) > 0) {
throw new Zend_Service_WindowsAzure_Exception("Select operations can only be performed in an empty batch transaction.");
}
$this->_isSingleSelect = true;
}
// Clean path
if (strpos($path, '/') !== 0) {
$path = '/' . $path;
}
// Clean headers
if (is_null($headers)) {
$headers = array();
}
// URL encoding
$path = Zend_Service_WindowsAzure_Storage::urlencode($path);
$queryString = Zend_Service_WindowsAzure_Storage::urlencode($queryString);
// Generate URL
$requestUrl = $this->getBaseUrl() . $path . $queryString;
// Generate $rawData
if (is_null($rawData)) {
$rawData = '';
}
// Add headers
if ($httpVerb != Zend_Http_Client::GET) {
$headers['Content-ID'] = count($this->_operations) + 1;
if ($httpVerb != Zend_Http_Client::DELETE) {
$headers['Content-Type'] = 'application/atom+xml;type=entry';
}
$headers['Content-Length'] = strlen($rawData);
}
// Generate $operation
$operation = '';
$operation .= $httpVerb . ' ' . $requestUrl . ' HTTP/1.1' . "\n";
foreach ($headers as $key => $value)
{
$operation .= $key . ': ' . $value . "\n";
}
$operation .= "\n";
// Add data
$operation .= $rawData;
// Store operation
$this->_operations[] = $operation;
}
/**
* Commit current batch
*
* @return Zend_Http_Response
* @throws Zend_Service_WindowsAzure_Exception
*/
public function commit()
{
// Perform batch
$response = $this->_storageClient->performBatch($this->_operations, $this->_forTableStorage, $this->_isSingleSelect);
// Dispose
$this->_clean();
// Parse response
$errors = null;
preg_match_all('/<message (.*)>(.*)<\/message>/', $response->getBody(), $errors);
// Error?
if (count($errors[2]) > 0) {
throw new Zend_Service_WindowsAzure_Exception('An error has occured while committing a batch: ' . $errors[2][0]);
}
// Return
return $response;
}
/**
* Rollback current batch
*/
public function rollback()
{
// Dispose
$this->_clean();
}
/**
* Get operation count
*
* @return integer
*/
public function getOperationCount()
{
return count($this->_operations);
}
/**
* Is single select?
*
* @return boolean
*/
public function isSingleSelect()
{
return $this->_isSingleSelect;
}
}

View file

@ -0,0 +1,193 @@
<?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_Service_WindowsAzure
* @subpackage Storage
* @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: Storage.php 21617 2009-06-12 10:46:31Z unknown $
*/
/**
* @see Zend_Service_WindowsAzure_Storage
*/
require_once 'Zend/Service/WindowsAzure/Storage.php';
/**
* @see Zend_Service_WindowsAzure_Credentials_CredentialsAbstract
*/
require_once 'Zend/Service/WindowsAzure/Credentials/CredentialsAbstract.php';
/**
* @see Zend_Service_WindowsAzure_Exception
*/
require_once 'Zend/Service/WindowsAzure/Exception.php';
/**
* @see Zend_Service_WindowsAzure_Storage_Batch
*/
require_once 'Zend/Service/WindowsAzure/Storage/Batch.php';
/**
* @see Zend_Http_Client
*/
require_once 'Zend/Http/Client.php';
/**
* @see Zend_Http_Response
*/
require_once 'Zend/Http/Response.php';
/**
* @category Zend
* @package Zend_Service_WindowsAzure
* @subpackage Storage
* @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_Service_WindowsAzure_Storage_BatchStorageAbstract
extends Zend_Service_WindowsAzure_Storage
{
/**
* Current batch
*
* @var Zend_Service_WindowsAzure_Storage_Batch
*/
protected $_currentBatch = null;
/**
* Set current batch
*
* @param Zend_Service_WindowsAzure_Storage_Batch $batch Current batch
* @throws Zend_Service_WindowsAzure_Exception
*/
public function setCurrentBatch(Zend_Service_WindowsAzure_Storage_Batch $batch = null)
{
if (!is_null($batch) && $this->isInBatch()) {
throw new Zend_Service_WindowsAzure_Exception('Only one batch can be active at a time.');
}
$this->_currentBatch = $batch;
}
/**
* Get current batch
*
* @return Zend_Service_WindowsAzure_Storage_Batch
*/
public function getCurrentBatch()
{
return $this->_currentBatch;
}
/**
* Is there a current batch?
*
* @return boolean
*/
public function isInBatch()
{
return !is_null($this->_currentBatch);
}
/**
* Starts a new batch operation set
*
* @return Zend_Service_WindowsAzure_Storage_Batch
* @throws Zend_Service_WindowsAzure_Exception
*/
public function startBatch()
{
return new Zend_Service_WindowsAzure_Storage_Batch($this, $this->getBaseUrl());
}
/**
* Perform batch using Zend_Http_Client channel, combining all batch operations into one request
*
* @param array $operations Operations in batch
* @param boolean $forTableStorage Is the request for table storage?
* @param boolean $isSingleSelect Is the request a single select statement?
* @param string $resourceType Resource type
* @param string $requiredPermission Required permission
* @return Zend_Http_Response
*/
public function performBatch($operations = array(), $forTableStorage = false, $isSingleSelect = false, $resourceType = Zend_Service_WindowsAzure_Storage::RESOURCE_UNKNOWN, $requiredPermission = Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_READ)
{
// Generate boundaries
$batchBoundary = 'batch_' . md5(time() . microtime());
$changesetBoundary = 'changeset_' . md5(time() . microtime());
// Set headers
$headers = array();
// Add version header
$headers['x-ms-version'] = $this->_apiVersion;
// Add content-type header
$headers['Content-Type'] = 'multipart/mixed; boundary=' . $batchBoundary;
// Set path and query string
$path = '/$batch';
$queryString = '';
// Set verb
$httpVerb = Zend_Http_Client::POST;
// Generate raw data
$rawData = '';
// Single select?
if ($isSingleSelect) {
$operation = $operations[0];
$rawData .= '--' . $batchBoundary . "\n";
$rawData .= 'Content-Type: application/http' . "\n";
$rawData .= 'Content-Transfer-Encoding: binary' . "\n\n";
$rawData .= $operation;
$rawData .= '--' . $batchBoundary . '--';
} else {
$rawData .= '--' . $batchBoundary . "\n";
$rawData .= 'Content-Type: multipart/mixed; boundary=' . $changesetBoundary . "\n\n";
// Add operations
foreach ($operations as $operation)
{
$rawData .= '--' . $changesetBoundary . "\n";
$rawData .= 'Content-Type: application/http' . "\n";
$rawData .= 'Content-Transfer-Encoding: binary' . "\n\n";
$rawData .= $operation;
}
$rawData .= '--' . $changesetBoundary . '--' . "\n";
$rawData .= '--' . $batchBoundary . '--';
}
// Generate URL and sign request
$requestUrl = $this->_credentials->signRequestUrl($this->getBaseUrl() . $path . $queryString, $resourceType, $requiredPermission);
$requestHeaders = $this->_credentials->signRequestHeaders($httpVerb, $path, $queryString, $headers, $forTableStorage, $resourceType, $requiredPermission);
// Prepare request
$this->_httpClientChannel->resetParameters(true);
$this->_httpClientChannel->setUri($requestUrl);
$this->_httpClientChannel->setHeaders($requestHeaders);
$this->_httpClientChannel->setRawData($rawData);
// Execute request
$response = $this->_retryPolicy->execute(
array($this->_httpClientChannel, 'request'),
array($httpVerb)
);
return $response;
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,565 @@
<?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_Service_WindowsAzure_Storage
* @subpackage Blob
* @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://todo name_todo
* @version $Id: Blob.php 24511 2009-07-28 09:17:56Z unknown $
*/
/**
* @see Zend_Service_WindowsAzure_Storage_Blob
*/
require_once 'Zend/Service/WindowsAzure/Storage/Blob.php';
/**
* @see Zend_Service_WindowsAzure_Exception
*/
require_once 'Zend/Service/WindowsAzure/Exception.php';
/**
* @category Zend
* @package Zend_Service_WindowsAzure_Storage
* @subpackage Blob
* @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_Service_WindowsAzure_Storage_Blob_Stream
{
/**
* Current file name
*
* @var string
*/
private $_fileName = null;
/**
* Temporary file name
*
* @var string
*/
private $_temporaryFileName = null;
/**
* Temporary file handle
*
* @var resource
*/
private $_temporaryFileHandle = null;
/**
* Blob storage client
*
* @var Zend_Service_WindowsAzure_Storage_Blob
*/
private $_storageClient = null;
/**
* Write mode?
*
* @var boolean
*/
private $_writeMode = false;
/**
* List of blobs
*
* @var array
*/
private $_blobs = null;
/**
* Retrieve storage client for this stream type
*
* @param string $path
* @return Zend_Service_WindowsAzure_Storage_Blob
*/
protected function _getStorageClient($path = '')
{
if (is_null($this->_storageClient)) {
$url = explode(':', $path);
if (!$url) {
throw new Zend_Service_WindowsAzure_Exception('Could not parse path "' . $path . '".');
}
$this->_storageClient = Zend_Service_WindowsAzure_Storage_Blob::getWrapperClient($url[0]);
if (!$this->_storageClient) {
throw new Zend_Service_WindowsAzure_Exception('No storage client registered for stream type "' . $url[0] . '://".');
}
}
return $this->_storageClient;
}
/**
* Extract container name
*
* @param string $path
* @return string
*/
protected function _getContainerName($path)
{
$url = parse_url($path);
if ($url['host']) {
return $url['host'];
}
return '';
}
/**
* Extract file name
*
* @param string $path
* @return string
*/
protected function _getFileName($path)
{
$url = parse_url($path);
if ($url['host']) {
$fileName = isset($url['path']) ? $url['path'] : $url['host'];
if (strpos($fileName, '/') === 0) {
$fileName = substr($fileName, 1);
}
return $fileName;
}
return '';
}
/**
* Open the stream
*
* @param string $path
* @param string $mode
* @param integer $options
* @param string $opened_path
* @return boolean
*/
public function stream_open($path, $mode, $options, $opened_path)
{
$this->_fileName = $path;
$this->_temporaryFileName = tempnam(sys_get_temp_dir(), 'azure');
// Check the file can be opened
$fh = @fopen($this->_temporaryFileName, $mode);
if ($fh === false) {
return false;
}
fclose($fh);
// Write mode?
if (strpbrk($mode, 'wax+')) {
$this->_writeMode = true;
} else {
$this->_writeMode = false;
}
// If read/append, fetch the file
if (!$this->_writeMode || strpbrk($mode, 'ra+')) {
$this->_getStorageClient($this->_fileName)->getBlob(
$this->_getContainerName($this->_fileName),
$this->_getFileName($this->_fileName),
$this->_temporaryFileName
);
}
// Open temporary file handle
$this->_temporaryFileHandle = fopen($this->_temporaryFileName, $mode);
// Ok!
return true;
}
/**
* Close the stream
*
* @return void
*/
public function stream_close()
{
@fclose($this->_temporaryFileHandle);
// Upload the file?
if ($this->_writeMode) {
// Make sure the container exists
$containerExists = $this->_getStorageClient($this->_fileName)->containerExists(
$this->_getContainerName($this->_fileName)
);
if (!$containerExists) {
$this->_getStorageClient($this->_fileName)->createContainer(
$this->_getContainerName($this->_fileName)
);
}
// Upload the file
try {
$this->_getStorageClient($this->_fileName)->putBlob(
$this->_getContainerName($this->_fileName),
$this->_getFileName($this->_fileName),
$this->_temporaryFileName
);
} catch (Zend_Service_WindowsAzure_Exception $ex) {
@unlink($this->_temporaryFileName);
unset($this->_storageClient);
throw $ex;
}
}
@unlink($this->_temporaryFileName);
unset($this->_storageClient);
}
/**
* Read from the stream
*
* @param integer $count
* @return string
*/
public function stream_read($count)
{
if (!$this->_temporaryFileHandle) {
return false;
}
return fread($this->_temporaryFileHandle, $count);
}
/**
* Write to the stream
*
* @param string $data
* @return integer
*/
public function stream_write($data)
{
if (!$this->_temporaryFileHandle) {
return 0;
}
$len = strlen($data);
fwrite($this->_temporaryFileHandle, $data, $len);
return $len;
}
/**
* End of the stream?
*
* @return boolean
*/
public function stream_eof()
{
if (!$this->_temporaryFileHandle) {
return true;
}
return feof($this->_temporaryFileHandle);
}
/**
* What is the current read/write position of the stream?
*
* @return integer
*/
public function stream_tell()
{
return ftell($this->_temporaryFileHandle);
}
/**
* Update the read/write position of the stream
*
* @param integer $offset
* @param integer $whence
* @return boolean
*/
public function stream_seek($offset, $whence)
{
if (!$this->_temporaryFileHandle) {
return false;
}
return (fseek($this->_temporaryFileHandle, $offset, $whence) === 0);
}
/**
* Flush current cached stream data to storage
*
* @return boolean
*/
public function stream_flush()
{
$result = fflush($this->_temporaryFileHandle);
// Upload the file?
if ($this->_writeMode) {
// Make sure the container exists
$containerExists = $this->_getStorageClient($this->_fileName)->containerExists(
$this->_getContainerName($this->_fileName)
);
if (!$containerExists) {
$this->_getStorageClient($this->_fileName)->createContainer(
$this->_getContainerName($this->_fileName)
);
}
// Upload the file
try {
$this->_getStorageClient($this->_fileName)->putBlob(
$this->_getContainerName($this->_fileName),
$this->_getFileName($this->_fileName),
$this->_temporaryFileName
);
} catch (Zend_Service_WindowsAzure_Exception $ex) {
@unlink($this->_temporaryFileName);
unset($this->_storageClient);
throw $ex;
}
}
return $result;
}
/**
* Returns data array of stream variables
*
* @return array
*/
public function stream_stat()
{
if (!$this->_temporaryFileHandle) {
return false;
}
$stat = array();
$stat['dev'] = 0;
$stat['ino'] = 0;
$stat['mode'] = 0;
$stat['nlink'] = 0;
$stat['uid'] = 0;
$stat['gid'] = 0;
$stat['rdev'] = 0;
$stat['size'] = 0;
$stat['atime'] = 0;
$stat['mtime'] = 0;
$stat['ctime'] = 0;
$stat['blksize'] = 0;
$stat['blocks'] = 0;
$info = null;
try {
$info = $this->_getStorageClient($this->_fileName)->getBlobInstance(
$this->_getContainerName($this->_fileName),
$this->_getFileName($this->_fileName)
);
} catch (Zend_Service_WindowsAzure_Exception $ex) {
// Unexisting file...
}
if (!is_null($info)) {
$stat['size'] = $info->Size;
$stat['atime'] = time();
}
return $stat;
}
/**
* Attempt to delete the item
*
* @param string $path
* @return boolean
*/
public function unlink($path)
{
$this->_getStorageClient($path)->deleteBlob(
$this->_getContainerName($path),
$this->_getFileName($path)
);
}
/**
* Attempt to rename the item
*
* @param string $path_from
* @param string $path_to
* @return boolean False
*/
public function rename($path_from, $path_to)
{
if ($this->_getContainerName($path_from) != $this->_getContainerName($path_to)) {
throw new Zend_Service_WindowsAzure_Exception('Container name can not be changed.');
}
if ($this->_getFileName($path_from) == $this->_getContainerName($path_to)) {
return true;
}
$this->_getStorageClient($path_from)->copyBlob(
$this->_getContainerName($path_from),
$this->_getFileName($path_from),
$this->_getContainerName($path_to),
$this->_getFileName($path_to)
);
$this->_getStorageClient($path_from)->deleteBlob(
$this->_getContainerName($path_from),
$this->_getFileName($path_from)
);
return true;
}
/**
* Return array of URL variables
*
* @param string $path
* @param integer $flags
* @return array
*/
public function url_stat($path, $flags)
{
$stat = array();
$stat['dev'] = 0;
$stat['ino'] = 0;
$stat['mode'] = 0;
$stat['nlink'] = 0;
$stat['uid'] = 0;
$stat['gid'] = 0;
$stat['rdev'] = 0;
$stat['size'] = 0;
$stat['atime'] = 0;
$stat['mtime'] = 0;
$stat['ctime'] = 0;
$stat['blksize'] = 0;
$stat['blocks'] = 0;
$info = null;
try {
$info = $this->_getStorageClient($path)->getBlobInstance(
$this->_getContainerName($path),
$this->_getFileName($path)
);
} catch (Zend_Service_WindowsAzure_Exception $ex) {
// Unexisting file...
}
if (!is_null($info)) {
$stat['size'] = $info->Size;
$stat['atime'] = time();
}
return $stat;
}
/**
* Create a new directory
*
* @param string $path
* @param integer $mode
* @param integer $options
* @return boolean
*/
public function mkdir($path, $mode, $options)
{
if ($this->_getContainerName($path) == $this->_getFileName($path)) {
// Create container
try {
$this->_getStorageClient($path)->createContainer(
$this->_getContainerName($path)
);
} catch (Zend_Service_WindowsAzure_Exception $ex) {
return false;
}
} else {
throw new Zend_Service_WindowsAzure_Exception('mkdir() with multiple levels is not supported on Windows Azure Blob Storage.');
}
}
/**
* Remove a directory
*
* @param string $path
* @param integer $options
* @return boolean
*/
public function rmdir($path, $options)
{
if ($this->_getContainerName($path) == $this->_getFileName($path)) {
// Delete container
try {
$this->_getStorageClient($path)->deleteContainer(
$this->_getContainerName($path)
);
} catch (Zend_Service_WindowsAzure_Exception $ex) {
return false;
}
} else {
throw new Zend_Service_WindowsAzure_Exception('rmdir() with multiple levels is not supported on Windows Azure Blob Storage.');
}
}
/**
* Attempt to open a directory
*
* @param string $path
* @param integer $options
* @return boolean
*/
public function dir_opendir($path, $options)
{
$this->_blobs = $this->_getStorageClient($path)->listBlobs(
$this->_getContainerName($path)
);
return is_array($this->_blobs);
}
/**
* Return the next filename in the directory
*
* @return string
*/
public function dir_readdir()
{
$object = current($this->_blobs);
if ($object !== false) {
next($this->_blobs);
return $object->Name;
}
return false;
}
/**
* Reset the directory pointer
*
* @return boolean True
*/
public function dir_rewinddir()
{
reset($this->_blobs);
return true;
}
/**
* Close a directory
*
* @return boolean True
*/
public function dir_closedir()
{
$this->_blobs = null;
return true;
}
}

View file

@ -0,0 +1,95 @@
<?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_Service_WindowsAzure
* @subpackage Storage
* @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: BlobContainer.php 28585 2009-09-07 12:12:56Z unknown $
*/
/**
* @see Zend_Service_WindowsAzure_Exception
*/
require_once 'Zend/Service/WindowsAzure/Exception.php';
/**
* @category Zend
* @package Zend_Service_WindowsAzure
* @subpackage Storage
* @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*
* @property string $Name Name of the container
* @property string $Etag Etag of the container
* @property string $LastModified Last modified date of the container
* @property array $Metadata Key/value pairs of meta data
*/
class Zend_Service_WindowsAzure_Storage_BlobContainer
{
/**
* Data
*
* @var array
*/
protected $_data = null;
/**
* Constructor
*
* @param string $name Name
* @param string $etag Etag
* @param string $lastModified Last modified date
* @param array $metadata Key/value pairs of meta data
*/
public function __construct($name, $etag, $lastModified, $metadata = array())
{
$this->_data = array(
'name' => $name,
'etag' => $etag,
'lastmodified' => $lastModified,
'metadata' => $metadata
);
}
/**
* Magic overload for setting properties
*
* @param string $name Name of the property
* @param string $value Value to set
*/
public function __set($name, $value) {
if (array_key_exists(strtolower($name), $this->_data)) {
$this->_data[strtolower($name)] = $value;
return;
}
throw new Exception("Unknown property: " . $name);
}
/**
* Magic overload for getting properties
*
* @param string $name Name of the property
*/
public function __get($name) {
if (array_key_exists(strtolower($name), $this->_data)) {
return $this->_data[strtolower($name)];
}
throw new Exception("Unknown property: " . $name);
}
}

View file

@ -0,0 +1,116 @@
<?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_Service_WindowsAzure
* @subpackage Storage
* @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: BlobInstance.php 28585 2009-09-07 12:12:56Z unknown $
*/
/**
* @see Zend_Service_WindowsAzure_Exception
*/
require_once 'Zend/Service/WindowsAzure/Exception.php';
/**
* @category Zend
* @package Zend_Service_WindowsAzure
* @subpackage Storage
* @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*
* @property string $Container Container name
* @property string $Name Name
* @property string $Etag Etag
* @property string $LastModified Last modified date
* @property string $Url Url
* @property int $Size Size
* @property string $ContentType Content Type
* @property string $ContentEncoding Content Encoding
* @property string $ContentLanguage Content Language
* @property boolean $IsPrefix Is Prefix?
* @property array $Metadata Key/value pairs of meta data
*/
class Zend_Service_WindowsAzure_Storage_BlobInstance
{
/**
* Data
*
* @var array
*/
protected $_data = null;
/**
* Constructor
*
* @param string $containerName Container name
* @param string $name Name
* @param string $etag Etag
* @param string $lastModified Last modified date
* @param string $url Url
* @param int $size Size
* @param string $contentType Content Type
* @param string $contentEncoding Content Encoding
* @param string $contentLanguage Content Language
* @param boolean $isPrefix Is Prefix?
* @param array $metadata Key/value pairs of meta data
*/
public function __construct($containerName, $name, $etag, $lastModified, $url = '', $size = 0, $contentType = '', $contentEncoding = '', $contentLanguage = '', $isPrefix = false, $metadata = array())
{
$this->_data = array(
'container' => $containerName,
'name' => $name,
'etag' => $etag,
'lastmodified' => $lastModified,
'url' => $url,
'size' => $size,
'contenttype' => $contentType,
'contentencoding' => $contentEncoding,
'contentlanguage' => $contentLanguage,
'isprefix' => $isPrefix,
'metadata' => $metadata
);
}
/**
* Magic overload for setting properties
*
* @param string $name Name of the property
* @param string $value Value to set
*/
public function __set($name, $value) {
if (array_key_exists(strtolower($name), $this->_data)) {
$this->_data[strtolower($name)] = $value;
return;
}
throw new Exception("Unknown property: " . $name);
}
/**
* Magic overload for getting properties
*
* @param string $name Name of the property
*/
public function __get($name) {
if (array_key_exists(strtolower($name), $this->_data)) {
return $this->_data[strtolower($name)];
}
throw new Exception("Unknown property: " . $name);
}
}

View file

@ -0,0 +1,200 @@
<?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_Service_WindowsAzure
* @subpackage Storage
* @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: BlobInstance.php 14561 2009-05-07 08:05:12Z unknown $
*/
/**
* @see Zend_Service_WindowsAzure_Exception
*/
require_once 'Zend/Service/WindowsAzure/Exception.php';
/**
* @see Zend_Service_WindowsAzure_Storage_TableEntity
*/
require_once 'Zend/Service/WindowsAzure/Storage/TableEntity.php';
/**
* @category Zend
* @package Zend_Service_WindowsAzure
* @subpackage Storage
* @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_Service_WindowsAzure_Storage_DynamicTableEntity extends Zend_Service_WindowsAzure_Storage_TableEntity
{
/**
* Dynamic properties
*
* @var array
*/
protected $_dynamicProperties = array();
/**
* Magic overload for setting properties
*
* @param string $name Name of the property
* @param string $value Value to set
*/
public function __set($name, $value) {
$this->setAzureProperty($name, $value, null);
}
/**
* Magic overload for getting properties
*
* @param string $name Name of the property
*/
public function __get($name) {
return $this->getAzureProperty($name);
}
/**
* Set an Azure property
*
* @param string $name Property name
* @param mixed $value Property value
* @param string $type Property type (Edm.xxxx)
* @return Zend_Service_WindowsAzure_Storage_DynamicTableEntity
*/
public function setAzureProperty($name, $value = '', $type = null)
{
if (strtolower($name) == 'partitionkey') {
$this->setPartitionKey($value);
} else if (strtolower($name) == 'rowkey') {
$this->setRowKey($value);
} else if (strtolower($name) == 'etag') {
$this->setEtag($value);
} else {
if (!array_key_exists(strtolower($name), $this->_dynamicProperties)) {
// Determine type?
if (is_null($type)) {
$type = 'Edm.String';
if (is_int($value)) {
$type = 'Edm.Int32';
} else if (is_float($value)) {
$type = 'Edm.Double';
} else if (is_bool($value)) {
$type = 'Edm.Boolean';
}
}
// Set dynamic property
$this->_dynamicProperties[strtolower($name)] = (object)array(
'Name' => $name,
'Type' => $type,
'Value' => $value,
);
}
$this->_dynamicProperties[strtolower($name)]->Value = $value;
}
return $this;
}
/**
* Set an Azure property type
*
* @param string $name Property name
* @param string $type Property type (Edm.xxxx)
* @return Zend_Service_WindowsAzure_Storage_DynamicTableEntity
*/
public function setAzurePropertyType($name, $type = 'Edm.String')
{
if (!array_key_exists(strtolower($name), $this->_dynamicProperties)) {
$this->setAzureProperty($name, '', $type);
} else {
$this->_dynamicProperties[strtolower($name)]->Type = $type;
}
return $this;
}
/**
* Get an Azure property
*
* @param string $name Property name
* @param mixed $value Property value
* @param string $type Property type (Edm.xxxx)
* @return Zend_Service_WindowsAzure_Storage_DynamicTableEntity
*/
public function getAzureProperty($name)
{
if (strtolower($name) == 'partitionkey') {
return $this->getPartitionKey();
}
if (strtolower($name) == 'rowkey') {
return $this->getRowKey();
}
if (strtolower($name) == 'etag') {
return $this->getEtag();
}
if (!array_key_exists(strtolower($name), $this->_dynamicProperties)) {
$this->setAzureProperty($name);
}
return $this->_dynamicProperties[strtolower($name)]->Value;
}
/**
* Get an Azure property type
*
* @param string $name Property name
* @return string Property type (Edm.xxxx)
*/
public function getAzurePropertyType($name)
{
if (!array_key_exists(strtolower($name), $this->_dynamicProperties)) {
$this->setAzureProperty($name, '', $type);
}
return $this->_dynamicProperties[strtolower($name)]->Type;
}
/**
* Get Azure values
*
* @return array
*/
public function getAzureValues()
{
return array_merge(array_values($this->_dynamicProperties), parent::getAzureValues());
}
/**
* Set Azure values
*
* @param array $values
* @param boolean $throwOnError Throw Zend_Service_WindowsAzure_Exception when a property is not specified in $values?
* @throws Zend_Service_WindowsAzure_Exception
*/
public function setAzureValues($values = array(), $throwOnError = false)
{
// Set parent values
parent::setAzureValues($values, false);
// Set current values
foreach ($values as $key => $value)
{
$this->$key = $value;
}
}
}

View file

@ -0,0 +1,547 @@
<?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_Service_WindowsAzure
* @subpackage Storage
* @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://todo name_todo
* @version $Id: Blob.php 24241 2009-07-22 09:43:13Z unknown $
*/
/**
* @see Zend_Service_WindowsAzure_Credentials_SharedKey
*/
require_once 'Zend/Service/WindowsAzure/Credentials/SharedKey.php';
/**
* @see Zend_Service_WindowsAzure_RetryPolicy_RetryPolicyAbstract
*/
require_once 'Zend/Service/WindowsAzure/RetryPolicy/RetryPolicyAbstract.php';
/**
* @see Zend_Http_Client
*/
require_once 'Zend/Http/Client.php';
/**
* @see Zend_Http_Response
*/
require_once 'Zend/Http/Response.php';
/**
* @see Zend_Service_WindowsAzure_Storage
*/
require_once 'Zend/Service/WindowsAzure/Storage.php';
/**
* Zend_Service_WindowsAzure_Storage_QueueInstance
*/
require_once 'Zend/Service/WindowsAzure/Storage/QueueInstance.php';
/**
* Zend_Service_WindowsAzure_Storage_QueueMessage
*/
require_once 'Zend/Service/WindowsAzure/Storage/QueueMessage.php';
/**
* @see Zend_Service_WindowsAzure_Exception
*/
require_once 'Zend/Service/WindowsAzure/Exception.php';
/**
* @category Zend
* @package Zend_Service_WindowsAzure
* @subpackage Storage
* @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_Service_WindowsAzure_Storage_Queue extends Zend_Service_WindowsAzure_Storage
{
/**
* Maximal message size (in bytes)
*/
const MAX_MESSAGE_SIZE = 8388608;
/**
* Maximal message ttl (in seconds)
*/
const MAX_MESSAGE_TTL = 604800;
/**
* Creates a new Zend_Service_WindowsAzure_Storage_Queue instance
*
* @param string $host Storage host name
* @param string $accountName Account name for Windows Azure
* @param string $accountKey Account key for Windows Azure
* @param boolean $usePathStyleUri Use path-style URI's
* @param Zend_Service_WindowsAzure_RetryPolicy_RetryPolicyAbstract $retryPolicy Retry policy to use when making requests
*/
public function __construct($host = Zend_Service_WindowsAzure_Storage::URL_DEV_QUEUE, $accountName = Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::DEVSTORE_ACCOUNT, $accountKey = Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::DEVSTORE_KEY, $usePathStyleUri = false, Zend_Service_WindowsAzure_RetryPolicy_RetryPolicyAbstract $retryPolicy = null)
{
parent::__construct($host, $accountName, $accountKey, $usePathStyleUri, $retryPolicy);
// API version
$this->_apiVersion = '2009-04-14';
}
/**
* Check if a queue exists
*
* @param string $queueName Queue name
* @return boolean
*/
public function queueExists($queueName = '')
{
if ($queueName === '') {
throw new Zend_Service_WindowsAzure_Exception('Queue name is not specified.');
}
if (!self::isValidQueueName($queueName)) {
throw new Zend_Service_WindowsAzure_Exception('Queue name does not adhere to queue naming conventions. See http://msdn.microsoft.com/en-us/library/dd179349.aspx for more information.');
}
// List queues
$queues = $this->listQueues($queueName, 1);
foreach ($queues as $queue) {
if ($queue->Name == $queueName) {
return true;
}
}
return false;
}
/**
* Create queue
*
* @param string $queueName Queue name
* @param array $metadata Key/value pairs of meta data
* @return object Queue properties
* @throws Zend_Service_WindowsAzure_Exception
*/
public function createQueue($queueName = '', $metadata = array())
{
if ($queueName === '') {
throw new Zend_Service_WindowsAzure_Exception('Queue name is not specified.');
}
if (!self::isValidQueueName($queueName)) {
throw new Zend_Service_WindowsAzure_Exception('Queue name does not adhere to queue naming conventions. See http://msdn.microsoft.com/en-us/library/dd179349.aspx for more information.');
}
// Create metadata headers
$headers = array();
$headers = array_merge($headers, $this->_generateMetadataHeaders($metadata));
// Perform request
$response = $this->_performRequest($queueName, '', Zend_Http_Client::PUT, $headers);
if ($response->isSuccessful()) {
return new Zend_Service_WindowsAzure_Storage_QueueInstance(
$queueName,
$metadata
);
} else {
throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
}
}
/**
* Get queue
*
* @param string $queueName Queue name
* @return Zend_Service_WindowsAzure_Storage_QueueInstance
* @throws Zend_Service_WindowsAzure_Exception
*/
public function getQueue($queueName = '')
{
if ($queueName === '') {
throw new Zend_Service_WindowsAzure_Exception('Queue name is not specified.');
}
if (!self::isValidQueueName($queueName)) {
throw new Zend_Service_WindowsAzure_Exception('Queue name does not adhere to queue naming conventions. See http://msdn.microsoft.com/en-us/library/dd179349.aspx for more information.');
}
// Perform request
$response = $this->_performRequest($queueName, '?comp=metadata', Zend_Http_Client::GET);
if ($response->isSuccessful()) {
// Parse metadata
$metadata = $this->_parseMetadataHeaders($response->getHeaders());
// Return queue
$queue = new Zend_Service_WindowsAzure_Storage_QueueInstance(
$queueName,
$metadata
);
$queue->ApproximateMessageCount = intval($response->getHeader('x-ms-approximate-message-count'));
return $queue;
} else {
throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
}
}
/**
* Get queue metadata
*
* @param string $queueName Queue name
* @return array Key/value pairs of meta data
* @throws Zend_Service_WindowsAzure_Exception
*/
public function getQueueMetadata($queueName = '')
{
if ($queueName === '') {
throw new Zend_Service_WindowsAzure_Exception('Queue name is not specified.');
}
if (!self::isValidQueueName($queueName)) {
throw new Zend_Service_WindowsAzure_Exception('Queue name does not adhere to queue naming conventions. See http://msdn.microsoft.com/en-us/library/dd179349.aspx for more information.');
}
return $this->getQueue($queueName)->Metadata;
}
/**
* Set queue metadata
*
* Calling the Set Queue Metadata operation overwrites all existing metadata that is associated with the queue. It's not possible to modify an individual name/value pair.
*
* @param string $queueName Queue name
* @param array $metadata Key/value pairs of meta data
* @throws Zend_Service_WindowsAzure_Exception
*/
public function setQueueMetadata($queueName = '', $metadata = array())
{
if ($queueName === '') {
throw new Zend_Service_WindowsAzure_Exception('Queue name is not specified.');
}
if (!self::isValidQueueName($queueName)) {
throw new Zend_Service_WindowsAzure_Exception('Queue name does not adhere to queue naming conventions. See http://msdn.microsoft.com/en-us/library/dd179349.aspx for more information.');
}
if (count($metadata) == 0) {
return;
}
// Create metadata headers
$headers = array();
$headers = array_merge($headers, $this->_generateMetadataHeaders($metadata));
// Perform request
$response = $this->_performRequest($queueName, '?comp=metadata', Zend_Http_Client::PUT, $headers);
if (!$response->isSuccessful()) {
throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
}
}
/**
* Delete queue
*
* @param string $queueName Queue name
* @throws Zend_Service_WindowsAzure_Exception
*/
public function deleteQueue($queueName = '')
{
if ($queueName === '') {
throw new Zend_Service_WindowsAzure_Exception('Queue name is not specified.');
}
if (!self::isValidQueueName($queueName)) {
throw new Zend_Service_WindowsAzure_Exception('Queue name does not adhere to queue naming conventions. See http://msdn.microsoft.com/en-us/library/dd179349.aspx for more information.');
}
// Perform request
$response = $this->_performRequest($queueName, '', Zend_Http_Client::DELETE);
if (!$response->isSuccessful()) {
throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
}
}
/**
* List queues
*
* @param string $prefix Optional. Filters the results to return only queues whose name begins with the specified prefix.
* @param int $maxResults Optional. Specifies the maximum number of queues to return per call to Azure storage. This does NOT affect list size returned by this function. (maximum: 5000)
* @param string $marker Optional string value that identifies the portion of the list to be returned with the next list operation.
* @param int $currentResultCount Current result count (internal use)
* @return array
* @throws Zend_Service_WindowsAzure_Exception
*/
public function listQueues($prefix = null, $maxResults = null, $marker = null, $currentResultCount = 0)
{
// Build query string
$queryString = '?comp=list';
if (!is_null($prefix)) {
$queryString .= '&prefix=' . $prefix;
}
if (!is_null($maxResults)) {
$queryString .= '&maxresults=' . $maxResults;
}
if (!is_null($marker)) {
$queryString .= '&marker=' . $marker;
}
// Perform request
$response = $this->_performRequest('', $queryString, Zend_Http_Client::GET);
if ($response->isSuccessful()) {
$xmlQueues = $this->_parseResponse($response)->Queues->Queue;
$xmlMarker = (string)$this->_parseResponse($response)->NextMarker;
$queues = array();
if (!is_null($xmlQueues)) {
for ($i = 0; $i < count($xmlQueues); $i++) {
$queues[] = new Zend_Service_WindowsAzure_Storage_QueueInstance(
(string)$xmlQueues[$i]->QueueName
);
}
}
$currentResultCount = $currentResultCount + count($queues);
if (!is_null($maxResults) && $currentResultCount < $maxResults) {
if (!is_null($xmlMarker) && $xmlMarker != '') {
$queues = array_merge($queues, $this->listQueues($prefix, $maxResults, $xmlMarker, $currentResultCount));
}
}
if (!is_null($maxResults) && count($queues) > $maxResults) {
$queues = array_slice($queues, 0, $maxResults);
}
return $queues;
} else {
throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
}
}
/**
* Put message into queue
*
* @param string $queueName Queue name
* @param string $message Message
* @param int $ttl Message Time-To-Live (in seconds). Defaults to 7 days if the parameter is omitted.
* @throws Zend_Service_WindowsAzure_Exception
*/
public function putMessage($queueName = '', $message = '', $ttl = null)
{
if ($queueName === '') {
throw new Zend_Service_WindowsAzure_Exception('Queue name is not specified.');
}
if (!self::isValidQueueName($queueName)) {
throw new Zend_Service_WindowsAzure_Exception('Queue name does not adhere to queue naming conventions. See http://msdn.microsoft.com/en-us/library/dd179349.aspx for more information.');
}
if (strlen($message) > self::MAX_MESSAGE_SIZE) {
throw new Zend_Service_WindowsAzure_Exception('Message is too big. Message content should be < 8KB.');
}
if ($message == '') {
throw new Zend_Service_WindowsAzure_Exception('Message is not specified.');
}
if (!is_null($ttl) && ($ttl <= 0 || $ttl > self::MAX_MESSAGE_SIZE)) {
throw new Zend_Service_WindowsAzure_Exception('Message TTL is invalid. Maximal TTL is 7 days (' . self::MAX_MESSAGE_SIZE . ' seconds) and should be greater than zero.');
}
// Build query string
$queryString = '';
if (!is_null($ttl)) {
$queryString .= '?messagettl=' . $ttl;
}
// Build body
$rawData = '';
$rawData .= '<QueueMessage>';
$rawData .= ' <MessageText>' . base64_encode($message) . '</MessageText>';
$rawData .= '</QueueMessage>';
// Perform request
$response = $this->_performRequest($queueName . '/messages', $queryString, Zend_Http_Client::POST, array(), false, $rawData);
if (!$response->isSuccessful()) {
throw new Zend_Service_WindowsAzure_Exception('Error putting message into queue.');
}
}
/**
* Get queue messages
*
* @param string $queueName Queue name
* @param string $numOfMessages Optional. A nonzero integer value that specifies the number of messages to retrieve from the queue, up to a maximum of 32. By default, a single message is retrieved from the queue with this operation.
* @param int $visibilityTimeout Optional. An integer value that specifies the message's visibility timeout in seconds. The maximum value is 2 hours. The default message visibility timeout is 30 seconds.
* @param string $peek Peek only?
* @return array
* @throws Zend_Service_WindowsAzure_Exception
*/
public function getMessages($queueName = '', $numOfMessages = 1, $visibilityTimeout = null, $peek = false)
{
if ($queueName === '') {
throw new Zend_Service_WindowsAzure_Exception('Queue name is not specified.');
}
if (!self::isValidQueueName($queueName)) {
throw new Zend_Service_WindowsAzure_Exception('Queue name does not adhere to queue naming conventions. See http://msdn.microsoft.com/en-us/library/dd179349.aspx for more information.');
}
if ($numOfMessages < 1 || $numOfMessages > 32 || intval($numOfMessages) != $numOfMessages) {
throw new Zend_Service_WindowsAzure_Exception('Invalid number of messages to retrieve.');
}
if (!is_null($visibilityTimeout) && ($visibilityTimeout <= 0 || $visibilityTimeout > 7200)) {
throw new Zend_Service_WindowsAzure_Exception('Visibility timeout is invalid. Maximum value is 2 hours (7200 seconds) and should be greater than zero.');
}
// Build query string
$query = array();
if ($peek) {
$query[] = 'peekonly=true';
}
if ($numOfMessages > 1) {
$query[] = 'numofmessages=' . $numOfMessages;
}
if (!$peek && !is_null($visibilityTimeout)) {
$query[] = 'visibilitytimeout=' . $visibilityTimeout;
}
$queryString = '?' . implode('&', $query);
// Perform request
$response = $this->_performRequest($queueName . '/messages', $queryString, Zend_Http_Client::GET);
if ($response->isSuccessful()) {
// Parse results
$result = $this->_parseResponse($response);
if (!$result) {
return array();
}
$xmlMessages = null;
if (count($result->QueueMessage) > 1) {
$xmlMessages = $result->QueueMessage;
} else {
$xmlMessages = array($result->QueueMessage);
}
$messages = array();
for ($i = 0; $i < count($xmlMessages); $i++) {
$messages[] = new Zend_Service_WindowsAzure_Storage_QueueMessage(
(string)$xmlMessages[$i]->MessageId,
(string)$xmlMessages[$i]->InsertionTime,
(string)$xmlMessages[$i]->ExpirationTime,
($peek ? '' : (string)$xmlMessages[$i]->PopReceipt),
($peek ? '' : (string)$xmlMessages[$i]->TimeNextVisible),
base64_decode((string)$xmlMessages[$i]->MessageText)
);
}
return $messages;
} else {
throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
}
}
/**
* Peek queue messages
*
* @param string $queueName Queue name
* @param string $numOfMessages Optional. A nonzero integer value that specifies the number of messages to retrieve from the queue, up to a maximum of 32. By default, a single message is retrieved from the queue with this operation.
* @return array
* @throws Zend_Service_WindowsAzure_Exception
*/
public function peekMessages($queueName = '', $numOfMessages = 1)
{
return $this->getMessages($queueName, $numOfMessages, null, true);
}
/**
* Clear queue messages
*
* @param string $queueName Queue name
* @throws Zend_Service_WindowsAzure_Exception
*/
public function clearMessages($queueName = '')
{
if ($queueName === '') {
throw new Zend_Service_WindowsAzure_Exception('Queue name is not specified.');
}
if (!self::isValidQueueName($queueName)) {
throw new Zend_Service_WindowsAzure_Exception('Queue name does not adhere to queue naming conventions. See http://msdn.microsoft.com/en-us/library/dd179349.aspx for more information.');
}
// Perform request
$response = $this->_performRequest($queueName . '/messages', '', Zend_Http_Client::DELETE);
if (!$response->isSuccessful()) {
throw new Zend_Service_WindowsAzure_Exception('Error clearing messages from queue.');
}
}
/**
* Delete queue message
*
* @param string $queueName Queue name
* @param Zend_Service_WindowsAzure_Storage_QueueMessage $message Message to delete from queue. A message retrieved using "peekMessages" can NOT be deleted!
* @throws Zend_Service_WindowsAzure_Exception
*/
public function deleteMessage($queueName = '', Zend_Service_WindowsAzure_Storage_QueueMessage $message)
{
if ($queueName === '') {
throw new Zend_Service_WindowsAzure_Exception('Queue name is not specified.');
}
if (!self::isValidQueueName($queueName)) {
throw new Zend_Service_WindowsAzure_Exception('Queue name does not adhere to queue naming conventions. See http://msdn.microsoft.com/en-us/library/dd179349.aspx for more information.');
}
if ($message->PopReceipt == '') {
throw new Zend_Service_WindowsAzure_Exception('A message retrieved using "peekMessages" can NOT be deleted! Use "getMessages" instead.');
}
// Perform request
$response = $this->_performRequest($queueName . '/messages/' . $message->MessageId, '?popreceipt=' . $message->PopReceipt, Zend_Http_Client::DELETE);
if (!$response->isSuccessful()) {
throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
}
}
/**
* Is valid queue name?
*
* @param string $queueName Queue name
* @return boolean
*/
public static function isValidQueueName($queueName = '')
{
if (preg_match("/^[a-z0-9][a-z0-9-]*$/", $queueName) === 0) {
return false;
}
if (strpos($queueName, '--') !== false) {
return false;
}
if (strtolower($queueName) != $queueName) {
return false;
}
if (strlen($queueName) < 3 || strlen($queueName) > 63) {
return false;
}
if (substr($queueName, -1) == '-') {
return false;
}
return true;
}
/**
* Get error message from Zend_Http_Response
*
* @param Zend_Http_Response $response Repsonse
* @param string $alternativeError Alternative error message
* @return string
*/
protected function _getErrorMessage(Zend_Http_Response $response, $alternativeError = 'Unknown error.')
{
$response = $this->_parseResponse($response);
if ($response && $response->Message) {
return (string)$response->Message;
} else {
return $alternativeError;
}
}
}

View file

@ -0,0 +1,91 @@
<?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_Service_WindowsAzure
* @subpackage Storage
* @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: BlobContainer.php 17553 2009-05-15 10:40:55Z unknown $
*/
/**
* @see Zend_Service_WindowsAzure_Exception
*/
require_once 'Zend/Service/WindowsAzure/Exception.php';
/**
* @category Zend
* @package Zend_Service_WindowsAzure
* @subpackage Storage
* @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*
* @property string $Name Name of the queue
* @property array $Metadata Key/value pairs of meta data
* @property integer $ApproximateMessageCount The approximate number of messages in the queue
*/
class Zend_Service_WindowsAzure_Storage_QueueInstance
{
/**
* Data
*
* @var array
*/
protected $_data = null;
/**
* Constructor
*
* @param string $name Name
* @param array $metadata Key/value pairs of meta data
*/
public function __construct($name, $metadata = array())
{
$this->_data = array(
'name' => $name,
'metadata' => $metadata,
'approximatemessagecount' => 0
);
}
/**
* Magic overload for setting properties
*
* @param string $name Name of the property
* @param string $value Value to set
*/
public function __set($name, $value) {
if (array_key_exists(strtolower($name), $this->_data)) {
$this->_data[strtolower($name)] = $value;
return;
}
throw new Exception("Unknown property: " . $name);
}
/**
* Magic overload for getting properties
*
* @param string $name Name of the property
*/
public function __get($name) {
if (array_key_exists(strtolower($name), $this->_data)) {
return $this->_data[strtolower($name)];
}
throw new Exception("Unknown property: " . $name);
}
}

View file

@ -0,0 +1,101 @@
<?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_Service_WindowsAzure
* @subpackage Storage
* @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: BlobContainer.php 17553 2009-05-15 10:40:55Z unknown $
*/
/**
* @see Zend_Service_WindowsAzure_Exception
*/
require_once 'Zend/Service/WindowsAzure/Exception.php';
/**
* @category Zend
* @package Zend_Service_WindowsAzure
* @subpackage Storage
* @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*
* @property string $MessageId Message ID
* @property string $InsertionTime Insertion time
* @property string $ExpirationTime Expiration time
* @property string $PopReceipt Receipt verification for deleting the message from queue.
* @property string $TimeNextVisible Next time the message is visible in the queue
* @property string $MessageText Message text
*/
class Zend_Service_WindowsAzure_Storage_QueueMessage
{
/**
* Data
*
* @var array
*/
protected $_data = null;
/**
* Constructor
*
* @param string $messageId Message ID
* @param string $insertionTime Insertion time
* @param string $expirationTime Expiration time
* @param string $popReceipt Receipt verification for deleting the message from queue.
* @param string $timeNextVisible Next time the message is visible in the queue
* @param string $messageText Message text
*/
public function __construct($messageId, $insertionTime, $expirationTime, $popReceipt, $timeNextVisible, $messageText)
{
$this->_data = array(
'messageid' => $messageId,
'insertiontime' => $insertionTime,
'expirationtime' => $expirationTime,
'popreceipt' => $popReceipt,
'timenextvisible' => $timeNextVisible,
'messagetext' => $messageText
);
}
/**
* Magic overload for setting properties
*
* @param string $name Name of the property
* @param string $value Value to set
*/
public function __set($name, $value) {
if (array_key_exists(strtolower($name), $this->_data)) {
$this->_data[strtolower($name)] = $value;
return;
}
throw new Exception("Unknown property: " . $name);
}
/**
* Magic overload for getting properties
*
* @param string $name Name of the property
*/
public function __get($name) {
if (array_key_exists(strtolower($name), $this->_data)) {
return $this->_data[strtolower($name)];
}
throw new Exception("Unknown property: " . $name);
}
}

View file

@ -0,0 +1,94 @@
<?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_Service_WindowsAzure
* @subpackage Storage
* @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: BlobContainer.php 24352 2009-07-24 06:44:32Z unknown $
*/
/**
* @see Zend_Service_WindowsAzure_Exception
*/
require_once 'Zend/Service/WindowsAzure/Exception.php';
/**
* @category Zend
* @package Zend_Service_WindowsAzure
* @subpackage Storage
* @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*
* @property string $Id Id for the signed identifier
* @property string $Start The time at which the Shared Access Signature becomes valid.
* @property string $Expiry The time at which the Shared Access Signature becomes invalid.
* @property string $Permissions Signed permissions - read (r), write (w), delete (d) and list (l)
*/
class Zend_Service_WindowsAzure_Storage_SignedIdentifier
{
/**
* Data
*
* @var array
*/
protected $_data = null;
/**
* Constructor
*
* @param string $id Id for the signed identifier
* @param string $start The time at which the Shared Access Signature becomes valid.
* @param string $expiry The time at which the Shared Access Signature becomes invalid.
* @param string $permissions Signed permissions - read (r), write (w), delete (d) and list (l)
*/
public function __construct($id = '', $start = '', $expiry = '', $permissions = '')
{
$this->_data = array(
'id' => $id,
'start' => $start,
'expiry' => $expiry,
'permissions' => $permissions
);
}
/**
* Magic overload for setting properties
*
* @param string $name Name of the property
* @param string $value Value to set
*/
public function __set($name, $value) {
if (array_key_exists(strtolower($name), $this->_data)) {
$this->_data[strtolower($name)] = $value;
return;
}
throw new Exception("Unknown property: " . $name);
}
/**
* Magic overload for getting properties
*
* @param string $name Name of the property
*/
public function __get($name) {
if (array_key_exists(strtolower($name), $this->_data)) {
return $this->_data[strtolower($name)];
}
throw new Exception("Unknown property: " . $name);
}
}

View file

@ -0,0 +1,816 @@
<?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_Service_WindowsAzure
* @subpackage Storage
* @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: Blob.php 14561 2009-05-07 08:05:12Z unknown $
*/
/**
* @see Zend_Service_WindowsAzure_Credentials_CredentialsAbstract
*/
require_once 'Zend/Service/WindowsAzure/Credentials/CredentialsAbstract.php';
/**
* @see Zend_Service_WindowsAzure_Credentials_SharedKey
*/
require_once 'Zend/Service/WindowsAzure/Credentials/SharedKey.php';
/**
* @see Zend_Service_WindowsAzure_Credentials_SharedKeyLite
*/
require_once 'Zend/Service/WindowsAzure/Credentials/SharedKeyLite.php';
/**
* @see Zend_Service_WindowsAzure_RetryPolicy_RetryPolicyAbstract
*/
require_once 'Zend/Service/WindowsAzure/RetryPolicy/RetryPolicyAbstract.php';
/**
* @see Zend_Http_Client
*/
require_once 'Zend/Http/Client.php';
/**
* @see Zend_Http_Response
*/
require_once 'Zend/Http/Response.php';
/**
* @see Zend_Service_WindowsAzure_Storage
*/
require_once 'Zend/Service/WindowsAzure/Storage.php';
/**
* @see Zend_Service_WindowsAzure_Storage_BatchStorageAbstract
*/
require_once 'Zend/Service/WindowsAzure/Storage/BatchStorageAbstract.php';
/**
* @see Zend_Service_WindowsAzure_Storage_TableInstance
*/
require_once 'Zend/Service/WindowsAzure/Storage/TableInstance.php';
/**
* @see Zend_Service_WindowsAzure_Storage_TableEntity
*/
require_once 'Zend/Service/WindowsAzure/Storage/TableEntity.php';
/**
* @see Zend_Service_WindowsAzure_Storage_DynamicTableEntity
*/
require_once 'Zend/Service/WindowsAzure/Storage/DynamicTableEntity.php';
/**
* @see Zend_Service_WindowsAzure_Storage_TableEntityQuery
*/
require_once 'Zend/Service/WindowsAzure/Storage/TableEntityQuery.php';
/**
* @see Zend_Service_WindowsAzure_Exception
*/
require_once 'Zend/Service/WindowsAzure/Exception.php';
/**
* @category Zend
* @package Zend_Service_WindowsAzure
* @subpackage Storage
* @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_Service_WindowsAzure_Storage_Table
extends Zend_Service_WindowsAzure_Storage_BatchStorageAbstract
{
/**
* Creates a new Zend_Service_WindowsAzure_Storage_Table instance
*
* @param string $host Storage host name
* @param string $accountName Account name for Windows Azure
* @param string $accountKey Account key for Windows Azure
* @param boolean $usePathStyleUri Use path-style URI's
* @param Zend_Service_WindowsAzure_RetryPolicy_RetryPolicyAbstract $retryPolicy Retry policy to use when making requests
*/
public function __construct($host = Zend_Service_WindowsAzure_Storage::URL_DEV_TABLE, $accountName = Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::DEVSTORE_ACCOUNT, $accountKey = Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::DEVSTORE_KEY, $usePathStyleUri = false, Zend_Service_WindowsAzure_RetryPolicy_RetryPolicyAbstract $retryPolicy = null)
{
parent::__construct($host, $accountName, $accountKey, $usePathStyleUri, $retryPolicy);
// Always use SharedKeyLite authentication
$this->_credentials = new Zend_Service_WindowsAzure_Credentials_SharedKeyLite($accountName, $accountKey, $this->_usePathStyleUri);
// API version
$this->_apiVersion = '2009-04-14';
}
/**
* Check if a table exists
*
* @param string $tableName Table name
* @return boolean
*/
public function tableExists($tableName = '')
{
if ($tableName === '') {
throw new Zend_Service_WindowsAzure_Exception('Table name is not specified.');
}
// List tables
$tables = $this->listTables($tableName);
foreach ($tables as $table) {
if ($table->Name == $tableName) {
return true;
}
}
return false;
}
/**
* List tables
*
* @param string $nextTableName Next table name, used for listing tables when total amount of tables is > 1000.
* @return array
* @throws Zend_Service_WindowsAzure_Exception
*/
public function listTables($nextTableName = '')
{
// Build query string
$queryString = '';
if ($nextTableName != '') {
$queryString = '?NextTableName=' . $nextTableName;
}
// Perform request
$response = $this->_performRequest('Tables', $queryString, Zend_Http_Client::GET, null, true);
if ($response->isSuccessful()) {
// Parse result
$result = $this->_parseResponse($response);
if (!$result || !$result->entry) {
return array();
}
$entries = null;
if (count($result->entry) > 1) {
$entries = $result->entry;
} else {
$entries = array($result->entry);
}
// Create return value
$returnValue = array();
foreach ($entries as $entry) {
$tableName = $entry->xpath('.//m:properties/d:TableName');
$tableName = (string)$tableName[0];
$returnValue[] = new Zend_Service_WindowsAzure_Storage_TableInstance(
(string)$entry->id,
$tableName,
(string)$entry->link['href'],
(string)$entry->updated
);
}
// More tables?
if (!is_null($response->getHeader('x-ms-continuation-NextTableName'))) {
$returnValue = array_merge($returnValue, $this->listTables($response->getHeader('x-ms-continuation-NextTableName')));
}
return $returnValue;
} else {
throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
}
}
/**
* Create table
*
* @param string $tableName Table name
* @return Zend_Service_WindowsAzure_Storage_TableInstance
* @throws Zend_Service_WindowsAzure_Exception
*/
public function createTable($tableName = '')
{
if ($tableName === '') {
throw new Zend_Service_WindowsAzure_Exception('Table name is not specified.');
}
// Generate request body
$requestBody = '<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<entry
xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices"
xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"
xmlns="http://www.w3.org/2005/Atom">
<title />
<updated>{tpl:Updated}</updated>
<author>
<name />
</author>
<id />
<content type="application/xml">
<m:properties>
<d:TableName>{tpl:TableName}</d:TableName>
</m:properties>
</content>
</entry>';
$requestBody = $this->_fillTemplate($requestBody, array(
'BaseUrl' => $this->getBaseUrl(),
'TableName' => htmlspecialchars($tableName),
'Updated' => $this->isoDate(),
'AccountName' => $this->_accountName
));
// Add header information
$headers = array();
$headers['Content-Type'] = 'application/atom+xml';
$headers['DataServiceVersion'] = '1.0;NetFx';
$headers['MaxDataServiceVersion'] = '1.0;NetFx';
// Perform request
$response = $this->_performRequest('Tables', '', Zend_Http_Client::POST, $headers, true, $requestBody);
if ($response->isSuccessful()) {
// Parse response
$entry = $this->_parseResponse($response);
$tableName = $entry->xpath('.//m:properties/d:TableName');
$tableName = (string)$tableName[0];
return new Zend_Service_WindowsAzure_Storage_TableInstance(
(string)$entry->id,
$tableName,
(string)$entry->link['href'],
(string)$entry->updated
);
} else {
throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
}
}
/**
* Delete table
*
* @param string $tableName Table name
* @throws Zend_Service_WindowsAzure_Exception
*/
public function deleteTable($tableName = '')
{
if ($tableName === '') {
throw new Zend_Service_WindowsAzure_Exception('Table name is not specified.');
}
// Add header information
$headers = array();
$headers['Content-Type'] = 'application/atom+xml';
// Perform request
$response = $this->_performRequest('Tables(\'' . $tableName . '\')', '', Zend_Http_Client::DELETE, $headers, true, null);
if (!$response->isSuccessful()) {
throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
}
}
/**
* Insert entity into table
*
* @param string $tableName Table name
* @param Zend_Service_WindowsAzure_Storage_TableEntity $entity Entity to insert
* @return Zend_Service_WindowsAzure_Storage_TableEntity
* @throws Zend_Service_WindowsAzure_Exception
*/
public function insertEntity($tableName = '', Zend_Service_WindowsAzure_Storage_TableEntity $entity = null)
{
if ($tableName === '') {
throw new Zend_Service_WindowsAzure_Exception('Table name is not specified.');
}
if (is_null($entity)) {
throw new Zend_Service_WindowsAzure_Exception('Entity is not specified.');
}
// Generate request body
$requestBody = '<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<entry xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns="http://www.w3.org/2005/Atom">
<title />
<updated>{tpl:Updated}</updated>
<author>
<name />
</author>
<id />
<content type="application/xml">
<m:properties>
{tpl:Properties}
</m:properties>
</content>
</entry>';
$requestBody = $this->_fillTemplate($requestBody, array(
'Updated' => $this->isoDate(),
'Properties' => $this->_generateAzureRepresentation($entity)
));
// Add header information
$headers = array();
$headers['Content-Type'] = 'application/atom+xml';
// Perform request
$response = null;
if ($this->isInBatch()) {
$this->getCurrentBatch()->enlistOperation($tableName, '', Zend_Http_Client::POST, $headers, true, $requestBody);
return null;
} else {
$response = $this->_performRequest($tableName, '', Zend_Http_Client::POST, $headers, true, $requestBody);
}
if ($response->isSuccessful()) {
// Parse result
$result = $this->_parseResponse($response);
$timestamp = $result->xpath('//m:properties/d:Timestamp');
$timestamp = (string)$timestamp[0];
$etag = $result->attributes('http://schemas.microsoft.com/ado/2007/08/dataservices/metadata');
$etag = (string)$etag['etag'];
// Update properties
$entity->setTimestamp($timestamp);
$entity->setEtag($etag);
return $entity;
} else {
throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
}
}
/**
* Delete entity from table
*
* @param string $tableName Table name
* @param Zend_Service_WindowsAzure_Storage_TableEntity $entity Entity to delete
* @param boolean $verifyEtag Verify etag of the entity (used for concurrency)
* @throws Zend_Service_WindowsAzure_Exception
*/
public function deleteEntity($tableName = '', Zend_Service_WindowsAzure_Storage_TableEntity $entity = null, $verifyEtag = false)
{
if ($tableName === '') {
throw new Zend_Service_WindowsAzure_Exception('Table name is not specified.');
}
if (is_null($entity)) {
throw new Zend_Service_WindowsAzure_Exception('Entity is not specified.');
}
// Add header information
$headers = array();
if (!$this->isInBatch()) {
// http://social.msdn.microsoft.com/Forums/en-US/windowsazure/thread/9e255447-4dc7-458a-99d3-bdc04bdc5474/
$headers['Content-Type'] = 'application/atom+xml';
}
$headers['Content-Length'] = 0;
if (!$verifyEtag) {
$headers['If-Match'] = '*';
} else {
$headers['If-Match'] = $entity->getEtag();
}
// Perform request
$response = null;
if ($this->isInBatch()) {
$this->getCurrentBatch()->enlistOperation($tableName . '(PartitionKey=\'' . $entity->getPartitionKey() . '\', RowKey=\'' . $entity->getRowKey() . '\')', '', Zend_Http_Client::DELETE, $headers, true, null);
return null;
} else {
$response = $this->_performRequest($tableName . '(PartitionKey=\'' . $entity->getPartitionKey() . '\', RowKey=\'' . $entity->getRowKey() . '\')', '', Zend_Http_Client::DELETE, $headers, true, null);
}
if (!$response->isSuccessful()) {
throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
}
}
/**
* Retrieve entity from table, by id
*
* @param string $tableName Table name
* @param string $partitionKey Partition key
* @param string $rowKey Row key
* @param string $entityClass Entity class name*
* @return Zend_Service_WindowsAzure_Storage_TableEntity
* @throws Zend_Service_WindowsAzure_Exception
*/
public function retrieveEntityById($tableName = '', $partitionKey = '', $rowKey = '', $entityClass = 'Zend_Service_WindowsAzure_Storage_DynamicTableEntity')
{
if ($tableName === '') {
throw new Zend_Service_WindowsAzure_Exception('Table name is not specified.');
}
if ($partitionKey === '') {
throw new Zend_Service_WindowsAzure_Exception('Partition key is not specified.');
}
if ($rowKey === '') {
throw new Zend_Service_WindowsAzure_Exception('Row key is not specified.');
}
if ($entityClass === '') {
throw new Zend_Service_WindowsAzure_Exception('Entity class is not specified.');
}
// Check for combined size of partition key and row key
// http://msdn.microsoft.com/en-us/library/dd179421.aspx
if (strlen($partitionKey . $rowKey) >= 256) {
// Start a batch if possible
if ($this->isInBatch()) {
throw new Zend_Service_WindowsAzure_Exception('Entity cannot be retrieved. A transaction is required to retrieve the entity, but another transaction is already active.');
}
$this->startBatch();
}
// Fetch entities from Azure
$result = $this->retrieveEntities(
$this->select()
->from($tableName)
->wherePartitionKey($partitionKey)
->whereRowKey($rowKey),
'',
$entityClass
);
// Return
if (count($result) == 1) {
return $result[0];
}
return null;
}
/**
* Create a new Zend_Service_WindowsAzure_Storage_TableEntityQuery
*
* @return Zend_Service_WindowsAzure_Storage_TableEntityQuery
*/
public function select()
{
return new Zend_Service_WindowsAzure_Storage_TableEntityQuery();
}
/**
* Retrieve entities from table
*
* @param string $tableName|Zend_Service_WindowsAzure_Storage_TableEntityQuery Table name -or- Zend_Service_WindowsAzure_Storage_TableEntityQuery instance
* @param string $filter Filter condition (not applied when $tableName is a Zend_Service_WindowsAzure_Storage_TableEntityQuery instance)
* @param string $entityClass Entity class name
* @param string $nextPartitionKey Next partition key, used for listing entities when total amount of entities is > 1000.
* @param string $nextRowKey Next row key, used for listing entities when total amount of entities is > 1000.
* @return array Array of Zend_Service_WindowsAzure_Storage_TableEntity
* @throws Zend_Service_WindowsAzure_Exception
*/
public function retrieveEntities($tableName = '', $filter = '', $entityClass = 'Zend_Service_WindowsAzure_Storage_DynamicTableEntity', $nextPartitionKey = null, $nextRowKey = null)
{
if ($tableName === '') {
throw new Zend_Service_WindowsAzure_Exception('Table name is not specified.');
}
if ($entityClass === '') {
throw new Zend_Service_WindowsAzure_Exception('Entity class is not specified.');
}
// Convenience...
if (class_exists($filter)) {
$entityClass = $filter;
$filter = '';
}
// Query string
$queryString = '';
// Determine query
if (is_string($tableName)) {
// Option 1: $tableName is a string
// Append parentheses
$tableName .= '()';
// Build query
$query = array();
// Filter?
if ($filter !== '') {
$query[] = '$filter=' . rawurlencode($filter);
}
// Build queryString
if (count($query) > 0) {
$queryString = '?' . implode('&', $query);
}
} else if (get_class($tableName) == 'Zend_Service_WindowsAzure_Storage_TableEntityQuery') {
// Option 2: $tableName is a Zend_Service_WindowsAzure_Storage_TableEntityQuery instance
// Build queryString
$queryString = $tableName->assembleQueryString(true);
// Change $tableName
$tableName = $tableName->assembleFrom(true);
} else {
throw new Zend_Service_WindowsAzure_Exception('Invalid argument: $tableName');
}
// Add continuation querystring parameters?
if (!is_null($nextPartitionKey) && !is_null($nextRowKey)) {
if ($queryString !== '') {
$queryString .= '&';
}
$queryString .= '&NextPartitionKey=' . rawurlencode($nextPartitionKey) . '&NextRowKey=' . rawurlencode($nextRowKey);
}
// Perform request
$response = null;
if ($this->isInBatch() && $this->getCurrentBatch()->getOperationCount() == 0) {
$this->getCurrentBatch()->enlistOperation($tableName, $queryString, Zend_Http_Client::GET, array(), true, null);
$response = $this->getCurrentBatch()->commit();
// Get inner response (multipart)
$innerResponse = $response->getBody();
$innerResponse = substr($innerResponse, strpos($innerResponse, 'HTTP/1.1 200 OK'));
$innerResponse = substr($innerResponse, 0, strpos($innerResponse, '--batchresponse'));
$response = Zend_Http_Response::fromString($innerResponse);
} else {
$response = $this->_performRequest($tableName, $queryString, Zend_Http_Client::GET, array(), true, null);
}
if ($response->isSuccessful()) {
// Parse result
$result = $this->_parseResponse($response);
if (!$result) {
return array();
}
$entries = null;
if ($result->entry) {
if (count($result->entry) > 1) {
$entries = $result->entry;
} else {
$entries = array($result->entry);
}
} else {
// This one is tricky... If we have properties defined, we have an entity.
$properties = $result->xpath('//m:properties');
if ($properties) {
$entries = array($result);
} else {
return array();
}
}
// Create return value
$returnValue = array();
foreach ($entries as $entry) {
// Parse properties
$properties = $entry->xpath('.//m:properties');
$properties = $properties[0]->children('http://schemas.microsoft.com/ado/2007/08/dataservices');
// Create entity
$entity = new $entityClass('', '');
$entity->setAzureValues((array)$properties, true);
// If we have a Zend_Service_WindowsAzure_Storage_DynamicTableEntity, make sure all property types are OK
if ($entity instanceof Zend_Service_WindowsAzure_Storage_DynamicTableEntity) {
foreach ($properties as $key => $value) {
$attributes = $value->attributes('http://schemas.microsoft.com/ado/2007/08/dataservices/metadata');
$type = (string)$attributes['type'];
if ($type !== '') {
$entity->setAzurePropertyType($key, $type);
}
}
}
// Update etag
$etag = $entry->attributes('http://schemas.microsoft.com/ado/2007/08/dataservices/metadata');
$etag = (string)$etag['etag'];
$entity->setEtag($etag);
// Add to result
$returnValue[] = $entity;
}
// More entities?
if (!is_null($response->getHeader('x-ms-continuation-NextPartitionKey')) && !is_null($response->getHeader('x-ms-continuation-NextRowKey'))) {
if (strpos($queryString, '$top') === false) {
$returnValue = array_merge($returnValue, $this->retrieveEntities($tableName, $filter, $entityClass, $response->getHeader('x-ms-continuation-NextPartitionKey'), $response->getHeader('x-ms-continuation-NextRowKey')));
}
}
// Return
return $returnValue;
} else {
throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
}
}
/**
* Update entity by replacing it
*
* @param string $tableName Table name
* @param Zend_Service_WindowsAzure_Storage_TableEntity $entity Entity to update
* @param boolean $verifyEtag Verify etag of the entity (used for concurrency)
* @throws Zend_Service_WindowsAzure_Exception
*/
public function updateEntity($tableName = '', Zend_Service_WindowsAzure_Storage_TableEntity $entity = null, $verifyEtag = false)
{
return $this->_changeEntity(Zend_Http_Client::PUT, $tableName, $entity, $verifyEtag);
}
/**
* Update entity by adding or updating properties
*
* @param string $tableName Table name
* @param Zend_Service_WindowsAzure_Storage_TableEntity $entity Entity to update
* @param boolean $verifyEtag Verify etag of the entity (used for concurrency)
* @param array $properties Properties to merge. All properties will be used when omitted.
* @throws Zend_Service_WindowsAzure_Exception
*/
public function mergeEntity($tableName = '', Zend_Service_WindowsAzure_Storage_TableEntity $entity = null, $verifyEtag = false, $properties = array())
{
$mergeEntity = null;
if (is_array($properties) && count($properties) > 0) {
// Build a new object
$mergeEntity = new Zend_Service_WindowsAzure_Storage_DynamicTableEntity($entity->getPartitionKey(), $entity->getRowKey());
// Keep only values mentioned in $properties
$azureValues = $entity->getAzureValues();
foreach ($azureValues as $key => $value) {
if (in_array($value->Name, $properties)) {
$mergeEntity->setAzureProperty($value->Name, $value->Value, $value->Type);
}
}
} else {
$mergeEntity = $entity;
}
return $this->_changeEntity(Zend_Http_Client::MERGE, $tableName, $mergeEntity, $verifyEtag);
}
/**
* Get error message from Zend_Http_Response
*
* @param Zend_Http_Response $response Repsonse
* @param string $alternativeError Alternative error message
* @return string
*/
protected function _getErrorMessage(Zend_Http_Response $response, $alternativeError = 'Unknown error.')
{
$response = $this->_parseResponse($response);
if ($response && $response->message) {
return (string)$response->message;
} else {
return $alternativeError;
}
}
/**
* Update entity / merge entity
*
* @param string $httpVerb HTTP verb to use (PUT = update, MERGE = merge)
* @param string $tableName Table name
* @param Zend_Service_WindowsAzure_Storage_TableEntity $entity Entity to update
* @param boolean $verifyEtag Verify etag of the entity (used for concurrency)
* @throws Zend_Service_WindowsAzure_Exception
*/
protected function _changeEntity($httpVerb = Zend_Http_Client::PUT, $tableName = '', Zend_Service_WindowsAzure_Storage_TableEntity $entity = null, $verifyEtag = false)
{
if ($tableName === '') {
throw new Zend_Service_WindowsAzure_Exception('Table name is not specified.');
}
if (is_null($entity)) {
throw new Zend_Service_WindowsAzure_Exception('Entity is not specified.');
}
// Add header information
$headers = array();
$headers['Content-Type'] = 'application/atom+xml';
$headers['Content-Length'] = 0;
if (!$verifyEtag) {
$headers['If-Match'] = '*';
} else {
$headers['If-Match'] = $entity->getEtag();
}
// Generate request body
$requestBody = '<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<entry xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns="http://www.w3.org/2005/Atom">
<title />
<updated>{tpl:Updated}</updated>
<author>
<name />
</author>
<id />
<content type="application/xml">
<m:properties>
{tpl:Properties}
</m:properties>
</content>
</entry>';
$requestBody = $this->_fillTemplate($requestBody, array(
'Updated' => $this->isoDate(),
'Properties' => $this->_generateAzureRepresentation($entity)
));
// Add header information
$headers = array();
$headers['Content-Type'] = 'application/atom+xml';
if (!$verifyEtag) {
$headers['If-Match'] = '*';
} else {
$headers['If-Match'] = $entity->getEtag();
}
// Perform request
$response = null;
if ($this->isInBatch()) {
$this->getCurrentBatch()->enlistOperation($tableName . '(PartitionKey=\'' . $entity->getPartitionKey() . '\', RowKey=\'' . $entity->getRowKey() . '\')', '', $httpVerb, $headers, true, $requestBody);
return null;
} else {
$response = $this->_performRequest($tableName . '(PartitionKey=\'' . $entity->getPartitionKey() . '\', RowKey=\'' . $entity->getRowKey() . '\')', '', $httpVerb, $headers, true, $requestBody);
}
if ($response->isSuccessful()) {
// Update properties
$entity->setEtag($response->getHeader('Etag'));
$entity->setTimestamp($response->getHeader('Last-modified'));
return $entity;
} else {
throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
}
}
/**
* Generate RFC 1123 compliant date string
*
* @return string
*/
protected function _rfcDate()
{
return gmdate('D, d M Y H:i:s', time()) . ' GMT'; // RFC 1123
}
/**
* Fill text template with variables from key/value array
*
* @param string $templateText Template text
* @param array $variables Array containing key/value pairs
* @return string
*/
protected function _fillTemplate($templateText, $variables = array())
{
foreach ($variables as $key => $value) {
$templateText = str_replace('{tpl:' . $key . '}', $value, $templateText);
}
return $templateText;
}
/**
* Generate Azure representation from entity (creates atompub markup from properties)
*
* @param Zend_Service_WindowsAzure_Storage_TableEntity $entity
* @return string
*/
protected function _generateAzureRepresentation(Zend_Service_WindowsAzure_Storage_TableEntity $entity = null)
{
// Generate Azure representation from entity
$azureRepresentation = array();
$azureValues = $entity->getAzureValues();
foreach ($azureValues as $azureValue) {
$value = array();
$value[] = '<d:' . $azureValue->Name;
if ($azureValue->Type != '') {
$value[] = ' m:type="' . $azureValue->Type . '"';
}
if (is_null($azureValue->Value)) {
$value[] = ' m:null="true"';
}
$value[] = '>';
if (!is_null($azureValue->Value)) {
if (strtolower($azureValue->Type) == 'edm.boolean') {
$value[] = ($azureValue->Value == true ? '1' : '0');
} else {
$value[] = htmlspecialchars($azureValue->Value);
}
}
$value[] = '</d:' . $azureValue->Name . '>';
$azureRepresentation[] = implode('', $value);
}
return implode('', $azureRepresentation);
}
}

View file

@ -0,0 +1,323 @@
<?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_Service_WindowsAzure
* @subpackage Storage
* @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: BlobInstance.php 14561 2009-05-07 08:05:12Z unknown $
*/
/**
* @see Zend_Service_WindowsAzure_Exception
*/
require_once 'Zend/Service/WindowsAzure/Exception.php';
/**
* @category Zend
* @package Zend_Service_WindowsAzure
* @subpackage Storage
* @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_Service_WindowsAzure_Storage_TableEntity
{
/**
* Partition key
*
* @var string
*/
protected $_partitionKey;
/**
* Row key
*
* @var string
*/
protected $_rowKey;
/**
* Timestamp
*
* @var string
*/
protected $_timestamp = '1900-01-01T00:00:00';
/**
* Etag
*
* @var string
*/
protected $_etag = '';
/**
* Constructor
*
* @param string $partitionKey Partition key
* @param string $rowKey Row key
*/
public function __construct($partitionKey = '', $rowKey = '')
{
$this->_partitionKey = $partitionKey;
$this->_rowKey = $rowKey;
}
/**
* Get partition key
*
* @azure PartitionKey
* @return string
*/
public function getPartitionKey()
{
return $this->_partitionKey;
}
/**
* Set partition key
*
* @azure PartitionKey
* @param string $value
*/
public function setPartitionKey($value)
{
$this->_partitionKey = $value;
}
/**
* Get row key
*
* @azure RowKey
* @return string
*/
public function getRowKey()
{
return $this->_rowKey;
}
/**
* Set row key
*
* @azure RowKey
* @param string $value
*/
public function setRowKey($value)
{
$this->_rowKey = $value;
}
/**
* Get timestamp
*
* @azure Timestamp Edm.DateTime
* @return string
*/
public function getTimestamp()
{
return $this->_timestamp;
}
/**
* Set timestamp
*
* @azure Timestamp Edm.DateTime
* @param string $value
*/
public function setTimestamp($value = '1900-01-01T00:00:00')
{
$this->_timestamp = $value;
}
/**
* Get etag
*
* @return string
*/
public function getEtag()
{
return $this->_etag;
}
/**
* Set etag
*
* @param string $value
*/
public function setEtag($value = '')
{
$this->_etag = $value;
}
/**
* Get Azure values
*
* @return array
*/
public function getAzureValues()
{
// Get accessors
$accessors = self::getAzureAccessors(get_class($this));
// Loop accessors and retrieve values
$returnValue = array();
foreach ($accessors as $accessor) {
if ($accessor->EntityType == 'ReflectionProperty') {
$property = $accessor->EntityAccessor;
$returnValue[] = (object)array(
'Name' => $accessor->AzurePropertyName,
'Type' => $accessor->AzurePropertyType,
'Value' => $this->$property,
);
} else if ($accessor->EntityType == 'ReflectionMethod' && substr(strtolower($accessor->EntityAccessor), 0, 3) == 'get') {
$method = $accessor->EntityAccessor;
$returnValue[] = (object)array(
'Name' => $accessor->AzurePropertyName,
'Type' => $accessor->AzurePropertyType,
'Value' => $this->$method(),
);
}
}
// Return
return $returnValue;
}
/**
* Set Azure values
*
* @param array $values
* @param boolean $throwOnError Throw Zend_Service_WindowsAzure_Exception when a property is not specified in $values?
* @throws Zend_Service_WindowsAzure_Exception
*/
public function setAzureValues($values = array(), $throwOnError = false)
{
// Get accessors
$accessors = self::getAzureAccessors(get_class($this));
// Loop accessors and set values
$returnValue = array();
foreach ($accessors as $accessor) {
if (isset($values[$accessor->AzurePropertyName])) {
// Cast to correct type
if ($accessor->AzurePropertyType != '') {
switch (strtolower($accessor->AzurePropertyType)) {
case 'edm.int32':
case 'edm.int64':
$values[$accessor->AzurePropertyName] = intval($values[$accessor->AzurePropertyName]); break;
case 'edm.boolean':
if ($values[$accessor->AzurePropertyName] == 'true' || $values[$accessor->AzurePropertyName] == '1')
$values[$accessor->AzurePropertyName] = true;
else
$values[$accessor->AzurePropertyName] = false;
break;
case 'edm.double':
$values[$accessor->AzurePropertyName] = floatval($values[$accessor->AzurePropertyName]); break;
}
}
// Assign value
if ($accessor->EntityType == 'ReflectionProperty') {
$property = $accessor->EntityAccessor;
$this->$property = $values[$accessor->AzurePropertyName];
} else if ($accessor->EntityType == 'ReflectionMethod' && substr(strtolower($accessor->EntityAccessor), 0, 3) == 'set') {
$method = $accessor->EntityAccessor;
$this->$method($values[$accessor->AzurePropertyName]);
}
} else if ($throwOnError) {
throw new Zend_Service_WindowsAzure_Exception("Property '" . $accessor->AzurePropertyName . "' was not found in \$values array");
}
}
// Return
return $returnValue;
}
/**
* Get Azure accessors from class
*
* @param string $className Class to get accessors for
* @return array
*/
public static function getAzureAccessors($className = '')
{
// List of accessors
$azureAccessors = array();
// Get all types
$type = new ReflectionClass($className);
// Loop all properties
$properties = $type->getProperties();
foreach ($properties as $property) {
$accessor = self::getAzureAccessor($property);
if (!is_null($accessor)) {
$azureAccessors[] = $accessor;
}
}
// Loop all methods
$methods = $type->getMethods();
foreach ($methods as $method) {
$accessor = self::getAzureAccessor($method);
if (!is_null($accessor)) {
$azureAccessors[] = $accessor;
}
}
// Return
return $azureAccessors;
}
/**
* Get Azure accessor from reflection member
*
* @param ReflectionProperty|ReflectionMethod $member
* @return object
*/
public static function getAzureAccessor($member)
{
// Get comment
$docComment = $member->getDocComment();
// Check for Azure comment
if (strpos($docComment, '@azure') === false)
{
return null;
}
// Search for @azure contents
$azureComment = '';
$commentLines = explode("\n", $docComment);
foreach ($commentLines as $commentLine) {
if (strpos($commentLine, '@azure') !== false) {
$azureComment = trim(substr($commentLine, strpos($commentLine, '@azure') + 6));
while (strpos($azureComment, ' ') !== false) {
$azureComment = str_replace(' ', ' ', $azureComment);
}
break;
}
}
// Fetch @azure properties
$azureProperties = explode(' ', $azureComment);
return (object)array(
'EntityAccessor' => $member->getName(),
'EntityType' => get_class($member),
'AzurePropertyName' => $azureProperties[0],
'AzurePropertyType' => isset($azureProperties[1]) ? $azureProperties[1] : ''
);
}
}

View file

@ -0,0 +1,326 @@
<?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_Service_WindowsAzure
* @subpackage Storage
* @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: Blob.php 14561 2009-05-07 08:05:12Z unknown $
*/
/**
* @category Zend
* @package Zend_Service_WindowsAzure
* @subpackage Storage
* @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_Service_WindowsAzure_Storage_TableEntityQuery
{
/**
* From
*
* @var string
*/
protected $_from = '';
/**
* Where
*
* @var array
*/
protected $_where = array();
/**
* Order by
*
* @var array
*/
protected $_orderBy = array();
/**
* Top
*
* @var int
*/
protected $_top = null;
/**
* Partition key
*
* @var string
*/
protected $_partitionKey = null;
/**
* Row key
*
* @var string
*/
protected $_rowKey = null;
/**
* Select clause
*
* @return Zend_Service_WindowsAzure_Storage_TableEntityQuery
*/
public function select()
{
return $this;
}
/**
* From clause
*
* @param string $name Table name to select entities from
* @return Zend_Service_WindowsAzure_Storage_TableEntityQuery
*/
public function from($name)
{
$this->_from = $name;
return $this;
}
/**
* Specify partition key
*
* @param string $value Partition key to query for
* @return Zend_Service_WindowsAzure_Storage_TableEntityQuery
*/
public function wherePartitionKey($value = null)
{
$this->_partitionKey = $value;
return $this;
}
/**
* Specify row key
*
* @param string $value Row key to query for
* @return Zend_Service_WindowsAzure_Storage_TableEntityQuery
*/
public function whereRowKey($value = null)
{
$this->_rowKey = $value;
return $this;
}
/**
* Add where clause
*
* @param string $condition Condition, can contain question mark(s) (?) for parameter insertion.
* @param string|array $value Value(s) to insert in question mark (?) parameters.
* @param string $cond Condition for the clause (and/or/not)
* @return Zend_Service_WindowsAzure_Storage_TableEntityQuery
*/
public function where($condition, $value = null, $cond = '')
{
$condition = $this->_replaceOperators($condition);
if (!is_null($value)) {
$condition = $this->_quoteInto($condition, $value);
}
if (count($this->_where) == 0) {
$cond = '';
} else if ($cond !== '') {
$cond = ' ' . strtolower(trim($cond)) . ' ';
}
$this->_where[] = $cond . $condition;
return $this;
}
/**
* Add where clause with AND condition
*
* @param string $condition Condition, can contain question mark(s) (?) for parameter insertion.
* @param string|array $value Value(s) to insert in question mark (?) parameters.
* @return Zend_Service_WindowsAzure_Storage_TableEntityQuery
*/
public function andWhere($condition, $value = null)
{
return $this->where($condition, $value, 'and');
}
/**
* Add where clause with OR condition
*
* @param string $condition Condition, can contain question mark(s) (?) for parameter insertion.
* @param string|array $value Value(s) to insert in question mark (?) parameters.
* @return Zend_Service_WindowsAzure_Storage_TableEntityQuery
*/
public function orWhere($condition, $value = null)
{
return $this->where($condition, $value, 'or');
}
/**
* OrderBy clause
*
* @param string $column Column to sort by
* @param string $direction Direction to sort (asc/desc)
* @return Zend_Service_WindowsAzure_Storage_TableEntityQuery
*/
public function orderBy($column, $direction = 'asc')
{
$this->_orderBy[] = $column . ' ' . $direction;
return $this;
}
/**
* Top clause
*
* @param int $top Top to fetch
* @return Zend_Service_WindowsAzure_Storage_TableEntityQuery
*/
public function top($top = null)
{
$this->_top = (int)$top;
return $this;
}
/**
* Assembles the query string
*
* @param boolean $urlEncode Apply URL encoding to the query string
* @return string
*/
public function assembleQueryString($urlEncode = false)
{
$query = array();
if (count($this->_where) != 0) {
$filter = implode('', $this->_where);
$query[] = '$filter=' . ($urlEncode ? urlencode($filter) : $filter);
}
if (count($this->_orderBy) != 0) {
$orderBy = implode(',', $this->_orderBy);
$query[] = '$orderby=' . ($urlEncode ? urlencode($orderBy) : $orderBy);
}
if (!is_null($this->_top)) {
$query[] = '$top=' . $this->_top;
}
if (count($query) != 0) {
return '?' . implode('&', $query);
}
return '';
}
/**
* Assemble from
*
* @param boolean $includeParentheses Include parentheses? ()
* @return string
*/
public function assembleFrom($includeParentheses = true)
{
$identifier = '';
if ($includeParentheses) {
$identifier .= '(';
if (!is_null($this->_partitionKey)) {
$identifier .= 'PartitionKey=\'' . $this->_partitionKey . '\'';
}
if (!is_null($this->_partitionKey) && !is_null($this->_rowKey)) {
$identifier .= ', ';
}
if (!is_null($this->_rowKey)) {
$identifier .= 'RowKey=\'' . $this->_rowKey . '\'';
}
$identifier .= ')';
}
return $this->_from . $identifier;
}
/**
* Assemble full query
*
* @return string
*/
public function assembleQuery()
{
$assembledQuery = $this->assembleFrom();
$queryString = $this->assembleQueryString();
if ($queryString !== '') {
$assembledQuery .= $queryString;
}
return $assembledQuery;
}
/**
* Quotes a variable into a condition
*
* @param string $text Condition, can contain question mark(s) (?) for parameter insertion.
* @param string|array $value Value(s) to insert in question mark (?) parameters.
* @return string
*/
protected function _quoteInto($text, $value = null)
{
if (!is_array($value)) {
$text = str_replace('?', '\'' . addslashes($value) . '\'', $text);
} else {
$i = 0;
while(strpos($text, '?') !== false) {
if (is_numeric($value[$i])) {
$text = substr_replace($text, $value[$i++], strpos($text, '?'), 1);
} else {
$text = substr_replace($text, '\'' . addslashes($value[$i++]) . '\'', strpos($text, '?'), 1);
}
}
}
return $text;
}
/**
* Replace operators
*
* @param string $text
* @return string
*/
protected function _replaceOperators($text)
{
$text = str_replace('==', 'eq', $text);
$text = str_replace('>', 'gt', $text);
$text = str_replace('<', 'lt', $text);
$text = str_replace('>=', 'ge', $text);
$text = str_replace('<=', 'le', $text);
$text = str_replace('!=', 'ne', $text);
$text = str_replace('&&', 'and', $text);
$text = str_replace('||', 'or', $text);
$text = str_replace('!', 'not', $text);
return $text;
}
/**
* __toString overload
*
* @return string
*/
public function __toString()
{
return $this->assembleQuery();
}
}

View file

@ -0,0 +1,95 @@
<?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_Service_WindowsAzure
* @subpackage Storage
* @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: BlobInstance.php 14561 2009-05-07 08:05:12Z unknown $
*/
/**
* @see Zend_Service_WindowsAzure_Exception
*/
require_once 'Zend/Service/WindowsAzure/Exception.php';
/**
* @category Zend
* @package Zend_Service_WindowsAzure
* @subpackage Storage
* @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*
* @property string $Id Id
* @property string $Name Name
* @property string $Href Href
* @property string $Updated Updated
*/
class Zend_Service_WindowsAzure_Storage_TableInstance
{
/**
* Data
*
* @var array
*/
protected $_data = null;
/**
* Constructor
*
* @param string $id Id
* @param string $name Name
* @param string $href Href
* @param string $updated Updated
*/
public function __construct($id, $name, $href, $updated)
{
$this->_data = array(
'id' => $id,
'name' => $name,
'href' => $href,
'updated' => $updated
);
}
/**
* Magic overload for setting properties
*
* @param string $name Name of the property
* @param string $value Value to set
*/
public function __set($name, $value) {
if (array_key_exists(strtolower($name), $this->_data)) {
$this->_data[strtolower($name)] = $value;
return;
}
throw new Exception("Unknown property: " . $name);
}
/**
* Magic overload for getting properties
*
* @param string $name Name of the property
*/
public function __get($name) {
if (array_key_exists(strtolower($name), $this->_data)) {
return $this->_data[strtolower($name)];
}
throw new Exception("Unknown property: " . $name);
}
}