Merge branch 'master' into multi_app_dir
Conflicts: apps/bookmarks/ajax/addBookmark.php config/config.sample.php lib/app.php remote.php
This commit is contained in:
commit
4753cc3ebd
|
@ -40,6 +40,9 @@ nbproject
|
|||
# Cloud9IDE
|
||||
.settings.xml
|
||||
|
||||
# vim ex mode
|
||||
.vimrc
|
||||
|
||||
# Mac OS
|
||||
.DS_Store
|
||||
|
||||
|
|
|
@ -0,0 +1,380 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Dropbox API class
|
||||
*
|
||||
* @package Dropbox
|
||||
* @copyright Copyright (C) 2010 Rooftop Solutions. All rights reserved.
|
||||
* @author Evert Pot (http://www.rooftopsolutions.nl/)
|
||||
* @license http://code.google.com/p/dropbox-php/wiki/License MIT
|
||||
*/
|
||||
class Dropbox_API {
|
||||
|
||||
/**
|
||||
* Sandbox root-path
|
||||
*/
|
||||
const ROOT_SANDBOX = 'sandbox';
|
||||
|
||||
/**
|
||||
* Dropbox root-path
|
||||
*/
|
||||
const ROOT_DROPBOX = 'dropbox';
|
||||
|
||||
/**
|
||||
* API URl
|
||||
*/
|
||||
protected $api_url = 'https://api.dropbox.com/1/';
|
||||
|
||||
/**
|
||||
* Content API URl
|
||||
*/
|
||||
protected $api_content_url = 'https://api-content.dropbox.com/1/';
|
||||
|
||||
/**
|
||||
* OAuth object
|
||||
*
|
||||
* @var Dropbox_OAuth
|
||||
*/
|
||||
protected $oauth;
|
||||
|
||||
/**
|
||||
* Default root-path, this will most likely be 'sandbox' or 'dropbox'
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $root;
|
||||
protected $useSSL;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param Dropbox_OAuth Dropbox_Auth object
|
||||
* @param string $root default root path (sandbox or dropbox)
|
||||
*/
|
||||
public function __construct(Dropbox_OAuth $oauth, $root = self::ROOT_DROPBOX, $useSSL = true) {
|
||||
|
||||
$this->oauth = $oauth;
|
||||
$this->root = $root;
|
||||
$this->useSSL = $useSSL;
|
||||
if (!$this->useSSL)
|
||||
{
|
||||
throw new Dropbox_Exception('Dropbox REST API now requires that all requests use SSL');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns information about the current dropbox account
|
||||
*
|
||||
* @return stdclass
|
||||
*/
|
||||
public function getAccountInfo() {
|
||||
|
||||
$data = $this->oauth->fetch($this->api_url . 'account/info');
|
||||
return json_decode($data['body'],true);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a file's contents
|
||||
*
|
||||
* @param string $path path
|
||||
* @param string $root Use this to override the default root path (sandbox/dropbox)
|
||||
* @return string
|
||||
*/
|
||||
public function getFile($path = '', $root = null) {
|
||||
|
||||
if (is_null($root)) $root = $this->root;
|
||||
$path = str_replace(array('%2F','~'), array('/','%7E'), rawurlencode($path));
|
||||
$result = $this->oauth->fetch($this->api_content_url . 'files/' . $root . '/' . ltrim($path,'/'));
|
||||
return $result['body'];
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Uploads a new file
|
||||
*
|
||||
* @param string $path Target path (including filename)
|
||||
* @param string $file Either a path to a file or a stream resource
|
||||
* @param string $root Use this to override the default root path (sandbox/dropbox)
|
||||
* @return bool
|
||||
*/
|
||||
public function putFile($path, $file, $root = null) {
|
||||
|
||||
$directory = dirname($path);
|
||||
$filename = basename($path);
|
||||
|
||||
if($directory==='.') $directory = '';
|
||||
$directory = str_replace(array('%2F','~'), array('/','%7E'), rawurlencode($directory));
|
||||
// $filename = str_replace('~', '%7E', rawurlencode($filename));
|
||||
if (is_null($root)) $root = $this->root;
|
||||
|
||||
if (is_string($file)) {
|
||||
|
||||
$file = fopen($file,'rb');
|
||||
|
||||
} elseif (!is_resource($file)) {
|
||||
throw new Dropbox_Exception('File must be a file-resource or a string');
|
||||
}
|
||||
$result=$this->multipartFetch($this->api_content_url . 'files/' .
|
||||
$root . '/' . trim($directory,'/'), $file, $filename);
|
||||
|
||||
if(!isset($result["httpStatus"]) || $result["httpStatus"] != 200)
|
||||
throw new Dropbox_Exception("Uploading file to Dropbox failed");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Copies a file or directory from one location to another
|
||||
*
|
||||
* This method returns the file information of the newly created file.
|
||||
*
|
||||
* @param string $from source path
|
||||
* @param string $to destination path
|
||||
* @param string $root Use this to override the default root path (sandbox/dropbox)
|
||||
* @return stdclass
|
||||
*/
|
||||
public function copy($from, $to, $root = null) {
|
||||
|
||||
if (is_null($root)) $root = $this->root;
|
||||
$response = $this->oauth->fetch($this->api_url . 'fileops/copy', array('from_path' => $from, 'to_path' => $to, 'root' => $root));
|
||||
|
||||
return json_decode($response['body'],true);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new folder
|
||||
*
|
||||
* This method returns the information from the newly created directory
|
||||
*
|
||||
* @param string $path
|
||||
* @param string $root Use this to override the default root path (sandbox/dropbox)
|
||||
* @return stdclass
|
||||
*/
|
||||
public function createFolder($path, $root = null) {
|
||||
|
||||
if (is_null($root)) $root = $this->root;
|
||||
|
||||
// Making sure the path starts with a /
|
||||
// $path = '/' . ltrim($path,'/');
|
||||
|
||||
$response = $this->oauth->fetch($this->api_url . 'fileops/create_folder', array('path' => $path, 'root' => $root),'POST');
|
||||
return json_decode($response['body'],true);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a file or folder.
|
||||
*
|
||||
* This method will return the metadata information from the deleted file or folder, if successful.
|
||||
*
|
||||
* @param string $path Path to new folder
|
||||
* @param string $root Use this to override the default root path (sandbox/dropbox)
|
||||
* @return array
|
||||
*/
|
||||
public function delete($path, $root = null) {
|
||||
|
||||
if (is_null($root)) $root = $this->root;
|
||||
$response = $this->oauth->fetch($this->api_url . 'fileops/delete', array('path' => $path, 'root' => $root));
|
||||
return json_decode($response['body']);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves a file or directory to a new location
|
||||
*
|
||||
* This method returns the information from the newly created directory
|
||||
*
|
||||
* @param mixed $from Source path
|
||||
* @param mixed $to destination path
|
||||
* @param string $root Use this to override the default root path (sandbox/dropbox)
|
||||
* @return stdclass
|
||||
*/
|
||||
public function move($from, $to, $root = null) {
|
||||
|
||||
if (is_null($root)) $root = $this->root;
|
||||
$response = $this->oauth->fetch($this->api_url . 'fileops/move', array('from_path' => rawurldecode($from), 'to_path' => rawurldecode($to), 'root' => $root));
|
||||
|
||||
return json_decode($response['body'],true);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns file and directory information
|
||||
*
|
||||
* @param string $path Path to receive information from
|
||||
* @param bool $list When set to true, this method returns information from all files in a directory. When set to false it will only return infromation from the specified directory.
|
||||
* @param string $hash If a hash is supplied, this method simply returns true if nothing has changed since the last request. Good for caching.
|
||||
* @param int $fileLimit Maximum number of file-information to receive
|
||||
* @param string $root Use this to override the default root path (sandbox/dropbox)
|
||||
* @return array|true
|
||||
*/
|
||||
public function getMetaData($path, $list = true, $hash = null, $fileLimit = null, $root = null) {
|
||||
|
||||
if (is_null($root)) $root = $this->root;
|
||||
|
||||
$args = array(
|
||||
'list' => $list,
|
||||
);
|
||||
|
||||
if (!is_null($hash)) $args['hash'] = $hash;
|
||||
if (!is_null($fileLimit)) $args['file_limit'] = $fileLimit;
|
||||
|
||||
$path = str_replace(array('%2F','~'), array('/','%7E'), rawurlencode($path));
|
||||
$response = $this->oauth->fetch($this->api_url . 'metadata/' . $root . '/' . ltrim($path,'/'), $args);
|
||||
|
||||
/* 304 is not modified */
|
||||
if ($response['httpStatus']==304) {
|
||||
return true;
|
||||
} else {
|
||||
return json_decode($response['body'],true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* A way of letting you keep up with changes to files and folders in a user's Dropbox. You can periodically call /delta to get a list of "delta entries", which are instructions on how to update your local state to match the server's state.
|
||||
*
|
||||
* This method returns the information from the newly created directory
|
||||
*
|
||||
* @param string $cursor A string that is used to keep track of your current state. On the next call pass in this value to return delta entries that have been recorded since the cursor was returned.
|
||||
* @return stdclass
|
||||
*/
|
||||
public function delta($cursor) {
|
||||
|
||||
$arg['cursor'] = $cursor;
|
||||
|
||||
$response = $this->oauth->fetch($this->api_url . 'delta', $arg, 'POST');
|
||||
return json_decode($response['body'],true);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a thumbnail (as a string) for a file path.
|
||||
*
|
||||
* @param string $path Path to file
|
||||
* @param string $size small, medium or large
|
||||
* @param string $root Use this to override the default root path (sandbox/dropbox)
|
||||
* @return string
|
||||
*/
|
||||
public function getThumbnail($path, $size = 'small', $root = null) {
|
||||
|
||||
if (is_null($root)) $root = $this->root;
|
||||
$path = str_replace(array('%2F','~'), array('/','%7E'), rawurlencode($path));
|
||||
$response = $this->oauth->fetch($this->api_content_url . 'thumbnails/' . $root . '/' . ltrim($path,'/'),array('size' => $size));
|
||||
|
||||
return $response['body'];
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is used to generate multipart POST requests for file upload
|
||||
*
|
||||
* @param string $uri
|
||||
* @param array $arguments
|
||||
* @return bool
|
||||
*/
|
||||
protected function multipartFetch($uri, $file, $filename) {
|
||||
|
||||
/* random string */
|
||||
$boundary = 'R50hrfBj5JYyfR3vF3wR96GPCC9Fd2q2pVMERvEaOE3D8LZTgLLbRpNwXek3';
|
||||
|
||||
$headers = array(
|
||||
'Content-Type' => 'multipart/form-data; boundary=' . $boundary,
|
||||
);
|
||||
|
||||
$body="--" . $boundary . "\r\n";
|
||||
$body.="Content-Disposition: form-data; name=file; filename=".rawurldecode($filename)."\r\n";
|
||||
$body.="Content-type: application/octet-stream\r\n";
|
||||
$body.="\r\n";
|
||||
$body.=stream_get_contents($file);
|
||||
$body.="\r\n";
|
||||
$body.="--" . $boundary . "--";
|
||||
|
||||
// Dropbox requires the filename to also be part of the regular arguments, so it becomes
|
||||
// part of the signature.
|
||||
$uri.='?file=' . $filename;
|
||||
|
||||
return $this->oauth->fetch($uri, $body, 'POST', $headers);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Search
|
||||
*
|
||||
* Returns metadata for all files and folders that match the search query.
|
||||
*
|
||||
* @added by: diszo.sasil
|
||||
*
|
||||
* @param string $query
|
||||
* @param string $root Use this to override the default root path (sandbox/dropbox)
|
||||
* @param string $path
|
||||
* @return array
|
||||
*/
|
||||
public function search($query = '', $root = null, $path = ''){
|
||||
if (is_null($root)) $root = $this->root;
|
||||
if(!empty($path)){
|
||||
$path = str_replace(array('%2F','~'), array('/','%7E'), rawurlencode($path));
|
||||
}
|
||||
$response = $this->oauth->fetch($this->api_url . 'search/' . $root . '/' . ltrim($path,'/'),array('query' => $query));
|
||||
return json_decode($response['body'],true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and returns a shareable link to files or folders.
|
||||
*
|
||||
* Note: Links created by the /shares API call expire after thirty days.
|
||||
*
|
||||
* @param type $path
|
||||
* @param type $root
|
||||
* @return type
|
||||
*/
|
||||
public function share($path, $root = null) {
|
||||
if (is_null($root)) $root = $this->root;
|
||||
$path = str_replace(array('%2F','~'), array('/','%7E'), rawurlencode($path));
|
||||
$response = $this->oauth->fetch($this->api_url. 'shares/'. $root . '/' . ltrim($path, '/'), array(), 'POST');
|
||||
return json_decode($response['body'],true);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a link directly to a file.
|
||||
* Similar to /shares. The difference is that this bypasses the Dropbox webserver, used to provide a preview of the file, so that you can effectively stream the contents of your media.
|
||||
*
|
||||
* Note: The /media link expires after four hours, allotting enough time to stream files, but not enough to leave a connection open indefinitely.
|
||||
*
|
||||
* @param type $path
|
||||
* @param type $root
|
||||
* @return type
|
||||
*/
|
||||
public function media($path, $root = null) {
|
||||
|
||||
if (is_null($root)) $root = $this->root;
|
||||
$path = str_replace(array('%2F','~'), array('/','%7E'), rawurlencode($path));
|
||||
$response = $this->oauth->fetch($this->api_url. 'media/'. $root . '/' . ltrim($path, '/'), array(), 'POST');
|
||||
return json_decode($response['body'],true);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and returns a copy_ref to a file. This reference string can be used to copy that file to another user's Dropbox by passing it in as the from_copy_ref parameter on /fileops/copy.
|
||||
*
|
||||
* @param type $path
|
||||
* @param type $root
|
||||
* @return type
|
||||
*/
|
||||
public function copy_ref($path, $root = null) {
|
||||
|
||||
if (is_null($root)) $root = $this->root;
|
||||
$path = str_replace(array('%2F','~'), array('/','%7E'), rawurlencode($path));
|
||||
$response = $this->oauth->fetch($this->api_url. 'copy_ref/'. $root . '/' . ltrim($path, '/'));
|
||||
return json_decode($response['body'],true);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Dropbox base exception
|
||||
*
|
||||
* @package Dropbox
|
||||
* @copyright Copyright (C) 2010 Rooftop Solutions. All rights reserved.
|
||||
* @author Evert Pot (http://www.rooftopsolutions.nl/)
|
||||
* @license http://code.google.com/p/dropbox-php/wiki/License MIT
|
||||
*/
|
||||
|
||||
/**
|
||||
* Base exception class
|
||||
*/
|
||||
class Dropbox_Exception extends Exception { }
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Dropbox Forbidden exception
|
||||
*
|
||||
* @package Dropbox
|
||||
* @copyright Copyright (C) 2010 Rooftop Solutions. All rights reserved.
|
||||
* @author Evert Pot (http://www.rooftopsolutions.nl/)
|
||||
* @license http://code.google.com/p/dropbox-php/wiki/License MIT
|
||||
*/
|
||||
|
||||
/**
|
||||
* This exception is thrown when we receive the 403 forbidden response
|
||||
*/
|
||||
class Dropbox_Exception_Forbidden extends Dropbox_Exception {
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Dropbox Not Found exception
|
||||
*
|
||||
* @package Dropbox
|
||||
* @copyright Copyright (C) 2010 Rooftop Solutions. All rights reserved.
|
||||
* @author Evert Pot (http://www.rooftopsolutions.nl/)
|
||||
* @license http://code.google.com/p/dropbox-php/wiki/License MIT
|
||||
*/
|
||||
|
||||
/**
|
||||
* This exception is thrown when a non-existant uri is accessed.
|
||||
*
|
||||
* Basically, this exception is used when we get back a 404.
|
||||
*/
|
||||
class Dropbox_Exception_NotFound extends Dropbox_Exception {
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Dropbox Over Quota exception
|
||||
*
|
||||
* @package Dropbox
|
||||
* @copyright Copyright (C) 2010 Rooftop Solutions. All rights reserved.
|
||||
* @author Evert Pot (http://www.rooftopsolutions.nl/)
|
||||
* @license http://code.google.com/p/dropbox-php/wiki/License MIT
|
||||
*/
|
||||
|
||||
/**
|
||||
* This exception is thrown when the operation required more space than the available quota.
|
||||
*
|
||||
* Basically, this exception is used when we get back a 507.
|
||||
*/
|
||||
class Dropbox_Exception_OverQuota extends Dropbox_Exception {
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Dropbox RequestToken exception
|
||||
*
|
||||
* @package Dropbox
|
||||
* @copyright Copyright (C) 2010 Rooftop Solutions. All rights reserved.
|
||||
* @author Evert Pot (http://www.rooftopsolutions.nl/)
|
||||
* @license http://code.google.com/p/dropbox-php/wiki/License MIT
|
||||
*/
|
||||
|
||||
/**
|
||||
* This exception is thrown when an error occured during the request_token process.
|
||||
*/
|
||||
class Dropbox_Exception_RequestToken extends Dropbox_Exception {
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
Copyright (c) 2010 Rooftop Solutions
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
|
@ -0,0 +1,151 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Dropbox OAuth
|
||||
*
|
||||
* @package Dropbox
|
||||
* @copyright Copyright (C) 2010 Rooftop Solutions. All rights reserved.
|
||||
* @author Evert Pot (http://www.rooftopsolutions.nl/)
|
||||
* @license http://code.google.com/p/dropbox-php/wiki/License MIT
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* This class is an abstract OAuth class.
|
||||
*
|
||||
* It must be extended by classes who wish to provide OAuth functionality
|
||||
* using different libraries.
|
||||
*/
|
||||
abstract class Dropbox_OAuth {
|
||||
|
||||
/**
|
||||
* After a user has authorized access, dropbox can redirect the user back
|
||||
* to this url.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $authorizeCallbackUrl = null;
|
||||
|
||||
/**
|
||||
* Uri used to fetch request tokens
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const URI_REQUEST_TOKEN = 'https://api.dropbox.com/1/oauth/request_token';
|
||||
|
||||
/**
|
||||
* Uri used to redirect the user to for authorization.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const URI_AUTHORIZE = 'https://www.dropbox.com/1/oauth/authorize';
|
||||
|
||||
/**
|
||||
* Uri used to
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const URI_ACCESS_TOKEN = 'https://api.dropbox.com/1/oauth/access_token';
|
||||
|
||||
/**
|
||||
* An OAuth request token.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $oauth_token = null;
|
||||
|
||||
/**
|
||||
* OAuth token secret
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $oauth_token_secret = null;
|
||||
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param string $consumerKey
|
||||
* @param string $consumerSecret
|
||||
*/
|
||||
abstract public function __construct($consumerKey, $consumerSecret);
|
||||
|
||||
/**
|
||||
* Sets the request token and secret.
|
||||
*
|
||||
* The tokens can also be passed as an array into the first argument.
|
||||
* The array must have the elements token and token_secret.
|
||||
*
|
||||
* @param string|array $token
|
||||
* @param string $token_secret
|
||||
* @return void
|
||||
*/
|
||||
public function setToken($token, $token_secret = null) {
|
||||
|
||||
if (is_array($token)) {
|
||||
$this->oauth_token = $token['token'];
|
||||
$this->oauth_token_secret = $token['token_secret'];
|
||||
} else {
|
||||
$this->oauth_token = $token;
|
||||
$this->oauth_token_secret = $token_secret;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the oauth request tokens as an associative array.
|
||||
*
|
||||
* The array will contain the elements 'token' and 'token_secret'.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getToken() {
|
||||
|
||||
return array(
|
||||
'token' => $this->oauth_token,
|
||||
'token_secret' => $this->oauth_token_secret,
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the authorization url
|
||||
*
|
||||
* @param string $callBack Specify a callback url to automatically redirect the user back
|
||||
* @return string
|
||||
*/
|
||||
public function getAuthorizeUrl($callBack = null) {
|
||||
|
||||
// Building the redirect uri
|
||||
$token = $this->getToken();
|
||||
$uri = self::URI_AUTHORIZE . '?oauth_token=' . $token['token'];
|
||||
if ($callBack) $uri.='&oauth_callback=' . $callBack;
|
||||
return $uri;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches a secured oauth url and returns the response body.
|
||||
*
|
||||
* @param string $uri
|
||||
* @param mixed $arguments
|
||||
* @param string $method
|
||||
* @param array $httpHeaders
|
||||
* @return string
|
||||
*/
|
||||
public abstract function fetch($uri, $arguments = array(), $method = 'GET', $httpHeaders = array());
|
||||
|
||||
/**
|
||||
* Requests the OAuth request token.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
abstract public function getRequestToken();
|
||||
|
||||
/**
|
||||
* Requests the OAuth access tokens.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
abstract public function getAccessToken();
|
||||
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
<?php
|
||||
/**
|
||||
* HTTP OAuth Consumer
|
||||
*
|
||||
* Adapted from halldirector's code in
|
||||
* http://code.google.com/p/dropbox-php/issues/detail?id=36#c5
|
||||
*
|
||||
* @package Dropbox
|
||||
* @copyright Copyright (C) 2011 Joe Constant / halldirector. All rights reserved.
|
||||
* @author Joe Constant / halldirector
|
||||
* @license http://code.google.com/p/dropbox-php/wiki/License MIT
|
||||
*/
|
||||
|
||||
require_once 'HTTP/OAuth.php';
|
||||
require_once 'HTTP/OAuth/Consumer.php';
|
||||
|
||||
/*
|
||||
* This class is to help work around aomw ssl issues.
|
||||
*/
|
||||
class Dropbox_OAuth_Consumer_Dropbox extends HTTP_OAuth_Consumer
|
||||
{
|
||||
public function getOAuthConsumerRequest()
|
||||
{
|
||||
if (!$this->consumerRequest instanceof HTTP_OAuth_Consumer_Request) {
|
||||
$this->consumerRequest = new HTTP_OAuth_Consumer_Request;
|
||||
}
|
||||
|
||||
// TODO: Change this and add in code to validate the SSL cert.
|
||||
// see https://github.com/bagder/curl/blob/master/lib/mk-ca-bundle.pl
|
||||
$this->consumerRequest->setConfig(array(
|
||||
'ssl_verify_peer' => false,
|
||||
'ssl_verify_host' => false
|
||||
));
|
||||
|
||||
return $this->consumerRequest;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,282 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Dropbox OAuth
|
||||
*
|
||||
* @package Dropbox
|
||||
* @copyright Copyright (C) 2011 Daniel Huesken
|
||||
* @author Daniel Huesken (http://www.danielhuesken.de/)
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
/**
|
||||
* This class is used to sign all requests to dropbox.
|
||||
*
|
||||
* This specific class uses WordPress WP_Http to authenticate.
|
||||
*/
|
||||
class Dropbox_OAuth_Curl extends Dropbox_OAuth {
|
||||
|
||||
/**
|
||||
*
|
||||
* @var string ConsumerKey
|
||||
*/
|
||||
protected $consumerKey = null;
|
||||
/**
|
||||
*
|
||||
* @var string ConsumerSecret
|
||||
*/
|
||||
protected $consumerSecret = null;
|
||||
/**
|
||||
*
|
||||
* @var string ProzessCallBack
|
||||
*/
|
||||
public $ProgressFunction = false;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param string $consumerKey
|
||||
* @param string $consumerSecret
|
||||
*/
|
||||
public function __construct($consumerKey, $consumerSecret) {
|
||||
if (!function_exists('curl_exec'))
|
||||
throw new Dropbox_Exception('The PHP curl functions not available!');
|
||||
|
||||
$this->consumerKey = $consumerKey;
|
||||
$this->consumerSecret = $consumerSecret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches a secured oauth url and returns the response body.
|
||||
*
|
||||
* @param string $uri
|
||||
* @param mixed $arguments
|
||||
* @param string $method
|
||||
* @param array $httpHeaders
|
||||
* @return string
|
||||
*/
|
||||
public function fetch($uri, $arguments = array(), $method = 'GET', $httpHeaders = array()) {
|
||||
|
||||
$uri=str_replace('http://', 'https://', $uri); // all https, upload makes problems if not
|
||||
if (is_string($arguments) and strtoupper($method) == 'POST') {
|
||||
preg_match("/\?file=(.*)$/i", $uri, $matches);
|
||||
if (isset($matches[1])) {
|
||||
$uri = str_replace($matches[0], "", $uri);
|
||||
$filename = $matches[1];
|
||||
$httpHeaders=array_merge($httpHeaders,$this->getOAuthHeader($uri, array("file" => $filename), $method));
|
||||
}
|
||||
} else {
|
||||
$httpHeaders=array_merge($httpHeaders,$this->getOAuthHeader($uri, $arguments, $method));
|
||||
}
|
||||
$ch = curl_init();
|
||||
if (strtoupper($method) == 'POST') {
|
||||
curl_setopt($ch, CURLOPT_URL, $uri);
|
||||
curl_setopt($ch, CURLOPT_POST, true);
|
||||
// if (is_array($arguments))
|
||||
// $arguments=http_build_query($arguments);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $arguments);
|
||||
// $httpHeaders['Content-Length']=strlen($arguments);
|
||||
} else {
|
||||
curl_setopt($ch, CURLOPT_URL, $uri.'?'.http_build_query($arguments));
|
||||
curl_setopt($ch, CURLOPT_POST, false);
|
||||
}
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 300);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
|
||||
// curl_setopt($ch, CURLOPT_CAINFO, "rootca");
|
||||
curl_setopt($ch, CURLOPT_FRESH_CONNECT, true);
|
||||
//Build header
|
||||
$headers = array();
|
||||
foreach ($httpHeaders as $name => $value) {
|
||||
$headers[] = "{$name}: $value";
|
||||
}
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
|
||||
if (!ini_get('safe_mode') && !ini_get('open_basedir'))
|
||||
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true );
|
||||
if (function_exists($this->ProgressFunction) and defined('CURLOPT_PROGRESSFUNCTION')) {
|
||||
curl_setopt($ch, CURLOPT_NOPROGRESS, false);
|
||||
curl_setopt($ch, CURLOPT_PROGRESSFUNCTION, $this->ProgressFunction);
|
||||
curl_setopt($ch, CURLOPT_BUFFERSIZE, 512);
|
||||
}
|
||||
$response=curl_exec($ch);
|
||||
$errorno=curl_errno($ch);
|
||||
$error=curl_error($ch);
|
||||
$status=curl_getinfo($ch,CURLINFO_HTTP_CODE);
|
||||
curl_close($ch);
|
||||
|
||||
|
||||
if (!empty($errorno))
|
||||
throw new Dropbox_Exception_NotFound('Curl error: ('.$errorno.') '.$error."\n");
|
||||
|
||||
if ($status>=300) {
|
||||
$body = json_decode($response,true);
|
||||
switch ($status) {
|
||||
// Not modified
|
||||
case 304 :
|
||||
return array(
|
||||
'httpStatus' => 304,
|
||||
'body' => null,
|
||||
);
|
||||
break;
|
||||
case 403 :
|
||||
throw new Dropbox_Exception_Forbidden('Forbidden.
|
||||
This could mean a bad OAuth request, or a file or folder already existing at the target location.
|
||||
' . $body["error"] . "\n");
|
||||
case 404 :
|
||||
throw new Dropbox_Exception_NotFound('Resource at uri: ' . $uri . ' could not be found. ' .
|
||||
$body["error"] . "\n");
|
||||
case 507 :
|
||||
throw new Dropbox_Exception_OverQuota('This dropbox is full. ' .
|
||||
$body["error"] . "\n");
|
||||
}
|
||||
if (!empty($body["error"]))
|
||||
throw new Dropbox_Exception_RequestToken('Error: ('.$status.') '.$body["error"]."\n");
|
||||
}
|
||||
|
||||
return array(
|
||||
'body' => $response,
|
||||
'httpStatus' => $status
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns named array with oauth parameters for further use
|
||||
* @return array Array with oauth_ parameters
|
||||
*/
|
||||
private function getOAuthBaseParams() {
|
||||
$params['oauth_version'] = '1.0';
|
||||
$params['oauth_signature_method'] = 'HMAC-SHA1';
|
||||
|
||||
$params['oauth_consumer_key'] = $this->consumerKey;
|
||||
$tokens = $this->getToken();
|
||||
if (isset($tokens['token']) && $tokens['token']) {
|
||||
$params['oauth_token'] = $tokens['token'];
|
||||
}
|
||||
$params['oauth_timestamp'] = time();
|
||||
$params['oauth_nonce'] = md5(microtime() . mt_rand());
|
||||
return $params;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates valid Authorization header for OAuth, based on URI and Params
|
||||
*
|
||||
* @param string $uri
|
||||
* @param array $params
|
||||
* @param string $method GET or POST, standard is GET
|
||||
* @param array $oAuthParams optional, pass your own oauth_params here
|
||||
* @return array Array for request's headers section like
|
||||
* array('Authorization' => 'OAuth ...');
|
||||
*/
|
||||
private function getOAuthHeader($uri, $params, $method = 'GET', $oAuthParams = null) {
|
||||
$oAuthParams = $oAuthParams ? $oAuthParams : $this->getOAuthBaseParams();
|
||||
|
||||
// create baseString to encode for the sent parameters
|
||||
$baseString = $method . '&';
|
||||
$baseString .= $this->oauth_urlencode($uri) . "&";
|
||||
|
||||
// OAuth header does not include GET-Parameters
|
||||
$signatureParams = array_merge($params, $oAuthParams);
|
||||
|
||||
// sorting the parameters
|
||||
ksort($signatureParams);
|
||||
|
||||
$encodedParams = array();
|
||||
foreach ($signatureParams as $key => $value) {
|
||||
$encodedParams[] = $this->oauth_urlencode($key) . '=' . $this->oauth_urlencode($value);
|
||||
}
|
||||
|
||||
$baseString .= $this->oauth_urlencode(implode('&', $encodedParams));
|
||||
|
||||
// encode the signature
|
||||
$tokens = $this->getToken();
|
||||
$hash = $this->hash_hmac_sha1($this->consumerSecret.'&'.$tokens['token_secret'], $baseString);
|
||||
$signature = base64_encode($hash);
|
||||
|
||||
// add signature to oAuthParams
|
||||
$oAuthParams['oauth_signature'] = $signature;
|
||||
|
||||
$oAuthEncoded = array();
|
||||
foreach ($oAuthParams as $key => $value) {
|
||||
$oAuthEncoded[] = $key . '="' . $this->oauth_urlencode($value) . '"';
|
||||
}
|
||||
|
||||
return array('Authorization' => 'OAuth ' . implode(', ', $oAuthEncoded));
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests the OAuth request token.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function getRequestToken() {
|
||||
$result = $this->fetch(self::URI_REQUEST_TOKEN, array(), 'POST');
|
||||
if ($result['httpStatus'] == "200") {
|
||||
$tokens = array();
|
||||
parse_str($result['body'], $tokens);
|
||||
$this->setToken($tokens['oauth_token'], $tokens['oauth_token_secret']);
|
||||
return $this->getToken();
|
||||
} else {
|
||||
throw new Dropbox_Exception_RequestToken('We were unable to fetch request tokens. This likely means that your consumer key and/or secret are incorrect.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests the OAuth access tokens.
|
||||
*
|
||||
* This method requires the 'unauthorized' request tokens
|
||||
* and, if successful will set the authorized request tokens.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function getAccessToken() {
|
||||
$result = $this->fetch(self::URI_ACCESS_TOKEN, array(), 'POST');
|
||||
if ($result['httpStatus'] == "200") {
|
||||
$tokens = array();
|
||||
parse_str($result['body'], $tokens);
|
||||
$this->setToken($tokens['oauth_token'], $tokens['oauth_token_secret']);
|
||||
return $this->getToken();
|
||||
} else {
|
||||
throw new Dropbox_Exception_RequestToken('We were unable to fetch request tokens. This likely means that your consumer key and/or secret are incorrect.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to properly urlencode parameters.
|
||||
* See http://php.net/manual/en/function.oauth-urlencode.php
|
||||
*
|
||||
* @param string $string
|
||||
* @return string
|
||||
*/
|
||||
private function oauth_urlencode($string) {
|
||||
return str_replace('%E7', '~', rawurlencode($string));
|
||||
}
|
||||
|
||||
/**
|
||||
* Hash function for hmac_sha1; uses native function if available.
|
||||
*
|
||||
* @param string $key
|
||||
* @param string $data
|
||||
* @return string
|
||||
*/
|
||||
private function hash_hmac_sha1($key, $data) {
|
||||
if (function_exists('hash_hmac') && in_array('sha1', hash_algos())) {
|
||||
return hash_hmac('sha1', $data, $key, true);
|
||||
} else {
|
||||
$blocksize = 64;
|
||||
$hashfunc = 'sha1';
|
||||
if (strlen($key) > $blocksize) {
|
||||
$key = pack('H*', $hashfunc($key));
|
||||
}
|
||||
|
||||
$key = str_pad($key, $blocksize, chr(0x00));
|
||||
$ipad = str_repeat(chr(0x36), $blocksize);
|
||||
$opad = str_repeat(chr(0x5c), $blocksize);
|
||||
$hash = pack('H*', $hashfunc(( $key ^ $opad ) . pack('H*', $hashfunc(($key ^ $ipad) . $data))));
|
||||
|
||||
return $hash;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
Dropbox-php
|
||||
===========
|
||||
|
||||
This PHP library allows you to easily integrate dropbox with PHP.
|
||||
|
||||
The following PHP extension is required:
|
||||
|
||||
* json
|
||||
|
||||
The library makes use of OAuth. At the moment you can use either of these libraries:
|
||||
|
||||
[PHP OAuth extension](http://pecl.php.net/package/oauth)
|
||||
[PEAR's HTTP_OAUTH package](http://pear.php.net/package/http_oauth)
|
||||
|
||||
The extension is recommended, but if you can't install php extensions you should go for the pear package.
|
||||
Installing
|
||||
----------
|
||||
|
||||
pear channel-discover pear.dropbox-php.com
|
||||
pear install dropbox-php/Dropbox-alpha
|
||||
|
||||
Documentation
|
||||
-------------
|
||||
Check out the [documentation](http://www.dropbox-php.com/docs).
|
||||
|
||||
Questions?
|
||||
----------
|
||||
|
||||
[Dropbox-php Mailing list](http://groups.google.com/group/dropbox-php)
|
||||
[Official Dropbox developer forum](http://forums.dropbox.com/forum.php?id=5)
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* This file registers a new autoload function using spl_autoload_register.
|
||||
*
|
||||
* @package Dropbox
|
||||
* @copyright Copyright (C) 2010 Rooftop Solutions. All rights reserved.
|
||||
* @author Evert Pot (http://www.rooftopsolutions.nl/)
|
||||
* @license http://code.google.com/p/dropbox-php/wiki/License MIT
|
||||
*/
|
||||
|
||||
/**
|
||||
* Autoloader function
|
||||
*
|
||||
* @param $className string
|
||||
* @return void
|
||||
*/
|
||||
function Dropbox_autoload($className) {
|
||||
|
||||
if(strpos($className,'Dropbox_')===0) {
|
||||
|
||||
include dirname(__FILE__) . '/' . str_replace('_','/',substr($className,8)) . '.php';
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
spl_autoload_register('Dropbox_autoload');
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
The MIT License
|
||||
|
||||
Copyright (c) 2007 Andy Smith
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
|
@ -0,0 +1,751 @@
|
|||
<?php
|
||||
// vim: foldmethod=marker
|
||||
|
||||
/* Generic exception class
|
||||
*/
|
||||
class OAuthException extends Exception {/*{{{*/
|
||||
// pass
|
||||
}/*}}}*/
|
||||
|
||||
class OAuthConsumer {/*{{{*/
|
||||
public $key;
|
||||
public $secret;
|
||||
|
||||
public function __construct($key, $secret, $callback_url=NULL) {/*{{{*/
|
||||
$this->key = $key;
|
||||
$this->secret = $secret;
|
||||
$this->callback_url = $callback_url;
|
||||
}/*}}}*/
|
||||
}/*}}}*/
|
||||
|
||||
class OAuthToken {/*{{{*/
|
||||
// access tokens and request tokens
|
||||
public $key;
|
||||
public $secret;
|
||||
|
||||
/**
|
||||
* key = the token
|
||||
* secret = the token secret
|
||||
*/
|
||||
function __construct($key, $secret) {/*{{{*/
|
||||
$this->key = $key;
|
||||
$this->secret = $secret;
|
||||
}/*}}}*/
|
||||
|
||||
/**
|
||||
* generates the basic string serialization of a token that a server
|
||||
* would respond to request_token and access_token calls with
|
||||
*/
|
||||
function to_string() {/*{{{*/
|
||||
return "oauth_token=" . OAuthUtil::urlencodeRFC3986($this->key) .
|
||||
"&oauth_token_secret=" . OAuthUtil::urlencodeRFC3986($this->secret);
|
||||
}/*}}}*/
|
||||
|
||||
function __toString() {/*{{{*/
|
||||
return $this->to_string();
|
||||
}/*}}}*/
|
||||
}/*}}}*/
|
||||
|
||||
class OAuthSignatureMethod {/*{{{*/
|
||||
public function check_signature(&$request, $consumer, $token, $signature) {
|
||||
$built = $this->build_signature($request, $consumer, $token);
|
||||
return $built == $signature;
|
||||
}
|
||||
}/*}}}*/
|
||||
|
||||
class OAuthSignatureMethod_HMAC_SHA1 extends OAuthSignatureMethod {/*{{{*/
|
||||
function get_name() {/*{{{*/
|
||||
return "HMAC-SHA1";
|
||||
}/*}}}*/
|
||||
|
||||
public function build_signature($request, $consumer, $token, $privKey=NULL) {/*{{{*/
|
||||
$base_string = $request->get_signature_base_string();
|
||||
$request->base_string = $base_string;
|
||||
|
||||
$key_parts = array(
|
||||
$consumer->secret,
|
||||
($token) ? $token->secret : ""
|
||||
);
|
||||
|
||||
$key_parts = array_map(array('OAuthUtil','urlencodeRFC3986'), $key_parts);
|
||||
$key = implode('&', $key_parts);
|
||||
|
||||
return base64_encode( hash_hmac('sha1', $base_string, $key, true));
|
||||
}/*}}}*/
|
||||
}/*}}}*/
|
||||
|
||||
class OAuthSignatureMethod_RSA_SHA1 extends OAuthSignatureMethod {/*{{{*/
|
||||
public function get_name() {/*{{{*/
|
||||
return "RSA-SHA1";
|
||||
}/*}}}*/
|
||||
|
||||
protected function fetch_public_cert(&$request) {/*{{{*/
|
||||
// not implemented yet, ideas are:
|
||||
// (1) do a lookup in a table of trusted certs keyed off of consumer
|
||||
// (2) fetch via http using a url provided by the requester
|
||||
// (3) some sort of specific discovery code based on request
|
||||
//
|
||||
// either way should return a string representation of the certificate
|
||||
throw Exception("fetch_public_cert not implemented");
|
||||
}/*}}}*/
|
||||
|
||||
protected function fetch_private_cert($privKey) {//&$request) {/*{{{*/
|
||||
// not implemented yet, ideas are:
|
||||
// (1) do a lookup in a table of trusted certs keyed off of consumer
|
||||
//
|
||||
// either way should return a string representation of the certificate
|
||||
throw Exception("fetch_private_cert not implemented");
|
||||
}/*}}}*/
|
||||
|
||||
public function build_signature(&$request, $consumer, $token, $privKey) {/*{{{*/
|
||||
$base_string = $request->get_signature_base_string();
|
||||
|
||||
// Fetch the private key cert based on the request
|
||||
//$cert = $this->fetch_private_cert($consumer->privKey);
|
||||
|
||||
//Pull the private key ID from the certificate
|
||||
//$privatekeyid = openssl_get_privatekey($cert);
|
||||
|
||||
// hacked in
|
||||
if ($privKey == '') {
|
||||
$fp = fopen($GLOBALS['PRIV_KEY_FILE'], "r");
|
||||
$privKey = fread($fp, 8192);
|
||||
fclose($fp);
|
||||
}
|
||||
$privatekeyid = openssl_get_privatekey($privKey);
|
||||
|
||||
//Check the computer signature against the one passed in the query
|
||||
$ok = openssl_sign($base_string, $signature, $privatekeyid);
|
||||
|
||||
//Release the key resource
|
||||
openssl_free_key($privatekeyid);
|
||||
|
||||
return base64_encode($signature);
|
||||
} /*}}}*/
|
||||
|
||||
public function check_signature(&$request, $consumer, $token, $signature) {/*{{{*/
|
||||
$decoded_sig = base64_decode($signature);
|
||||
|
||||
$base_string = $request->get_signature_base_string();
|
||||
|
||||
// Fetch the public key cert based on the request
|
||||
$cert = $this->fetch_public_cert($request);
|
||||
|
||||
//Pull the public key ID from the certificate
|
||||
$publickeyid = openssl_get_publickey($cert);
|
||||
|
||||
//Check the computer signature against the one passed in the query
|
||||
$ok = openssl_verify($base_string, $decoded_sig, $publickeyid);
|
||||
|
||||
//Release the key resource
|
||||
openssl_free_key($publickeyid);
|
||||
|
||||
return $ok == 1;
|
||||
} /*}}}*/
|
||||
}/*}}}*/
|
||||
|
||||
class OAuthRequest {/*{{{*/
|
||||
private $parameters;
|
||||
private $http_method;
|
||||
private $http_url;
|
||||
// for debug purposes
|
||||
public $base_string;
|
||||
public static $version = '1.0';
|
||||
|
||||
function __construct($http_method, $http_url, $parameters=NULL) {/*{{{*/
|
||||
@$parameters or $parameters = array();
|
||||
$this->parameters = $parameters;
|
||||
$this->http_method = $http_method;
|
||||
$this->http_url = $http_url;
|
||||
}/*}}}*/
|
||||
|
||||
|
||||
/**
|
||||
* attempt to build up a request from what was passed to the server
|
||||
*/
|
||||
public static function from_request($http_method=NULL, $http_url=NULL, $parameters=NULL) {/*{{{*/
|
||||
$scheme = (!isset($_SERVER['HTTPS']) || $_SERVER['HTTPS'] != "on") ? 'http' : 'https';
|
||||
@$http_url or $http_url = $scheme . '://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
|
||||
@$http_method or $http_method = $_SERVER['REQUEST_METHOD'];
|
||||
|
||||
$request_headers = OAuthRequest::get_headers();
|
||||
|
||||
// let the library user override things however they'd like, if they know
|
||||
// which parameters to use then go for it, for example XMLRPC might want to
|
||||
// do this
|
||||
if ($parameters) {
|
||||
$req = new OAuthRequest($http_method, $http_url, $parameters);
|
||||
}
|
||||
// next check for the auth header, we need to do some extra stuff
|
||||
// if that is the case, namely suck in the parameters from GET or POST
|
||||
// so that we can include them in the signature
|
||||
else if (@substr($request_headers['Authorization'], 0, 5) == "OAuth") {
|
||||
$header_parameters = OAuthRequest::split_header($request_headers['Authorization']);
|
||||
if ($http_method == "GET") {
|
||||
$req_parameters = $_GET;
|
||||
}
|
||||
else if ($http_method = "POST") {
|
||||
$req_parameters = $_POST;
|
||||
}
|
||||
$parameters = array_merge($header_parameters, $req_parameters);
|
||||
$req = new OAuthRequest($http_method, $http_url, $parameters);
|
||||
}
|
||||
else if ($http_method == "GET") {
|
||||
$req = new OAuthRequest($http_method, $http_url, $_GET);
|
||||
}
|
||||
else if ($http_method == "POST") {
|
||||
$req = new OAuthRequest($http_method, $http_url, $_POST);
|
||||
}
|
||||
return $req;
|
||||
}/*}}}*/
|
||||
|
||||
/**
|
||||
* pretty much a helper function to set up the request
|
||||
*/
|
||||
public static function from_consumer_and_token($consumer, $token, $http_method, $http_url, $parameters=NULL) {/*{{{*/
|
||||
@$parameters or $parameters = array();
|
||||
$defaults = array("oauth_version" => OAuthRequest::$version,
|
||||
"oauth_nonce" => OAuthRequest::generate_nonce(),
|
||||
"oauth_timestamp" => OAuthRequest::generate_timestamp(),
|
||||
"oauth_consumer_key" => $consumer->key);
|
||||
$parameters = array_merge($defaults, $parameters);
|
||||
|
||||
if ($token) {
|
||||
$parameters['oauth_token'] = $token->key;
|
||||
}
|
||||
|
||||
// oauth v1.0a
|
||||
/*if (isset($_REQUEST['oauth_verifier'])) {
|
||||
$parameters['oauth_verifier'] = $_REQUEST['oauth_verifier'];
|
||||
}*/
|
||||
|
||||
|
||||
return new OAuthRequest($http_method, $http_url, $parameters);
|
||||
}/*}}}*/
|
||||
|
||||
public function set_parameter($name, $value) {/*{{{*/
|
||||
$this->parameters[$name] = $value;
|
||||
}/*}}}*/
|
||||
|
||||
public function get_parameter($name) {/*{{{*/
|
||||
return $this->parameters[$name];
|
||||
}/*}}}*/
|
||||
|
||||
public function get_parameters() {/*{{{*/
|
||||
return $this->parameters;
|
||||
}/*}}}*/
|
||||
|
||||
/**
|
||||
* Returns the normalized parameters of the request
|
||||
*
|
||||
* This will be all (except oauth_signature) parameters,
|
||||
* sorted first by key, and if duplicate keys, then by
|
||||
* value.
|
||||
*
|
||||
* The returned string will be all the key=value pairs
|
||||
* concated by &.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_signable_parameters() {/*{{{*/
|
||||
// Grab all parameters
|
||||
$params = $this->parameters;
|
||||
|
||||
// Remove oauth_signature if present
|
||||
if (isset($params['oauth_signature'])) {
|
||||
unset($params['oauth_signature']);
|
||||
}
|
||||
|
||||
// Urlencode both keys and values
|
||||
$keys = array_map(array('OAuthUtil', 'urlencodeRFC3986'), array_keys($params));
|
||||
$values = array_map(array('OAuthUtil', 'urlencodeRFC3986'), array_values($params));
|
||||
$params = array_combine($keys, $values);
|
||||
|
||||
// Sort by keys (natsort)
|
||||
uksort($params, 'strnatcmp');
|
||||
|
||||
if(isset($params['title']) && isset($params['title-exact'])) {
|
||||
$temp = $params['title-exact'];
|
||||
$title = $params['title'];
|
||||
|
||||
unset($params['title']);
|
||||
unset($params['title-exact']);
|
||||
|
||||
$params['title-exact'] = $temp;
|
||||
$params['title'] = $title;
|
||||
}
|
||||
|
||||
// Generate key=value pairs
|
||||
$pairs = array();
|
||||
foreach ($params as $key=>$value ) {
|
||||
if (is_array($value)) {
|
||||
// If the value is an array, it's because there are multiple
|
||||
// with the same key, sort them, then add all the pairs
|
||||
natsort($value);
|
||||
foreach ($value as $v2) {
|
||||
$pairs[] = $key . '=' . $v2;
|
||||
}
|
||||
} else {
|
||||
$pairs[] = $key . '=' . $value;
|
||||
}
|
||||
}
|
||||
|
||||
// Return the pairs, concated with &
|
||||
return implode('&', $pairs);
|
||||
}/*}}}*/
|
||||
|
||||
/**
|
||||
* Returns the base string of this request
|
||||
*
|
||||
* The base string defined as the method, the url
|
||||
* and the parameters (normalized), each urlencoded
|
||||
* and the concated with &.
|
||||
*/
|
||||
public function get_signature_base_string() {/*{{{*/
|
||||
$parts = array(
|
||||
$this->get_normalized_http_method(),
|
||||
$this->get_normalized_http_url(),
|
||||
$this->get_signable_parameters()
|
||||
);
|
||||
|
||||
$parts = array_map(array('OAuthUtil', 'urlencodeRFC3986'), $parts);
|
||||
|
||||
return implode('&', $parts);
|
||||
}/*}}}*/
|
||||
|
||||
/**
|
||||
* just uppercases the http method
|
||||
*/
|
||||
public function get_normalized_http_method() {/*{{{*/
|
||||
return strtoupper($this->http_method);
|
||||
}/*}}}*/
|
||||
|
||||
/**
|
||||
* parses the url and rebuilds it to be
|
||||
* scheme://host/path
|
||||
*/
|
||||
public function get_normalized_http_url() {
|
||||
$parts = parse_url($this->http_url);
|
||||
|
||||
$scheme = (isset($parts['scheme'])) ? $parts['scheme'] : 'http';
|
||||
$port = (isset($parts['port'])) ? $parts['port'] : (($scheme == 'https') ? '443' : '80');
|
||||
$host = (isset($parts['host'])) ? strtolower($parts['host']) : '';
|
||||
$path = (isset($parts['path'])) ? $parts['path'] : '';
|
||||
|
||||
if (($scheme == 'https' && $port != '443')
|
||||
|| ($scheme == 'http' && $port != '80')) {
|
||||
$host = "$host:$port";
|
||||
}
|
||||
return "$scheme://$host$path";
|
||||
}
|
||||
|
||||
/**
|
||||
* builds a url usable for a GET request
|
||||
*/
|
||||
public function to_url() {/*{{{*/
|
||||
$out = $this->get_normalized_http_url() . "?";
|
||||
$out .= $this->to_postdata();
|
||||
return $out;
|
||||
}/*}}}*/
|
||||
|
||||
/**
|
||||
* builds the data one would send in a POST request
|
||||
*/
|
||||
public function to_postdata() {/*{{{*/
|
||||
$total = array();
|
||||
foreach ($this->parameters as $k => $v) {
|
||||
$total[] = OAuthUtil::urlencodeRFC3986($k) . "=" . OAuthUtil::urlencodeRFC3986($v);
|
||||
}
|
||||
$out = implode("&", $total);
|
||||
return $out;
|
||||
}/*}}}*/
|
||||
|
||||
/**
|
||||
* builds the Authorization: header
|
||||
*/
|
||||
public function to_header() {/*{{{*/
|
||||
$out ='Authorization: OAuth ';
|
||||
$total = array();
|
||||
|
||||
/*
|
||||
$sig = $this->parameters['oauth_signature'];
|
||||
unset($this->parameters['oauth_signature']);
|
||||
uksort($this->parameters, 'strnatcmp');
|
||||
$this->parameters['oauth_signature'] = $sig;
|
||||
*/
|
||||
|
||||
foreach ($this->parameters as $k => $v) {
|
||||
if (substr($k, 0, 5) != "oauth") continue;
|
||||
$out .= OAuthUtil::urlencodeRFC3986($k) . '="' . OAuthUtil::urlencodeRFC3986($v) . '", ';
|
||||
}
|
||||
$out = substr_replace($out, '', strlen($out) - 2);
|
||||
|
||||
return $out;
|
||||
}/*}}}*/
|
||||
|
||||
public function __toString() {/*{{{*/
|
||||
return $this->to_url();
|
||||
}/*}}}*/
|
||||
|
||||
|
||||
public function sign_request($signature_method, $consumer, $token, $privKey=NULL) {/*{{{*/
|
||||
$this->set_parameter("oauth_signature_method", $signature_method->get_name());
|
||||
$signature = $this->build_signature($signature_method, $consumer, $token, $privKey);
|
||||
$this->set_parameter("oauth_signature", $signature);
|
||||
}/*}}}*/
|
||||
|
||||
public function build_signature($signature_method, $consumer, $token, $privKey=NULL) {/*{{{*/
|
||||
$signature = $signature_method->build_signature($this, $consumer, $token, $privKey);
|
||||
return $signature;
|
||||
}/*}}}*/
|
||||
|
||||
/**
|
||||
* util function: current timestamp
|
||||
*/
|
||||
private static function generate_timestamp() {/*{{{*/
|
||||
return time();
|
||||
}/*}}}*/
|
||||
|
||||
/**
|
||||
* util function: current nonce
|
||||
*/
|
||||
private static function generate_nonce() {/*{{{*/
|
||||
$mt = microtime();
|
||||
$rand = mt_rand();
|
||||
|
||||
return md5($mt . $rand); // md5s look nicer than numbers
|
||||
}/*}}}*/
|
||||
|
||||
/**
|
||||
* util function for turning the Authorization: header into
|
||||
* parameters, has to do some unescaping
|
||||
*/
|
||||
private static function split_header($header) {/*{{{*/
|
||||
// this should be a regex
|
||||
// error cases: commas in parameter values
|
||||
$parts = explode(",", $header);
|
||||
$out = array();
|
||||
foreach ($parts as $param) {
|
||||
$param = ltrim($param);
|
||||
// skip the "realm" param, nobody ever uses it anyway
|
||||
if (substr($param, 0, 5) != "oauth") continue;
|
||||
|
||||
$param_parts = explode("=", $param);
|
||||
|
||||
// rawurldecode() used because urldecode() will turn a "+" in the
|
||||
// value into a space
|
||||
$out[$param_parts[0]] = rawurldecode(substr($param_parts[1], 1, -1));
|
||||
}
|
||||
return $out;
|
||||
}/*}}}*/
|
||||
|
||||
/**
|
||||
* helper to try to sort out headers for people who aren't running apache
|
||||
*/
|
||||
private static function get_headers() {/*{{{*/
|
||||
if (function_exists('apache_request_headers')) {
|
||||
// we need this to get the actual Authorization: header
|
||||
// because apache tends to tell us it doesn't exist
|
||||
return apache_request_headers();
|
||||
}
|
||||
// otherwise we don't have apache and are just going to have to hope
|
||||
// that $_SERVER actually contains what we need
|
||||
$out = array();
|
||||
foreach ($_SERVER as $key => $value) {
|
||||
if (substr($key, 0, 5) == "HTTP_") {
|
||||
// this is chaos, basically it is just there to capitalize the first
|
||||
// letter of every word that is not an initial HTTP and strip HTTP
|
||||
// code from przemek
|
||||
$key = str_replace(" ", "-", ucwords(strtolower(str_replace("_", " ", substr($key, 5)))));
|
||||
$out[$key] = $value;
|
||||
}
|
||||
}
|
||||
return $out;
|
||||
}/*}}}*/
|
||||
}/*}}}*/
|
||||
|
||||
class OAuthServer {/*{{{*/
|
||||
protected $timestamp_threshold = 300; // in seconds, five minutes
|
||||
protected $version = 1.0; // hi blaine
|
||||
protected $signature_methods = array();
|
||||
|
||||
protected $data_store;
|
||||
|
||||
function __construct($data_store) {/*{{{*/
|
||||
$this->data_store = $data_store;
|
||||
}/*}}}*/
|
||||
|
||||
public function add_signature_method($signature_method) {/*{{{*/
|
||||
$this->signature_methods[$signature_method->get_name()] =
|
||||
$signature_method;
|
||||
}/*}}}*/
|
||||
|
||||
// high level functions
|
||||
|
||||
/**
|
||||
* process a request_token request
|
||||
* returns the request token on success
|
||||
*/
|
||||
public function fetch_request_token(&$request) {/*{{{*/
|
||||
$this->get_version($request);
|
||||
|
||||
$consumer = $this->get_consumer($request);
|
||||
|
||||
// no token required for the initial token request
|
||||
$token = NULL;
|
||||
|
||||
$this->check_signature($request, $consumer, $token);
|
||||
|
||||
$new_token = $this->data_store->new_request_token($consumer);
|
||||
|
||||
return $new_token;
|
||||
}/*}}}*/
|
||||
|
||||
/**
|
||||
* process an access_token request
|
||||
* returns the access token on success
|
||||
*/
|
||||
public function fetch_access_token(&$request) {/*{{{*/
|
||||
$this->get_version($request);
|
||||
|
||||
$consumer = $this->get_consumer($request);
|
||||
|
||||
// requires authorized request token
|
||||
$token = $this->get_token($request, $consumer, "request");
|
||||
|
||||
$this->check_signature($request, $consumer, $token);
|
||||
|
||||
$new_token = $this->data_store->new_access_token($token, $consumer);
|
||||
|
||||
return $new_token;
|
||||
}/*}}}*/
|
||||
|
||||
/**
|
||||
* verify an api call, checks all the parameters
|
||||
*/
|
||||
public function verify_request(&$request) {/*{{{*/
|
||||
$this->get_version($request);
|
||||
$consumer = $this->get_consumer($request);
|
||||
$token = $this->get_token($request, $consumer, "access");
|
||||
$this->check_signature($request, $consumer, $token);
|
||||
return array($consumer, $token);
|
||||
}/*}}}*/
|
||||
|
||||
// Internals from here
|
||||
/**
|
||||
* version 1
|
||||
*/
|
||||
private function get_version(&$request) {/*{{{*/
|
||||
$version = $request->get_parameter("oauth_version");
|
||||
if (!$version) {
|
||||
$version = 1.0;
|
||||
}
|
||||
if ($version && $version != $this->version) {
|
||||
throw new OAuthException("OAuth version '$version' not supported");
|
||||
}
|
||||
return $version;
|
||||
}/*}}}*/
|
||||
|
||||
/**
|
||||
* figure out the signature with some defaults
|
||||
*/
|
||||
private function get_signature_method(&$request) {/*{{{*/
|
||||
$signature_method =
|
||||
@$request->get_parameter("oauth_signature_method");
|
||||
if (!$signature_method) {
|
||||
$signature_method = "PLAINTEXT";
|
||||
}
|
||||
if (!in_array($signature_method,
|
||||
array_keys($this->signature_methods))) {
|
||||
throw new OAuthException(
|
||||
"Signature method '$signature_method' not supported try one of the following: " . implode(", ", array_keys($this->signature_methods))
|
||||
);
|
||||
}
|
||||
return $this->signature_methods[$signature_method];
|
||||
}/*}}}*/
|
||||
|
||||
/**
|
||||
* try to find the consumer for the provided request's consumer key
|
||||
*/
|
||||
private function get_consumer(&$request) {/*{{{*/
|
||||
$consumer_key = @$request->get_parameter("oauth_consumer_key");
|
||||
if (!$consumer_key) {
|
||||
throw new OAuthException("Invalid consumer key");
|
||||
}
|
||||
|
||||
$consumer = $this->data_store->lookup_consumer($consumer_key);
|
||||
if (!$consumer) {
|
||||
throw new OAuthException("Invalid consumer");
|
||||
}
|
||||
|
||||
return $consumer;
|
||||
}/*}}}*/
|
||||
|
||||
/**
|
||||
* try to find the token for the provided request's token key
|
||||
*/
|
||||
private function get_token(&$request, $consumer, $token_type="access") {/*{{{*/
|
||||
$token_field = @$request->get_parameter('oauth_token');
|
||||
$token = $this->data_store->lookup_token(
|
||||
$consumer, $token_type, $token_field
|
||||
);
|
||||
if (!$token) {
|
||||
throw new OAuthException("Invalid $token_type token: $token_field");
|
||||
}
|
||||
return $token;
|
||||
}/*}}}*/
|
||||
|
||||
/**
|
||||
* all-in-one function to check the signature on a request
|
||||
* should guess the signature method appropriately
|
||||
*/
|
||||
private function check_signature(&$request, $consumer, $token) {/*{{{*/
|
||||
// this should probably be in a different method
|
||||
$timestamp = @$request->get_parameter('oauth_timestamp');
|
||||
$nonce = @$request->get_parameter('oauth_nonce');
|
||||
|
||||
$this->check_timestamp($timestamp);
|
||||
$this->check_nonce($consumer, $token, $nonce, $timestamp);
|
||||
|
||||
$signature_method = $this->get_signature_method($request);
|
||||
|
||||
$signature = $request->get_parameter('oauth_signature');
|
||||
$valid_sig = $signature_method->check_signature(
|
||||
$request,
|
||||
$consumer,
|
||||
$token,
|
||||
$signature
|
||||
);
|
||||
|
||||
if (!$valid_sig) {
|
||||
throw new OAuthException("Invalid signature");
|
||||
}
|
||||
}/*}}}*/
|
||||
|
||||
/**
|
||||
* check that the timestamp is new enough
|
||||
*/
|
||||
private function check_timestamp($timestamp) {/*{{{*/
|
||||
// verify that timestamp is recentish
|
||||
$now = time();
|
||||
if ($now - $timestamp > $this->timestamp_threshold) {
|
||||
throw new OAuthException("Expired timestamp, yours $timestamp, ours $now");
|
||||
}
|
||||
}/*}}}*/
|
||||
|
||||
/**
|
||||
* check that the nonce is not repeated
|
||||
*/
|
||||
private function check_nonce($consumer, $token, $nonce, $timestamp) {/*{{{*/
|
||||
// verify that the nonce is uniqueish
|
||||
$found = $this->data_store->lookup_nonce($consumer, $token, $nonce, $timestamp);
|
||||
if ($found) {
|
||||
throw new OAuthException("Nonce already used: $nonce");
|
||||
}
|
||||
}/*}}}*/
|
||||
|
||||
|
||||
|
||||
}/*}}}*/
|
||||
|
||||
class OAuthDataStore {/*{{{*/
|
||||
function lookup_consumer($consumer_key) {/*{{{*/
|
||||
// implement me
|
||||
}/*}}}*/
|
||||
|
||||
function lookup_token($consumer, $token_type, $token) {/*{{{*/
|
||||
// implement me
|
||||
}/*}}}*/
|
||||
|
||||
function lookup_nonce($consumer, $token, $nonce, $timestamp) {/*{{{*/
|
||||
// implement me
|
||||
}/*}}}*/
|
||||
|
||||
function fetch_request_token($consumer) {/*{{{*/
|
||||
// return a new token attached to this consumer
|
||||
}/*}}}*/
|
||||
|
||||
function fetch_access_token($token, $consumer) {/*{{{*/
|
||||
// return a new access token attached to this consumer
|
||||
// for the user associated with this token if the request token
|
||||
// is authorized
|
||||
// should also invalidate the request token
|
||||
}/*}}}*/
|
||||
|
||||
}/*}}}*/
|
||||
|
||||
|
||||
/* A very naive dbm-based oauth storage
|
||||
*/
|
||||
class SimpleOAuthDataStore extends OAuthDataStore {/*{{{*/
|
||||
private $dbh;
|
||||
|
||||
function __construct($path = "oauth.gdbm") {/*{{{*/
|
||||
$this->dbh = dba_popen($path, 'c', 'gdbm');
|
||||
}/*}}}*/
|
||||
|
||||
function __destruct() {/*{{{*/
|
||||
dba_close($this->dbh);
|
||||
}/*}}}*/
|
||||
|
||||
function lookup_consumer($consumer_key) {/*{{{*/
|
||||
$rv = dba_fetch("consumer_$consumer_key", $this->dbh);
|
||||
if ($rv === FALSE) {
|
||||
return NULL;
|
||||
}
|
||||
$obj = unserialize($rv);
|
||||
if (!($obj instanceof OAuthConsumer)) {
|
||||
return NULL;
|
||||
}
|
||||
return $obj;
|
||||
}/*}}}*/
|
||||
|
||||
function lookup_token($consumer, $token_type, $token) {/*{{{*/
|
||||
$rv = dba_fetch("${token_type}_${token}", $this->dbh);
|
||||
if ($rv === FALSE) {
|
||||
return NULL;
|
||||
}
|
||||
$obj = unserialize($rv);
|
||||
if (!($obj instanceof OAuthToken)) {
|
||||
return NULL;
|
||||
}
|
||||
return $obj;
|
||||
}/*}}}*/
|
||||
|
||||
function lookup_nonce($consumer, $token, $nonce, $timestamp) {/*{{{*/
|
||||
return dba_exists("nonce_$nonce", $this->dbh);
|
||||
}/*}}}*/
|
||||
|
||||
function new_token($consumer, $type="request") {/*{{{*/
|
||||
$key = md5(time());
|
||||
$secret = time() + time();
|
||||
$token = new OAuthToken($key, md5(md5($secret)));
|
||||
if (!dba_insert("${type}_$key", serialize($token), $this->dbh)) {
|
||||
throw new OAuthException("doooom!");
|
||||
}
|
||||
return $token;
|
||||
}/*}}}*/
|
||||
|
||||
function new_request_token($consumer) {/*{{{*/
|
||||
return $this->new_token($consumer, "request");
|
||||
}/*}}}*/
|
||||
|
||||
function new_access_token($token, $consumer) {/*{{{*/
|
||||
|
||||
$token = $this->new_token($consumer, 'access');
|
||||
dba_delete("request_" . $token->key, $this->dbh);
|
||||
return $token;
|
||||
}/*}}}*/
|
||||
}/*}}}*/
|
||||
|
||||
class OAuthUtil {/*{{{*/
|
||||
public static function urlencodeRFC3986($string) {/*{{{*/
|
||||
return str_replace('%7E', '~', rawurlencode($string));
|
||||
}/*}}}*/
|
||||
|
||||
public static function urldecodeRFC3986($string) {/*{{{*/
|
||||
return rawurldecode($string);
|
||||
}/*}}}*/
|
||||
}/*}}}*/
|
||||
|
||||
?>
|
|
@ -0,0 +1,185 @@
|
|||
<?php
|
||||
/* Copyright (c) 2009 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* Author: Eric Bidelman <e.bidelman@google.com>
|
||||
*/
|
||||
|
||||
$PRIV_KEY_FILE = '/path/to/your/rsa_private_key.pem';
|
||||
|
||||
// OAuth library - http://oauth.googlecode.com/svn/code/php/
|
||||
require_once('OAuth.php');
|
||||
|
||||
// Google's accepted signature methods
|
||||
$hmac_method = new OAuthSignatureMethod_HMAC_SHA1();
|
||||
$rsa_method = new OAuthSignatureMethod_RSA_SHA1();
|
||||
$SIG_METHODS = array($rsa_method->get_name() => $rsa_method,
|
||||
$hmac_method->get_name() => $hmac_method);
|
||||
|
||||
/**
|
||||
* Makes an HTTP request to the specified URL
|
||||
*
|
||||
* @param string $http_method The HTTP method (GET, POST, PUT, DELETE)
|
||||
* @param string $url Full URL of the resource to access
|
||||
* @param array $extraHeaders (optional) Additional headers to include in each
|
||||
* request. Elements are header/value pair strings ('Host: example.com')
|
||||
* @param string $postData (optional) POST/PUT request body
|
||||
* @param bool $returnResponseHeaders True if resp. headers should be returned.
|
||||
* @return string Response body from the server
|
||||
*/
|
||||
function send_signed_request($http_method, $url, $extraHeaders=null,
|
||||
$postData=null, $returnResponseHeaders=true) {
|
||||
$curl = curl_init($url);
|
||||
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($curl, CURLOPT_FAILONERROR, false);
|
||||
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
|
||||
|
||||
// Return request headers in the reponse
|
||||
// curl_setopt($curl, CURLINFO_HEADER_OUT, true);
|
||||
|
||||
// Return response headers ni the response?
|
||||
if ($returnResponseHeaders) {
|
||||
curl_setopt($curl, CURLOPT_HEADER, true);
|
||||
}
|
||||
|
||||
$headers = array();
|
||||
//$headers[] = 'GData-Version: 2.0'; // use GData v2 by default
|
||||
if (is_array($extraHeaders)) {
|
||||
$headers = array_merge($headers, $extraHeaders);
|
||||
}
|
||||
|
||||
// Setup default curl options for each type of HTTP request.
|
||||
// This is also a great place to add additional headers for each request.
|
||||
switch($http_method) {
|
||||
case 'GET':
|
||||
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
|
||||
break;
|
||||
case 'POST':
|
||||
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
|
||||
curl_setopt($curl, CURLOPT_POST, 1);
|
||||
curl_setopt($curl, CURLOPT_POSTFIELDS, $postData);
|
||||
break;
|
||||
case 'PUT':
|
||||
$headers[] = 'If-Match: *';
|
||||
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
|
||||
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $http_method);
|
||||
curl_setopt($curl, CURLOPT_POSTFIELDS, $postData);
|
||||
break;
|
||||
case 'DELETE':
|
||||
$headers[] = 'If-Match: *';
|
||||
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
|
||||
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $http_method);
|
||||
break;
|
||||
default:
|
||||
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
|
||||
}
|
||||
|
||||
// Execute the request. If an error occures, fill the response body with it.
|
||||
$response = curl_exec($curl);
|
||||
if (!$response) {
|
||||
$response = curl_error($curl);
|
||||
}
|
||||
|
||||
// Add server's response headers to our response body
|
||||
$response = curl_getinfo($curl, CURLINFO_HEADER_OUT) . $response;
|
||||
|
||||
curl_close($curl);
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes XML as a string and returns it nicely indented
|
||||
*
|
||||
* @param string $xml The xml to beautify
|
||||
* @param boolean $html_output True if returned XML should be escaped for HTML.
|
||||
* @return string The beautified xml
|
||||
*/
|
||||
function xml_pretty_printer($xml, $html_output=false) {
|
||||
$xml_obj = new SimpleXMLElement($xml);
|
||||
$level = 2;
|
||||
|
||||
// Get an array containing each XML element
|
||||
$xml = explode("\n", preg_replace('/>\s*</', ">\n<", $xml_obj->asXML()));
|
||||
|
||||
// Hold current indentation level
|
||||
$indent = 0;
|
||||
|
||||
$pretty = array();
|
||||
|
||||
// Shift off opening XML tag if present
|
||||
if (count($xml) && preg_match('/^<\?\s*xml/', $xml[0])) {
|
||||
$pretty[] = array_shift($xml);
|
||||
}
|
||||
|
||||
foreach ($xml as $el) {
|
||||
if (preg_match('/^<([\w])+[^>\/]*>$/U', $el)) {
|
||||
// opening tag, increase indent
|
||||
$pretty[] = str_repeat(' ', $indent) . $el;
|
||||
$indent += $level;
|
||||
} else {
|
||||
if (preg_match('/^<\/.+>$/', $el)) {
|
||||
$indent -= $level; // closing tag, decrease indent
|
||||
}
|
||||
if ($indent < 0) {
|
||||
$indent += $level;
|
||||
}
|
||||
$pretty[] = str_repeat(' ', $indent) . $el;
|
||||
}
|
||||
}
|
||||
|
||||
$xml = implode("\n", $pretty);
|
||||
return $html_output ? htmlentities($xml) : $xml;
|
||||
}
|
||||
|
||||
/**
|
||||
* Joins key/value pairs by $inner_glue and each pair together by $outer_glue.
|
||||
*
|
||||
* Example: implode_assoc('=', '&', array('a' => 1, 'b' => 2)) === 'a=1&b=2'
|
||||
*
|
||||
* @param string $inner_glue What to implode each key/value pair with
|
||||
* @param string $outer_glue What to impode each key/value string subset with
|
||||
* @param array $array Associative array of query parameters
|
||||
* @return string Urlencoded string of query parameters
|
||||
*/
|
||||
function implode_assoc($inner_glue, $outer_glue, $array) {
|
||||
$output = array();
|
||||
foreach($array as $key => $item) {
|
||||
$output[] = $key . $inner_glue . urlencode($item);
|
||||
}
|
||||
return implode($outer_glue, $output);
|
||||
}
|
||||
|
||||
/**
|
||||
* Explodes a string of key/value url parameters into an associative array.
|
||||
* This method performs the compliment operations of implode_assoc().
|
||||
*
|
||||
* Example: explode_assoc('=', '&', 'a=1&b=2') === array('a' => 1, 'b' => 2)
|
||||
*
|
||||
* @param string $inner_glue What each key/value pair is joined with
|
||||
* @param string $outer_glue What each set of key/value pairs is joined with.
|
||||
* @param array $array Associative array of query parameters
|
||||
* @return array Urlencoded string of query parameters
|
||||
*/
|
||||
function explode_assoc($inner_glue, $outer_glue, $params) {
|
||||
$tempArr = explode($outer_glue, $params);
|
||||
foreach($tempArr as $val) {
|
||||
$pos = strpos($val, $inner_glue);
|
||||
$key = substr($val, 0, $pos);
|
||||
$array2[$key] = substr($val, $pos + 1, strlen($val));
|
||||
}
|
||||
return $array2;
|
||||
}
|
||||
|
||||
?>
|
|
@ -0,0 +1,136 @@
|
|||
# AWS SDK for PHP
|
||||
|
||||
The AWS SDK for PHP enables developers to build solutions for Amazon Simple Storage Service (Amazon S3),
|
||||
Amazon Elastic Compute Cloud (Amazon EC2), Amazon SimpleDB, and more. With the AWS SDK for PHP, developers
|
||||
can get started in minutes with a single, downloadable package.
|
||||
|
||||
The SDK features:
|
||||
|
||||
* **AWS PHP Libraries:** Build PHP applications on top of APIs that take the complexity out of coding directly
|
||||
against a web service interface. The toolkit provides APIs that hide much of the lower-level implementation.
|
||||
* **Code Samples:** Practical examples for how to use the toolkit to build applications.
|
||||
* **Documentation:** Complete SDK reference documentation with samples demonstrating how to use the SDK.
|
||||
* **PEAR package:** The ability to install the AWS SDK for PHP as a PEAR package.
|
||||
* **SDK Compatibility Test:** Includes both an HTML-based and a CLI-based SDK Compatibility Test that you can
|
||||
run on your server to determine whether or not your PHP environment meets the minimum requirements.
|
||||
|
||||
For more information about the AWS SDK for PHP, including a complete list of supported services, see
|
||||
[aws.amazon.com/sdkforphp](http://aws.amazon.com/sdkforphp).
|
||||
|
||||
|
||||
## Signing up for Amazon Web Services
|
||||
|
||||
Before you can begin, you must sign up for each service you want to use.
|
||||
|
||||
To sign up for a service:
|
||||
|
||||
* Go to the home page for the service. You can find a list of services on
|
||||
[aws.amazon.com/products](http://aws.amazon.com/products).
|
||||
* Click the Sign Up button on the top right corner of the page. If you don't already have an AWS account, you
|
||||
are prompted to create one as part of the sign up process.
|
||||
* Follow the on-screen instructions.
|
||||
* AWS sends you a confirmation e-mail after the sign-up process is complete. At any time, you can view your
|
||||
current account activity and manage your account by going to [aws.amazon.com](http://aws.amazon.com) and
|
||||
clicking "Your Account".
|
||||
|
||||
|
||||
## Source
|
||||
The source tree for includes the following files and directories:
|
||||
|
||||
* `_compatibility_test` -- Includes both an HTML-based and a CLI-based SDK Compatibility Test that you can
|
||||
run on your server to determine whether or not your PHP environment meets the minimum requirements.
|
||||
* `_docs` -- Informational documents, the contents of which should be fairly self-explanatory.
|
||||
* `_samples` -- Code samples that you can run out of the box.
|
||||
* `extensions` -- Extra code that can be used to enhance usage of the SDK, but isn't a service class or a
|
||||
third-party library.
|
||||
* `lib` -- Contains any third-party libraries that the SDK depends on. The licenses for these projects will
|
||||
always be Apache 2.0-compatible.
|
||||
* `services` -- Contains the service-specific classes that communicate with AWS. These classes are always
|
||||
prefixed with `Amazon`.
|
||||
* `utilities` -- Contains any utility-type methods that the SDK uses. Includes extensions to built-in PHP
|
||||
classes, as well as new functionality that is entirely custom. These classes are always prefixed with `CF`.
|
||||
* `README` -- The document you're reading right now.
|
||||
* `config-sample.inc.php` -- A sample configuration file that should be filled out and renamed to `config.inc.php`.
|
||||
* `sdk.class.php` -- The SDK loader that you would include in your projects. Contains the base functionality
|
||||
that the rest of the SDK depends on.
|
||||
|
||||
|
||||
## Minimum Requirements in a nutshell
|
||||
|
||||
* You are at least an intermediate-level PHP developer and have a basic understanding of object-oriented PHP.
|
||||
* You have a valid AWS account, and you've already signed up for the services you want to use.
|
||||
* The PHP interpreter, version 5.2 or newer. PHP 5.2.17 or 5.3.x is highly recommended for use with the AWS SDK for PHP.
|
||||
* The cURL PHP extension (compiled with the [OpenSSL](http://openssl.org) libraries for HTTPS support).
|
||||
* The ability to read from and write to the file system via [file_get_contents()](http://php.net/file_get_contents) and [file_put_contents()](http://php.net/file_put_contents).
|
||||
|
||||
If you're not sure whether your PHP environment meets these requirements, run the
|
||||
[SDK Compatibility Test](http://github.com/amazonwebservices/aws-sdk-for-php/tree/master/_compatibility_test/) script
|
||||
included in the SDK download.
|
||||
|
||||
|
||||
## Installation
|
||||
|
||||
### Via GitHub
|
||||
|
||||
[Git](http://git-scm.com) is an extremely fast, efficient, distributed version control system ideal for the
|
||||
collaborative development of software. [GitHub](http://github.com/amazonwebservices) is the best way to
|
||||
collaborate with others. Fork, send pull requests and manage all your public and private git repositories.
|
||||
We believe that GitHub is the ideal service for working collaboratively with the open source PHP community.
|
||||
|
||||
Git is primarily a command-line tool. GitHub provides instructions for installing Git on
|
||||
[Mac OS X](http://help.github.com/mac-git-installation/), [Windows](http://help.github.com/win-git-installation/),
|
||||
and [Linux](http://help.github.com/linux-git-installation/). If you're unfamiliar with Git, there are a variety
|
||||
of resources on the net that will help you learn more:
|
||||
|
||||
* [Git Immersion](http://gitimmersion.com) is a guided tour that walks through the fundamentals of Git, inspired
|
||||
by the premise that to know a thing is to do it.
|
||||
* The [PeepCode screencast on Git](https://peepcode.com/products/git) ($12) will teach you how to install and
|
||||
use Git. You'll learn how to create a repository, use branches, and work with remote repositories.
|
||||
* [Git Reference](http://gitref.org) is meant to be a quick reference for learning and remembering the most
|
||||
important and commonly used Git commands.
|
||||
* [Git Ready](http://gitready.com) provides a collection of Git tips and tricks.
|
||||
* If you want to dig even further, I've [bookmarked other Git references](http://pinboard.in/u:skyzyx/t:git).
|
||||
|
||||
If you're comfortable working with Git and/or GitHub, you can pull down the source code as follows:
|
||||
|
||||
git clone git://github.com/amazonwebservices/aws-sdk-for-php.git AWSSDKforPHP
|
||||
cd ./AWSSDKforPHP
|
||||
|
||||
### Via PEAR
|
||||
|
||||
[PEAR](http://pear.php.net) stands for the _PHP Extension and Application Repository_ and is a framework and
|
||||
distribution system for reusable PHP components. It is the PHP equivalent to package management software such as
|
||||
[MacPorts](http://macports.org) and [Homebrew](https://github.com/mxcl/homebrew) for Mac OS X,
|
||||
[Yum](http://fedoraproject.org/wiki/Tools/yum) and [Apt](http://wiki.debian.org/Apt) for GNU/Linux,
|
||||
[RubyGems](http://rubygems.org) for Ruby, [Easy Install](http://packages.python.org/distribute/easy_install.html)
|
||||
for Python, [Maven](http://maven.apache.org) for Java, and [NPM](http://npm.mape.me) for Node.js.
|
||||
|
||||
PEAR packages are very easy to install, and are available in your PHP environment path so that they are accessible
|
||||
to any PHP project. PEAR packages are not specific to your project, but rather to the machine that they're
|
||||
installed on.
|
||||
|
||||
From the command-line, you can install the SDK with PEAR as follows:
|
||||
|
||||
pear channel-discover pear.amazonwebservices.com
|
||||
pear install aws/sdk
|
||||
|
||||
You may need to use `sudo` for the above commands. Once the SDK has been installed via PEAR, you can load it into
|
||||
your project with:
|
||||
|
||||
require_once 'AWSSDKforPHP/sdk.class.php';
|
||||
|
||||
### Configuration
|
||||
|
||||
1. Copy the contents of [config-sample.inc.php](https://github.com/amazonwebservices/aws-sdk-for-php/raw/master/config-sample.inc.php)
|
||||
and add your credentials as instructed in the file.
|
||||
2. Move your file to `~/.aws/sdk/config.inc.php`.
|
||||
3. Make sure that `getenv('HOME')` points to your user directory. If not you'll need to set
|
||||
`putenv('HOME=<your-user-directory>')`.
|
||||
|
||||
|
||||
## Additional Information
|
||||
|
||||
* AWS SDK for PHP: <http://aws.amazon.com/sdkforphp>
|
||||
* Documentation: <http://docs.amazonwebservices.com/AWSSDKforPHP/latest/>
|
||||
* License: <http://aws.amazon.com/apache2.0/>
|
||||
* Discuss: <http://aws.amazon.com/forums>
|
|
@ -0,0 +1,37 @@
|
|||
# Compatibility Test
|
||||
|
||||
## Via your web browser
|
||||
|
||||
1. Upload `sdk_compatibility_test.php` to the web-accessible root of your website.
|
||||
For example, if your website is `www.example.com`, upload it so that you can get
|
||||
to it at `www.example.com/sdk_compatibility_test.php`
|
||||
|
||||
2. Open your web browser and go to the page you just uploaded.
|
||||
|
||||
|
||||
## Via the command line
|
||||
|
||||
### Windows
|
||||
|
||||
1. Upload `sdk_compatibility_test_cli.php` to your server via SFTP.
|
||||
|
||||
2. SSH/RDP into the machine, and find the directory where you uploaded the test.
|
||||
|
||||
3. Run the test, and review the results:
|
||||
|
||||
php .\sdk_compatibility_test_cli.php
|
||||
|
||||
|
||||
### Non-Windows (Mac or *nix)
|
||||
|
||||
1. Upload `sdk_compatibility_test_cli.php` to your server via SFTP.
|
||||
|
||||
2. SSH into the machine, and find the directory where you uploaded the test.
|
||||
|
||||
3. Set the executable bit:
|
||||
|
||||
chmod +x ./sdk_compatibility_test_cli.php
|
||||
|
||||
4. Run the test, and review the results:
|
||||
|
||||
./sdk_compatibility_test_cli.php
|
|
@ -0,0 +1,75 @@
|
|||
<?php
|
||||
|
||||
define('REQUIREMENTS_ALL_MET', 100);
|
||||
define('REQUIREMENTS_MIN_MET', 10);
|
||||
define('REQUIREMENTS_NOT_MET', 0);
|
||||
|
||||
// Required
|
||||
$php_ok = (function_exists('version_compare') && version_compare(phpversion(), '5.2.0', '>='));
|
||||
$simplexml_ok = extension_loaded('simplexml');
|
||||
$dom_ok = extension_loaded('dom');
|
||||
$json_ok = (extension_loaded('json') && function_exists('json_encode') && function_exists('json_decode'));
|
||||
$spl_ok = extension_loaded('spl');
|
||||
$pcre_ok = extension_loaded('pcre');
|
||||
$curl_ok = false;
|
||||
if (function_exists('curl_version'))
|
||||
{
|
||||
$curl_version = curl_version();
|
||||
$curl_ok = (function_exists('curl_exec') && in_array('https', $curl_version['protocols'], true));
|
||||
}
|
||||
$file_ok = (function_exists('file_get_contents') && function_exists('file_put_contents'));
|
||||
|
||||
// Optional, but recommended
|
||||
$openssl_ok = (extension_loaded('openssl') && function_exists('openssl_sign'));
|
||||
$zlib_ok = extension_loaded('zlib');
|
||||
|
||||
// Optional
|
||||
$apc_ok = extension_loaded('apc');
|
||||
$xcache_ok = extension_loaded('xcache');
|
||||
$memcached_ok = extension_loaded('memcached');
|
||||
$memcache_ok = extension_loaded('memcache');
|
||||
$mc_ok = ($memcache_ok || $memcached_ok);
|
||||
$pdo_ok = extension_loaded('pdo');
|
||||
$pdo_sqlite_ok = extension_loaded('pdo_sqlite');
|
||||
$sqlite2_ok = extension_loaded('sqlite');
|
||||
$sqlite3_ok = extension_loaded('sqlite3');
|
||||
$sqlite_ok = ($pdo_ok && $pdo_sqlite_ok && ($sqlite2_ok || $sqlite3_ok));
|
||||
|
||||
// Other
|
||||
$int64_ok = (PHP_INT_MAX === 9223372036854775807);
|
||||
$ini_memory_limit = get_ini('memory_limit');
|
||||
$ini_open_basedir = get_ini('open_basedir');
|
||||
$ini_safe_mode = get_ini('safe_mode');
|
||||
$ini_zend_enable_gc = get_ini('zend.enable_gc');
|
||||
|
||||
if ($php_ok && $int64_ok && $curl_ok && $simplexml_ok && $dom_ok && $spl_ok && $json_ok && $pcre_ok && $file_ok && $openssl_ok && $zlib_ok && ($apc_ok || $xcache_ok || $mc_ok || $sqlite_ok))
|
||||
{
|
||||
$compatiblity = REQUIREMENTS_ALL_MET;
|
||||
}
|
||||
elseif ($php_ok && $curl_ok && $simplexml_ok && $dom_ok && $spl_ok && $json_ok && $pcre_ok && $file_ok)
|
||||
{
|
||||
$compatiblity = REQUIREMENTS_MIN_MET;
|
||||
}
|
||||
else
|
||||
{
|
||||
$compatiblity = REQUIREMENTS_NOT_MET;
|
||||
}
|
||||
|
||||
function get_ini($config)
|
||||
{
|
||||
$cfg_value = ini_get($config);
|
||||
|
||||
if ($cfg_value === false || $cfg_value === '' || $cfg_value === 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
elseif ($cfg_value === true || $cfg_value === '1' || $cfg_value === 1)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
function is_windows()
|
||||
{
|
||||
return strtolower(substr(PHP_OS, 0, 3)) === 'win';
|
||||
}
|
|
@ -0,0 +1,789 @@
|
|||
<?php
|
||||
if (isset($_GET['logopng']))
|
||||
{
|
||||
$data = <<<IMAGE
|
||||
iVBORw0KGgoAAAANSUhEUgAAASwAAABwCAYAAACkRk1NAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz
|
||||
AAALEgAACxIB0t1+/AAAABx0RVh0U29mdHdhcmUAQWRvYmUgRmlyZXdvcmtzIENTNXG14zYAAAAU
|
||||
dEVYdENyZWF0aW9uIFRpbWUAOS80LzEwZyhWjQAAGJpJREFUeNrtnQ2wXEWVgJvwjKksP2MKMAKV
|
||||
HXbZIqUgU1CLWBtkLLZc1IU3CK4ssDAEFVlhM7qIyhYwiqALCqOFIkbNGDSsSszsqllA1zfhT0SX
|
||||
DD8aFgJv+DU/JG9CfpYErNluc+6m35m+ffvvvrkz75yqU8mbudO3b9/u755z+txuxkhISEhISEhI
|
||||
SEgyJa8tnlvgWgUtZqxuOa4lqFtF1JXuGAnJ9AJUHgZ/g2uHa1ehTYBEoQ/1K3KtcW3F1K3Ntc61
|
||||
LK6F7igJyfABqgyDvB0DAZ12AG6VNAABFl4FINl10BYATlhiObrjJCSDBajIjdJZKT4qWzg5h/qZ
|
||||
WHg+2syie0tCQqKGwYoUIBCnq23AAKBaPUV1mwBok9VFQjIAVtZ5AK+JwCAY47rIxz0EsC5KAV7i
|
||||
WpdwHaVeQEIyuAAbhYHsCq8VAMBcCnXzhdc4QYqEZHBg1IR4kFFMyQJexpCCmJmIa3XQ50WIedVM
|
||||
Zhwt4CUgdaNFmVFQv0Y9hoSk/8CSB3PDdMpfgte4DaTA5YxmHicFzhXAUgXsS5ZurSuk8KRDk3oM
|
||||
CUm2gIWn/IOkI0iQauisnwRg4XQJI3gZ1q9gMDNKwCIhyTCwVPAqWJSdN4GUI7BUuV5WqRISpEzz
|
||||
ywhYJCQDAizsminjShp3Kk1gdWPc2pwmXuaSBEvAIiEZQGDJWkTleaUWBAKWEjCQEBqsPBISEgIW
|
||||
AYuEhISARcAiISFgEbBISEgIWAQsEhISApa7UqY7CQkBa2CAVaUeQ0JCwCJgkZCQELAIWCQkBCwC
|
||||
FgkJCQGLgEVCQkLAImCRkBCwCFgkJCQELAIWCQkJAYuARUJCwCJgkZCQELAIWCQkJNkE1jgqq+C5
|
||||
L2JoYFWox5CQ9BdYJc/dnn2Blbibjce+iCGAtdp341cSEpLw4MLbYqUJLOMttzzh5QqsFQQpEpLh
|
||||
hJcpsJwh5QEvG2Cltjs1CUnWB3wRD+SM1a8AdcwFgJcOWMEhZQmvJGCNEaRIpqtFUlLsZOy0X16K
|
||||
sSrVHnwN081SJXit1gBrDMBR7OO1jgJgawpgUUyKZFpCKtp/r2ETBA61k7IhXKJNTDsWm6VWLbZz
|
||||
p4FPQpJxV6rqukmo6WakASDaDFS/YFvBk5CQ9NeVCqkdVzg4bLfuWr9MuLYkJCR6GNwIweNuyhoF
|
||||
qE+0tKgWoZhSWjoBsalR6hkkJIMBr9BwCDaLlhK8CFIkJEMALx84GEPKNaAN9TvPMYPd2NKDwH5q
|
||||
LuLIjL1zXItcK1yrSMXn+am87+J8cF6hBYffR78t9qG9SlPdXinfi6LPvQhUh4JUh3y/YGQVEDeE
|
||||
l/juKsPyJgX2Fd83bWJehkmgVhCFwH5LldYQCApigLW4dg20DcfnLQd2VaM5xbFtxbk7XOvy8TED
|
||||
qxFTd3GN5QCQqli2V812gME5mgG1YQMa6Be1hOtsQj1zDuCJ6wsVRT3qcO/j+kN+qoGlms0rGQ7m
|
||||
CA5jptP+usB5DLCcAvYIXmMekIpNHPUceDXDQRenVYunc2I50JE7Buft4MEH19MwrHfL1kqQ2quT
|
||||
dnvB+bopaDWlftHBoEk4h/Y+oX5j2h/K/QJWkNk8xXmKJrN7BsDqKhJBvWfzLGYfiwFgVYixYFy0
|
||||
HgJYFrDqgRYMspbDIMtbtFcrUHu1TCySfgArQL9oGl5bMwlYUBfb85f6DSwVvIzhEJMN3w0MLGd4
|
||||
OaZIFD1hlfe0ElRaCwCspsvgh/JdLcWmocURur3qWQOWwwPDGciGwHIBZ8fWPU0TWEZwcIFUQGCp
|
||||
suyD1i8AsFopDYaCB7B8nupVz3oXfQZXiuedMmA5Wqg6bXi2acXj3JWsAiv1FTg9gZVK/XyAJfz8
|
||||
lAaC1mowAFY/taapd6kf7dUHYNVSOFfFA1g+D7AWAWt4gNUytFjyCDYmv2sPKLCantZVDbVXwfB3
|
||||
HZ/AtKO7lI8JERgFtaW0gqqB+xjrnqVotU4K2hOwBhhYhh2zrHEZ2q4dxRJYdRgQNccnbfR70wHf
|
||||
0VyzU3tZPBy84y0W7lMl5vd1F3ffMCheDQCshpTy0A7hbhOwBgNYRZ8AtGGsKOcJrIJHbKWFLQjT
|
||||
maaU2quc9sCymEBpekBZ5zLXXaxuC2CVHfsDAWtILKyWi7VgAZ2ix2/rnnG3gqsF4dhelbTaK7CL
|
||||
H5u+Ydi2ec8YX8ERWPV+PQgIWBmJYSkGVPRaSSWAheYLrKJHALrlY+lY5GIVobxU28uwPqazo6XQ
|
||||
FpKlhVZ1BFbBoz9UCVhDBqwUXEovYCWcu+3hthT7EaRNE1gWSZUNz3Y1yVPr2JZhAKyO5zlTBdYE
|
||||
ASs7wFK80FuHDtbqI7CaI+4JkakCS2qvcqj2MjhfeyRAEqVvQrArfAx+00yrP4QAVpOA1T9gQaym
|
||||
ArMxvpnOrsDqDAqwpJefGwFeb3IBVm0kTGJqMYRrZeLeOfymRsAiYKlAVR+ZguztADNufQfWVLZX
|
||||
gPSQWqCyTIBVd5j99QIOAWuaAcvz1YdpByxw9zpT1V4ay65jmN6Rm0JgVW2vk4BFwLKBVX0kvSzj
|
||||
oQNWinC3BVbDJ72DgEXAGuZ3CTsQKylDx86lPEuYSWBZvEsYLSQXpL086lG16AsELAJWphNHTV2K
|
||||
Wh/SGjIHLJv2UrlgoYDlm81OwCJgDSqwTGaXKn3Kw8oisCo+AzogsJojHtnsnrlcIdIauqGBQ8Ca
|
||||
HsBKmoJv9zFxNIvAavWrvRziZ2XHPhFigUMCFgErLLAMV2pIyn0pTzNg+a5nVfIBVqhs9oQ6ekHZ
|
||||
8EHYHDZgVT2z3UMCYUXG67faZSuyEPEKw9nFoQBWoPaqeQLLdQXQDrRXNWmNc8N7mkuIi6bxLmF2
|
||||
gSUN5FHYRHRiioGwAna2yWW0fsa7AaUFLIsAdIWAZWx56NaLqgZMnejEbTNmaAWWPK3uwlACywMO
|
||||
LkAwgpRB/cazWD/HAdjwnAmKXTVhSIHVChB7anvAzkXLDg+ipsd9aacBnMwByxJepkAwhgDsJ5g3
|
||||
rF8B9hscn6r6pQSsuKeh7TrwlSEAlmn8qOjR1jqXKc0loXMObmHZEcrlaQcsA3jpgGADqWjz0qZi
|
||||
U9eCBbxs6jeWFqQcYg3y2t3RWll1RxekMA2C7tG1Vj3bS/WuXZrAKjpMyET5ZkVwI02us+2xpvtw
|
||||
AAtZQNGOygX03ZgFpGz2BbTa1FWCq6p+XjGplGaEUtsRZkCB1ZjC9mr0C1gpxMxMYl/TC1ieoPPd
|
||||
FxDvi5gfhGtPeYuvpFjJIAJrKnf6qfYTWCk80OppAmeogQWuXhkA001JW+BOFjIOLd9OWTaYri8P
|
||||
Qx6W4XlN2qvq0F46NyvaRaYkuaKRqxbtFtRyAFaozVTrBv2QgKWB1ZIAq5ra5EmVMgys3Ij7FuCl
|
||||
BPB1hvDlZ9dB3JFBFFP/TpzbpIBUxeHVm2hhxqbFWum+0Kob1o2AlWKe15SmIEwRtGwsh6Zi+yzc
|
||||
sdueW9X7Aqvsce6OQXvVA7dXJ6G9amApFQPOEtcN3w3MOcS02klJqpbxQV9gVdgwSQB4DRSkNJ24
|
||||
prj5bSlTOulp3ICBkDMYBBVpQ0yshYTfFzS/rRicX3fukmF75aX26ni0V8PWWurjg62isbg6cC1l
|
||||
h7J197NqcD+9fp81GDVtAuIArxsNkkBtUiT+P7DPSEiGQADYUbwsRy0SFliqgLgJvOQk0Amwwkxe
|
||||
28lJgf2O7mVqEhISEh2wnOBlcJ6cyewj3REvmc31QK5voKYgmY7A6rpmsUPZqmz4LgErFbmG6wau
|
||||
W+HfedQkwWQG13O5rgE9m5ok+8AygpcEqVaI9bVIjOXHXLuSvoeaJJj8GddXpLYVD4UjqFkGB1hT
|
||||
tiAgibGsJGClJl9CbSv0FGoWAhYBi4CVRZnDdZPUti+z3fFCEgIWCQErk7If11u4fp2agoBFwCJg
|
||||
kZAQsAZQ5nO9nO0OoovZvse43s71Aq4HOAJLTI6czvVUrkdynRmgngdx/dMArpG4JtGHjuU6bAmW
|
||||
oo1EmsnrPMqYy/VdcN/28ShHTBzMI2ANN7D+iu2exv4t12Wa40a53s11jOtZmuMENO7kegdX/IrL
|
||||
/mx3asILrDfAG+kTXBdaAOtvuK7l2pE+38ZVLFf8dw7tIcq7B+q4GeI6W7g+znU517dw3dugHDHw
|
||||
ylx/zfVZqNME1xe53g9toxvkZ3A9h+vBXPeCzy7m+ijUZ5zrvvD5J7neB/UuG9TtMK5LoT2jd+xE
|
||||
WkMVyl/N9TLN74/i+hVoE9H2T3N9jutd0DdmGcbMLoW+Jx5aO6C918F1HGvYzlWpP70C7bwT6nSd
|
||||
1EZ/lIPnHFDm2kQqPqvB//NwXDH6joCVLfmBNNB3wUBRyf3ScaJTjyiOEZ/9r3TcF6XvZsGA36mB
|
||||
VVfqeGcaAEuU/7KmHHE9N1hYQT/huj2hbuL77yaUdQiAfVdC3e6MsbgE1F+F40R7/gW0HS7v43D8
|
||||
i9JnG8Ha1Mld0vF/gM9yAI2udF4se8EDqYXucxed/46E8x8HD0hdX9iZ0M7HAOiS+tJ6+QELIKpy
|
||||
bYNWJTh1xd9wXF3+m4CVHbkYWSfLYwbgk9Ix68BVwnIydJAuWAGyhXWbooM+A+f7BXR0+TtRp7cl
|
||||
AGtnwt8RGC4zaId7DDq/fJ4vayyH31uU9ZDCfV0qff8S11tjri0C1n3o808ngFmu35gErO3ooYHl
|
||||
eAOgR78dA4say59D3zBtn9sUD8f5YLWaliEs2wXI0vqjdYX+7gDEcgArAlYGgXUkuBfRzX1Rccz7
|
||||
EVCEVXOu4rgrpCfvBohNRE/UHagT3Q6xD9lNeRgd83gCsOSnurBKTgIXB8PvNa6Ha9rgVMVA/B3X
|
||||
xVy/wPU/wV3Bg3Kewg28QwHMu+EcZ8BA3oaOuVYDrC2Kc++Ez6NBuAhZPPdrrvU0qX3ENXzYEFiH
|
||||
Iis76gfiem8GV162dkXi6T8pYNlSPJiEZftutju7/lfIknxVESL4maI9xO++yXbPcD7JJifBdsFl
|
||||
TQJWZFXVAF5NAlY2g+6y9STAkkffq5IK64py5Cf9g1Js5CH027jtsMSgaKO6HJ8ArE0KGB2rAKRu
|
||||
qn4MHbtSEYeZCxYhPk6WhWiwCVBeqDjfpZLLFw3aA2KA9Qfkji6DwS0f/1aweuXBGRd8riNL+WBD
|
||||
YC1ClriwcE5Ex1yPjmmhIPo1CCTbwSrH8m1kUa6VytkXrE45Xnk+ineNQPxvAt2Lv04AlnAPWwCt
|
||||
OgEru8Bagp5WH9bEr2QLZCayLmTL5ibJnXwZxUaO0dTlixowrlRYL+8ziM1FlmNcMPgFdP3HxRz3
|
||||
dmkgiXOvQt//Cp1zVUzgeCbEAeVjL4sBljzg4t7vmwUxIRmA5yiOez2yYtdI3yUB62H03eWK8l+H
|
||||
Hk6bJSDtB1aYfE1LYq5nNopP7YJZxMhal/vZU4bxWdHv3msArAoAq0TAyi6wFqIn479J3x2k6Ghd
|
||||
iIPI75qdInWyrWxPysEV6HfPxgTsI1mABs46DbB+l+DqTiBr7a0xx76EgPXOmONmwGzpVxXHFFBs
|
||||
5hWYTdO5obI1dl8CsFYk3MOvo+OXxwSqn5eO+awhsI5Cv9scE5+KZjfljPnPS/1jK3L1kmb/5Ov5
|
||||
AXw+itrtSQCxSgQk/4XrJyB2JruEBaHo7zzEr4ryZwSs7MnhyBV7nu2ZSh+VgrTbpEEpOvSHUPxK
|
||||
DhRHs18/QR3vFxCwj9N3INB0ARQqYH0l4bqeQ8cvijluHB13vxR/M5V/VABdJ/OQ5bmR7UlzWKqw
|
||||
JJPyi96F2u1Z1pvTdKkU61qHJjV0wKqgGNk9mnrMRX1pKXx+C7qm3yRczwmoPmsk6G5GbXMp88vf
|
||||
ypYQsIzkURRbiAbs51CQVY6V3Cr9/t6YGNXjikDtRo2+hOIX2yAgrwJW0lLGOAC+2CCuI7uQPwdX
|
||||
bQHTJ7QKaSgmDD6o0UuQRbYVYngqYD0tPUCYxi2cQLE9HGNaJX0/jr7TAesbhuCP5GRot49wfTN8
|
||||
9iAq496E9rkStc8mcKVnIgsugtYasMLOAotwNgFruIH1NTR4TofPH5A+F0mQjyCXbBYM5rXS51+K
|
||||
Cei7qADW0THASno151Z0/PdjjjsMYkRxdRDtsR4GnQgcz0+YcHDVY2OAdZvhPfwvjQWKU1OWWQDr
|
||||
TnQ/XHaBesKzbTZBeELIlxOO7YCFK/rLeQNnfRGwjORs9ERbAjMyckBaDNZr0WzU0chtFIP7A1K5
|
||||
L3p21B2SO4SBdWrCNWHLoKE59iLFkztON4AFMDMmKO2qb4sB1rcM7+H5bHLKxNPSd/8gxRi3wD0z
|
||||
Bdbd6NpH+wSsg6XyHjD83S7og0cTsIYLWIdCB49u9CNgwWyQOsxJAKPNUqf+KJj/cpLeG6Vy26gD
|
||||
fQbiE6aa0wTdkyysGwwC0bKcCYDeZTAQXkUxPOz6boRBaqq/kcC8VDODqJP9UWB7o+SSLUEza4dY
|
||||
AKsZAFjPKGJ8bQt9QOHm3YwmTHT6HNPn4mUKWPUMAWs8w031axQ4v5ZNTgTdF2C0Cc3ejKHBMEMq
|
||||
839Qx/m8R/0wsE5POB7Hpr5neB6R+/VVcHm3aQAm7mU0i4QTIm/2uE4MrEssfvtLNnnGU/z2T+Ba
|
||||
cHa7i0u4Faw1W8H94MxAfTYH3sESiMNOsPhXfpazQRFY1ngR7MQ81cAah513Chlvpn9FwfFHFbM6
|
||||
M5B5vxZZZt9AZeJljW8NCKxywvE/Qsdf43je46Bt1ikGwUVwzO3o85/2CVjyTGAXXFXRf6O0BPHd
|
||||
hZbAwjltVyfUQUxSLET35xFUxg0p9eE54AksY71vPKyD7wcuCG8LLxdgDQqkZDkDmdhyIFp+d+6b
|
||||
yO2IYl+iw+MVEq5WWCU6mQ1PSzF1fhMKcGNgfTuhLOymvduzfeaiyQW5Dtcx8xwx2YU7LDCwjlDE
|
||||
DT/H9mT+i0F7pCWwPsV6U1Pi5E1gZa+HvvSjGKD/h8G1HKhwXW3kBIV1/HY2yGIIL1NgDSKkZDmA
|
||||
TU4QjF6jWI8C6adJkNqBXBC8+oBoCzkpdTtDL6Iq4khyJ/uZBlhrNeW8mU3OcxLXcFAMhH4Mg1wM
|
||||
sKMS2ujqGDfzJOSK7Ig5nwzmh+CcImfqqkDAYqw3RUWOH/03U68VpgNWCYUBhJU2SxP436KYMLiQ
|
||||
9b6QrEsgFvG8NdA+T0kupEjYfQz6yG8T2mEG682xG55FHzXw0gFr0CGF5UGF2/MMsgT2Z+o37p+P
|
||||
KRO7A+uZOhFyHnRO+djrNcDapoljLWe9yaAq+Rg6Trxeo1uHaTFT53bNYb0rCCzWlPNJNvm9ujUB
|
||||
gYVfb5JdxJs0saA4YOWQZbmdxS9DhFMgzpTurfy6jZi0+KCFWxw9uNqojI8ntAV2C49nwygAr6sA
|
||||
SBhYY7ADdHEIL/0aBYhUT7LHmHopEJWcznpXQxCD+yPQkXNgweEZHzFjd6gGWNG09QL0VD0XWXW6
|
||||
dw4LyEoUbvC1McceznpXWrgoxlWOrCzVYoRFNnk2T+iVAYG1AFnKslVzogOwGOtNEXmM9c66XYLa
|
||||
XZQhL1J4N+tNIlY9cD6K2kfcv7NiHhjPQXuq5Ep0TZuY/RsMJBmXU1jvqzGqGa/Pst4lPj6gKfen
|
||||
TL2ulEiR+D3rXYjvNcXTc6XCXY0G4kpwz1ax3sXlxOB6vaZu9yog+CTA+xywJm5gva/6dBBQD0QD
|
||||
NrIyxJT8h8DaaCjaVwykfQICazbrfbk6SiXYxxFYf6mAtZj5uwWgvIJNXmdL/B6vyzWf9S77IsB0
|
||||
B5Tx93D/8DGPSy7ofLZnzTX5PtwJ/eU0cEvvUjwU7qXhPXyyD4pXiM5wgeK4k5GJjwcvljkKMOiS
|
||||
/aoK10wG1jJFh4xbITQp/6agCKab5GF9RlHW2QpoJWVlnxAw6B7J1xTn+nfN8SYL+H1M4WJFuXX4
|
||||
M9W7gnuB1bPTon1eUFhFCy3LiMCYp+E9nPIQeiqrBvy+yO1Ya1j29Sw5KznOfVspuVri7ft/Vjz1
|
||||
8fuAJxjWa36MGxX3utB1msDzBcwsa35DjEuEgXWxwz18L+vdZ/B8zfH7sd4JFJXcyPTLUgvr9p6E
|
||||
h8QXEu6bbFnFxYYvYuYrlz7F1OtukQyJCBiI4PsvwdJhmoEppq1/yPasV2QiYpaqAgNTTJGLd+C+
|
||||
Y1CGeL2iyXYvFyJbR6sArC/BIBUzQ3XmtoPK5eDqbGeTZyt3wFNaBH+PMShHDNifQxmvIijvhDaL
|
||||
i6ecA4NxA0PrOFmIsJi+C23xBLhMSe/UidQVsQGFSCC+IuaYvWHwi+TTdaDRDKvIx7vaME4kZnEf
|
||||
hrbZhSy7DliIcwzaOLrGLQqLStxH8V7rm2hIk2RNhLXzRhZmG60Z0MmLXP8WBugRHuWJcspsd3qA
|
||||
yWzyCFzLkZ7nTVNEHQ+BazvZ8Lri7ts7wZV+D9vzKpFtGW+BuogyFjAKrpOQkJCQkJCQkJCQkJCE
|
||||
l/8Df+8XDp+g0JUAAAAASUVORK5CYII=
|
||||
IMAGE;
|
||||
|
||||
|
||||
header('Content-type: image/png');
|
||||
echo base64_decode($data);
|
||||
exit;
|
||||
}
|
||||
elseif (isset($_GET['background']))
|
||||
{
|
||||
$data = <<<IMAGE
|
||||
R0lGODlhMAEeAeYAAP///8ni6cTf5+72+PD3+c3k6+nz9ufy9ev099Pn7bnZ48bg6LfY4uHv8/r8
|
||||
/f3+/v7//7bX4cjh6fj7/Mvj6vz9/rva4+z19/X6+/f7/Pn8/fb6+7jZ4vv9/bra473b5Lzb5LXX
|
||||
4b7c5b/c5e31+NTo7tvs8dfq7/H3+bjY4tnq79Hm7c/l69nr8PL4+t7t8sDd5cLe5uPw9Nvr8Mri
|
||||
6fP4+tLn7er099Hm7O/2+dDm7OTw9OXx9Nbp7tbp7+Lv8+Du8szj6sXg57bY4d3s8djq7+jz9tzs
|
||||
8cPe58fh6M7k68Pf5+by9fz+/sDd5vT5+vT5+97t8bbY4trr8P7+/v7+/+Pw8+Xx9dXo7sHe5vH4
|
||||
+fP5+sHd5t/u8s/l7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5
|
||||
BAAAAAAALAAAAAAwAR4BAAf/gCGCg4SFhoeIiYqLjI2Oj5CRkpOUlZaXmJmam5ydnp+goaKNEaWm
|
||||
p6ipqqusra6vsLGys7S1tre4ubq7vL2+v8DBwsPExbBDyMnKy8zNzs/Q0dLT1NXW19jZ2tvc3d7K
|
||||
UuHi4+Tl5ufo6err7O3u7/Dx8vP09fb34wz6+/z9/v8AAwocSLCgwYMIEypcyLChw4cQI0qcSLGi
|
||||
xYsYM2osmKKjx48gQ4ocSbKkyZMoU6pcybKly5cwY8qc+ZGDzZs4c+rcybOnz59AgwodSrSo0aNI
|
||||
kypdyrSp06dQo0qdSrWq1aAKsmrdyrWr169gw4odS7as2bNo06pdy7at27dw/+PKnUu3rt27ePOS
|
||||
9cC3r9+/gAMLHky4sOHDiBMrXsy4sePHkCNLnky5suXLmDNr3sz5sIXPoEOLHk26tOnTqFOrXs26
|
||||
tevXsGPLnk27tu3buHPr3s27t+/fqkEIH068uPHjyJMrX868ufPn0KNLn069uvXr2LNr3869u/fv
|
||||
4MOLb/6hvPnz6NOrX8++vfv38OPLn0+/vv37+PPr38+/v///AAYo4IAEFgifCAgmqOCCDDbo4IMQ
|
||||
RijhhBRWaOGFGGao4YYcdujhhyCGKOKIJJZo4okoTjjCiiy26OKLMMYo44w01mjjjTjmqOOOPPbo
|
||||
449ABinkkEQWaeSRSCap5P+SNsLg5JNQRinllFRWaeWVWGap5ZZcdunll2CGKeaYZELpxJlopqnm
|
||||
mmy26eabcMYp55x01mnnnXjmqeeefPaZJheABirooIQWauihiCaq6KKMNuroo5BGKumklFZqqaBZ
|
||||
ZKrpppx26umnoIYq6qiklmrqqaimquqqrLbq6qubxiDrrLTWauutuOaq66689urrr8AGK+ywxBZr
|
||||
7LHI0orEssw26+yz0EYr7bTUVmvttdhmq+223Hbr7bfghtvsEuSWa+656Kar7rrstuvuu/DGK++8
|
||||
9NZr77345quvuQL06++/AAcs8MAEF2zwwQgnrPDCDDfs8MMQRyzxxBRXbPH/xRhnrPHGHHeMsBAg
|
||||
hyzyyCSXbPLJKKes8sost+zyyzDHLPPMNNdss8gL5Kzzzjz37PPPQAct9NBEF2300UgnrfTSTDft
|
||||
9NNQRy311FRXbfXVWGdNdBJcd+3112CHLfbYZJdt9tlop6322my37fbbcMctt9cS1G333Xjnrffe
|
||||
fPft99+ABy744IQXbvjhiCeu+OKMN+7445BHLvnklFcOeACYZ6755px37vnnoIcu+uikl2766ain
|
||||
rvrqrLfu+uuwxy777LTXbvvtuI9Ow+689+7778AHL/zwxBdv/PHIJ6/88sw37/zz0EffOwXUV2/9
|
||||
9dhnr/323Hfv/ffghy/+//jkl2/++einr/767Lfv/vvwxy///PR/H8T9+Oev//789+///wAMoAAH
|
||||
SMACGvCACEygAhfIwAbmrwAQjKAEJ0jBClrwghjMoAY3yMEOevCDIAyhCEdIwhKa8IQoTKEKV8jC
|
||||
FrrwhTDcoBJmSMMa2vCGOMyhDnfIwx768IdADKIQh0jEIhrxiEhMYg1ZwMQmOvGJUIyiFKdIxSpa
|
||||
8YpYzKIWt8jFLnrxi2AMoxid6IUymvGMaEyjGtfIxja68Y1wjKMc50jHOtrxjnjMox73eEYd+PGP
|
||||
gAykIAdJyEIa8pCITKQiF8nIRjrykZCMpCQnSUlA4uCSmMykJjfJyU568v+ToAylKEdJylKa8pSo
|
||||
TKUqV8nKVmZyBbCMpSxnScta2vKWuMylLnfJy1768pfADKYwh0nMYhpTljZIpjKXycxmOvOZ0Iym
|
||||
NKdJzWpa85rYzKY2t8nNbnrzm8tMgDjHSc5ymvOc6EynOtfJzna6853wjKc850nPetrznvjMpz73
|
||||
yc9++vOfAA2oQNtZgoIa9KAITahCF8rQhjr0oRCNqEQnStGKWvSiGM2oRjd6UCx49KMgDalIR0rS
|
||||
kpr0pChNqUpXytKWuvSlMI2pTGdKU5D24KY4zalOd8rTnvr0p0ANqlCHStSiGvWoSE2qUpfK1Kbm
|
||||
1AdQjapUp0rVqlr1qlj/zapWt8rVrnr1q2ANq1jHStaymlWqJ0irWtfK1ra69a1wjatc50rXutr1
|
||||
rnjNq173yte++vWvay2CYAdL2MIa9rCITaxiF8vYxjr2sZCNrGQnS9nKWvaymCWsCjbL2c569rOg
|
||||
Da1oR0va0pr2tKhNrWpXy9rWuva1sI1tZ1tA29ra9ra4za1ud8vb3vr2t8ANrnCHS9ziGve4yE2u
|
||||
cm07heY697nQja50p0vd6lr3utjNrna3y93ueve74A2veMf73BmY97zoTa9618ve9rr3vfCNr3zn
|
||||
S9/62ve++M2vfvfLX/Sa4L8ADrCAB0zgAhv4wAhOsIIXzOAGO/jBEI6w/4QnTOEKB/gIGM6whjfM
|
||||
4Q57+MMgDrGIR0ziEpv4xChOsYpXzOIWu1jDRIixjGdM4xrb+MY4zrGOd8zjHvv4x0AOspCHTOQi
|
||||
G/nIM46CkpfM5CY7+clQjrKUp0zlKlv5yljOspa3zOUue/nLYGbyC8ZM5jKb+cxoTrOa18zmNrv5
|
||||
zXCOs5znTOc62/nOeM5zmbvA5z77+c+ADrSgB03oQhv60IhOtKIXzehGO/rRkI60pP0MhEpb+tKY
|
||||
zrSmN83pTnv606AOtahHTepSm/rUqE61qld96Qa4+tWwjrWsZ03rWtv61rjOta53zete+/rXwA62
|
||||
sIdN7GIb+9jITrayl//N7GY7O9c/iLa0p03talv72tjOtra3ze1ue/vb4A63uMdN7nKb+9zTtoK6
|
||||
183udrv73fCOt7znTe962/ve+M63vvfN7377+98AZ7cMBk7wghv84AhPuMIXzvCGO/zhEI+4xCdO
|
||||
8Ypb/OIYz3jBd8Dxjnv84yAPuchHTvKSm/zkKE+5ylfO8pa7/OUwj7nMPc6Dmtv85jjPuc53zvOe
|
||||
+/znQA+60IdO9KIb/ehIT7rSl37zKzj96VCPutSnTvWqW/3qWM+61rfO9a57/etgD7vYx052qDPh
|
||||
7GhPu9rXzva2u/3tcI+73OdO97rb/e54z7ve9873vqf9AIAPvOAHT/j/whv+8IhPvOIXz/jGO/7x
|
||||
kI+85CdP+cpb/vKYz7zmN8/5znv+86BfvBFGT/rSm/70qE+96lfP+ta7/vWwj73sZ0/72tv+9rjP
|
||||
fekNwPve+/73wA++8IdP/OIb//jIT77yl8/85jv/+dCPvvSnT/3qW//62M++9rfP/ePf4PvgD7/4
|
||||
x0/+8pv//OhPv/rXz/72u//98I+//OdP//qHHwH4z7/+98///vv//wAYgAI4gARYgAZ4gAiYgAq4
|
||||
gAzYgA74gBAYgRI4gRRYgRZ4gRg4gBewgRzYgR74gSAYgiI4giRYgiZ4giiYgiq4gizYgi74gjAY
|
||||
gzI4gzRYgzZ4gziY/4M6uIMmSAI++INAGIRCOIREWIRGeIRImIRKuIRM2IRO+IRQGIVSOIVUCIQD
|
||||
cIVYmIVauIVc2IVe+IVgGIZiOIZkWIZmeIZomIZquIZs2IZu+IZwGIdyOId0WId2eIdimAN6uId8
|
||||
2Id++IeAGIiCOIiEWIiGeIiImIiKuIiM2IiO+IiQyIcEMImUWImWeImYmImauImc2Ime+ImgGIqi
|
||||
OIqkWIqmeIqomIqquIqs2Iqu+IqwGIuyOIueiAK2eIu4mIu6uIu82Iu++IvAGIzCOIzEWIzGeIzI
|
||||
mIzKuIzMiIta8IzQGI3SOI3UWI3WeI3YmI3auI3c2I3e+I3gGI7iOP+O5FiO0egC6JiO6riO7NiO
|
||||
7viO8BiP8jiP9FiP9niP+JiP+riP/NiP/qiONRCQAjmQBFmQBnmQCJmQCrmQDNmQDvmQEBmREjmR
|
||||
FFmRFnmRA7kFGrmRHNmRHvmRIBmSIjmSJFmSJnmSKJmSKrmSLNmSLvmSMMmRTzCTNFmTNnmTOJmT
|
||||
OrmTPNmTPvmTQBmUQjmURFmURnmUSJmUNQkFTNmUTvmUUBmVUjmVVFmVVnmVWJmVWrmVXNmVXvmV
|
||||
YBmWYumUGFCWZnmWaJmWarmWbNmWbvmWcBmXcjmXdFmXdnmXeJmXermXfNmXfvmXgBmYgjmYhFmY
|
||||
cLkBiJmYirmYjNn/mI75mJAZmZI5mZRZmZZ5mZiZmZq5mZzZmZ75maAZmqI5mqRZmqZ5mqg5mRmw
|
||||
mqzZmq75mrAZm7I5m7RZm7Z5m7iZm7q5m7zZm775m8AZnMI5nMRZnMZ5nMiZnMq5nLY5Ac75nNAZ
|
||||
ndI5ndRZndZ5ndiZndq5ndzZnd75neAZnuI5nuRZnuZ5nuiZnuq5nuzZnu6ZnRoQn/I5n/RZn/Z5
|
||||
n/iZn/q5n/zZn/75nwAaoAI6oARaoAZ6oAiaoAq6oAzaoA76oBAaofzpABRaoRZ6oRiaoRq6oRza
|
||||
oR76oSAaoiI6oiRaoiZ6oiiaoiq6oizaoi76ojAaozI6ozT6oR1w/6M4mqM6uqM82qM++qNAGqRC
|
||||
OqREWqRGeqRImqRKuqRM2qRO+qRQGqVSOqVUWqVWeqVCWgFauqVc2qVe+qVgGqZiOqZkWqZmeqZo
|
||||
mqZquqZs2qZu+qZwGqdyOqd0Wqd2eqd4mqd6WqZN0Kd++qeAGqiCOqiEWqiGeqiImqiKuqiM2qiO
|
||||
+qiQGqmSOql/+gCWeqmYmqmauqmc2qme+qmgGqqiOqqkWqqmeqqomqqquqqs2qqu+qqwGquyOqu0
|
||||
Wqu2GqpUkKu6uqu82qu++qvAGqzCOqzEWqzGeqzImqzKuqzM2qzO+qy7WgXSOq3UWq3Weq3Ymq3a
|
||||
uq3c2q3e+q3gGv+u4jqu5Fqu5nqu6EqtELCu7Nqu7vqu8Bqv8jqv9Fqv9nqv+Jqv+rqv/Nqv/vqv
|
||||
ABuwAjuwBFuwBnuwCJuwCruw9goADvuwEBuxEjuxFFuxFnuxGJuxGruxHNuxHvuxIBuyIjuyJFuy
|
||||
JnuyKJuyKruyLNuyLvuyMBuzMjuzNFuzNnuzOJuzOruzPNuzPvuzQBu0Qju0RFu0Rnu0SJu0Sru0
|
||||
TNu0Tvu0UBu1Uju1VFu1Vnu1WJu1Wru1XNu1Xvu1YBu2Yju2ZFu2Znu2aJu2aru2bNu2bvu2cBu3
|
||||
cju3dFu3dnu3eJu3eru3fNu3fvu3gBu4gju4hFu4hnu4iJu4irv/uIzbuI77uJAbuZI7uZRbuZZ7
|
||||
uZibuZq7uZzbuZ77uaAbuqI7uqRbuqZ7uqibuqq7uqzbuq77urAbu7I7u7Rbu7Z7u7ibu7q7u7zb
|
||||
u777u8AbvMI7vMRbvMZ7vMibvMq7vMzbvM77vNAbvdI7vdRbvdZ7vdibvdq7vdzbvd77veAbvuI7
|
||||
vuRbvuZ7vuibvuq7vuzbvu77vvAbv/I7v/Rbv/Z7v/ibv/q7v/zbv/77vwAcwAI8wARcwAZ8wAic
|
||||
wAq8wAzcwA78wBAcwRI8wRRcwRZ8wRicwRq8wRzcwR78wSAcwiI8wiRcwiZ8wiicwiq8wizcwi78
|
||||
wjAcwzI8wzRcFcM2fMM4nMM6vMM83MM+/MNArLmBAAA7
|
||||
IMAGE;
|
||||
|
||||
header('Content-type: image/gif');
|
||||
echo base64_decode($data);
|
||||
exit;
|
||||
}
|
||||
elseif (isset($_GET['loader']))
|
||||
{
|
||||
$data = <<<IMAGE
|
||||
R0lGODlhEAALAPQAAP///wBmzNro9tDi9Ory+gZpzQBmzC6B1YKz5WCf3rrV8CJ60kqS2oq452Sh
|
||||
377X8SZ80wRozE6U2+bv+djn9vT4/DiH19zp9/L2+7bS76DF68re8+70+gAAAAAAAAAAACH/C05F
|
||||
VFNDQVBFMi4wAwEAAAAh/hpDcmVhdGVkIHdpdGggYWpheGxvYWQuaW5mbwAh+QQJCwAAACwAAAAA
|
||||
EAALAAAFLSAgjmRpnqSgCuLKAq5AEIM4zDVw03ve27ifDgfkEYe04kDIDC5zrtYKRa2WQgAh+QQJ
|
||||
CwAAACwAAAAAEAALAAAFJGBhGAVgnqhpHIeRvsDawqns0qeN5+y967tYLyicBYE7EYkYAgAh+QQJ
|
||||
CwAAACwAAAAAEAALAAAFNiAgjothLOOIJAkiGgxjpGKiKMkbz7SN6zIawJcDwIK9W/HISxGBzdHT
|
||||
uBNOmcJVCyoUlk7CEAAh+QQJCwAAACwAAAAAEAALAAAFNSAgjqQIRRFUAo3jNGIkSdHqPI8Tz3V5
|
||||
5zuaDacDyIQ+YrBH+hWPzJFzOQQaeavWi7oqnVIhACH5BAkLAAAALAAAAAAQAAsAAAUyICCOZGme
|
||||
1rJY5kRRk7hI0mJSVUXJtF3iOl7tltsBZsNfUegjAY3I5sgFY55KqdX1GgIAIfkECQsAAAAsAAAA
|
||||
ABAACwAABTcgII5kaZ4kcV2EqLJipmnZhWGXaOOitm2aXQ4g7P2Ct2ER4AMul00kj5g0Al8tADY2
|
||||
y6C+4FIIACH5BAkLAAAALAAAAAAQAAsAAAUvICCOZGme5ERRk6iy7qpyHCVStA3gNa/7txxwlwv2
|
||||
isSacYUc+l4tADQGQ1mvpBAAIfkECQsAAAAsAAAAABAACwAABS8gII5kaZ7kRFGTqLLuqnIcJVK0
|
||||
DeA1r/u3HHCXC/aKxJpxhRz6Xi0ANAZDWa+kEAA7AAAAAAAAAAAA
|
||||
IMAGE;
|
||||
header('Content-type: image/gif');
|
||||
echo base64_decode($data);
|
||||
exit;
|
||||
}
|
||||
elseif (isset($_GET['ssl_check']))
|
||||
{
|
||||
header('Content-type: text/plain; charset=utf-8');
|
||||
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, 'https://email.us-east-1.amazonaws.com');
|
||||
curl_setopt($ch, CURLOPT_FRESH_CONNECT, true);
|
||||
curl_setopt($ch, CURLOPT_HEADER, false);
|
||||
curl_setopt($ch, CURLOPT_NOBODY, true);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 5184000);
|
||||
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 120);
|
||||
curl_setopt($ch, CURLOPT_NOSIGNAL, true);
|
||||
curl_setopt($ch, CURLOPT_USERAGENT, 'aws-sdk-php/compat-www');
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
|
||||
curl_setopt($ch, CURLOPT_VERBOSE, true);
|
||||
|
||||
curl_exec($ch);
|
||||
echo (curl_getinfo($ch, CURLINFO_SSL_VERIFYRESULT) === 0) ? 'false' : 'true';
|
||||
curl_close($ch);
|
||||
|
||||
exit;
|
||||
}
|
||||
|
||||
// Include the compatibility test logic
|
||||
require dirname(__FILE__) . DIRECTORY_SEPARATOR . 'sdk_compatibility.inc.php';
|
||||
|
||||
header('Content-type: text/html; charset=UTF-8');
|
||||
|
||||
?><!DOCTYPE html>
|
||||
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>AWS SDK for PHP: Environment Compatibility Test</title>
|
||||
<meta name="ROBOTS" content="NOINDEX, NOFOLLOW, NOARCHIVE" />
|
||||
|
||||
<script type="text/javascript" charset="utf-8">
|
||||
/*!
|
||||
* Reqwest! A x-browser general purpose XHR connection manager
|
||||
* copyright Dustin Diaz 2011
|
||||
* https://github.com/ded/reqwest
|
||||
* license MIT
|
||||
*/
|
||||
!function(window){function serial(a){var b=a.name;if(a.disabled||!b)return"";b=enc(b);switch(a.tagName.toLowerCase()){case"input":switch(a.type){case"reset":case"button":case"image":case"file":return"";case"checkbox":case"radio":return a.checked?b+"="+(a.value?enc(a.value):!0)+"&":"";default:return b+"="+(a.value?enc(a.value):"")+"&"}break;case"textarea":return b+"="+enc(a.value)+"&";case"select":return b+"="+enc(a.options[a.selectedIndex].value)+"&"}return""}function enc(a){return encodeURIComponent(a)}function reqwest(a,b){return new Reqwest(a,b)}function init(o,fn){function error(a){o.error&&o.error(a),complete(a)}function success(resp){o.timeout&&clearTimeout(self.timeout)&&(self.timeout=null);var r=resp.responseText;if(r)switch(type){case"json":resp=window.JSON?window.JSON.parse(r):eval("("+r+")");break;case"js":resp=eval(r);break;case"html":resp=r}fn(resp),o.success&&o.success(resp),complete(resp)}function complete(a){o.complete&&o.complete(a)}this.url=typeof o=="string"?o:o.url,this.timeout=null;var type=o.type||setType(this.url),self=this;fn=fn||function(){},o.timeout&&(this.timeout=setTimeout(function(){self.abort(),error()},o.timeout)),this.request=getRequest(o,success,error)}function setType(a){return/\.json$/.test(a)?"json":/\.jsonp$/.test(a)?"jsonp":/\.js$/.test(a)?"js":/\.html?$/.test(a)?"html":/\.xml$/.test(a)?"xml":"js"}function Reqwest(a,b){this.o=a,this.fn=b,init.apply(this,arguments)}function getRequest(a,b,c){if(a.type!="jsonp"){var f=xhr();f.open(a.method||"GET",typeof a=="string"?a:a.url,!0),setHeaders(f,a),f.onreadystatechange=readyState(f,b,c),a.before&&a.before(f),f.send(a.data||null);return f}var d=doc.createElement("script");window[getCallbackName(a)]=generalCallback,d.type="text/javascript",d.src=a.url,d.async=!0;var e=function(){a.success&&a.success(lastValue),lastValue=undefined,head.removeChild(d)};d.onload=e,d.onreadystatechange=function(){/^loaded|complete$/.test(d.readyState)&&e()},head.appendChild(d)}function generalCallback(a){lastValue=a}function getCallbackName(a){var b=a.jsonpCallback||"callback";if(a.url.slice(-(b.length+2))==b+"=?"){var c="reqwest_"+uniqid++;a.url=a.url.substr(0,a.url.length-1)+c;return c}var d=new RegExp(b+"=([\\w]+)");return a.url.match(d)[1]}function setHeaders(a,b){var c=b.headers||{};c.Accept=c.Accept||"text/javascript, text/html, application/xml, text/xml, */*",b.crossOrigin||(c["X-Requested-With"]=c["X-Requested-With"]||"XMLHttpRequest");if(b.data){c["Content-type"]=c["Content-type"]||"application/x-www-form-urlencoded";for(var d in c)c.hasOwnProperty(d)&&a.setRequestHeader(d,c[d],!1)}}function readyState(a,b,c){return function(){a&&a.readyState==4&&(twoHundo.test(a.status)?b(a):c(a))}}var v=window.v;!v&&typeof require!="undefined"&&(v=require("valentine"));var twoHundo=/^20\d$/,doc=document,byTag="getElementsByTagName",head=doc[byTag]("head")[0],xhr="XMLHttpRequest"in window?function(){return new XMLHttpRequest}:function(){return new ActiveXObject("Microsoft.XMLHTTP")},uniqid=0,lastValue;Reqwest.prototype={abort:function(){this.request.abort()},retry:function(){init.call(this,this.o,this.fn)}},reqwest.serialize=function(a){var b=a[byTag]("input"),c=a[byTag]("select"),d=a[byTag]("textarea");return(v(b).chain().toArray().map(serial).value().join("")+v(c).chain().toArray().map(serial).value().join("")+v(d).chain().toArray().map(serial).value().join("")).replace(/&$/,"")},reqwest.serializeArray=function(a){for(var b=this.serialize(a).split("&"),c=0,d=b.length,e=[],f;c<d;c++)b[c]&&(f=b[c].split("="))&&e.push({name:f[0],value:f[1]});return e};var old=window.reqwest;reqwest.noConflict=function(){window.reqwest=old;return this},window.reqwest=reqwest}(this)
|
||||
</script>
|
||||
|
||||
<style type="text/css">
|
||||
body {
|
||||
font:14px/1.4em "Helvetica Neue", Helvetica, "Lucida Grande", Roboto, "Droid Sans", Ubuntu, Verdana, Arial, Clean, Sans, sans-serif;
|
||||
letter-spacing:0px;
|
||||
color:#333;
|
||||
margin:0;
|
||||
padding:0;
|
||||
background:#fff url(<?php echo pathinfo(__FILE__, PATHINFO_BASENAME); ?>?background) repeat-x top left;
|
||||
}
|
||||
|
||||
div#site {
|
||||
width:650px;
|
||||
margin:20px auto 0 auto;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #326EA1;
|
||||
text-decoration: underline;
|
||||
padding: 1px 2px;
|
||||
-webkit-transition: background-color 0.15s;
|
||||
-webkit-transition: color 0.15s;
|
||||
-moz-transition: background-color 0.15s;
|
||||
-moz-transition: color 0.15s;
|
||||
transition: background-color 0.15s;
|
||||
transition: color 0.15s;
|
||||
-webkit-border-radius: 2px;
|
||||
-moz-border-radius: 2px;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
a:hover, a.hover {
|
||||
color: #fff;
|
||||
background-color: #333;
|
||||
text-decoration: none;
|
||||
padding: 1px 2px;
|
||||
}
|
||||
|
||||
p {
|
||||
margin:0;
|
||||
padding:5px 0;
|
||||
}
|
||||
|
||||
em {
|
||||
font-style:normal;
|
||||
background-color:#ffc;
|
||||
}
|
||||
|
||||
ul, ol {
|
||||
margin:10px 0 10px 20px;
|
||||
padding:0 0 0 15px;
|
||||
}
|
||||
|
||||
ul li, ol li {
|
||||
margin:0 0 4px 0;
|
||||
padding:0 0 0 3px;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size:18px;
|
||||
padding:0;
|
||||
margin:0 0 10px 0;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size:16px;
|
||||
padding:0;
|
||||
margin:20px 0 5px 0;
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size:14px;
|
||||
padding:0;
|
||||
margin:15px 0 5px 0;
|
||||
}
|
||||
|
||||
pre, code {
|
||||
font-family: "Panic Sans", "Bitstream Vera Sans Mono", Monaco, Consolas, "Andale Mono", monospace;
|
||||
background-color: #F0F0F0;
|
||||
border-radius: 3px 3px 3px 3px;
|
||||
padding: 0 3px;
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
em strong {
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
table.chart {
|
||||
border-collapse:collapse;
|
||||
}
|
||||
|
||||
table.chart th {
|
||||
background-color:#eee;
|
||||
padding:2px 3px;
|
||||
border:1px solid #fff;
|
||||
}
|
||||
|
||||
table.chart td {
|
||||
text-align:center;
|
||||
padding:2px 3px;
|
||||
border:1px solid #eee;
|
||||
}
|
||||
|
||||
table.chart tr.enabled td {
|
||||
/* Leave this alone */
|
||||
}
|
||||
|
||||
table.chart tr.disabled td,
|
||||
table.chart tr.disabled td a {
|
||||
color:#999;
|
||||
font-style:italic;
|
||||
}
|
||||
|
||||
table.chart tr.disabled td a {
|
||||
text-decoration:underline;
|
||||
}
|
||||
|
||||
div.chunk {
|
||||
margin:0;
|
||||
padding:10px;
|
||||
border-bottom:1px solid #ccc;
|
||||
}
|
||||
|
||||
div.important {
|
||||
background-color:#ffc;
|
||||
}
|
||||
|
||||
div.ok {
|
||||
background-color:#cfc;
|
||||
}
|
||||
|
||||
div.error {
|
||||
background-color:#fcc;
|
||||
}
|
||||
|
||||
div.important h3 {
|
||||
margin: 7px 0 5px 0;
|
||||
}
|
||||
|
||||
.footnote,
|
||||
.footnote a {
|
||||
font:12px/1.4em "Helvetica Neue", Helvetica, "Lucida Grande", Verdana, Arial, Clean, Sans, sans-serif;
|
||||
color:#aaa;
|
||||
}
|
||||
|
||||
.footnote em {
|
||||
background-color:transparent;
|
||||
font-style:italic;
|
||||
}
|
||||
</style>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div id="site">
|
||||
<div id="content">
|
||||
|
||||
<div class="chunk">
|
||||
<h2 style="text-align:center;"><img src="<?php echo pathinfo(__FILE__, PATHINFO_BASENAME); ?>?logopng" alt="SDK Compatibility Test" title="SDK Compatibility Test" /></h2>
|
||||
|
||||
<h3>Minimum Requirements</h3>
|
||||
<table cellpadding="0" cellspacing="0" border="0" width="100%" class="chart">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Test</th>
|
||||
<th>Should Be</th>
|
||||
<th>What You Have</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr class="<?php echo ($php_ok) ? 'enabled' : 'disabled'; ?>">
|
||||
<td>PHP</td>
|
||||
<td>5.2 or newer</td>
|
||||
<td><?php echo phpversion(); ?></td>
|
||||
</tr>
|
||||
<tr class="<?php echo ($curl_ok) ? 'enabled' : 'disabled'; ?>">
|
||||
<td><a href="http://php.net/curl">cURL</a></td>
|
||||
<td>7.15.0 or newer, with SSL</td>
|
||||
<td><?php echo ($curl_ok) ? ($curl_version['version'] . ' (' . $curl_version['ssl_version'] . ')') : ($curl_version['version'] . (in_array('https', $curl_version['protocols'], true) ? ' (with ' . $curl_version['ssl_version'] . ')' : ' (without SSL)')); ?></td>
|
||||
</tr>
|
||||
<tr class="<?php echo ($simplexml_ok) ? 'enabled' : 'disabled'; ?>">
|
||||
<td><a href="http://php.net/simplexml">SimpleXML</a></td>
|
||||
<td>Enabled</td>
|
||||
<td><?php echo ($simplexml_ok) ? 'Enabled' : 'Disabled'; ?></td>
|
||||
</tr>
|
||||
<tr class="<?php echo ($dom_ok) ? 'enabled' : 'disabled'; ?>">
|
||||
<td><a href="http://php.net/dom">DOM</a></td>
|
||||
<td>Enabled</td>
|
||||
<td><?php echo ($dom_ok) ? 'Enabled' : 'Disabled'; ?></td>
|
||||
</tr>
|
||||
<tr class="<?php echo ($spl_ok) ? 'enabled' : 'disabled'; ?>">
|
||||
<td><a href="http://php.net/spl">SPL</a></td>
|
||||
<td>Enabled</td>
|
||||
<td><?php echo ($spl_ok) ? 'Enabled' : 'Disabled'; ?></td>
|
||||
</tr>
|
||||
<tr class="<?php echo ($json_ok) ? 'enabled' : 'disabled'; ?>">
|
||||
<td><a href="http://php.net/json">JSON</a></td>
|
||||
<td>Enabled</td>
|
||||
<td><?php echo ($json_ok) ? 'Enabled' : 'Disabled'; ?></td>
|
||||
</tr>
|
||||
<tr class="<?php echo ($pcre_ok) ? 'enabled' : 'disabled'; ?>">
|
||||
<td><a href="http://php.net/pcre">PCRE</a></td>
|
||||
<td>Enabled</td>
|
||||
<td><?php echo ($pcre_ok) ? 'Enabled' : 'Disabled'; ?></td>
|
||||
</tr>
|
||||
<tr class="<?php echo ($file_ok) ? 'enabled' : 'disabled'; ?>">
|
||||
<td>File System <a href="http://php.net/file_get_contents">Read</a>/<a href="http://php.net/file_put_contents">Write</a></td>
|
||||
<td>Enabled</td>
|
||||
<td><?php echo ($file_ok) ? 'Enabled' : 'Disabled'; ?></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<h3>Optional Extensions</h3>
|
||||
<table cellpadding="0" cellspacing="0" border="0" width="100%" class="chart">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Test</th>
|
||||
<th>Would Like To Be</th>
|
||||
<th>What You Have</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr class="<?php echo ($openssl_ok) ? 'enabled' : 'disabled'; ?>">
|
||||
<td><a href="http://php.net/openssl">OpenSSL</a></td>
|
||||
<td>Enabled</td>
|
||||
<td><?php echo ($openssl_ok) ? 'Enabled' : 'Disabled'; ?></td>
|
||||
</tr>
|
||||
<tr class="<?php echo ($zlib_ok) ? 'enabled' : 'disabled'; ?>">
|
||||
<td><a href="http://php.net/zlib">Zlib</a></td>
|
||||
<td>Enabled</td>
|
||||
<td><?php echo ($zlib_ok) ? 'Enabled' : 'Disabled'; ?></td>
|
||||
</tr>
|
||||
<tr class="<?php echo ($apc_ok) ? 'enabled' : 'disabled'; ?>">
|
||||
<td><a href="http://php.net/apc">APC</a></td>
|
||||
<td>Enabled</td>
|
||||
<td><?php echo ($apc_ok) ? 'Enabled' : 'Disabled'; ?></td>
|
||||
</tr>
|
||||
<tr class="<?php echo ($xcache_ok) ? 'enabled' : 'disabled'; ?>">
|
||||
<td><a href="http://xcache.lighttpd.net">XCache</a></td>
|
||||
<td>Enabled</td>
|
||||
<td><?php echo ($xcache_ok) ? 'Enabled' : 'Disabled'; ?></td>
|
||||
</tr>
|
||||
<tr class="<?php echo ($memcache_ok) ? 'enabled' : 'disabled'; ?>">
|
||||
<td><a href="http://php.net/memcache">Memcache</a></td>
|
||||
<td>Enabled</td>
|
||||
<td><?php echo ($memcache_ok) ? 'Enabled' : 'Disabled'; ?></td>
|
||||
</tr>
|
||||
<tr class="<?php echo ($memcached_ok) ? 'enabled' : 'disabled'; ?>">
|
||||
<td><a href="http://php.net/memcached">Memcached</a></td>
|
||||
<td>Enabled</td>
|
||||
<td><?php echo ($memcached_ok) ? 'Enabled' : 'Disabled'; ?></td>
|
||||
</tr>
|
||||
<tr class="<?php echo ($pdo_ok) ? 'enabled' : 'disabled'; ?>">
|
||||
<td><a href="http://php.net/pdo">PDO</a></td>
|
||||
<td>Enabled</td>
|
||||
<td><?php echo ($pdo_ok) ? 'Enabled' : 'Disabled'; ?></td>
|
||||
</tr>
|
||||
<tr class="<?php echo ($pdo_sqlite_ok) ? 'enabled' : 'disabled'; ?>">
|
||||
<td><a href="http://php.net/pdo-sqlite">PDO-SQLite</a></td>
|
||||
<td>Enabled</td>
|
||||
<td><?php echo ($pdo_sqlite_ok) ? 'Enabled' : 'Disabled'; ?></td>
|
||||
</tr>
|
||||
<tr class="<?php echo ($sqlite2_ok) ? 'enabled' : 'disabled'; ?>">
|
||||
<td><a href="http://php.net/sqlite">SQLite 2</a></td>
|
||||
<td>Enabled</td>
|
||||
<td><?php echo ($sqlite2_ok) ? 'Enabled' : 'Disabled'; ?></td>
|
||||
</tr>
|
||||
<tr class="<?php echo ($sqlite3_ok) ? 'enabled' : 'disabled'; ?>">
|
||||
<td><a href="http://php.net/sqlite3">SQLite 3</a></td>
|
||||
<td>Enabled</td>
|
||||
<td><?php echo ($sqlite3_ok) ? 'Enabled' : 'Disabled'; ?></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<h3>Settings for php.ini</h3>
|
||||
<table cellpadding="0" cellspacing="0" border="0" width="100%" class="chart">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Test</th>
|
||||
<th>Would Like To Be</th>
|
||||
<th>What You Have</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr class="<?php echo (!$ini_open_basedir) ? 'enabled' : 'disabled'; ?>">
|
||||
<td><a href="http://php.net/open_basedir">open_basedir</a></td>
|
||||
<td>off</td>
|
||||
<td><?php echo ($ini_open_basedir) ? 'on' : 'off'; ?></td>
|
||||
</tr>
|
||||
<tr class="<?php echo (!$ini_safe_mode) ? 'enabled' : 'disabled'; ?>">
|
||||
<td><a href="http://php.net/safe_mode">safe_mode</a></td>
|
||||
<td>off</td>
|
||||
<td><?php echo ($ini_safe_mode) ? 'on' : 'off'; ?></td>
|
||||
</tr>
|
||||
<tr class="<?php echo ($ini_zend_enable_gc) ? 'enabled' : 'disabled'; ?>">
|
||||
<td><a href="http://php.net/zend.enable_gc">zend.enable_gc</a></td>
|
||||
<td>on</td>
|
||||
<td><?php echo ($ini_zend_enable_gc) ? 'on' : 'off'; ?></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<h3>Other</h3>
|
||||
<table cellpadding="0" cellspacing="0" border="0" width="100%" class="chart">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Test</th>
|
||||
<th>Would Like To Be</th>
|
||||
<th>What You Have</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr class="<?php echo ($int64_ok) ? 'enabled' : 'disabled'; ?>">
|
||||
<td><a href="https://aws.amazon.com/amis/4158">Architecture</a></td>
|
||||
<td>64-bit</td>
|
||||
<td><?php echo ($int64_ok) ? '64-bit' : '32-bit'; ?><?php if (is_windows()): ?>
|
||||
(<a href="#win64">why?</a>)
|
||||
<?php endif; ?></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<br>
|
||||
</div>
|
||||
|
||||
<?php if ($compatiblity == REQUIREMENTS_ALL_MET): ?>
|
||||
<div class="chunk important ok">
|
||||
<h3>Bottom Line: Yes, you can!</h3>
|
||||
<p>Your PHP environment is ready to go, and can take advantage of all possible features!</p>
|
||||
</div>
|
||||
<div class="chunk">
|
||||
<h3>What's Next?</h3>
|
||||
<p>You can download the latest version of the <a href="http://aws.amazon.com/sdkforphp"><strong>AWS SDK for PHP</strong></a> and install it by <a href="http://aws.amazon.com/articles/4261">following the instructions</a>. Also, check out our library of <a href="http://aws.amazon.com/articles/4262">screencasts and tutorials</a>.</p>
|
||||
<p>Take the time to read <a href="http://aws.amazon.com/articles/4261">"Getting Started"</a> to make sure you're prepared to use the AWS SDK for PHP. No seriously, read it.</p>
|
||||
</div>
|
||||
<?php elseif ($compatiblity == REQUIREMENTS_MIN_MET): ?>
|
||||
<div class="chunk important ok">
|
||||
<h3>Bottom Line: Yes, you can!</h3>
|
||||
<p>Your PHP environment is ready to go! <i>There are a couple of minor features that you won't be able to take advantage of, but nothing that's a show-stopper.</i></p>
|
||||
</div>
|
||||
<div class="chunk">
|
||||
<h3>What's Next?</h3>
|
||||
<p>You can download the latest version of the <a href="http://aws.amazon.com/sdkforphp"><strong>AWS SDK for PHP</strong></a> and install it by <a href="http://aws.amazon.com/articles/4261">following the instructions</a>. Also, check out our library of <a href="http://aws.amazon.com/articles/4262">screencasts and tutorials</a>.</p>
|
||||
<p>Take the time to read <a href="http://aws.amazon.com/articles/4261">"Getting Started"</a> to make sure you're prepared to use the AWS SDK for PHP. No seriously, read it.</p>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div class="chunk important error">
|
||||
<h3>Bottom Line: We're sorry…</h3>
|
||||
<p>Your PHP environment does not support the minimum requirements for the <strong>AWS SDK for PHP</strong>.</p>
|
||||
</div>
|
||||
<div class="chunk">
|
||||
<h3>What's Next?</h3>
|
||||
<p>If you're using a shared hosting plan, it may be a good idea to contact your web host and ask them to install a more recent version of PHP and relevant extensions.</p>
|
||||
<p>If you have control over your PHP environment, we recommended that you upgrade your PHP environment. Check out the "Set Up Your Environment" section of the <a href="http://aws.amazon.com/articles/4261">Getting Started Guide</a> for more information.</p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($compatiblity >= REQUIREMENTS_MIN_MET): ?>
|
||||
<div class="chunk">
|
||||
<h3>Recommended settings for config.inc.php</h3>
|
||||
<p>Based on your particular server configuration, the following settings are recommended.</p>
|
||||
<br>
|
||||
<table cellpadding="0" cellspacing="0" border="0" width="100%" class="chart">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Configuration Setting</th>
|
||||
<th>Recommended Value</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><code>default_cache_config</code></td>
|
||||
<?php if ($apc_ok): ?>
|
||||
<td><code>apc</code></td>
|
||||
<?php elseif ($xcache_ok): ?>
|
||||
<td><code>xcache</code></td>
|
||||
<?php elseif ($file_ok): ?>
|
||||
<td>Any valid, server-writable file system path</td>
|
||||
<?php endif; ?>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>certificate_authority</code></td>
|
||||
<?php if (is_windows()): ?>
|
||||
<td id="ssl_check"><code>true</code></td>
|
||||
<?php else: ?>
|
||||
<td id="ssl_check"><img src="<?php echo pathinfo(__FILE__, PATHINFO_BASENAME); ?>?loader" alt="Loading..."></td>
|
||||
<?php endif; ?>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<br>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="chunk">
|
||||
<h3>Give me the details!</h3>
|
||||
<?php if ($compatiblity >= REQUIREMENTS_MIN_MET): ?>
|
||||
<ol>
|
||||
<li><em>Your environment meets the minimum requirements for using the <strong>AWS SDK for PHP</strong>!</em></li>
|
||||
|
||||
<?php if (version_compare(PHP_VERSION, '5.3.0') < 0): ?>
|
||||
<li>You're still running <strong>PHP <?php echo PHP_VERSION; ?></strong>. The PHP 5.2 family is no longer supported by the PHP team, and future versions of the AWS SDK for PHP will <i>require</i> PHP 5.3 or newer.</li>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($openssl_ok): ?>
|
||||
<li>The <a href="http://php.net/openssl">OpenSSL</a> extension is installed. This will allow you to use <a href="http://docs.amazonwebservices.com/AmazonCloudFront/latest/DeveloperGuide/PrivateContent.html">CloudFront Private URLs</a> and decrypt Microsoft® Windows® instance passwords.</li>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($zlib_ok): ?>
|
||||
<li>The <a href="http://php.net/zlib">Zlib</a> extension is installed. The SDK will request gzipped data whenever possible.</li>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (!$int64_ok): ?>
|
||||
<li>You're running on a <strong>32-bit</strong> system. This means that PHP does not correctly handle files larger than 2GB (this is a <a href="http://www.google.com/search?q=php+2gb+32-bit">well-known PHP issue</a>). For more information, please see: <a href="http://docs.php.net/manual/en/function.filesize.php#refsect1-function.filesize-returnvalues">PHP filesize: Return values</a>.</li>
|
||||
<?php if (is_windows()): ?>
|
||||
<li id="win64"><em>Note that PHP on Microsoft® Windows® <a href="http://j.mp/php64win">does not support 64-bit integers at all</a>, even if both the hardware and PHP are 64-bit.</em></li>
|
||||
<?php endif; ?>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($ini_open_basedir || $ini_safe_mode): ?>
|
||||
<li>You have <a href="http://php.net/open_basedir">open_basedir</a> or <a href="http://php.net/safe_mode">safe_mode</a> enabled in your <code>php.ini</code> file. Sometimes PHP behaves strangely when these settings are enabled. Disable them if you can.</li>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (!$ini_zend_enable_gc): ?>
|
||||
<li>The PHP garbage collector (available in PHP 5.3+) is not enabled in your <code>php.ini</code> file. Enabling <a href="http://php.net/zend.enable_gc">zend.enable_gc</a> will provide better memory management in the PHP core.</li>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php
|
||||
$storage_types = array();
|
||||
if ($file_ok) { $storage_types[] = '<a href="http://php.net/file_put_contents">The file system</a>'; }
|
||||
if ($apc_ok) { $storage_types[] = '<a href="http://php.net/apc">APC</a>'; }
|
||||
if ($xcache_ok) { $storage_types[] = '<a href="http://xcache.lighttpd.net">XCache</a>'; }
|
||||
if ($sqlite_ok && $sqlite3_ok) { $storage_types[] = '<a href="http://php.net/sqlite3">SQLite 3</a>'; }
|
||||
elseif ($sqlite_ok && $sqlite2_ok) { $storage_types[] = '<a href="http://php.net/sqlite">SQLite 2</a>'; }
|
||||
if ($memcached_ok) { $storage_types[] = '<a href="http://php.net/memcached">Memcached</a>'; }
|
||||
elseif ($memcache_ok) { $storage_types[] = '<a href="http://php.net/memcache">Memcache</a>'; }
|
||||
?>
|
||||
<li>Storage types available for response caching: <?php echo implode(', ', $storage_types); ?></li>
|
||||
</ol>
|
||||
|
||||
<?php if (!$openssl_ok && !$zlib_ok): ?>
|
||||
<p class="footnote"><strong>NOTE:</strong> You're missing the <a href="http://php.net/openssl">OpenSSL</a> extension, which means that you won't be able to take advantage of <a href="http://docs.amazonwebservices.com/AmazonCloudFront/latest/DeveloperGuide/PrivateContent.html">CloudFront Private URLs</a> or decrypt Microsoft® Windows® instance passwords. You're also missing the <a href="http://php.net/zlib">Zlib</a> extension, which means that the SDK will be unable to request gzipped data from Amazon and you won't be able to take advantage of compression with the <i>response caching</i> feature.</p>
|
||||
<?php elseif (!$zlib_ok): ?>
|
||||
<p class="footnote"><strong>NOTE:</strong> You're missing the <a href="http://php.net/zlib">Zlib</a> extension, which means that the SDK will be unable to request gzipped data from Amazon and you won't be able to take advantage of compression with the <i>response caching</i> feature.</p>
|
||||
<?php elseif (!$openssl_ok): ?>
|
||||
<p class="footnote"><strong>NOTE:</strong> You're missing the <a href="http://php.net/openssl">OpenSSL</a> extension, which means that you won't be able to take advantage of <a href="http://docs.amazonwebservices.com/AmazonCloudFront/latest/DeveloperGuide/PrivateContent.html">CloudFront Private URLs</a> or decrypt Microsoft® Windows® instance passwords.</p>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php else: ?>
|
||||
<ol>
|
||||
<?php if (!$php_ok): ?>
|
||||
<li><strong>PHP:</strong> You are running an unsupported version of PHP.</li>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (!$curl_ok): ?>
|
||||
<li><strong>cURL:</strong> The <a href="http://php.net/curl">cURL</a> extension is not available. Without cURL, the SDK cannot connect to — or authenticate with — Amazon's services.</li>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (!$simplexml_ok): ?>
|
||||
<li><strong>SimpleXML:</strong> The <a href="http://php.net/simplexml">SimpleXML</a> extension is not available. Without SimpleXML, the SDK cannot parse the XML responses from Amazon's services.</li>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (!$dom_ok): ?>
|
||||
<li><strong>DOM:</strong> The <a href="http://php.net/dom">DOM</a> extension is not available. Without DOM, the SDK cannot transliterate JSON responses from Amazon's services into the common SimpleXML-based pattern used throughout the SDK.</li>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (!$spl_ok): ?>
|
||||
<li><strong>SPL:</strong> <a href="http://php.net/spl">Standard PHP Library</a> support is not available. Without SPL support, the SDK cannot autoload the required PHP classes.</li>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (!$json_ok): ?>
|
||||
<li><strong>JSON:</strong> <a href="http://php.net/json">JSON</a> support is not available. AWS leverages JSON heavily in many of its services.</li>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (!$pcre_ok): ?>
|
||||
<li><strong>PCRE:</strong> Your PHP installation doesn't support Perl-Compatible Regular Expressions (PCRE). Without PCRE, the SDK cannot do any filtering via regular expressions.</li>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (!$file_ok): ?>
|
||||
<li><strong>File System Read/Write:</strong> The <a href="http://php.net/file_get_contents">file_get_contents()</a> and/or <a href="http://php.net/file_put_contents">file_put_contents()</a> functions have been disabled. Without them, the SDK cannot read from, or write to, the file system.</li>
|
||||
<?php endif; ?>
|
||||
</ol>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<div class="chunk">
|
||||
<p class="footnote"><strong>NOTE</strong>: Passing this test does not guarantee that the AWS SDK for PHP will run on your web server — it only ensures that the requirements have been addressed.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<?php if (!is_windows()): ?>
|
||||
<script type="text/javascript" charset="utf-8">
|
||||
reqwest('<?php echo pathinfo(__FILE__, PATHINFO_BASENAME); ?>?ssl_check', function(resp) {
|
||||
$sslCheck = document.getElementById('ssl_check');
|
||||
$sslCheck.innerHTML = '';
|
||||
$sslCheck.innerHTML = '<code>' + resp + '</code>';
|
||||
});
|
||||
</script>
|
||||
<?php endif; ?>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,186 @@
|
|||
#! /usr/bin/env php
|
||||
<?php
|
||||
|
||||
//Prevent script from being called via browser
|
||||
if (PHP_SAPI !== 'cli')
|
||||
{
|
||||
die('ERROR: You may only run the compatibility test from the command line.');
|
||||
}
|
||||
|
||||
// Include the compatibility test logic
|
||||
require dirname(__FILE__) . DIRECTORY_SEPARATOR . 'sdk_compatibility.inc.php';
|
||||
|
||||
// CLI display
|
||||
function success($s = 'Yes')
|
||||
{
|
||||
return is_windows() ? $s : "\033[1;37m\033[42m " . $s . " \033[0m";
|
||||
}
|
||||
|
||||
function info($s = 'Info')
|
||||
{
|
||||
return is_windows() ? $s : "\033[1;37m\033[44m " . $s . " \033[0m";
|
||||
}
|
||||
|
||||
function failure($s = 'No ')
|
||||
{
|
||||
return is_windows() ? $s : "\033[1;37m\033[41m " . $s . " \033[0m";
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
echo PHP_EOL;
|
||||
|
||||
echo info('AWS SDK for PHP') . PHP_EOL;
|
||||
echo 'PHP Environment Compatibility Test (CLI)' . PHP_EOL;
|
||||
echo '----------------------------------------' . PHP_EOL;
|
||||
echo PHP_EOL;
|
||||
|
||||
echo 'PHP 5.2 or newer............ ' . ($php_ok ? (success() . ' ' . phpversion()) : failure()) . PHP_EOL;
|
||||
echo '64-bit architecture......... ' . ($int64_ok ? success() : failure()) . (is_windows() ? ' (see note below)' : '') . PHP_EOL;
|
||||
echo 'cURL with SSL............... ' . ($curl_ok ? (success() . ' ' . $curl_version['version'] . ' (' . $curl_version['ssl_version'] . ')') : failure($curl_version['version'] . (in_array('https', $curl_version['protocols'], true) ? ' (with ' . $curl_version['ssl_version'] . ')' : ' (without SSL)'))) . PHP_EOL;
|
||||
echo 'Standard PHP Library........ ' . ($spl_ok ? success() : failure()) . PHP_EOL;
|
||||
echo 'SimpleXML................... ' . ($simplexml_ok ? success() : failure()) . PHP_EOL;
|
||||
echo 'DOM......................... ' . ($dom_ok ? success() : failure()) . PHP_EOL;
|
||||
echo 'JSON........................ ' . ($json_ok ? success() : failure()) . PHP_EOL;
|
||||
echo 'PCRE........................ ' . ($pcre_ok ? success() : failure()) . PHP_EOL;
|
||||
echo 'File system read/write...... ' . ($file_ok ? success() : failure()) . PHP_EOL;
|
||||
echo 'OpenSSL extension........... ' . ($openssl_ok ? success() : failure()) . PHP_EOL;
|
||||
echo 'Zlib........................ ' . ($zlib_ok ? success() : failure()) . PHP_EOL;
|
||||
echo 'APC......................... ' . ($apc_ok ? success() : failure()) . PHP_EOL;
|
||||
echo 'XCache...................... ' . ($xcache_ok ? success() : failure()) . PHP_EOL;
|
||||
echo 'Memcache.................... ' . ($memcache_ok ? success() : failure()) . PHP_EOL;
|
||||
echo 'Memcached................... ' . ($memcached_ok ? success() : failure()) . PHP_EOL;
|
||||
echo 'PDO......................... ' . ($pdo_ok ? success() : failure()) . PHP_EOL;
|
||||
echo 'SQLite 2.................... ' . ($sqlite2_ok ? success() : failure()) . PHP_EOL;
|
||||
echo 'SQLite 3.................... ' . ($sqlite3_ok ? success() : failure()) . PHP_EOL;
|
||||
echo 'PDO-SQLite driver........... ' . ($pdo_sqlite_ok ? success() : failure()) . PHP_EOL;
|
||||
echo 'open_basedir disabled....... ' . (!$ini_open_basedir ? success() : failure()) . PHP_EOL;
|
||||
echo 'safe_mode disabled.......... ' . (!$ini_safe_mode ? success() : failure()) . PHP_EOL;
|
||||
echo 'Garbage Collector enabled... ' . ($ini_zend_enable_gc ? success() : failure()) . PHP_EOL;
|
||||
|
||||
// Test SSL cert
|
||||
if (!is_windows())
|
||||
{
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, 'https://email.us-east-1.amazonaws.com');
|
||||
curl_setopt($ch, CURLOPT_FRESH_CONNECT, true);
|
||||
curl_setopt($ch, CURLOPT_HEADER, false);
|
||||
curl_setopt($ch, CURLOPT_NOBODY, true);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, false);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 5184000);
|
||||
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 120);
|
||||
curl_setopt($ch, CURLOPT_NOSIGNAL, true);
|
||||
curl_setopt($ch, CURLOPT_USERAGENT, 'aws-sdk-php/compat-cli');
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
|
||||
curl_setopt($ch, CURLOPT_VERBOSE, false);
|
||||
curl_exec($ch);
|
||||
$ssl_result = !(curl_getinfo($ch, CURLINFO_SSL_VERIFYRESULT) === 0);
|
||||
curl_close($ch);
|
||||
|
||||
echo 'Valid SSL certificate....... ' . ($ssl_result ? failure() : success()) . PHP_EOL;
|
||||
}
|
||||
else
|
||||
{
|
||||
$ssl_result = false;
|
||||
echo 'Valid SSL certificate....... ' . failure() . ' (will use the bundled certificate instead)' . PHP_EOL;
|
||||
}
|
||||
|
||||
echo PHP_EOL;
|
||||
|
||||
echo '----------------------------------------' . PHP_EOL;
|
||||
echo PHP_EOL;
|
||||
|
||||
if ($compatiblity >= REQUIREMENTS_MIN_MET)
|
||||
{
|
||||
echo success('Your environment meets the minimum requirements for using the AWS SDK for PHP!') . PHP_EOL . PHP_EOL;
|
||||
if (version_compare(PHP_VERSION, '5.3.0') < 0) { echo '* You\'re still running PHP ' . PHP_VERSION . '. The PHP 5.2 family is no longer supported' . PHP_EOL . ' by the PHP team, and future versions of the AWS SDK for PHP will *require*' . PHP_EOL . ' PHP 5.3 or newer.' . PHP_EOL . PHP_EOL; }
|
||||
if ($openssl_ok) { echo '* The OpenSSL extension is installed. This will allow you to use CloudFront' . PHP_EOL . ' Private URLs and decrypt Windows instance passwords.' . PHP_EOL . PHP_EOL; }
|
||||
if ($zlib_ok) { echo '* The Zlib extension is installed. The SDK will request gzipped data' . PHP_EOL . ' whenever possible.' . PHP_EOL . PHP_EOL; }
|
||||
if (!$int64_ok) { echo '* You\'re running on a 32-bit system. This means that PHP does not correctly' . PHP_EOL . ' handle files larger than 2GB (this is a well-known PHP issue).' . PHP_EOL . PHP_EOL; }
|
||||
if (!$int64_ok && is_windows()) { echo '* Note that PHP on Microsoft(R) Windows(R) does not support 64-bit integers' . PHP_EOL . ' at all, even if both the hardware and PHP are 64-bit. http://j.mp/php64win' . PHP_EOL . PHP_EOL; }
|
||||
|
||||
if ($ini_open_basedir || $ini_safe_mode) { echo '* You have open_basedir or safe_mode enabled in your php.ini file. Sometimes' . PHP_EOL . ' PHP behaves strangely when these settings are enabled. Disable them if you can.' . PHP_EOL . PHP_EOL; }
|
||||
if (!$ini_zend_enable_gc) { echo '* The PHP garbage collector (available in PHP 5.3+) is not enabled in your' . PHP_EOL . ' php.ini file. Enabling zend.enable_gc will provide better memory management' . PHP_EOL . ' in the PHP core.' . PHP_EOL . PHP_EOL; }
|
||||
|
||||
$storage_types = array();
|
||||
if ($file_ok) { $storage_types[] = 'The file system'; }
|
||||
if ($apc_ok) { $storage_types[] = 'APC'; }
|
||||
if ($xcache_ok) { $storage_types[] = 'XCache'; }
|
||||
if ($sqlite_ok && $sqlite3_ok) { $storage_types[] = 'SQLite 3'; }
|
||||
elseif ($sqlite_ok && $sqlite2_ok) { $storage_types[] = 'SQLite 2'; }
|
||||
if ($memcached_ok) { $storage_types[] = 'Memcached'; }
|
||||
elseif ($memcache_ok) { $storage_types[] = 'Memcache'; }
|
||||
echo '* Storage types available for response caching:' . PHP_EOL . ' ' . implode(', ', $storage_types) . PHP_EOL . PHP_EOL;
|
||||
|
||||
if (!$openssl_ok) { echo '* You\'re missing the OpenSSL extension, which means that you won\'t be able' . PHP_EOL . ' to take advantage of CloudFront Private URLs or Windows password decryption.' . PHP_EOL . PHP_EOL; }
|
||||
if (!$zlib_ok) { echo '* You\'re missing the Zlib extension, which means that the SDK will be unable' . PHP_EOL . ' to request gzipped data from Amazon and you won\'t be able to take advantage' . PHP_EOL . ' of compression with the response caching feature.' . PHP_EOL . PHP_EOL; }
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!$php_ok) { echo '* ' . failure('PHP:') . ' You are running an unsupported version of PHP.' . PHP_EOL . PHP_EOL; }
|
||||
if (!$curl_ok) { echo '* ' . failure('cURL:') . ' The cURL extension is not available. Without cURL, the SDK cannot' . PHP_EOL . ' connect to -- or authenticate with -- Amazon\'s services.' . PHP_EOL . PHP_EOL; }
|
||||
if (!$simplexml_ok) { echo '* ' . failure('SimpleXML:') . ': The SimpleXML extension is not available. Without SimpleXML,' . PHP_EOL . ' the SDK cannot parse the XML responses from Amazon\'s services.' . PHP_EOL . PHP_EOL; }
|
||||
if (!$dom_ok) { echo '* ' . failure('DOM:') . ': The DOM extension is not available. Without DOM, the SDK' . PHP_EOL . ' Without DOM, the SDK cannot transliterate JSON responses from Amazon\'s' . PHP_EOL . ' services into the common SimpleXML-based pattern used throughout the SDK.' . PHP_EOL . PHP_EOL; }
|
||||
if (!$spl_ok) { echo '* ' . failure('SPL:') . ' Standard PHP Library support is not available. Without SPL support,' . PHP_EOL . ' the SDK cannot autoload the required PHP classes.' . PHP_EOL . PHP_EOL; }
|
||||
if (!$json_ok) { echo '* ' . failure('JSON:') . ' JSON support is not available. AWS leverages JSON heavily in many' . PHP_EOL . ' of its services.' . PHP_EOL . PHP_EOL; }
|
||||
if (!$pcre_ok) { echo '* ' . failure('PCRE:') . ' Your PHP installation doesn\'t support Perl-Compatible Regular' . PHP_EOL . ' Expressions (PCRE). Without PCRE, the SDK cannot do any filtering via' . PHP_EOL . ' regular expressions.' . PHP_EOL . PHP_EOL; }
|
||||
if (!$file_ok) { echo '* ' . failure('File System Read/Write:') . ' The file_get_contents() and/or file_put_contents()' . PHP_EOL . ' functions have been disabled. Without them, the SDK cannot read from,' . PHP_EOL . ' or write to, the file system.' . PHP_EOL . PHP_EOL; }
|
||||
}
|
||||
|
||||
echo '----------------------------------------' . PHP_EOL;
|
||||
echo PHP_EOL;
|
||||
|
||||
if ($compatiblity === REQUIREMENTS_ALL_MET)
|
||||
{
|
||||
echo success('Bottom Line: Yes, you can!') . PHP_EOL;
|
||||
echo PHP_EOL;
|
||||
echo 'Your PHP environment is ready to go, and can take advantage of all possible features!' . PHP_EOL;
|
||||
|
||||
echo PHP_EOL;
|
||||
echo info('Recommended settings for config.inc.php') . PHP_EOL;
|
||||
echo PHP_EOL;
|
||||
|
||||
echo "CFCredentials::set(array(" . PHP_EOL;
|
||||
echo " '@default' => array(" . PHP_EOL;
|
||||
echo " 'key' => 'aws-key'," . PHP_EOL;
|
||||
echo " 'secret' => 'aws-secret'," . PHP_EOL;
|
||||
echo " 'default_cache_config' => ";
|
||||
if ($apc_ok) echo success('\'apc\'');
|
||||
elseif ($xcache_ok) echo success('\'xcache\'');
|
||||
elseif ($file_ok) echo success('\'/path/to/cache/folder\'');
|
||||
echo "," . PHP_EOL;
|
||||
echo " 'certificate_authority' => " . success($ssl_result ? 'true' : 'false') . PHP_EOL;
|
||||
echo " )" . PHP_EOL;
|
||||
echo "));" . PHP_EOL;
|
||||
}
|
||||
elseif ($compatiblity === REQUIREMENTS_MIN_MET)
|
||||
{
|
||||
echo success('Bottom Line: Yes, you can!') . PHP_EOL;
|
||||
echo PHP_EOL;
|
||||
echo 'Your PHP environment is ready to go! There are a couple of minor features that' . PHP_EOL . 'you won\'t be able to take advantage of, but nothing that\'s a show-stopper.' . PHP_EOL;
|
||||
|
||||
echo PHP_EOL;
|
||||
echo info('Recommended settings for config.inc.php') . PHP_EOL;
|
||||
echo PHP_EOL;
|
||||
|
||||
echo "CFCredentials::set(array(" . PHP_EOL;
|
||||
echo " '@default' => array(" . PHP_EOL;
|
||||
echo " 'key' => 'aws-key'," . PHP_EOL;
|
||||
echo " 'secret' => 'aws-secret'," . PHP_EOL;
|
||||
echo " 'default_cache_config' => ";
|
||||
if ($apc_ok) echo success('\'apc\'');
|
||||
elseif ($xcache_ok) echo success('\'xcache\'');
|
||||
elseif ($file_ok) echo success('\'/path/to/cache/folder\'');
|
||||
echo "," . PHP_EOL;
|
||||
echo " 'certificate_authority' => " . ($ssl_result ? 'false' : 'true') . PHP_EOL;
|
||||
echo " )" . PHP_EOL;
|
||||
echo "));" . PHP_EOL;
|
||||
}
|
||||
else
|
||||
{
|
||||
echo failure('Bottom Line: We\'re sorry...') . PHP_EOL;
|
||||
echo 'Your PHP environment does not support the minimum requirements for the ' . PHP_EOL . 'AWS SDK for PHP.' . PHP_EOL;
|
||||
}
|
||||
|
||||
echo PHP_EOL;
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,64 @@
|
|||
# Contributors
|
||||
|
||||
## AWS SDK for PHP Contributors
|
||||
|
||||
Contributions were provided under the Apache 2.0 License, as appropriate.
|
||||
|
||||
The following people have provided ideas, support and bug fixes:
|
||||
|
||||
* [arech8](http://developer.amazonwebservices.com/connect/profile.jspa?userID=154435) (bug fixes)
|
||||
* [Aizat Faiz](http://aizatto.com) (bug fixes)
|
||||
* [Ben Lumley](http://github.com/benlumley) (bug fixes)
|
||||
* [David Chan](http://www.chandeeland.org) (bug fixes)
|
||||
* [Eric Caron](http://www.ericcaron.com) (bug fixes)
|
||||
* [Jason Ardell](http://ardell.posterous.com/) (bug fixes)
|
||||
* [Jeremy Archuleta](http://code.google.com/u/jeremy.archuleta/) (bug fixes)
|
||||
* [Jimmy Berry](http://blog.boombatower.com/) (bug fixes, patches)
|
||||
* [Paul Voegler](mailto:voegler@gmx.de) (bug fixes, bug reports, patches)
|
||||
* [Peter Bowen](http://github.com/pzb) (feedback, bug reports)
|
||||
* [zoxa](https://github.com/zoxa) (bug fixes)
|
||||
|
||||
|
||||
## CloudFusion/CacheCore/RequestCore Contributors
|
||||
|
||||
Contributions were provided under the New BSD License, as appropriate.
|
||||
|
||||
The following people have provided ideas, support and bug fixes:
|
||||
|
||||
* [Aaron Collegeman](http://blog.aaroncollegeman.com) (bug fixes)
|
||||
* [Alex Schenkel](http://code.google.com/u/alex.schenkel/) (bug fixes)
|
||||
* [Andrzej Bednarczyk](http://kreo-consulting.com) (bug fixes)
|
||||
* [bprater](http://code.google.com/u/bprater/) (bug fixes)
|
||||
* [castoware](http://code.google.com/u/castoware/) (bug fixes)
|
||||
* [Chris Chen](http://github.com/chrischen) (bug fixes, patches, support)
|
||||
* [Chris Mytton](http://hecticjeff.net) (bug fixes)
|
||||
* [evgen.dm](http://code.google.com/u/evgen.dm/) (bug fixes)
|
||||
* [gafitescu](http://code.google.com/u/gafitescu/) (bug fixes)
|
||||
* [Gary Richardson](http://code.google.com/u/gary.richardson/) (bug fixes)
|
||||
* [Gil Hildebrand](http://squidoo.com) (bug fixes)
|
||||
* [Guilherme Blanco](http://blog.bisna.com) (bug fixes)
|
||||
* [hammjazz](http://code.google.com/u/hammjazz/) (bug fixes)
|
||||
* [HelloBunty](http://code.google.com/u/HelloBunty/) (bug fixes)
|
||||
* [inputrequired](http://code.google.com/u/inputrequired/) (bug fixes)
|
||||
* [Ivo Beckers](http://infopractica.nl) (bug fixes)
|
||||
* [Jason Litka](http://jasonlitka.com) (bug fixes, patches)
|
||||
* [Jeremy Archuleta](http://code.google.com/u/jeremy.archuleta/) (bug fixes)
|
||||
* [John Beales](http://johnbeales.com) (bug fixes)
|
||||
* [John Parker](http://code.google.com/u/john3parker/) (bug fixes)
|
||||
* [Jon Cianciullo](http://code.google.com/u/jon.cianciullo/) (bug fixes)
|
||||
* [kris0476](http://code.google.com/u/kris0476/) (bug fixes)
|
||||
* [Matt Terenzio](http://jour.nali.st/blog) (bug fixes, patches)
|
||||
* [Mike Jetter](http://mbjetter.com) (bug fixes)
|
||||
* [Morten Blinksbjerg Nielsen](http://mbn.dk) (bug fixes)
|
||||
* [nathell](http://code.google.com/u/nathell/) (bug fixes)
|
||||
* [nickgsuperstar](http://code.google.com/u/nickgsuperstar/) (bug fixes)
|
||||
* [ofpichon](http://code.google.com/u/ofpichon/) (bug fixes)
|
||||
* [Otavio Ferreira](http://otaviofff.me) (bug fixes)
|
||||
* [Paul Voegler](mailto:voegler@gmx.de) (bug fixes, bug reports, patches)
|
||||
* [Steve Brozosky](http://code.google.com/u/@UBZWSlJVBxhHXAN1/) (bug fixes)
|
||||
* [Steve Chu](http://stevechu.org) (bug fixes)
|
||||
* [tommusic](http://code.google.com/u/tommusic/) (bug fixes)
|
||||
* [Tyler Hall](http://clickontyler.com) (bug fixes)
|
||||
* [webcentrica.co.uk](http://code.google.com/u/@VhBQQldUBBBEXAF1/) (bug fixes)
|
||||
* [worden341](http://github.com/worden341) (bug fixes)
|
||||
* [yakkyjunk](http://code.google.com/u/yakkyjunk/) (bug fixes)
|
|
@ -0,0 +1,235 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
|
||||
<title>README</title>
|
||||
<style type="text/css" media="screen">
|
||||
body {
|
||||
font: 18px/1.5em 'Book Antiqua', 'Palatino Linotype', Palatino, 'Minion Pro', Cambria, Georgia, serif;
|
||||
padding: 50px 10%;
|
||||
max-width: 1000px;
|
||||
margin: 0 auto;
|
||||
color: #080000;
|
||||
background-color: #fbfbf9;
|
||||
}
|
||||
code {
|
||||
font: 13px/1.4em Monaco, monospace;
|
||||
background-color: #f3f3f3;
|
||||
color: #444;
|
||||
padding: 1px 2px;
|
||||
|
||||
border-radius: 2px;
|
||||
-webkit-border-radius: 2px;
|
||||
-moz-border-radius: 2px;
|
||||
}
|
||||
pre {
|
||||
border: 1px solid #ddd;
|
||||
border-left: 6px solid #c0c0c0;
|
||||
background-color: #f3f3f3;
|
||||
color: #444;
|
||||
font: 13px/1.4em Monaco, monospace;
|
||||
overflow: auto;
|
||||
|
||||
margin: 1em 0 1.5em 0;
|
||||
padding: 1em;
|
||||
text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5);
|
||||
|
||||
-webkit-border-top-right-radius: 5px;
|
||||
-webkit-border-bottom-right-radius: 5px;
|
||||
-moz-border-radius-topright: 5px;
|
||||
-moz-border-radius-bottomright: 5px;
|
||||
border-top-right-radius: 5px;
|
||||
border-bottom-right-radius: 5px;
|
||||
}
|
||||
pre code {
|
||||
font-family: inherit;
|
||||
font-size: inherit;
|
||||
background-color: inherit;
|
||||
color: inherit;
|
||||
padding: 0;
|
||||
|
||||
border-radius: none;
|
||||
-webkit-border-radius: none;
|
||||
-moz-border-radius: none;
|
||||
}
|
||||
a {
|
||||
color: #326EA1;
|
||||
text-decoration: underline;
|
||||
padding: 1px 2px;
|
||||
-webkit-transition: background-color 0.15s;
|
||||
-webkit-transition: color 0.15s;
|
||||
-moz-transition: background-color 0.15s;
|
||||
-moz-transition: color 0.15s;
|
||||
transition: background-color 0.15s;
|
||||
transition: color 0.15s;
|
||||
-webkit-border-radius: 2px;
|
||||
-moz-border-radius: 2px;
|
||||
border-radius: 2px;
|
||||
}
|
||||
a:hover, a.hover {
|
||||
color: #fff;
|
||||
background-color: #333;
|
||||
text-decoration: none;
|
||||
padding: 1px 2px;
|
||||
}
|
||||
a.active {
|
||||
font-weight: bold;
|
||||
}
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
padding: 0.8em 0 0.2em 0;
|
||||
margin: 0;
|
||||
}
|
||||
h1 {
|
||||
margin-top: 30px;
|
||||
padding: 15px 0 5px 5px;
|
||||
font-size: 2em;
|
||||
line-height: 1.3em;
|
||||
border-bottom: 3px solid #cdcdcc;
|
||||
}
|
||||
h2 {
|
||||
margin-top: 30px;
|
||||
padding: 15px 0 5px 5px;
|
||||
font-size: 1.5em;
|
||||
line-height: 1.3em;
|
||||
border-bottom: 1px solid #cdcdcc;
|
||||
}
|
||||
li {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
em, i {
|
||||
font-style: italic;
|
||||
}
|
||||
strong, b {
|
||||
font-weight: bold;
|
||||
color: #000;
|
||||
}
|
||||
p {
|
||||
margin: 0;
|
||||
padding: 0.5em 0;
|
||||
}
|
||||
ul.columns {
|
||||
-moz-column-count: 3;
|
||||
-moz-column-gap: 20px;
|
||||
-webkit-column-count: 3;
|
||||
-webkit-column-gap: 20px;
|
||||
column-count: 3;
|
||||
column-gap: 20px;
|
||||
}
|
||||
dl dt {
|
||||
font: 13px/1.4em Monaco, monospace;
|
||||
font-weight: bold;
|
||||
}
|
||||
dl dd {
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>DynamoDB Session Handler</h1>
|
||||
<p>The <strong>DynamoDB Session Handler</strong> is a custom session handler for PHP that allows Amazon DynamoDB to be used as a session store while still using PHP’s native session functions.</p>
|
||||
|
||||
<h2>What issues does this address?</h2>
|
||||
<p>The native PHP session handler stores sessions on the local file system. This is unreliable in distributed web applications, because the user may be routed to servers that do not contain the session data. To solve this problem, PHP developers have implemented custom solutions for storing user session data using databases, shared file systems, Memcache servers, tamper-proof cookies, etc., by taking advantage of the interface provided by PHP via the <code>session_set_save_handler()</code> function. Unfortunately, most of these solutions require a lot of configuration or prior knowledge about the storage mechanism in order to setup. Some of them also require the provisioning or management of additional servers.</p>
|
||||
|
||||
<h2>Proposed solution</h2>
|
||||
<p>The DynamoDB Session Handler uses Amazon DynamoDB as a session store, which alleviates many of the problems with existing solutions. There are no additional servers to manage, and there is very little configuration required. The Amazon DynamoDB is also fundamentally designed for low latency (the data is even stored on <abbr title="Solid State Drive">SSD</abbr>s), so the performance impact is much smaller when compared to other databases. Since the Session Handler is designed to be a drop in replacement for the default PHP session handler, it also implements session locking in a familiar way.</p>
|
||||
|
||||
<h2>How do I use it?</h2>
|
||||
<p>The first step is to instantiate the Amazon DynamoDB client and register the session handler.</p>
|
||||
<pre>require_once 'AWSSDKforPHP/sdk.class.php';
|
||||
|
||||
// Instantiate the Amazon DynamoDB client.
|
||||
// REMEMBER: You need to set 'default_cache_config' in your config.inc.php.
|
||||
$dynamodb = new AmazonDynamoDB();
|
||||
|
||||
// Register the DynamoDB Session Handler.
|
||||
$handler = $dynamodb->register_session_handler(array(
|
||||
'table_name' => 'my-sessions-table'
|
||||
));</pre>
|
||||
<p>Before you can use the session handler, you need to create a table to store the sessions in. This can be done through the <a href="https://console.aws.amazon.com/dynamodb/home">AWS Console for Amazon DynamoDB</a>, or using the session handler class (which you must configure with the table name like in the example above).</p>
|
||||
<pre>// Create a table for session storage with default settings.
|
||||
$handler->create_sessions_table();</pre>
|
||||
<p>If you create the table via the AWS Console, you need to make sure the primary key is a string. By default the DynamoDB Session Handler looks for a key named "id", so if you name the key something else, you will need to specify that when you configure the session handler (see the <a href="#configuration">Configuration section</a> below).</p>
|
||||
<p>Once the session handler is registered with a valid table, you can write to (and read from) the session using the standard <code>$_SESSION</code> superglobal.</p>
|
||||
<pre>// Start the session. This will acquire a lock if session locking is enabled.
|
||||
session_start();
|
||||
|
||||
// Alter the session data.
|
||||
$_SESSION['username'] = 'jeremy';
|
||||
$_SESSION['role'] = 'admin';
|
||||
|
||||
// Close and write to the session.
|
||||
// REMEMBER: You should close the session ASAP to release the session lock.
|
||||
session_write_close();</pre>
|
||||
|
||||
<h3>Removing expired sessions</h3>
|
||||
<p>The session handler ties into PHP's native session garbage collection functionality, so expired sessions will be deleted periodically and automatically based on how you configure PHP to do the garbage collection. See the PHP manual for the following PHP INI settings: <a href="http://www.php.net/manual/en/session.configuration.php#ini.session.gc-probability">session.gc_probability</a>, <a href="http://www.php.net/manual/en/session.configuration.php#ini.session.gc-divisor">session.gc_divisor</a>, and <a href="http://www.php.net/manual/en/session.configuration.php#ini.session.gc-maxlifetime">session.gc_maxlifetime</a>. You may also manually call the <code>DynamoDBSessionHandler::garbage_collect()</code> to clean up the expired sessions.</p>
|
||||
|
||||
<h2 id="configuration">Configuring the DynamoDB Session Handler</h2>
|
||||
<p>You may configure the behavior of the session handler using a the following settings:</p>
|
||||
<dl>
|
||||
<dt>table_name</dt>
|
||||
<dd>The name of the DynamoDB table in which to store sessions.</dd>
|
||||
|
||||
<dt>hash_key</dt>
|
||||
<dd>The name of the primary hash key in the DynamoDB sessions table.</dd>
|
||||
|
||||
<dt>session_lifetime</dt>
|
||||
<dd>The lifetime of an inactive session before it should be garbage collected. If <code>0</code> is used, then the actual lifetime value that will be used is <code>ini_get('session.gc_maxlifetime')</code>.</dd>
|
||||
|
||||
<dt>consistent_reads</dt>
|
||||
<dd>Whether or not the session handler should do consistent reads from DynamoDB.</dd>
|
||||
|
||||
<dt>session_locking</dt>
|
||||
<dd>Whether or not the session handler should do session locking (see the <a href="#session_locking">Session locking section</a> for more information).</dd>
|
||||
|
||||
<dt>max_lock_wait_time</dt>
|
||||
<dd>Maximum time, in seconds, that the session handler should take to acquire a lock before giving up. Only used if <code>session_locking</code> is <code>true</code>.</dd>
|
||||
|
||||
<dt>min_lock_retry_utime</dt>
|
||||
<dd>Minimum time, in microseconds, that the session handler should wait to retry acquiring a lock. Only used if <code>session_locking</code> is <code>true</code>.</dd>
|
||||
|
||||
<dt>max_lock_retry_utime</dt>
|
||||
<dd>Maximum time, in microseconds, that the session handler should wait to retry acquiring a lock. Only used if <code>session_locking</code> is <code>true</code>.</dd>
|
||||
</dl>
|
||||
|
||||
<p>To configure the Session Handle, you must pass the configuration data into the constructor. (<strong>Note</strong>: The values used below are actually the default settings.)</p>
|
||||
<pre>$dynamodb = new AmazonDynamoDB();
|
||||
$handler = $dynamodb->register_session_handler(array(
|
||||
'table_name' => 'sessions',
|
||||
'hash_key' => 'id',
|
||||
'session_lifetime' => 0,
|
||||
'consistent_reads' => true,
|
||||
'session_locking' => true,
|
||||
'max_lock_wait_time' => 15,
|
||||
'min_lock_retry_utime' => 5000,
|
||||
'max_lock_retry_utime' => 50000,
|
||||
));</pre>
|
||||
|
||||
<h2 id="session_locking">Session locking</h2>
|
||||
<p>The default session handler for PHP locks sessions using a pessimistic locking algorithm. If a request (process) opens a session for reading using the <code>session_start()</code> function, it first acquires a lock. The lock is closed when that request writes back to the session, either when the request is complete, or via the <code>session_write_close()</code> function. Since the DynamoDB Session Handler is meant to be a drop in replacement for the default session handler, it also implements the same locking scheme. However, this can be slow, undesirable, and costly when multiple, simultaneous requests from the same user occur, particularly with ajax requests or HTML iframes. In some cases, you may not want or need the session to be locked. After evaluating whether or not your application actually requires session locking, you may turn off locking when you configure the session handler by setting <code>session_locking</code> to <code>false</code>.</p>
|
||||
|
||||
<h2 id="pricing">Pricing</h2>
|
||||
<p>Aside from nominal data storage and data transfer fees, the costs associated with using Amazon DynamoDB are calculated based on provisioned throughput capacity and item size (see the <a href="http://aws.amazon.com/dynamodb/#pricing">Amazon DynamoDB pricing</a> details). Throughput is measured in units of Read Capacity and Write Capacity. Ultimately, the throughput and costs required for your sessions table is going to be based on your website traffic, but the following is a list of the capacity units required for each session-related operation:</p>
|
||||
<ul>
|
||||
<li><strong>Reading</strong> via <code>session_start()</code>
|
||||
<p>With locking enabled: 1 unit of Write Capacity + 1 unit of Write Capacity for each time it must retry acquiring the lock</p>
|
||||
<p>With locking disabed: 1 unit of Read Capacity (or 0.5 units of Read Capacity if <i>consistent reads</i> are disabled)</p>
|
||||
</li>
|
||||
<li><strong>Writing</strong> via <code>session_write_close()</code>
|
||||
<p>1 unit of Write Capacity</p>
|
||||
</li>
|
||||
<li><strong>Deleting</strong> via <code>session_destroy()</code>
|
||||
<p>1 unit of Write Capacity</p>
|
||||
</li>
|
||||
<li><strong>Garbage Collecting</strong> via <code>DyanamoDBSessionHandler::garbage_collect()</code>
|
||||
<p>0.5 units of Read Capacity per KB of data in the sessions table + 1 unit of Write Capacity per expired item</p>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h2 id="more_information">More information</h2>
|
||||
<p>For more information on the Amazon DynamoDB service please visit the <a href="http://aws.amazon.com/dynamodb">Amazon DynamoDB homepage</a>.</p>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,65 @@
|
|||
# Known Issues
|
||||
|
||||
## 2GB limit for 32-bit stacks; all Windows stacks.
|
||||
|
||||
Because PHP's integer type is signed and many platforms use 32-bit integers, the AWS SDK for PHP does not correctly
|
||||
handle files larger than 2GB on a 32-bit stack (where "stack" includes CPU, OS, web server, and PHP binary). This is a
|
||||
[well-known PHP issue]. In the case of Microsoft® Windows®, there are no official builds of PHP that support 64-bit
|
||||
integers.
|
||||
|
||||
The recommended solution is to use a 64-bit Linux stack, such as the [64-bit Amazon Linux AMI] with the latest version of
|
||||
PHP installed.
|
||||
|
||||
For more information, please see: [PHP filesize: Return values]. A workaround is suggested in
|
||||
`AmazonS3::create_mpu_object()` [with files bigger than 2GB].
|
||||
|
||||
[well-known PHP issue]: http://www.google.com/search?q=php+2gb+32-bit
|
||||
[64-bit Amazon Linux AMI]: http://aws.amazon.com/amazon-linux-ami/
|
||||
[PHP filesize: Return values]: http://docs.php.net/manual/en/function.filesize.php#refsect1-function.filesize-returnvalues
|
||||
[with files bigger than 2GB]: https://forums.aws.amazon.com/thread.jspa?messageID=215487#215487
|
||||
|
||||
|
||||
## Amazon S3 Buckets containing periods
|
||||
|
||||
Amazon S3's SSL certificate covers domains that match `*.s3.amazonaws.com`. When buckets (e.g., `my-bucket`) are accessed
|
||||
using DNS-style addressing (e.g., `my-bucket.s3.amazonaws.com`), those SSL/HTTPS connections are covered by the certificate.
|
||||
|
||||
However, when a bucket name contains one or more periods (e.g., `s3.my-domain.com`) and is accessed using DNS-style
|
||||
addressing (e.g., `s3.my-domain.com.s3.amazonaws.com`), that SSL/HTTPS connection will fail because the certificate
|
||||
doesn't match.
|
||||
|
||||
The most secure workaround is to change the bucket name to one that does not contain periods. Less secure workarounds
|
||||
are to use `disable_ssl()` or `disable_ssl_verification()`. Because of the security implications, calling either of
|
||||
these methods will throw a warning. You can avoid the warning by adjusting your `error_reporting()` settings.
|
||||
|
||||
|
||||
## Expiring request signatures
|
||||
|
||||
When leveraging `AmazonS3::create_mpu_object()`, it's possible that later parts of the multipart upload will fail if
|
||||
the upload takes more than 15 minutes.
|
||||
|
||||
|
||||
## Too many open file connections
|
||||
|
||||
When leveraging `AmazonS3::create_mpu_object()`, it's possible that the SDK will attempt to open too many file resources
|
||||
at once. Because the file connection limit is not available to the PHP environment, the SDK is unable to automatically
|
||||
adjust the number of connections it attempts to open.
|
||||
|
||||
A workaround is to increase the part size so that fewer file connections are opened.
|
||||
|
||||
|
||||
## Exceptionally large batch requests
|
||||
|
||||
When leveraging the batch request feature to execute multiple requests in parallel, it's possible that the SDK will
|
||||
throw a fatal exception if a particular batch pool is exceptionally large and a service gets overloaded with requests.
|
||||
|
||||
This seems to be most common when attempting to send a large number of emails with the SES service.
|
||||
|
||||
|
||||
## Long-running processes using SSL leak memory
|
||||
|
||||
When making requests with the SDK over SSL during long-running processes, there will be a gradual memory leak that can
|
||||
eventually cause a crash. The leak occurs within the PHP bindings for cURL when attempting to verify the peer during an
|
||||
SSL handshake. See <https://bugs.php.net/61030> for details about the bug.
|
||||
|
||||
A workaround is to disable SSL for requests executed in long-running processes.
|
|
@ -0,0 +1,151 @@
|
|||
# Apache License
|
||||
Version 2.0, January 2004
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
|
||||
## 1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1
|
||||
through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the
|
||||
License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled
|
||||
by, or are under common control with that entity. For the purposes of this definition, "control" means
|
||||
(i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract
|
||||
or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial
|
||||
ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications, including but not limited to software
|
||||
source code, documentation source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form,
|
||||
including but not limited to compiled object code, generated documentation, and conversions to other media
|
||||
types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License,
|
||||
as indicated by a copyright notice that is included in or attached to the work (an example is provided in the
|
||||
Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from)
|
||||
the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent,
|
||||
as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not
|
||||
include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work
|
||||
and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including the original version of the Work and any
|
||||
modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to
|
||||
Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to
|
||||
submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of
|
||||
electronic, verbal, or written communication sent to the Licensor or its representatives, including but not
|
||||
limited to communication on electronic mailing lists, source code control systems, and issue tracking systems
|
||||
that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise designated in writing by the copyright
|
||||
owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been
|
||||
received by Licensor and subsequently incorporated within the Work.
|
||||
|
||||
|
||||
## 2. Grant of Copyright License.
|
||||
|
||||
Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare
|
||||
Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such
|
||||
Derivative Works in Source or Object form.
|
||||
|
||||
|
||||
## 3. Grant of Patent License.
|
||||
|
||||
Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent
|
||||
license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such
|
||||
license applies only to those patent claims licensable by such Contributor that are necessarily infringed by
|
||||
their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such
|
||||
Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim
|
||||
or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work
|
||||
constitutes direct or contributory patent infringement, then any patent licenses granted to You under this
|
||||
License for that Work shall terminate as of the date such litigation is filed.
|
||||
|
||||
|
||||
## 4. Redistribution.
|
||||
|
||||
You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You meet the following conditions:
|
||||
|
||||
1. You must give any other recipients of the Work or Derivative Works a copy of this License; and
|
||||
|
||||
2. You must cause any modified files to carry prominent notices stating that You changed the files; and
|
||||
|
||||
3. You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent,
|
||||
trademark, and attribution notices from the Source form of the Work, excluding those notices that do
|
||||
not pertain to any part of the Derivative Works; and
|
||||
|
||||
4. If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that
|
||||
You distribute must include a readable copy of the attribution notices contained within such NOTICE
|
||||
file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed as part of the Derivative Works; within
|
||||
the Source form or documentation, if provided along with the Derivative Works; or, within a display
|
||||
generated by the Derivative Works, if and wherever such third-party notices normally appear. The
|
||||
contents of the NOTICE file are for informational purposes only and do not modify the License. You may
|
||||
add Your own attribution notices within Derivative Works that You distribute, alongside or as an
|
||||
addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be
|
||||
construed as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and may provide additional or different license
|
||||
terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative
|
||||
Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the
|
||||
conditions stated in this License.
|
||||
|
||||
|
||||
## 5. Submission of Contributions.
|
||||
|
||||
Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by
|
||||
You to the Licensor shall be under the terms and conditions of this License, without any additional terms or
|
||||
conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate
|
||||
license agreement you may have executed with Licensor regarding such Contributions.
|
||||
|
||||
|
||||
## 6. Trademarks.
|
||||
|
||||
This License does not grant permission to use the trade names, trademarks, service marks, or product names of
|
||||
the Licensor, except as required for reasonable and customary use in describing the origin of the Work and
|
||||
reproducing the content of the NOTICE file.
|
||||
|
||||
|
||||
## 7. Disclaimer of Warranty.
|
||||
|
||||
Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor
|
||||
provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT,
|
||||
MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of
|
||||
permissions under this License.
|
||||
|
||||
|
||||
## 8. Limitation of Liability.
|
||||
|
||||
In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless
|
||||
required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any
|
||||
Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential
|
||||
damages of any character arising as a result of this License or out of the use or inability to use the Work
|
||||
(including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or
|
||||
any and all other commercial damages or losses), even if such Contributor has been advised of the possibility
|
||||
of such damages.
|
||||
|
||||
|
||||
## 9. Accepting Warranty or Additional Liability.
|
||||
|
||||
While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for,
|
||||
acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole
|
||||
responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold
|
||||
each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
|
@ -0,0 +1,444 @@
|
|||
# AWS SDK for PHP
|
||||
|
||||
Based on [CloudFusion](http://getcloudfusion.com). Includes other third-party software.
|
||||
|
||||
See below for complete copyright and licensing notices.
|
||||
|
||||
|
||||
## AWS SDK for PHP
|
||||
|
||||
<http://aws.amazon.com/php>
|
||||
|
||||
Copyright 2010-2012 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License").
|
||||
You may not use this file except in compliance with the License.
|
||||
A copy of the License is located at
|
||||
|
||||
<http://aws.amazon.com/apache2.0>
|
||||
|
||||
or in the "license" file accompanying this file. This file is distributed
|
||||
on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
express or implied. See the License for the specific language governing
|
||||
permissions and limitations under the License.
|
||||
|
||||
|
||||
## CloudFusion
|
||||
|
||||
<http://getcloudfusion.com>
|
||||
|
||||
* Copyright 2005-2010 [Ryan Parman](http://ryanparman.com)
|
||||
* Copyright 2007-2010 [Foleeo Inc.](http://warpshare.com)
|
||||
* Copyright 2007-2010 "CONTRIBUTORS" (see [CONTRIBUTORS.md](CONTRIBUTORS.md) for a list)
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name of the organization nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
<http://opensource.org/licenses/bsd-license.php>
|
||||
|
||||
|
||||
## CacheCore
|
||||
|
||||
<http://github.com/skyzyx/cachecore>
|
||||
|
||||
* Copyright 2007-2010 [Ryan Parman](http://ryanparman.com)
|
||||
* Copyright 2007-2010 [Foleeo Inc.](http://warpshare.com)
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name of the organization nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
<http://opensource.org/licenses/bsd-license.php>
|
||||
|
||||
|
||||
## RequestCore
|
||||
|
||||
<http://github.com/skyzyx/requestcore>
|
||||
|
||||
* Copyright 2007-2010 [Ryan Parman](http://ryanparman.com)
|
||||
* Copyright 2007-2010 [Foleeo Inc.](http://warpshare.com)
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name of the organization nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
<http://opensource.org/licenses/bsd-license.php>
|
||||
|
||||
|
||||
## SimplePie
|
||||
|
||||
<http://simplepie.org>
|
||||
|
||||
* Copyright 2004-2010 [Ryan Parman](http://ryanparman.com)
|
||||
* Copyright 2005-2010 [Geoffrey Sneddon](http://gsnedders.com)
|
||||
* Copyright 2008-2011 [Ryan McCue](http://ryanmccue.info)
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name of the organization nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
<http://opensource.org/licenses/bsd-license.php>
|
||||
|
||||
|
||||
## Reqwest
|
||||
|
||||
<https://github.com/ded/reqwest>
|
||||
|
||||
* Copyright 2011 [Dustin Diaz](http://dustindiaz.com)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
<http://www.opensource.org/licenses/mit-license.php>
|
||||
|
||||
|
||||
## Human readable file sizes
|
||||
|
||||
<http://aidanlister.com/2004/04/human-readable-file-sizes/>
|
||||
|
||||
* Copyright 2004-2010 [Aidan Lister](http://aidanlister.com)
|
||||
* Copyright 2007-2010 [Ryan Parman](http://ryanparman.com)
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, is permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
|
||||
3. The name "PHP" must not be used to endorse or promote products
|
||||
derived from this software without prior written permission. For
|
||||
written permission, please contact group@php.net.
|
||||
|
||||
4. Products derived from this software may not be called "PHP", nor
|
||||
may "PHP" appear in their name, without prior written permission
|
||||
from group@php.net. You may indicate that your software works in
|
||||
conjunction with PHP by saying "Foo for PHP" instead of calling
|
||||
it "PHP Foo" or "phpfoo"
|
||||
|
||||
5. The PHP Group may publish revised and/or new versions of the
|
||||
license from time to time. Each version will be given a
|
||||
distinguishing version number.
|
||||
Once covered code has been published under a particular version
|
||||
of the license, you may always continue to use it under the terms
|
||||
of that version. You may also choose to use such covered code
|
||||
under the terms of any subsequent version of the license
|
||||
published by the PHP Group. No one other than the PHP Group has
|
||||
the right to modify the terms applicable to covered code created
|
||||
under this License.
|
||||
|
||||
6. Redistributions of any form whatsoever must retain the following
|
||||
acknowledgment:
|
||||
"This product includes PHP software, freely available from
|
||||
<http://www.php.net/software/>".
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE PHP DEVELOPMENT TEAM ``AS IS'' AND
|
||||
ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PHP
|
||||
DEVELOPMENT TEAM OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
<http://www.php.net/license/3_01.txt>
|
||||
|
||||
|
||||
## Snippets from PHP.net documentation
|
||||
|
||||
* `CFUtilities::is_base64()` - Copyright 2008 "debug" <http://us.php.net/manual/en/function.base64-decode.php#81425>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, is permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
|
||||
3. The name "PHP" must not be used to endorse or promote products
|
||||
derived from this software without prior written permission. For
|
||||
written permission, please contact group@php.net.
|
||||
|
||||
4. Products derived from this software may not be called "PHP", nor
|
||||
may "PHP" appear in their name, without prior written permission
|
||||
from group@php.net. You may indicate that your software works in
|
||||
conjunction with PHP by saying "Foo for PHP" instead of calling
|
||||
it "PHP Foo" or "phpfoo"
|
||||
|
||||
5. The PHP Group may publish revised and/or new versions of the
|
||||
license from time to time. Each version will be given a
|
||||
distinguishing version number.
|
||||
Once covered code has been published under a particular version
|
||||
of the license, you may always continue to use it under the terms
|
||||
of that version. You may also choose to use such covered code
|
||||
under the terms of any subsequent version of the license
|
||||
published by the PHP Group. No one other than the PHP Group has
|
||||
the right to modify the terms applicable to covered code created
|
||||
under this License.
|
||||
|
||||
6. Redistributions of any form whatsoever must retain the following
|
||||
acknowledgment:
|
||||
"This product includes PHP software, freely available from
|
||||
<http://www.php.net/software/>".
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE PHP DEVELOPMENT TEAM ``AS IS'' AND
|
||||
ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PHP
|
||||
DEVELOPMENT TEAM OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
<http://www.php.net/license/3_01.txt>
|
||||
|
||||
|
||||
## phunction PHP framework
|
||||
|
||||
<http://sourceforge.net/projects/phunction/>
|
||||
|
||||
* Copyright 2010 [Alix Axel](mailto:alix-axel@users.sf.net)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
<http://www.opensource.org/licenses/mit-license.php>
|
||||
|
||||
|
||||
## Symfony YAML Component
|
||||
|
||||
<http://components.symfony-project.org/yaml/>
|
||||
|
||||
Copyright 2008-2009 [Fabien Potencier](http://fabien.potencier.org)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is furnished
|
||||
to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
<http://opensource.org/licenses/mit-license.php>
|
||||
|
||||
|
||||
## PEAR Console_ProgressBar
|
||||
|
||||
<http://pear.php.net/package/Console_ProgressBar/>
|
||||
|
||||
Copyright 2003-2007 [Stefan Walk](http://pear.php.net/user/et)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is furnished
|
||||
to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
<http://opensource.org/licenses/mit-license.php>
|
||||
|
||||
|
||||
## Mozilla Certificate Authority
|
||||
|
||||
* <http://curl.haxx.se/ca/cacert.pem>
|
||||
* <https://mxr.mozilla.org/mozilla/source/security/nss/lib/ckfw/builtins/certdata.txt?raw=1>
|
||||
|
||||
The contents of this file are subject to the Mozilla Public License Version
|
||||
1.1 (the "License"); you may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
http://www.mozilla.org/MPL/
|
||||
|
||||
Software distributed under the License is distributed on an "AS IS" basis,
|
||||
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
for the specific language governing rights and limitations under the
|
||||
License.
|
||||
|
||||
The Original Code is the Netscape security libraries.
|
||||
|
||||
The Initial Developer of the Original Code is Netscape Communications
|
||||
Corporation. Portions created by the Initial Developer are Copyright
|
||||
(C) 1994-2000 the Initial Developer. All Rights Reserved.
|
||||
|
||||
<http://www.mozilla.org/MPL/>
|
||||
|
||||
|
||||
## array-to-domdocument
|
||||
|
||||
<https://code.google.com/p/array-to-domdocument/>
|
||||
|
||||
* Copyright 2010-2011 [Omer Hassan](https://code.google.com/u/113495690012051782542/)
|
||||
* Portions copyright 2012 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is furnished
|
||||
to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
<http://opensource.org/licenses/mit-license.php>
|
|
@ -0,0 +1,243 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
|
||||
<title>README</title>
|
||||
<style type="text/css" media="screen">
|
||||
body {
|
||||
font: 18px/1.5em 'Book Antiqua', 'Palatino Linotype', Palatino, 'Minion Pro', Cambria, Georgia, serif;
|
||||
padding: 50px 10%;
|
||||
max-width: 1000px;
|
||||
margin: 0 auto;
|
||||
color: #080000;
|
||||
background-color: #fbfbf9;
|
||||
}
|
||||
code {
|
||||
font: 13px/1.4em Monaco, monospace;
|
||||
background-color: #f3f3f3;
|
||||
color: #444;
|
||||
padding: 1px 2px;
|
||||
|
||||
border-radius: 2px;
|
||||
-webkit-border-radius: 2px;
|
||||
-moz-border-radius: 2px;
|
||||
}
|
||||
pre {
|
||||
border: 1px solid #ddd;
|
||||
border-left: 6px solid #c0c0c0;
|
||||
background-color: #f3f3f3;
|
||||
color: #444;
|
||||
font: 13px/1.4em Monaco, monospace;
|
||||
overflow: auto;
|
||||
|
||||
margin: 1em 0 1.5em 0;
|
||||
padding: 1em;
|
||||
text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5);
|
||||
|
||||
-webkit-border-top-right-radius: 5px;
|
||||
-webkit-border-bottom-right-radius: 5px;
|
||||
-moz-border-radius-topright: 5px;
|
||||
-moz-border-radius-bottomright: 5px;
|
||||
border-top-right-radius: 5px;
|
||||
border-bottom-right-radius: 5px;
|
||||
}
|
||||
pre code {
|
||||
font-family: inherit;
|
||||
font-size: inherit;
|
||||
background-color: inherit;
|
||||
color: inherit;
|
||||
padding: 0;
|
||||
|
||||
border-radius: none;
|
||||
-webkit-border-radius: none;
|
||||
-moz-border-radius: none;
|
||||
}
|
||||
a {
|
||||
color: #326EA1;
|
||||
text-decoration: underline;
|
||||
padding: 1px 2px;
|
||||
-webkit-transition: background-color 0.15s;
|
||||
-webkit-transition: color 0.15s;
|
||||
-moz-transition: background-color 0.15s;
|
||||
-moz-transition: color 0.15s;
|
||||
transition: background-color 0.15s;
|
||||
transition: color 0.15s;
|
||||
-webkit-border-radius: 2px;
|
||||
-moz-border-radius: 2px;
|
||||
border-radius: 2px;
|
||||
}
|
||||
a:hover, a.hover {
|
||||
color: #fff;
|
||||
background-color: #333;
|
||||
text-decoration: none;
|
||||
padding: 1px 2px;
|
||||
}
|
||||
a.active {
|
||||
font-weight: bold;
|
||||
}
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
padding: 0.8em 0 0.2em 0;
|
||||
margin: 0;
|
||||
}
|
||||
h1 {
|
||||
margin-top: 30px;
|
||||
padding: 15px 0 5px 5px;
|
||||
font-size: 2em;
|
||||
line-height: 1.3em;
|
||||
border-bottom: 3px solid #cdcdcc;
|
||||
}
|
||||
h2 {
|
||||
margin-top: 30px;
|
||||
padding: 15px 0 5px 5px;
|
||||
font-size: 1.5em;
|
||||
line-height: 1.3em;
|
||||
border-bottom: 1px solid #cdcdcc;
|
||||
}
|
||||
li {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
em, i {
|
||||
font-style: italic;
|
||||
}
|
||||
strong, b {
|
||||
font-weight: bold;
|
||||
color: #000;
|
||||
}
|
||||
p {
|
||||
margin: 0;
|
||||
padding: 0.5em 0;
|
||||
}
|
||||
ul.columns {
|
||||
-moz-column-count: 3;
|
||||
-moz-column-gap: 20px;
|
||||
-webkit-column-count: 3;
|
||||
-webkit-column-gap: 20px;
|
||||
column-count: 3;
|
||||
column-gap: 20px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>S3 Stream Wrapper</h1>
|
||||
<p>The <strong>S3 Stream Wrapper</strong> is a stream wrapper interface for PHP that provides access to Amazon S3 using PHP’s standard File System API functions.</p>
|
||||
|
||||
<h2>What issues does this address?</h2>
|
||||
<p>There are a large number of existing applications, code snippets and other bits of PHP that are designed to read and write from the local file system as part of their normal operations. Many of these apps could benefit from moving into the cloud, but doing so would require rewriting a substantial amount of code.</p>
|
||||
<p>What if we could simplify this process so that the updates required to make an existing application cloud-backed would be very minimal?</p>
|
||||
|
||||
<h2>Proposed solution</h2>
|
||||
<p>PHP provides an interface for solving this exact kind of problem, called the <a href="http://php.net/streamwrapper">Stream Wrapper</a> interface. By writing a class that implements this interface and <a href="http://php.net/manual/en/function.stream-wrapper-register.php">registering it as a handler</a> we can reduce both the amount of rewriting that needs to be done for existing applications, as well as substantially lower the learning curve for reading and writing from Amazon S3.</p>
|
||||
|
||||
<h2>How do I use it?</h2>
|
||||
<p>After including the AWS SDK for PHP in your project, use the <code>AmazonS3::register_stream_wrapper()</code> method to register <code>s3://</code> as a <a href="http://php.net/manual/en/wrappers.php">supported stream wrapper</a> for Amazon S3. <em>It's that simple</em>. Amazon S3 file patterns take the following form: <code>s3://bucket/object</code>.</p>
|
||||
|
||||
<pre><code>require_once 'AWSSDKforPHP/sdk.class.php';
|
||||
|
||||
$s3 = new AmazonS3();
|
||||
$s3->register_stream_wrapper();
|
||||
|
||||
$directory = 's3://my-new-bucket';
|
||||
$filename = $directory . '/put.txt';
|
||||
$contents = '';
|
||||
|
||||
if (mkdir($directory))
|
||||
{
|
||||
if (file_put_contents($filename, 'This is some sample data.'))
|
||||
{
|
||||
$handle = fopen($filename, 'rb+');
|
||||
$contents = stream_get_contents($handle);
|
||||
fclose($handle);
|
||||
}
|
||||
|
||||
rmdir($directory);
|
||||
}
|
||||
|
||||
echo $contents;</code></pre>
|
||||
|
||||
<p>You may also pass a different protocol name as a parameter to <code>AmazonS3::register_stream_wrapper()</code> if you want to use something besides <code>s3://</code>. Using this technique you can create more than one stream wrapper with different configurations (e.g. for different regions). To do that you just need to create separate instances of the <code>AmazonS3</code> class, configure them, and then register a stream wrapper for each of them with different protocol names.</p>
|
||||
|
||||
<pre><code>require_once 'AWSSDKforPHP/sdk.class.php';
|
||||
|
||||
$s3east = new AmazonS3();
|
||||
$s3east->set_region(AmazonS3::REGION_US_E1);
|
||||
$s3east->register_stream_wrapper('s3east');
|
||||
mkdir('s3east://my-easterly-bucket');
|
||||
|
||||
$s3west = new AmazonS3();
|
||||
$s3west->set_region(AmazonS3::REGION_US_W1);
|
||||
$s3west->register_stream_wrapper('s3west');
|
||||
mkdir('s3west://my-westerly-bucket');</code></pre>
|
||||
|
||||
<h2>Tests and usage examples</h2>
|
||||
<p>We are also including tests written in the <a href="http://qa.php.net/phpt_details.php">PHPT</a> format. Not only do these tests show how the software can be used, but any tests submitted back to us should be in this format. These tests will likely fail for you unless you change the bucket names to be globally unique across S3. You can run the tests with <code>pear</code>.</p>
|
||||
<pre><code>cd S3StreamWrapper/tests;
|
||||
pear run-tests;</code></pre>
|
||||
<p>If you have <a href="http://phpunit.de">PHPUnit</a> 3.6+ and <a href="http://xdebug.org">Xdebug</a> installed, you can generate a code coverage report as follows:</p>
|
||||
<pre><code>cd S3StreamWrapper/tests && \
|
||||
phpunit --colors --coverage-html ./_coverage_report . && \
|
||||
open ./_coverage_report/index.html;</code></pre>
|
||||
|
||||
<h2>Notes and Known Issues</h2>
|
||||
<ul>
|
||||
<li><p><code>stream_lock()</code> and <code>stream_cast()</code> are not currently implemented, and likely won't be.</p></li>
|
||||
<li><p>Strangely <code>touch()</code> doesn’t seem to work. I think this is because of an issue with my implementation of <code>url_stat()</code>, but I can’t find any information on the magical combination of parameters that will make this work.</p></li>
|
||||
<li><p>Using <code>fopen()</code> will always open in <code>rb+</code> mode. Amazon S3 as a service doesn’t support anything else.</p></li>
|
||||
<li><p>Because of the way that PHP interacts with the <a href="http://php.net/manual/en/class.streamwrapper.php">StreamWrapper</a> interface, it’s difficult to optimize for batch requests under the hood. If you need to push or pull data from several objects, you may find that using <a href="http://docs.amazonwebservices.com/AWSSDKforPHP/latest/#m=CFRuntime/batch">batch requests</a> with the <a href="http://docs.amazonwebservices.com/AWSSDKforPHP/latest/#i=AmazonS3">standard interface</a> has better latency.</p></li>
|
||||
<li><p><code>rmdir()</code> does not do a force-delete, so you will need to iterate over the files to delete them one-by-one.</p></li>
|
||||
<li><p><code>realpath()</code>, <code>glob()</code>, <code>chmod()</code>, <code>chown()</code>, <code>chgrp()</code>, <code>tempnam()</code> and a few other functions don’t support the StreamWrapper interface at the PHP-level because they're designed to work with the (no/low-latency) local file system.</p></li>
|
||||
<li><p>Support for <code>ftruncate()</code> does not exist in any current release of PHP, but is implemented on the PHP trunk for a future release. <a href="http://bugs.php.net/53888">http://bugs.php.net/53888</a>.</p></li>
|
||||
<li><p>Since <a href="http://docs.amazonwebservices.com/AmazonS3/latest/gsg/WorkingWithS3.html#WriteObject">Amazon S3 doesn’t support appending data</a>, it is best to avoid functions that expect or rely on that functionality (e.g. <a href="http://php.net/fputcsv">fputcsv()</a>).</p></li>
|
||||
</ul>
|
||||
|
||||
<h2>Successfully tested with</h2>
|
||||
<ul class="columns">
|
||||
<li><a href="http://php.net/close_dir">close_dir()</a></li>
|
||||
<li><a href="http://php.net/file_exists">file_exists()</a></li>
|
||||
<li><a href="http://php.net/file_get_contents">file_get_contents()</a></li>
|
||||
<li><a href="http://php.net/file_put_contents">file_put_contents()</a></li>
|
||||
<li><a href="http://php.net/fclose">fclose()</a></li>
|
||||
<li><a href="http://php.net/feof">feof()</a></li>
|
||||
<li><a href="http://php.net/fflush">fflush()</a></li>
|
||||
<li><a href="http://php.net/fgetc">fgetc()</a></li>
|
||||
<li><a href="http://php.net/fgetcsv">fgetcsv()</a></li>
|
||||
<li><a href="http://php.net/fgets">fgets()</a></li>
|
||||
<li><a href="http://php.net/fgetss">fgetss()</a></li>
|
||||
<li><a href="http://php.net/fopen">fopen()</a></li>
|
||||
<li><a href="http://php.net/fpassthru">fpassthru()</a></li>
|
||||
<li><a href="http://php.net/fputs">fputs()</a></li>
|
||||
<li><a href="http://php.net/fread">fread()</a></li>
|
||||
<li><a href="http://php.net/fseek">fseek()</a></li>
|
||||
<li><a href="http://php.net/fstat">fstat()</a></li>
|
||||
<li><a href="http://php.net/ftell">ftell()</a></li>
|
||||
<li><a href="http://php.net/fwrite">fwrite()</a></li>
|
||||
<li><a href="http://php.net/is_dir">is_dir()</a></li>
|
||||
<li><a href="http://php.net/is_file">is_file()</a></li>
|
||||
<li><a href="http://php.net/is_readable">is_readable()</a></li>
|
||||
<li><a href="http://php.net/is_writable">is_writable()</a></li>
|
||||
<li><a href="http://php.net/mkdir">mkdir()</a></li>
|
||||
<li><a href="http://php.net/open_dir">open_dir()</a></li>
|
||||
<li><a href="http://php.net/read_dir">read_dir()</a></li>
|
||||
<li><a href="http://php.net/rewind">rewind()</a></li>
|
||||
<li><a href="http://php.net/rewinddir">rewinddir()</a></li>
|
||||
<li><a href="http://php.net/rmdir">rmdir()</a></li>
|
||||
<li><a href="http://php.net/scandir">scandir()</a></li>
|
||||
<li><a href="http://php.net/stream_get_contents">stream_get_contents()</a></li>
|
||||
<li><a href="http://php.net/unlink">unlink()</a></li>
|
||||
</ul>
|
||||
|
||||
<h2>Known issues with</h2>
|
||||
<ul>
|
||||
<li><a href="http://php.net/chgrp">chgrp()</a></li>
|
||||
<li><a href="http://php.net/chmod">chmod()</a></li>
|
||||
<li><a href="http://php.net/chown">chown()</a></li>
|
||||
<li><a href="http://php.net/fputcsv">fputcsv()</a></li>
|
||||
<li><a href="http://php.net/glob">glob()</a></li>
|
||||
<li><a href="http://php.net/realpath">realpath()</a></li>
|
||||
<li><a href="http://php.net/tempnam">tempnam()</a></li>
|
||||
<li><a href="http://php.net/touch">touch()</a></li>
|
||||
</ul>
|
||||
|
||||
<p>A future version <em>may</em> provide S3-specific implementations of some of these functions (e.g., <code>s3chmod()</code>, <code>s3glob()</code>, <code>s3touch()</code>).</p>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,2 @@
|
|||
You can find the API Reference at:
|
||||
http://docs.amazonwebservices.com/AWSSDKforPHP/latest/
|
|
@ -0,0 +1,48 @@
|
|||
<?php
|
||||
/*
|
||||
* Copyright 2010-2012 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
* A copy of the License is located at
|
||||
*
|
||||
* http://aws.amazon.com/apache2.0
|
||||
*
|
||||
* or in the "license" file accompanying this file. This file is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
* express or implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/*%******************************************************************************************%*/
|
||||
// INTERFACE
|
||||
|
||||
/**
|
||||
* The interface implemented by all signing classes.
|
||||
*
|
||||
* @version 2011.11.22
|
||||
* @license See the included NOTICE.md file for more information.
|
||||
* @copyright See the included NOTICE.md file for more information.
|
||||
* @link http://aws.amazon.com/php/ PHP Developer Center
|
||||
*/
|
||||
interface Signable
|
||||
{
|
||||
/**
|
||||
* Constructs a new instance of the implementing class.
|
||||
*
|
||||
* @param string $endpoint (Required) The endpoint to direct the request to.
|
||||
* @param string $operation (Required) The operation to execute as a result of this request.
|
||||
* @param array $payload (Required) The options to use as part of the payload in the request.
|
||||
* @param CFCredential $credentials (Required) The credentials to use for signing and making requests.
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($endpoint, $operation, $payload, CFCredential $credentials);
|
||||
|
||||
/**
|
||||
* Generates a cURL handle with all of the required authentication bits set.
|
||||
*
|
||||
* @return resource A cURL handle ready for executing.
|
||||
*/
|
||||
public function authenticate();
|
||||
}
|
|
@ -0,0 +1,163 @@
|
|||
<?php
|
||||
/*
|
||||
* Copyright 2010-2012 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
* A copy of the License is located at
|
||||
*
|
||||
* http://aws.amazon.com/apache2.0
|
||||
*
|
||||
* or in the "license" file accompanying this file. This file is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
* express or implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/*%******************************************************************************************%*/
|
||||
// CLASS
|
||||
|
||||
/**
|
||||
* Implements support for Signature v2 (AWS Query).
|
||||
*
|
||||
* @version 2011.11.22
|
||||
* @license See the included NOTICE.md file for more information.
|
||||
* @copyright See the included NOTICE.md file for more information.
|
||||
* @link http://aws.amazon.com/php/ PHP Developer Center
|
||||
*/
|
||||
class AuthV2Query extends Signer implements Signable
|
||||
{
|
||||
/**
|
||||
* Constructs a new instance of the <AuthV2Query> class.
|
||||
*
|
||||
* @param string $endpoint (Required) The endpoint to direct the request to.
|
||||
* @param string $operation (Required) The operation to execute as a result of this request.
|
||||
* @param array $payload (Required) The options to use as part of the payload in the request.
|
||||
* @param CFCredential $credentials (Required) The credentials to use for signing and making requests.
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($endpoint, $operation, $payload, CFCredential $credentials)
|
||||
{
|
||||
parent::__construct($endpoint, $operation, $payload, $credentials);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a cURL handle with all of the required authentication bits set.
|
||||
*
|
||||
* @return resource A cURL handle ready for executing.
|
||||
*/
|
||||
public function authenticate()
|
||||
{
|
||||
// Determine signing values
|
||||
$current_time = time();
|
||||
$date = gmdate(CFUtilities::DATE_FORMAT_RFC2616, $current_time);
|
||||
$timestamp = gmdate(CFUtilities::DATE_FORMAT_ISO8601, $current_time);
|
||||
$query = array();
|
||||
|
||||
// Do we have an authentication token?
|
||||
if ($this->auth_token)
|
||||
{
|
||||
$headers['X-Amz-Security-Token'] = $this->auth_token;
|
||||
$query['SecurityToken'] = $this->auth_token;
|
||||
}
|
||||
|
||||
// Only add it if it exists.
|
||||
if ($this->api_version)
|
||||
{
|
||||
$query['Version'] = $this->api_version;
|
||||
}
|
||||
|
||||
$query['Action'] = $this->operation;
|
||||
$query['AWSAccessKeyId'] = $this->key;
|
||||
$query['SignatureMethod'] = 'HmacSHA256';
|
||||
$query['SignatureVersion'] = 2;
|
||||
$query['Timestamp'] = $timestamp;
|
||||
|
||||
// Merge in any options that were passed in
|
||||
if (is_array($this->payload))
|
||||
{
|
||||
$query = array_merge($query, $this->payload);
|
||||
}
|
||||
|
||||
// Do a case-sensitive, natural order sort on the array keys.
|
||||
uksort($query, 'strcmp');
|
||||
|
||||
// Create the string that needs to be hashed.
|
||||
$canonical_query_string = $this->util->to_signable_string($query);
|
||||
|
||||
// Remove the default scheme from the domain.
|
||||
$domain = str_replace(array('http://', 'https://'), '', $this->endpoint);
|
||||
|
||||
// Parse our request.
|
||||
$parsed_url = parse_url('http://' . $domain);
|
||||
|
||||
// Set the proper host header.
|
||||
if (isset($parsed_url['port']) && (integer) $parsed_url['port'] !== 80 && (integer) $parsed_url['port'] !== 443)
|
||||
{
|
||||
$host_header = strtolower($parsed_url['host']) . ':' . $parsed_url['port'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$host_header = strtolower($parsed_url['host']);
|
||||
}
|
||||
|
||||
// Set the proper request URI.
|
||||
$request_uri = isset($parsed_url['path']) ? $parsed_url['path'] : '/';
|
||||
|
||||
// Prepare the string to sign
|
||||
$this->string_to_sign = "POST\n$host_header\n$request_uri\n$canonical_query_string";
|
||||
|
||||
// Hash the AWS secret key and generate a signature for the request.
|
||||
$query['Signature'] = base64_encode(hash_hmac('sha256', $this->string_to_sign, $this->secret_key, true));
|
||||
|
||||
// Generate the querystring from $query
|
||||
$this->querystring = $this->util->to_query_string($query);
|
||||
|
||||
// Gather information to pass along to other classes.
|
||||
$helpers = array(
|
||||
'utilities' => $this->utilities_class,
|
||||
'request' => $this->request_class,
|
||||
'response' => $this->response_class,
|
||||
);
|
||||
|
||||
// Compose the request.
|
||||
$request_url = ($this->use_ssl ? 'https://' : 'http://') . $domain;
|
||||
$request_url .= !isset($parsed_url['path']) ? '/' : '';
|
||||
|
||||
// Instantiate the request class
|
||||
$request = new $this->request_class($request_url, $this->proxy, $helpers, $this->credentials);
|
||||
$request->set_method('POST');
|
||||
$request->set_body($this->querystring);
|
||||
$headers['Content-Type'] = 'application/x-www-form-urlencoded; charset=utf-8';
|
||||
|
||||
// Pass along registered stream callbacks
|
||||
if ($this->registered_streaming_read_callback)
|
||||
{
|
||||
$request->register_streaming_read_callback($this->registered_streaming_read_callback);
|
||||
}
|
||||
|
||||
if ($this->registered_streaming_write_callback)
|
||||
{
|
||||
$request->register_streaming_write_callback($this->registered_streaming_write_callback);
|
||||
}
|
||||
|
||||
// Sort headers
|
||||
uksort($headers, 'strnatcasecmp');
|
||||
|
||||
// Add headers to request and compute the string to sign
|
||||
foreach ($headers as $header_key => $header_value)
|
||||
{
|
||||
// Strip linebreaks from header values as they're illegal and can allow for security issues
|
||||
$header_value = str_replace(array("\r", "\n"), '', $header_value);
|
||||
|
||||
// Add the header if it has a value
|
||||
if ($header_value !== '')
|
||||
{
|
||||
$request->add_header($header_key, $header_value);
|
||||
}
|
||||
}
|
||||
|
||||
return $request;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,235 @@
|
|||
<?php
|
||||
/*
|
||||
* Copyright 2010-2012 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
* A copy of the License is located at
|
||||
*
|
||||
* http://aws.amazon.com/apache2.0
|
||||
*
|
||||
* or in the "license" file accompanying this file. This file is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
* express or implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/*%******************************************************************************************%*/
|
||||
// CLASS
|
||||
|
||||
/**
|
||||
* Implements support for Signature v3 (JSON).
|
||||
*
|
||||
* @version 2011.12.08
|
||||
* @license See the included NOTICE.md file for more information.
|
||||
* @copyright See the included NOTICE.md file for more information.
|
||||
* @link http://aws.amazon.com/php/ PHP Developer Center
|
||||
*/
|
||||
class AuthV3JSON extends Signer implements Signable
|
||||
{
|
||||
/**
|
||||
* Constructs a new instance of the <AuthV3JSON> class.
|
||||
*
|
||||
* @param string $endpoint (Required) The endpoint to direct the request to.
|
||||
* @param string $operation (Required) The operation to execute as a result of this request.
|
||||
* @param array $payload (Required) The options to use as part of the payload in the request.
|
||||
* @param CFCredential $credentials (Required) The credentials to use for signing and making requests.
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($endpoint, $operation, $payload, CFCredential $credentials)
|
||||
{
|
||||
parent::__construct($endpoint, $operation, $payload, $credentials);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a cURL handle with all of the required authentication bits set.
|
||||
*
|
||||
* @return resource A cURL handle ready for executing.
|
||||
*/
|
||||
public function authenticate()
|
||||
{
|
||||
// Determine signing values
|
||||
$current_time = time();
|
||||
$date = gmdate(CFUtilities::DATE_FORMAT_RFC2616, $current_time);
|
||||
$timestamp = gmdate(CFUtilities::DATE_FORMAT_ISO8601, $current_time);
|
||||
$nonce = $this->util->generate_guid();
|
||||
$curlopts = array();
|
||||
$signed_headers = array();
|
||||
$return_curl_handle = false;
|
||||
$x_amz_target = null;
|
||||
$query = array('body' => $this->payload);
|
||||
|
||||
// Do we have an authentication token?
|
||||
if ($this->auth_token)
|
||||
{
|
||||
$headers['X-Amz-Security-Token'] = $this->auth_token;
|
||||
$query['SecurityToken'] = $this->auth_token;
|
||||
}
|
||||
|
||||
// Manage the key-value pairs that are used in the query.
|
||||
if (stripos($this->operation, 'x-amz-target') !== false)
|
||||
{
|
||||
$x_amz_target = trim(str_ireplace('x-amz-target:', '', $this->operation));
|
||||
}
|
||||
else
|
||||
{
|
||||
$query['Action'] = $this->operation;
|
||||
}
|
||||
|
||||
// Only add it if it exists.
|
||||
if ($this->api_version)
|
||||
{
|
||||
$query['Version'] = $this->api_version;
|
||||
}
|
||||
|
||||
$curlopts = array();
|
||||
|
||||
// Set custom CURLOPT settings
|
||||
if (is_array($this->payload) && isset($this->payload['curlopts']))
|
||||
{
|
||||
$curlopts = $this->payload['curlopts'];
|
||||
unset($this->payload['curlopts']);
|
||||
}
|
||||
|
||||
// Merge in any options that were passed in
|
||||
if (is_array($this->payload))
|
||||
{
|
||||
$query = array_merge($query, $this->payload);
|
||||
}
|
||||
|
||||
$return_curl_handle = isset($query['returnCurlHandle']) ? $query['returnCurlHandle'] : false;
|
||||
unset($query['returnCurlHandle']);
|
||||
|
||||
// Do a case-sensitive, natural order sort on the array keys.
|
||||
uksort($query, 'strcmp');
|
||||
|
||||
// Normalize JSON input
|
||||
if (isset($query['body']) && $query['body'] === '[]')
|
||||
{
|
||||
$query['body'] = '{}';
|
||||
}
|
||||
|
||||
// Create the string that needs to be hashed.
|
||||
$canonical_query_string = $this->util->encode_signature2($query['body']);
|
||||
|
||||
// Remove the default scheme from the domain.
|
||||
$domain = str_replace(array('http://', 'https://'), '', $this->endpoint);
|
||||
|
||||
// Parse our request.
|
||||
$parsed_url = parse_url('http://' . $domain);
|
||||
|
||||
// Set the proper host header.
|
||||
if (isset($parsed_url['port']) && (integer) $parsed_url['port'] !== 80 && (integer) $parsed_url['port'] !== 443)
|
||||
{
|
||||
$host_header = strtolower($parsed_url['host']) . ':' . $parsed_url['port'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$host_header = strtolower($parsed_url['host']);
|
||||
}
|
||||
|
||||
// Set the proper request URI.
|
||||
$request_uri = isset($parsed_url['path']) ? $parsed_url['path'] : '/';
|
||||
|
||||
// Generate the querystring from $query
|
||||
$this->querystring = $this->util->to_query_string($query);
|
||||
|
||||
// Gather information to pass along to other classes.
|
||||
$helpers = array(
|
||||
'utilities' => $this->utilities_class,
|
||||
'request' => $this->request_class,
|
||||
'response' => $this->response_class,
|
||||
);
|
||||
|
||||
// Compose the request.
|
||||
$request_url = ($this->use_ssl ? 'https://' : 'http://') . $domain;
|
||||
$request_url .= !isset($parsed_url['path']) ? '/' : '';
|
||||
|
||||
// Instantiate the request class
|
||||
$request = new $this->request_class($request_url, $this->proxy, $helpers, $this->credentials);
|
||||
$request->set_method('POST');
|
||||
//$request->set_body($this->querystring);
|
||||
//$headers['Content-Type'] = 'application/x-www-form-urlencoded; charset=utf-8';
|
||||
|
||||
// Signing using X-Amz-Target is handled differently.
|
||||
$headers['X-Amz-Target'] = $x_amz_target;
|
||||
$headers['Content-Type'] = 'application/x-amz-json-1.0';
|
||||
$request->set_body($query['body']);
|
||||
$this->querystring = $query['body'];
|
||||
|
||||
// Pass along registered stream callbacks
|
||||
if ($this->registered_streaming_read_callback)
|
||||
{
|
||||
$request->register_streaming_read_callback($this->registered_streaming_read_callback);
|
||||
}
|
||||
|
||||
if ($this->registered_streaming_write_callback)
|
||||
{
|
||||
$request->register_streaming_write_callback($this->registered_streaming_write_callback);
|
||||
}
|
||||
|
||||
// Add authentication headers
|
||||
// $headers['X-Amz-Nonce'] = $nonce;
|
||||
$headers['Date'] = $date;
|
||||
$headers['Content-Length'] = strlen($this->querystring);
|
||||
$headers['Content-MD5'] = $this->util->hex_to_base64(md5($this->querystring));
|
||||
$headers['Host'] = $host_header;
|
||||
|
||||
// Sort headers
|
||||
uksort($headers, 'strnatcasecmp');
|
||||
|
||||
// Prepare the string to sign (HTTP)
|
||||
$this->string_to_sign = "POST\n$request_uri\n\n";
|
||||
|
||||
// Add headers to request and compute the string to sign
|
||||
foreach ($headers as $header_key => $header_value)
|
||||
{
|
||||
// Strip linebreaks from header values as they're illegal and can allow for security issues
|
||||
$header_value = str_replace(array("\r", "\n"), '', $header_value);
|
||||
|
||||
// Add the header if it has a value
|
||||
if ($header_value !== '')
|
||||
{
|
||||
$request->add_header($header_key, $header_value);
|
||||
}
|
||||
|
||||
// Generate the string to sign
|
||||
if (
|
||||
substr(strtolower($header_key), 0, 8) === 'content-' ||
|
||||
strtolower($header_key) === 'date' ||
|
||||
strtolower($header_key) === 'expires' ||
|
||||
strtolower($header_key) === 'host' ||
|
||||
substr(strtolower($header_key), 0, 6) === 'x-amz-'
|
||||
)
|
||||
{
|
||||
$this->string_to_sign .= strtolower($header_key) . ':' . $header_value . "\n";
|
||||
$signed_headers[] = $header_key;
|
||||
}
|
||||
}
|
||||
|
||||
$this->string_to_sign .= "\n";
|
||||
|
||||
if (isset($query['body']) && $query['body'] !== '')
|
||||
{
|
||||
$this->string_to_sign .= $query['body'];
|
||||
}
|
||||
|
||||
// Convert from string-to-sign to bytes-to-sign
|
||||
$bytes_to_sign = hash('sha256', $this->string_to_sign, true);
|
||||
|
||||
// Hash the AWS secret key and generate a signature for the request.
|
||||
$signature = base64_encode(hash_hmac('sha256', $bytes_to_sign, $this->secret_key, true));
|
||||
|
||||
$headers['X-Amzn-Authorization'] = 'AWS3'
|
||||
. ' AWSAccessKeyId=' . $this->key
|
||||
. ',Algorithm=HmacSHA256'
|
||||
. ',SignedHeaders=' . implode(';', $signed_headers)
|
||||
. ',Signature=' . $signature;
|
||||
|
||||
$request->add_header('X-Amzn-Authorization', $headers['X-Amzn-Authorization']);
|
||||
$request->request_headers = $headers;
|
||||
|
||||
return $request;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,192 @@
|
|||
<?php
|
||||
/*
|
||||
* Copyright 2010-2012 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
* A copy of the License is located at
|
||||
*
|
||||
* http://aws.amazon.com/apache2.0
|
||||
*
|
||||
* or in the "license" file accompanying this file. This file is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
* express or implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/*%******************************************************************************************%*/
|
||||
// CLASS
|
||||
|
||||
/**
|
||||
* Implements support for Signature v3 (AWS Query).
|
||||
*
|
||||
* @version 2011.11.22
|
||||
* @license See the included NOTICE.md file for more information.
|
||||
* @copyright See the included NOTICE.md file for more information.
|
||||
* @link http://aws.amazon.com/php/ PHP Developer Center
|
||||
*/
|
||||
class AuthV3Query extends Signer implements Signable
|
||||
{
|
||||
/**
|
||||
* Constructs a new instance of the <AuthV3Query> class.
|
||||
*
|
||||
* @param string $endpoint (Required) The endpoint to direct the request to.
|
||||
* @param string $operation (Required) The operation to execute as a result of this request.
|
||||
* @param array $payload (Required) The options to use as part of the payload in the request.
|
||||
* @param CFCredential $credentials (Required) The credentials to use for signing and making requests.
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($endpoint, $operation, $payload, CFCredential $credentials)
|
||||
{
|
||||
parent::__construct($endpoint, $operation, $payload, $credentials);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a cURL handle with all of the required authentication bits set.
|
||||
*
|
||||
* @return resource A cURL handle ready for executing.
|
||||
*/
|
||||
public function authenticate()
|
||||
{
|
||||
// Determine signing values
|
||||
$current_time = time();
|
||||
$date = gmdate(CFUtilities::DATE_FORMAT_RFC2616, $current_time);
|
||||
$timestamp = gmdate(CFUtilities::DATE_FORMAT_ISO8601, $current_time);
|
||||
$nonce = $this->util->generate_guid();
|
||||
$curlopts = array();
|
||||
$signed_headers = array();
|
||||
|
||||
// Do we have an authentication token?
|
||||
if ($this->auth_token)
|
||||
{
|
||||
$headers['X-Amz-Security-Token'] = $this->auth_token;
|
||||
$query['SecurityToken'] = $this->auth_token;
|
||||
}
|
||||
|
||||
$query['Action'] = $this->operation;
|
||||
$query['Version'] = $this->api_version;
|
||||
|
||||
// Set custom CURLOPT settings
|
||||
if (is_array($this->payload) && isset($this->payload['curlopts']))
|
||||
{
|
||||
$curlopts = $this->payload['curlopts'];
|
||||
unset($this->payload['curlopts']);
|
||||
}
|
||||
|
||||
// Merge in any options that were passed in
|
||||
if (is_array($this->payload))
|
||||
{
|
||||
$query = array_merge($query, $this->payload);
|
||||
}
|
||||
|
||||
$return_curl_handle = isset($query['returnCurlHandle']) ? $query['returnCurlHandle'] : false;
|
||||
unset($query['returnCurlHandle']);
|
||||
|
||||
// Do a case-sensitive, natural order sort on the array keys.
|
||||
uksort($query, 'strcmp');
|
||||
$canonical_query_string = $this->util->to_signable_string($query);
|
||||
|
||||
// Remove the default scheme from the domain.
|
||||
$domain = str_replace(array('http://', 'https://'), '', $this->endpoint);
|
||||
|
||||
// Parse our request.
|
||||
$parsed_url = parse_url('http://' . $domain);
|
||||
|
||||
// Set the proper host header.
|
||||
if (isset($parsed_url['port']) && (integer) $parsed_url['port'] !== 80 && (integer) $parsed_url['port'] !== 443)
|
||||
{
|
||||
$host_header = strtolower($parsed_url['host']) . ':' . $parsed_url['port'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$host_header = strtolower($parsed_url['host']);
|
||||
}
|
||||
|
||||
// Set the proper request URI.
|
||||
$request_uri = isset($parsed_url['path']) ? $parsed_url['path'] : '/';
|
||||
|
||||
// Generate the querystring from $query
|
||||
$this->querystring = $this->util->to_query_string($query);
|
||||
|
||||
// Gather information to pass along to other classes.
|
||||
$helpers = array(
|
||||
'utilities' => $this->utilities_class,
|
||||
'request' => $this->request_class,
|
||||
'response' => $this->response_class,
|
||||
);
|
||||
|
||||
// Compose the request.
|
||||
$request_url = ($this->use_ssl ? 'https://' : 'http://') . $domain;
|
||||
$request_url .= !isset($parsed_url['path']) ? '/' : '';
|
||||
|
||||
// Instantiate the request class
|
||||
$request = new $this->request_class($request_url, $this->proxy, $helpers, $this->credentials);
|
||||
$request->set_method('POST');
|
||||
$request->set_body($this->querystring);
|
||||
$headers['Content-Type'] = 'application/x-www-form-urlencoded; charset=utf-8';
|
||||
|
||||
// Pass along registered stream callbacks
|
||||
if ($this->registered_streaming_read_callback)
|
||||
{
|
||||
$request->register_streaming_read_callback($this->registered_streaming_read_callback);
|
||||
}
|
||||
|
||||
if ($this->registered_streaming_write_callback)
|
||||
{
|
||||
$request->register_streaming_write_callback($this->registered_streaming_write_callback);
|
||||
}
|
||||
|
||||
// Add authentication headers
|
||||
$headers['X-Amz-Nonce'] = $nonce;
|
||||
$headers['Date'] = $date;
|
||||
$headers['Content-Length'] = strlen($this->querystring);
|
||||
$headers['Content-MD5'] = $this->util->hex_to_base64(md5($this->querystring));
|
||||
$headers['Host'] = $host_header;
|
||||
|
||||
// Sort headers
|
||||
uksort($headers, 'strnatcasecmp');
|
||||
|
||||
// Prepare the string to sign (HTTPS)
|
||||
$this->string_to_sign = $date . $nonce;
|
||||
|
||||
// Add headers to request and compute the string to sign
|
||||
foreach ($headers as $header_key => $header_value)
|
||||
{
|
||||
// Strip linebreaks from header values as they're illegal and can allow for security issues
|
||||
$header_value = str_replace(array("\r", "\n"), '', $header_value);
|
||||
|
||||
// Add the header if it has a value
|
||||
if ($header_value !== '')
|
||||
{
|
||||
$request->add_header($header_key, $header_value);
|
||||
}
|
||||
|
||||
// Generate the string to sign
|
||||
if (
|
||||
substr(strtolower($header_key), 0, 8) === 'content-' ||
|
||||
strtolower($header_key) === 'date' ||
|
||||
strtolower($header_key) === 'expires' ||
|
||||
strtolower($header_key) === 'host' ||
|
||||
substr(strtolower($header_key), 0, 6) === 'x-amz-'
|
||||
)
|
||||
{
|
||||
$signed_headers[] = $header_key;
|
||||
}
|
||||
}
|
||||
|
||||
// Hash the AWS secret key and generate a signature for the request.
|
||||
$signature = base64_encode(hash_hmac('sha256', $this->string_to_sign, $this->secret_key, true));
|
||||
|
||||
$headers['X-Amzn-Authorization'] = 'AWS3-HTTPS'
|
||||
. ' AWSAccessKeyId=' . $this->key
|
||||
. ',Algorithm=HmacSHA256'
|
||||
. ',SignedHeaders=' . implode(';', $signed_headers)
|
||||
. ',Signature=' . $signature;
|
||||
|
||||
$request->add_header('X-Amzn-Authorization', $headers['X-Amzn-Authorization']);
|
||||
$request->request_headers = $headers;
|
||||
|
||||
return $request;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,353 @@
|
|||
<?php
|
||||
/*
|
||||
* Copyright 2010-2012 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
* A copy of the License is located at
|
||||
*
|
||||
* http://aws.amazon.com/apache2.0
|
||||
*
|
||||
* or in the "license" file accompanying this file. This file is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
* express or implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/*%******************************************************************************************%*/
|
||||
// CLASS
|
||||
|
||||
/**
|
||||
* Implements support for Signature v4 (Query).
|
||||
*
|
||||
* @version 2011.01.03
|
||||
* @license See the included NOTICE.md file for more information.
|
||||
* @copyright See the included NOTICE.md file for more information.
|
||||
* @link http://aws.amazon.com/php/ PHP Developer Center
|
||||
*/
|
||||
class AuthV4JSON extends Signer implements Signable
|
||||
{
|
||||
/**
|
||||
* Constructs a new instance of the <AuthV4Query> class.
|
||||
*
|
||||
* @param string $endpoint (Required) The endpoint to direct the request to.
|
||||
* @param string $operation (Required) The operation to execute as a result of this request.
|
||||
* @param array $payload (Required) The options to use as part of the payload in the request.
|
||||
* @param CFCredential $credentials (Required) The credentials to use for signing and making requests.
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($endpoint, $operation, $payload, CFCredential $credentials)
|
||||
{
|
||||
parent::__construct($endpoint, $operation, $payload, $credentials);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a cURL handle with all of the required authentication bits set.
|
||||
*
|
||||
* @return resource A cURL handle ready for executing.
|
||||
*/
|
||||
public function authenticate()
|
||||
{
|
||||
// Determine signing values
|
||||
$current_time = time();
|
||||
$timestamp = gmdate(CFUtilities::DATE_FORMAT_SIGV4, $current_time);
|
||||
|
||||
// Initialize
|
||||
$x_amz_target = null;
|
||||
|
||||
$this->headers = array();
|
||||
$this->signed_headers = array();
|
||||
$this->canonical_headers = array();
|
||||
$this->query = array();
|
||||
|
||||
// Prepare JSON structure
|
||||
$decoded = json_decode($this->payload, true);
|
||||
$data = (array) (is_array($decoded) ? $decoded : $this->payload);
|
||||
unset($data['curlopts']);
|
||||
unset($data['returnCurlHandle']);
|
||||
$this->body = json_encode($data);
|
||||
if ($this->body === '' || $this->body === '[]')
|
||||
{
|
||||
$this->body = '{}';
|
||||
}
|
||||
|
||||
// Do we have an authentication token?
|
||||
if ($this->auth_token)
|
||||
{
|
||||
$this->headers['X-Amz-Security-Token'] = $this->auth_token;
|
||||
$this->query['SecurityToken'] = $this->auth_token;
|
||||
}
|
||||
|
||||
// Manage the key-value pairs that are used in the query.
|
||||
if (stripos($this->operation, 'x-amz-target') !== false)
|
||||
{
|
||||
$x_amz_target = trim(str_ireplace('x-amz-target:', '', $this->operation));
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->query['Action'] = $this->operation;
|
||||
}
|
||||
|
||||
// Only add it if it exists.
|
||||
if ($this->api_version)
|
||||
{
|
||||
$this->query['Version'] = $this->api_version;
|
||||
}
|
||||
|
||||
// Do a case-sensitive, natural order sort on the array keys.
|
||||
uksort($this->query, 'strcmp');
|
||||
|
||||
// Remove the default scheme from the domain.
|
||||
$domain = str_replace(array('http://', 'https://'), '', $this->endpoint);
|
||||
|
||||
// Parse our request.
|
||||
$parsed_url = parse_url('http://' . $domain);
|
||||
|
||||
// Set the proper host header.
|
||||
if (isset($parsed_url['port']) && (integer) $parsed_url['port'] !== 80 && (integer) $parsed_url['port'] !== 443)
|
||||
{
|
||||
$host_header = strtolower($parsed_url['host']) . ':' . $parsed_url['port'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$host_header = strtolower($parsed_url['host']);
|
||||
}
|
||||
|
||||
// Generate the querystring from $this->query
|
||||
$this->querystring = $this->util->to_query_string($this->query);
|
||||
|
||||
// Gather information to pass along to other classes.
|
||||
$helpers = array(
|
||||
'utilities' => $this->utilities_class,
|
||||
'request' => $this->request_class,
|
||||
'response' => $this->response_class,
|
||||
);
|
||||
|
||||
// Compose the request.
|
||||
$request_url = ($this->use_ssl ? 'https://' : 'http://') . $domain;
|
||||
$request_url .= !isset($parsed_url['path']) ? '/' : '';
|
||||
|
||||
// Instantiate the request class
|
||||
$request = new $this->request_class($request_url, $this->proxy, $helpers, $this->credentials);
|
||||
$request->set_method('POST');
|
||||
$request->set_body($this->body);
|
||||
$this->querystring = $this->body;
|
||||
$this->headers['Content-Type'] = 'application/x-amz-json-1.1';
|
||||
$this->headers['X-Amz-Target'] = $x_amz_target;
|
||||
|
||||
// Pass along registered stream callbacks
|
||||
if ($this->registered_streaming_read_callback)
|
||||
{
|
||||
$request->register_streaming_read_callback($this->registered_streaming_read_callback);
|
||||
}
|
||||
|
||||
if ($this->registered_streaming_write_callback)
|
||||
{
|
||||
$request->register_streaming_write_callback($this->registered_streaming_write_callback);
|
||||
}
|
||||
|
||||
// Add authentication headers
|
||||
$this->headers['X-Amz-Date'] = $timestamp;
|
||||
$this->headers['Content-Length'] = strlen($this->querystring);
|
||||
$this->headers['Host'] = $host_header;
|
||||
|
||||
// Sort headers
|
||||
uksort($this->headers, 'strnatcasecmp');
|
||||
|
||||
// Add headers to request and compute the string to sign
|
||||
foreach ($this->headers as $header_key => $header_value)
|
||||
{
|
||||
// Strip linebreaks from header values as they're illegal and can allow for security issues
|
||||
$header_value = str_replace(array("\r", "\n"), '', $header_value);
|
||||
|
||||
$request->add_header($header_key, $header_value);
|
||||
$this->canonical_headers[] = strtolower($header_key) . ':' . $header_value;
|
||||
|
||||
$this->signed_headers[] = strtolower($header_key);
|
||||
}
|
||||
|
||||
$this->headers['Authorization'] = $this->authorization($timestamp);
|
||||
$request->add_header('Authorization', $this->headers['Authorization']);
|
||||
$request->request_headers = $this->headers;
|
||||
|
||||
return $request;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the authorization string to use for the request.
|
||||
*
|
||||
* @param string $datetime (Required) The current timestamp.
|
||||
* @return string The authorization string.
|
||||
*/
|
||||
protected function authorization($datetime)
|
||||
{
|
||||
$access_key_id = $this->key;
|
||||
|
||||
$parts = array();
|
||||
$parts[] = "AWS4-HMAC-SHA256 Credential=${access_key_id}/" . $this->credential_string($datetime);
|
||||
$parts[] = 'SignedHeaders=' . implode(';', $this->signed_headers);
|
||||
$parts[] = 'Signature=' . $this->hex16($this->signature($datetime));
|
||||
|
||||
return implode(',', $parts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the signature.
|
||||
*
|
||||
* @param string $datetime (Required) The current timestamp.
|
||||
* @return string The signature.
|
||||
*/
|
||||
protected function signature($datetime)
|
||||
{
|
||||
$k_date = $this->hmac('AWS4' . $this->secret_key, substr($datetime, 0, 8));
|
||||
$k_region = $this->hmac($k_date, $this->region());
|
||||
$k_service = $this->hmac($k_region, $this->service());
|
||||
$k_credentials = $this->hmac($k_service, 'aws4_request');
|
||||
$signature = $this->hmac($k_credentials, $this->string_to_sign($datetime));
|
||||
|
||||
return $signature;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the string to sign.
|
||||
*
|
||||
* @param string $datetime (Required) The current timestamp.
|
||||
* @return string The string to sign.
|
||||
*/
|
||||
protected function string_to_sign($datetime)
|
||||
{
|
||||
$parts = array();
|
||||
$parts[] = 'AWS4-HMAC-SHA256';
|
||||
$parts[] = $datetime;
|
||||
$parts[] = $this->credential_string($datetime);
|
||||
$parts[] = $this->hex16($this->hash($this->canonical_request()));
|
||||
|
||||
$this->string_to_sign = implode("\n", $parts);
|
||||
|
||||
return $this->string_to_sign;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the credential string to use for signing.
|
||||
*
|
||||
* @param string $datetime (Required) The current timestamp.
|
||||
* @return string The credential string.
|
||||
*/
|
||||
protected function credential_string($datetime)
|
||||
{
|
||||
$parts = array();
|
||||
$parts[] = substr($datetime, 0, 8);
|
||||
$parts[] = $this->region();
|
||||
$parts[] = $this->service();
|
||||
$parts[] = 'aws4_request';
|
||||
|
||||
return implode('/', $parts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the canonical request.
|
||||
*
|
||||
* @return string The canonical request.
|
||||
*/
|
||||
protected function canonical_request()
|
||||
{
|
||||
$parts = array();
|
||||
$parts[] = 'POST';
|
||||
$parts[] = $this->canonical_uri();
|
||||
$parts[] = ''; // $parts[] = $this->canonical_querystring();
|
||||
$parts[] = implode("\n", $this->canonical_headers) . "\n";
|
||||
$parts[] = implode(';', $this->signed_headers);
|
||||
$parts[] = $this->hex16($this->hash($this->body));
|
||||
|
||||
$this->canonical_request = implode("\n", $parts);
|
||||
|
||||
return $this->canonical_request;
|
||||
}
|
||||
|
||||
/**
|
||||
* The region ID to use in the signature.
|
||||
*
|
||||
* @return return The region ID.
|
||||
*/
|
||||
protected function region()
|
||||
{
|
||||
$pieces = explode('.', $this->endpoint);
|
||||
|
||||
// Handle cases with single/no region (i.e. service.region.amazonaws.com vs. service.amazonaws.com)
|
||||
if (count($pieces < 4))
|
||||
{
|
||||
return 'us-east-1';
|
||||
}
|
||||
|
||||
return $pieces[1];
|
||||
}
|
||||
|
||||
/**
|
||||
* The service ID to use in the signature.
|
||||
*
|
||||
* @return return The service ID.
|
||||
*/
|
||||
protected function service()
|
||||
{
|
||||
$pieces = explode('.', $this->endpoint);
|
||||
return $pieces[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* The request URI path.
|
||||
*
|
||||
* @return string The request URI path.
|
||||
*/
|
||||
protected function canonical_uri()
|
||||
{
|
||||
return '/';
|
||||
}
|
||||
|
||||
/**
|
||||
* The canonical query string.
|
||||
*
|
||||
* @return string The canonical query string.
|
||||
*/
|
||||
protected function canonical_querystring()
|
||||
{
|
||||
if (!isset($this->canonical_querystring))
|
||||
{
|
||||
$this->canonical_querystring = $this->util->to_signable_string($this->query);
|
||||
}
|
||||
|
||||
return $this->canonical_querystring;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hex16-pack the data.
|
||||
*
|
||||
* @param string $value (Required) The data to hex16 pack.
|
||||
* @return string The hex16-packed data.
|
||||
*/
|
||||
protected function hex16($value)
|
||||
{
|
||||
$result = unpack('H*', $value);
|
||||
return reset($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies HMAC SHA-256 encryption to the string, salted by the key.
|
||||
*
|
||||
* @return string Raw HMAC SHA-256 hashed string.
|
||||
*/
|
||||
protected function hmac($key, $string)
|
||||
{
|
||||
return hash_hmac('sha256', $string, $key, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* SHA-256 hashes the string.
|
||||
*
|
||||
* @return string Raw SHA-256 hashed string.
|
||||
*/
|
||||
protected function hash($string)
|
||||
{
|
||||
return hash('sha256', $string, true);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,345 @@
|
|||
<?php
|
||||
/*
|
||||
* Copyright 2010-2012 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
* A copy of the License is located at
|
||||
*
|
||||
* http://aws.amazon.com/apache2.0
|
||||
*
|
||||
* or in the "license" file accompanying this file. This file is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
* express or implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/*%******************************************************************************************%*/
|
||||
// CLASS
|
||||
|
||||
/**
|
||||
* Implements support for Signature v4 (Query).
|
||||
*
|
||||
* @version 2011.01.03
|
||||
* @license See the included NOTICE.md file for more information.
|
||||
* @copyright See the included NOTICE.md file for more information.
|
||||
* @link http://aws.amazon.com/php/ PHP Developer Center
|
||||
*/
|
||||
class AuthV4Query extends Signer implements Signable
|
||||
{
|
||||
/**
|
||||
* Constructs a new instance of the <AuthV4Query> class.
|
||||
*
|
||||
* @param string $endpoint (Required) The endpoint to direct the request to.
|
||||
* @param string $operation (Required) The operation to execute as a result of this request.
|
||||
* @param array $payload (Required) The options to use as part of the payload in the request.
|
||||
* @param CFCredential $credentials (Required) The credentials to use for signing and making requests.
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($endpoint, $operation, $payload, CFCredential $credentials)
|
||||
{
|
||||
parent::__construct($endpoint, $operation, $payload, $credentials);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a cURL handle with all of the required authentication bits set.
|
||||
*
|
||||
* @return resource A cURL handle ready for executing.
|
||||
*/
|
||||
public function authenticate()
|
||||
{
|
||||
// Determine signing values
|
||||
$current_time = time();
|
||||
$timestamp = gmdate(CFUtilities::DATE_FORMAT_SIGV4, $current_time);
|
||||
|
||||
// Initialize
|
||||
$x_amz_target = null;
|
||||
|
||||
$this->headers = array();
|
||||
$this->signed_headers = array();
|
||||
$this->canonical_headers = array();
|
||||
$this->query = array('body' => is_array($this->payload) ? $this->payload : array());
|
||||
|
||||
// Do we have an authentication token?
|
||||
if ($this->auth_token)
|
||||
{
|
||||
$this->headers['X-Amz-Security-Token'] = $this->auth_token;
|
||||
$this->query['body']['SecurityToken'] = $this->auth_token;
|
||||
}
|
||||
|
||||
// Manage the key-value pairs that are used in the query.
|
||||
if (stripos($this->operation, 'x-amz-target') !== false)
|
||||
{
|
||||
$x_amz_target = trim(str_ireplace('x-amz-target:', '', $this->operation));
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->query['body']['Action'] = $this->operation;
|
||||
}
|
||||
|
||||
// Only add it if it exists.
|
||||
if ($this->api_version)
|
||||
{
|
||||
$this->query['body']['Version'] = $this->api_version;
|
||||
}
|
||||
|
||||
// Do a case-sensitive, natural order sort on the array keys.
|
||||
uksort($this->query['body'], 'strcmp');
|
||||
|
||||
// Remove the default scheme from the domain.
|
||||
$domain = str_replace(array('http://', 'https://'), '', $this->endpoint);
|
||||
|
||||
// Parse our request.
|
||||
$parsed_url = parse_url('http://' . $domain);
|
||||
|
||||
// Set the proper host header.
|
||||
if (isset($parsed_url['port']) && (integer) $parsed_url['port'] !== 80 && (integer) $parsed_url['port'] !== 443)
|
||||
{
|
||||
$host_header = strtolower($parsed_url['host']) . ':' . $parsed_url['port'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$host_header = strtolower($parsed_url['host']);
|
||||
}
|
||||
|
||||
// Generate the querystring from $this->query
|
||||
$this->querystring = $this->util->to_query_string($this->query);
|
||||
|
||||
// Gather information to pass along to other classes.
|
||||
$helpers = array(
|
||||
'utilities' => $this->utilities_class,
|
||||
'request' => $this->request_class,
|
||||
'response' => $this->response_class,
|
||||
);
|
||||
|
||||
// Compose the request.
|
||||
$request_url = ($this->use_ssl ? 'https://' : 'http://') . $domain;
|
||||
$request_url .= !isset($parsed_url['path']) ? '/' : '';
|
||||
|
||||
// Instantiate the request class
|
||||
$request = new $this->request_class($request_url, $this->proxy, $helpers, $this->credentials);
|
||||
$request->set_method('POST');
|
||||
$request->set_body($this->canonical_querystring());
|
||||
$this->querystring = $this->canonical_querystring();
|
||||
|
||||
$this->headers['Content-Type'] = 'application/x-www-form-urlencoded; charset=utf-8';
|
||||
$this->headers['X-Amz-Target'] = $x_amz_target;
|
||||
|
||||
// Pass along registered stream callbacks
|
||||
if ($this->registered_streaming_read_callback)
|
||||
{
|
||||
$request->register_streaming_read_callback($this->registered_streaming_read_callback);
|
||||
}
|
||||
|
||||
if ($this->registered_streaming_write_callback)
|
||||
{
|
||||
$request->register_streaming_write_callback($this->registered_streaming_write_callback);
|
||||
}
|
||||
|
||||
// Add authentication headers
|
||||
$this->headers['X-Amz-Date'] = $timestamp;
|
||||
$this->headers['Content-Length'] = strlen($this->querystring);
|
||||
$this->headers['Content-MD5'] = $this->util->hex_to_base64(md5($this->querystring));
|
||||
$this->headers['Host'] = $host_header;
|
||||
|
||||
// Sort headers
|
||||
uksort($this->headers, 'strnatcasecmp');
|
||||
|
||||
// Add headers to request and compute the string to sign
|
||||
foreach ($this->headers as $header_key => $header_value)
|
||||
{
|
||||
// Strip linebreaks from header values as they're illegal and can allow for security issues
|
||||
$header_value = str_replace(array("\r", "\n"), '', $header_value);
|
||||
|
||||
$request->add_header($header_key, $header_value);
|
||||
$this->canonical_headers[] = strtolower($header_key) . ':' . $header_value;
|
||||
|
||||
$this->signed_headers[] = strtolower($header_key);
|
||||
}
|
||||
|
||||
$this->headers['Authorization'] = $this->authorization($timestamp);
|
||||
|
||||
$request->add_header('Authorization', $this->headers['Authorization']);
|
||||
$request->request_headers = $this->headers;
|
||||
|
||||
return $request;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the authorization string to use for the request.
|
||||
*
|
||||
* @param string $datetime (Required) The current timestamp.
|
||||
* @return string The authorization string.
|
||||
*/
|
||||
protected function authorization($datetime)
|
||||
{
|
||||
$access_key_id = $this->key;
|
||||
|
||||
$parts = array();
|
||||
$parts[] = "AWS4-HMAC-SHA256 Credential=${access_key_id}/" . $this->credential_string($datetime);
|
||||
$parts[] = 'SignedHeaders=' . implode(';', $this->signed_headers);
|
||||
$parts[] = 'Signature=' . $this->hex16($this->signature($datetime));
|
||||
|
||||
return implode(',', $parts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the signature.
|
||||
*
|
||||
* @param string $datetime (Required) The current timestamp.
|
||||
* @return string The signature.
|
||||
*/
|
||||
protected function signature($datetime)
|
||||
{
|
||||
$k_date = $this->hmac('AWS4' . $this->secret_key, substr($datetime, 0, 8));
|
||||
$k_region = $this->hmac($k_date, $this->region());
|
||||
$k_service = $this->hmac($k_region, $this->service());
|
||||
$k_credentials = $this->hmac($k_service, 'aws4_request');
|
||||
$signature = $this->hmac($k_credentials, $this->string_to_sign($datetime));
|
||||
|
||||
return $signature;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the string to sign.
|
||||
*
|
||||
* @param string $datetime (Required) The current timestamp.
|
||||
* @return string The string to sign.
|
||||
*/
|
||||
protected function string_to_sign($datetime)
|
||||
{
|
||||
$parts = array();
|
||||
$parts[] = 'AWS4-HMAC-SHA256';
|
||||
$parts[] = $datetime;
|
||||
$parts[] = $this->credential_string($datetime);
|
||||
$parts[] = $this->hex16($this->hash($this->canonical_request()));
|
||||
|
||||
$this->string_to_sign = implode("\n", $parts);
|
||||
|
||||
return $this->string_to_sign;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the credential string to use for signing.
|
||||
*
|
||||
* @param string $datetime (Required) The current timestamp.
|
||||
* @return string The credential string.
|
||||
*/
|
||||
protected function credential_string($datetime)
|
||||
{
|
||||
$parts = array();
|
||||
$parts[] = substr($datetime, 0, 8);
|
||||
$parts[] = $this->region();
|
||||
$parts[] = $this->service();
|
||||
$parts[] = 'aws4_request';
|
||||
|
||||
return implode('/', $parts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the canonical request.
|
||||
*
|
||||
* @return string The canonical request.
|
||||
*/
|
||||
protected function canonical_request()
|
||||
{
|
||||
$parts = array();
|
||||
$parts[] = 'POST';
|
||||
$parts[] = $this->canonical_uri();
|
||||
$parts[] = ''; // $parts[] = $this->canonical_querystring();
|
||||
$parts[] = implode("\n", $this->canonical_headers) . "\n";
|
||||
$parts[] = implode(';', $this->signed_headers);
|
||||
$parts[] = $this->hex16($this->hash($this->canonical_querystring()));
|
||||
|
||||
$this->canonical_request = implode("\n", $parts);
|
||||
|
||||
return $this->canonical_request;
|
||||
}
|
||||
|
||||
/**
|
||||
* The region ID to use in the signature.
|
||||
*
|
||||
* @return return The region ID.
|
||||
*/
|
||||
protected function region()
|
||||
{
|
||||
$pieces = explode('.', $this->endpoint);
|
||||
|
||||
// Handle cases with single/no region (i.e. service.region.amazonaws.com vs. service.amazonaws.com)
|
||||
if (count($pieces < 4))
|
||||
{
|
||||
return 'us-east-1';
|
||||
}
|
||||
|
||||
return $pieces[1];
|
||||
}
|
||||
|
||||
/**
|
||||
* The service ID to use in the signature.
|
||||
*
|
||||
* @return return The service ID.
|
||||
*/
|
||||
protected function service()
|
||||
{
|
||||
$pieces = explode('.', $this->endpoint);
|
||||
return ($pieces[0] === 'email') ? 'ses' : $pieces[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* The request URI path.
|
||||
*
|
||||
* @return string The request URI path.
|
||||
*/
|
||||
protected function canonical_uri()
|
||||
{
|
||||
return '/';
|
||||
}
|
||||
|
||||
/**
|
||||
* The canonical query string.
|
||||
*
|
||||
* @return string The canonical query string.
|
||||
*/
|
||||
protected function canonical_querystring()
|
||||
{
|
||||
if (!isset($this->canonical_querystring))
|
||||
{
|
||||
$this->canonical_querystring = $this->util->to_signable_string($this->query['body']);
|
||||
}
|
||||
|
||||
return $this->canonical_querystring;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hex16-pack the data.
|
||||
*
|
||||
* @param string $value (Required) The data to hex16 pack.
|
||||
* @return string The hex16-packed data.
|
||||
*/
|
||||
protected function hex16($value)
|
||||
{
|
||||
$result = unpack('H*', $value);
|
||||
return reset($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies HMAC SHA-256 encryption to the string, salted by the key.
|
||||
*
|
||||
* @return string Raw HMAC SHA-256 hashed string.
|
||||
*/
|
||||
protected function hmac($key, $string)
|
||||
{
|
||||
return hash_hmac('sha256', $string, $key, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* SHA-256 hashes the string.
|
||||
*
|
||||
* @return string Raw SHA-256 hashed string.
|
||||
*/
|
||||
protected function hash($string)
|
||||
{
|
||||
return hash('sha256', $string, true);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
<?php
|
||||
/*
|
||||
* Copyright 2010-2012 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
* A copy of the License is located at
|
||||
*
|
||||
* http://aws.amazon.com/apache2.0
|
||||
*
|
||||
* or in the "license" file accompanying this file. This file is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
* express or implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/*%******************************************************************************************%*/
|
||||
// CLASS
|
||||
|
||||
/**
|
||||
* The abstract class that serves as the base class that signer classes extend.
|
||||
*
|
||||
* @version 2011.11.22
|
||||
* @license See the included NOTICE.md file for more information.
|
||||
* @copyright See the included NOTICE.md file for more information.
|
||||
* @link http://aws.amazon.com/php/ PHP Developer Center
|
||||
*/
|
||||
abstract class Signer
|
||||
{
|
||||
/**
|
||||
* The endpoint to direct the request to.
|
||||
*/
|
||||
public $endpoint;
|
||||
|
||||
/**
|
||||
* The operation to execute as a result of this request.
|
||||
*/
|
||||
public $operation;
|
||||
|
||||
/**
|
||||
* The options to use as part of the payload in the request.
|
||||
*/
|
||||
public $payload;
|
||||
|
||||
/**
|
||||
* The credentials to use for signing and making requests.
|
||||
*/
|
||||
public $credentials;
|
||||
|
||||
|
||||
/**
|
||||
* Constructs a new instance of the implementing class.
|
||||
*
|
||||
* @param string $endpoint (Required) The endpoint to direct the request to.
|
||||
* @param string $operation (Required) The operation to execute as a result of this request.
|
||||
* @param array $payload (Required) The options to use as part of the payload in the request.
|
||||
* @param CFCredential $credentials (Required) The credentials to use for signing and making requests.
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($endpoint, $operation, $payload, CFCredential $credentials)
|
||||
{
|
||||
$this->endpoint = $endpoint;
|
||||
$this->operation = $operation;
|
||||
$this->payload = $payload;
|
||||
$this->credentials = $credentials;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
Copyright (c) 2006-2010 Ryan Parman, Foleeo Inc., and contributors. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are
|
||||
permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this list of
|
||||
conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
of conditions and the following disclaimer in the documentation and/or other materials
|
||||
provided with the distribution.
|
||||
|
||||
* Neither the name of Ryan Parman, Foleeo Inc. nor the names of its contributors may be used to
|
||||
endorse or promote products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
|
||||
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
|
||||
AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
|
@ -0,0 +1 @@
|
|||
A simple caching system for PHP5 that provides a single interface for a variety of storage types.
|
|
@ -0,0 +1,5 @@
|
|||
The .sql files in this directory contain the code to create the tables for database caching.
|
||||
|
||||
If you're not using database caching, you can safely ignore these.
|
||||
|
||||
If you ARE using database caching, simply load the correct *.sql file into your database to set up the required tables.
|
|
@ -0,0 +1,7 @@
|
|||
CREATE TABLE `cache` (
|
||||
`id` char(40) NOT NULL default '',
|
||||
`expires` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
|
||||
`data` longtext,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `id` (`id`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8
|
|
@ -0,0 +1,6 @@
|
|||
CREATE TABLE "cache" (
|
||||
expires timestamp without time zone NOT NULL,
|
||||
id character(40) NOT NULL,
|
||||
data text NOT NULL
|
||||
)
|
||||
WITH (OIDS=TRUE);
|
|
@ -0,0 +1,2 @@
|
|||
CREATE TABLE cache (id TEXT, expires NUMERIC, data BLOB);
|
||||
CREATE UNIQUE INDEX idx ON cache(id ASC);
|
|
@ -0,0 +1,126 @@
|
|||
<?php
|
||||
/**
|
||||
* Container for all APC-based cache methods. Inherits additional methods from <CacheCore>. Adheres
|
||||
* to the ICacheCore interface.
|
||||
*
|
||||
* @version 2012.04.17
|
||||
* @copyright 2006-2012 Ryan Parman
|
||||
* @copyright 2006-2010 Foleeo, Inc.
|
||||
* @copyright 2012 Amazon.com, Inc. or its affiliates.
|
||||
* @copyright 2008-2010 Contributors
|
||||
* @license http://opensource.org/licenses/bsd-license.php Simplified BSD License
|
||||
* @link http://github.com/skyzyx/cachecore CacheCore
|
||||
* @link http://getcloudfusion.com CloudFusion
|
||||
* @link http://php.net/apc APC
|
||||
*/
|
||||
class CacheAPC extends CacheCore implements ICacheCore
|
||||
{
|
||||
|
||||
/*%******************************************************************************************%*/
|
||||
// CONSTRUCTOR
|
||||
|
||||
/**
|
||||
* Constructs a new instance of this class.
|
||||
*
|
||||
* @param string $name (Required) A name to uniquely identify the cache object.
|
||||
* @param string $location (Optional) The location to store the cache object in. This may vary by cache method. The default value is NULL.
|
||||
* @param integer $expires (Optional) The number of seconds until a cache object is considered stale. The default value is 0.
|
||||
* @param boolean $gzip (Optional) Whether data should be gzipped before being stored. The default value is true.
|
||||
* @return object Reference to the cache object.
|
||||
*/
|
||||
public function __construct($name, $location = null, $expires = 0, $gzip = true)
|
||||
{
|
||||
parent::__construct($name, null, $expires, $gzip);
|
||||
$this->id = $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new cache.
|
||||
*
|
||||
* @param mixed $data (Required) The data to cache.
|
||||
* @return boolean Whether the operation was successful.
|
||||
*/
|
||||
public function create($data)
|
||||
{
|
||||
$data = serialize($data);
|
||||
$data = $this->gzip ? gzcompress($data) : $data;
|
||||
|
||||
return apc_add($this->id, $data, $this->expires);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a cache.
|
||||
*
|
||||
* @return mixed Either the content of the cache object, or boolean `false`.
|
||||
*/
|
||||
public function read()
|
||||
{
|
||||
if ($data = apc_fetch($this->id))
|
||||
{
|
||||
$data = $this->gzip ? gzuncompress($data) : $data;
|
||||
return unserialize($data);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates an existing cache.
|
||||
*
|
||||
* @param mixed $data (Required) The data to cache.
|
||||
* @return boolean Whether the operation was successful.
|
||||
*/
|
||||
public function update($data)
|
||||
{
|
||||
$data = serialize($data);
|
||||
$data = $this->gzip ? gzcompress($data) : $data;
|
||||
|
||||
return apc_store($this->id, $data, $this->expires);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a cache.
|
||||
*
|
||||
* @return boolean Whether the operation was successful.
|
||||
*/
|
||||
public function delete()
|
||||
{
|
||||
return apc_delete($this->id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implemented here, but always returns `false`. APC manages its own expirations.
|
||||
*
|
||||
* @return boolean Whether the cache is expired or not.
|
||||
*/
|
||||
public function is_expired()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implemented here, but always returns `false`. APC manages its own expirations.
|
||||
*
|
||||
* @return mixed Either the Unix time stamp of the cache creation, or boolean `false`.
|
||||
*/
|
||||
public function timestamp()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implemented here, but always returns `false`. APC manages its own expirations.
|
||||
*
|
||||
* @return boolean Whether the operation was successful.
|
||||
*/
|
||||
public function reset()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*%******************************************************************************************%*/
|
||||
// EXCEPTIONS
|
||||
|
||||
class CacheAPC_Exception extends CacheCore_Exception {}
|
|
@ -0,0 +1,160 @@
|
|||
<?php
|
||||
/**
|
||||
* Container for all shared caching methods. This is not intended to be instantiated directly, but is
|
||||
* extended by the cache-specific classes.
|
||||
*
|
||||
* @version 2012.04.17
|
||||
* @copyright 2006-2012 Ryan Parman
|
||||
* @copyright 2006-2010 Foleeo, Inc.
|
||||
* @copyright 2012 Amazon.com, Inc. or its affiliates.
|
||||
* @copyright 2008-2010 Contributors
|
||||
* @license http://opensource.org/licenses/bsd-license.php Simplified BSD License
|
||||
* @link http://github.com/skyzyx/cachecore CacheCore
|
||||
* @link http://getcloudfusion.com CloudFusion
|
||||
*/
|
||||
class CacheCore
|
||||
{
|
||||
/**
|
||||
* A name to uniquely identify the cache object by.
|
||||
*/
|
||||
var $name;
|
||||
|
||||
/**
|
||||
* Where to store the cache.
|
||||
*/
|
||||
var $location;
|
||||
|
||||
/**
|
||||
* The number of seconds before a cache object is considered stale.
|
||||
*/
|
||||
var $expires;
|
||||
|
||||
/**
|
||||
* Used internally to uniquely identify the location + name of the cache object.
|
||||
*/
|
||||
var $id;
|
||||
|
||||
/**
|
||||
* Stores the time when the cache object was created.
|
||||
*/
|
||||
var $timestamp;
|
||||
|
||||
/**
|
||||
* Stores whether or not the content should be gzipped when stored
|
||||
*/
|
||||
var $gzip;
|
||||
|
||||
|
||||
/*%******************************************************************************************%*/
|
||||
// CONSTRUCTOR
|
||||
|
||||
/**
|
||||
* Constructs a new instance of this class.
|
||||
*
|
||||
* @param string $name (Required) A name to uniquely identify the cache object.
|
||||
* @param string $location (Optional) The location to store the cache object in. This may vary by cache method. The default value is NULL.
|
||||
* @param integer $expires (Optional) The number of seconds until a cache object is considered stale. The default value is 0.
|
||||
* @param boolean $gzip (Optional) Whether data should be gzipped before being stored. The default value is true.
|
||||
* @return object Reference to the cache object.
|
||||
*/
|
||||
public function __construct($name, $location = null, $expires = 0, $gzip = true)
|
||||
{
|
||||
if (!extension_loaded('zlib'))
|
||||
{
|
||||
$gzip = false;
|
||||
}
|
||||
|
||||
$this->name = $name;
|
||||
$this->location = $location;
|
||||
$this->expires = $expires;
|
||||
$this->gzip = $gzip;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows for chaining from the constructor. Requires PHP 5.3 or newer.
|
||||
*
|
||||
* @param string $name (Required) A name to uniquely identify the cache object.
|
||||
* @param string $location (Optional) The location to store the cache object in. This may vary by cache method. The default value is NULL.
|
||||
* @param integer $expires (Optional) The number of seconds until a cache object is considered stale. The default value is 0.
|
||||
* @param boolean $gzip (Optional) Whether data should be gzipped before being stored. The default value is true.
|
||||
* @return object Reference to the cache object.
|
||||
*/
|
||||
public static function init($name, $location = null, $expires = 0, $gzip = true)
|
||||
{
|
||||
if (version_compare(PHP_VERSION, '5.3.0', '<'))
|
||||
{
|
||||
throw new Exception('PHP 5.3 or newer is required to use CacheCore::init().');
|
||||
}
|
||||
|
||||
$self = get_called_class();
|
||||
return new $self($name, $location, $expires, $gzip);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the number of seconds until a cache expires.
|
||||
*
|
||||
* @param integer $expires (Optional) The number of seconds until a cache object is considered stale. The default value is 0.
|
||||
* @return $this
|
||||
*/
|
||||
public function expire_in($seconds)
|
||||
{
|
||||
$this->expires = $seconds;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides a simple, straightforward cache-logic mechanism. Useful for non-complex response caches.
|
||||
*
|
||||
* @param string|function $callback (Required) The name of the function to fire when we need to fetch new data to cache.
|
||||
* @param array params (Optional) Parameters to pass into the callback function, as an array.
|
||||
* @return array The cached data being requested.
|
||||
*/
|
||||
public function response_manager($callback, $params = null)
|
||||
{
|
||||
// Automatically handle $params values.
|
||||
$params = is_array($params) ? $params : array($params);
|
||||
|
||||
if ($data = $this->read())
|
||||
{
|
||||
if ($this->is_expired())
|
||||
{
|
||||
if ($data = call_user_func_array($callback, $params))
|
||||
{
|
||||
$this->update($data);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->reset();
|
||||
$data = $this->read();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($data = call_user_func_array($callback, $params))
|
||||
{
|
||||
$this->create($data);
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*%******************************************************************************************%*/
|
||||
// CORE DEPENDENCIES
|
||||
|
||||
// Include the ICacheCore interface.
|
||||
if (file_exists(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'icachecore.interface.php'))
|
||||
{
|
||||
include_once dirname(__FILE__) . DIRECTORY_SEPARATOR . 'icachecore.interface.php';
|
||||
}
|
||||
|
||||
|
||||
/*%******************************************************************************************%*/
|
||||
// EXCEPTIONS
|
||||
|
||||
class CacheCore_Exception extends Exception {}
|
|
@ -0,0 +1,189 @@
|
|||
<?php
|
||||
/**
|
||||
* Container for all file-based cache methods. Inherits additional methods from <CacheCore>. Adheres
|
||||
* to the ICacheCore interface.
|
||||
*
|
||||
* @version 2012.04.17
|
||||
* @copyright 2006-2012 Ryan Parman
|
||||
* @copyright 2006-2010 Foleeo, Inc.
|
||||
* @copyright 2012 Amazon.com, Inc. or its affiliates.
|
||||
* @copyright 2008-2010 Contributors
|
||||
* @license http://opensource.org/licenses/bsd-license.php Simplified BSD License
|
||||
* @link http://github.com/skyzyx/cachecore CacheCore
|
||||
* @link http://getcloudfusion.com CloudFusion
|
||||
*/
|
||||
class CacheFile extends CacheCore implements ICacheCore
|
||||
{
|
||||
|
||||
/*%******************************************************************************************%*/
|
||||
// CONSTRUCTOR
|
||||
|
||||
/**
|
||||
* Constructs a new instance of this class.
|
||||
*
|
||||
* @param string $name (Required) A name to uniquely identify the cache object.
|
||||
* @param string $location (Optional) The location to store the cache object in. This may vary by cache method. The default value is NULL.
|
||||
* @param integer $expires (Optional) The number of seconds until a cache object is considered stale. The default value is 0.
|
||||
* @param boolean $gzip (Optional) Whether data should be gzipped before being stored. The default value is true.
|
||||
* @return object Reference to the cache object.
|
||||
*/
|
||||
public function __construct($name, $location = null, $expires = 0, $gzip = true)
|
||||
{
|
||||
parent::__construct($name, $location, $expires, $gzip);
|
||||
$this->id = $this->location . '/' . $this->name . '.cache';
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new cache.
|
||||
*
|
||||
* @param mixed $data (Required) The data to cache.
|
||||
* @return boolean Whether the operation was successful.
|
||||
*/
|
||||
public function create($data)
|
||||
{
|
||||
if (file_exists($this->id))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
elseif (realpath($this->location) && file_exists($this->location) && is_writeable($this->location))
|
||||
{
|
||||
$data = serialize($data);
|
||||
$data = $this->gzip ? gzcompress($data) : $data;
|
||||
|
||||
return (bool) file_put_contents($this->id, $data);
|
||||
}
|
||||
elseif (realpath($this->location) && file_exists($this->location))
|
||||
{
|
||||
throw new CacheFile_Exception('The file system location "' . $this->location . '" is not writable. Check the file system permissions for this directory.');
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new CacheFile_Exception('The file system location "' . $this->location . '" does not exist. Create the directory, or double-check any relative paths that may have been set.');
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a cache.
|
||||
*
|
||||
* @return mixed Either the content of the cache object, or boolean `false`.
|
||||
*/
|
||||
public function read()
|
||||
{
|
||||
if (file_exists($this->id) && is_readable($this->id))
|
||||
{
|
||||
$data = file_get_contents($this->id);
|
||||
$data = $this->gzip ? gzuncompress($data) : $data;
|
||||
$data = unserialize($data);
|
||||
|
||||
if ($data === false)
|
||||
{
|
||||
/*
|
||||
This should only happen when someone changes the gzip settings and there is
|
||||
existing data or someone has been mucking about in the cache folder manually.
|
||||
Delete the bad entry since the file cache doesn't clean up after itself and
|
||||
then return false so fresh data will be retrieved.
|
||||
*/
|
||||
$this->delete();
|
||||
return false;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates an existing cache.
|
||||
*
|
||||
* @param mixed $data (Required) The data to cache.
|
||||
* @return boolean Whether the operation was successful.
|
||||
*/
|
||||
public function update($data)
|
||||
{
|
||||
if (file_exists($this->id) && is_writeable($this->id))
|
||||
{
|
||||
$data = serialize($data);
|
||||
$data = $this->gzip ? gzcompress($data) : $data;
|
||||
|
||||
return (bool) file_put_contents($this->id, $data);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new CacheFile_Exception('The file system location is not writeable. Check your file system permissions and ensure that the cache directory exists.');
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a cache.
|
||||
*
|
||||
* @return boolean Whether the operation was successful.
|
||||
*/
|
||||
public function delete()
|
||||
{
|
||||
if (file_exists($this->id))
|
||||
{
|
||||
return unlink($this->id);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the cache object is expired or not.
|
||||
*
|
||||
* @return boolean Whether the cache is expired or not.
|
||||
*/
|
||||
public function is_expired()
|
||||
{
|
||||
if ($this->timestamp() + $this->expires < time())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the timestamp of the cache.
|
||||
*
|
||||
* @return mixed Either the Unix time stamp of the cache creation, or boolean `false`.
|
||||
*/
|
||||
public function timestamp()
|
||||
{
|
||||
clearstatcache();
|
||||
|
||||
if (file_exists($this->id))
|
||||
{
|
||||
$this->timestamp = filemtime($this->id);
|
||||
return $this->timestamp;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the freshness of the cache.
|
||||
*
|
||||
* @return boolean Whether the operation was successful.
|
||||
*/
|
||||
public function reset()
|
||||
{
|
||||
if (file_exists($this->id))
|
||||
{
|
||||
return touch($this->id);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*%******************************************************************************************%*/
|
||||
// EXCEPTIONS
|
||||
|
||||
class CacheFile_Exception extends CacheCore_Exception {}
|
|
@ -0,0 +1,183 @@
|
|||
<?php
|
||||
/**
|
||||
* Container for all Memcache-based cache methods. Inherits additional methods from <CacheCore>. Adheres
|
||||
* to the ICacheCore interface.
|
||||
*
|
||||
* @version 2012.04.17
|
||||
* @copyright 2006-2012 Ryan Parman
|
||||
* @copyright 2006-2010 Foleeo, Inc.
|
||||
* @copyright 2012 Amazon.com, Inc. or its affiliates.
|
||||
* @copyright 2008-2010 Contributors
|
||||
* @license http://opensource.org/licenses/bsd-license.php Simplified BSD License
|
||||
* @link http://github.com/skyzyx/cachecore CacheCore
|
||||
* @link http://getcloudfusion.com CloudFusion
|
||||
* @link http://php.net/memcache Memcache
|
||||
* @link http://php.net/memcached Memcached
|
||||
*/
|
||||
class CacheMC extends CacheCore implements ICacheCore
|
||||
{
|
||||
/**
|
||||
* Holds the Memcache object.
|
||||
*/
|
||||
var $memcache = null;
|
||||
|
||||
/**
|
||||
* Whether the Memcached extension is being used (as opposed to Memcache).
|
||||
*/
|
||||
var $is_memcached = false;
|
||||
|
||||
|
||||
/*%******************************************************************************************%*/
|
||||
// CONSTRUCTOR
|
||||
|
||||
/**
|
||||
* Constructs a new instance of this class.
|
||||
*
|
||||
* @param string $name (Required) A name to uniquely identify the cache object.
|
||||
* @param string $location (Optional) The location to store the cache object in. This may vary by cache method. The default value is NULL.
|
||||
* @param integer $expires (Optional) The number of seconds until a cache object is considered stale. The default value is 0.
|
||||
* @param boolean $gzip (Optional) Whether data should be gzipped before being stored. The default value is true.
|
||||
* @return object Reference to the cache object.
|
||||
*/
|
||||
public function __construct($name, $location = null, $expires = 0, $gzip = true)
|
||||
{
|
||||
parent::__construct($name, null, $expires, $gzip);
|
||||
$this->id = $this->name;
|
||||
|
||||
// Prefer Memcached over Memcache.
|
||||
if (class_exists('Memcached'))
|
||||
{
|
||||
$this->memcache = new Memcached();
|
||||
$this->is_memcached = true;
|
||||
}
|
||||
elseif (class_exists('Memcache'))
|
||||
{
|
||||
$this->memcache = new Memcache();
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Enable compression, if available
|
||||
if ($this->gzip)
|
||||
{
|
||||
if ($this->is_memcached)
|
||||
{
|
||||
$this->memcache->setOption(Memcached::OPT_COMPRESSION, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->gzip = MEMCACHE_COMPRESSED;
|
||||
}
|
||||
}
|
||||
|
||||
// Process Memcached servers.
|
||||
if (isset($location) && sizeof($location) > 0)
|
||||
{
|
||||
foreach ($location as $loc)
|
||||
{
|
||||
if (isset($loc['port']) && !empty($loc['port']))
|
||||
{
|
||||
$this->memcache->addServer($loc['host'], $loc['port']);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->memcache->addServer($loc['host'], 11211);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new cache.
|
||||
*
|
||||
* @param mixed $data (Required) The data to cache.
|
||||
* @return boolean Whether the operation was successful.
|
||||
*/
|
||||
public function create($data)
|
||||
{
|
||||
if ($this->is_memcached)
|
||||
{
|
||||
return $this->memcache->set($this->id, $data, $this->expires);
|
||||
}
|
||||
return $this->memcache->set($this->id, $data, $this->gzip, $this->expires);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a cache.
|
||||
*
|
||||
* @return mixed Either the content of the cache object, or boolean `false`.
|
||||
*/
|
||||
public function read()
|
||||
{
|
||||
if ($this->is_memcached)
|
||||
{
|
||||
return $this->memcache->get($this->id);
|
||||
}
|
||||
return $this->memcache->get($this->id, $this->gzip);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates an existing cache.
|
||||
*
|
||||
* @param mixed $data (Required) The data to cache.
|
||||
* @return boolean Whether the operation was successful.
|
||||
*/
|
||||
public function update($data)
|
||||
{
|
||||
if ($this->is_memcached)
|
||||
{
|
||||
return $this->memcache->replace($this->id, $data, $this->expires);
|
||||
}
|
||||
return $this->memcache->replace($this->id, $data, $this->gzip, $this->expires);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a cache.
|
||||
*
|
||||
* @return boolean Whether the operation was successful.
|
||||
*/
|
||||
public function delete()
|
||||
{
|
||||
return $this->memcache->delete($this->id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implemented here, but always returns `false`. Memcache manages its own expirations.
|
||||
*
|
||||
* @return boolean Whether the cache is expired or not.
|
||||
*/
|
||||
public function is_expired()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implemented here, but always returns `false`. Memcache manages its own expirations.
|
||||
*
|
||||
* @return mixed Either the Unix time stamp of the cache creation, or boolean `false`.
|
||||
*/
|
||||
public function timestamp()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implemented here, but always returns `false`. Memcache manages its own expirations.
|
||||
*
|
||||
* @return boolean Whether the operation was successful.
|
||||
*/
|
||||
public function reset()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*%******************************************************************************************%*/
|
||||
// EXCEPTIONS
|
||||
|
||||
class CacheMC_Exception extends CacheCore_Exception {}
|
|
@ -0,0 +1,297 @@
|
|||
<?php
|
||||
/**
|
||||
* Container for all PDO-based cache methods. Inherits additional methods from <CacheCore>. Adheres
|
||||
* to the ICacheCore interface.
|
||||
*
|
||||
* @version 2012.04.17
|
||||
* @copyright 2006-2012 Ryan Parman
|
||||
* @copyright 2006-2010 Foleeo, Inc.
|
||||
* @copyright 2012 Amazon.com, Inc. or its affiliates.
|
||||
* @copyright 2008-2010 Contributors
|
||||
* @license http://opensource.org/licenses/bsd-license.php Simplified BSD License
|
||||
* @link http://github.com/skyzyx/cachecore CacheCore
|
||||
* @link http://getcloudfusion.com CloudFusion
|
||||
* @link http://php.net/pdo PDO
|
||||
*/
|
||||
class CachePDO extends CacheCore implements ICacheCore
|
||||
{
|
||||
/**
|
||||
* Reference to the PDO connection object.
|
||||
*/
|
||||
var $pdo = null;
|
||||
|
||||
/**
|
||||
* Holds the parsed URL components.
|
||||
*/
|
||||
var $dsn = null;
|
||||
|
||||
/**
|
||||
* Holds the PDO-friendly version of the connection string.
|
||||
*/
|
||||
var $dsn_string = null;
|
||||
|
||||
/**
|
||||
* Holds the prepared statement for creating an entry.
|
||||
*/
|
||||
var $create = null;
|
||||
|
||||
/**
|
||||
* Holds the prepared statement for reading an entry.
|
||||
*/
|
||||
var $read = null;
|
||||
|
||||
/**
|
||||
* Holds the prepared statement for updating an entry.
|
||||
*/
|
||||
var $update = null;
|
||||
|
||||
/**
|
||||
* Holds the prepared statement for resetting the expiry of an entry.
|
||||
*/
|
||||
var $reset = null;
|
||||
|
||||
/**
|
||||
* Holds the prepared statement for deleting an entry.
|
||||
*/
|
||||
var $delete = null;
|
||||
|
||||
/**
|
||||
* Holds the response of the read so we only need to fetch it once instead of doing
|
||||
* multiple queries.
|
||||
*/
|
||||
var $store_read = null;
|
||||
|
||||
|
||||
/*%******************************************************************************************%*/
|
||||
// CONSTRUCTOR
|
||||
|
||||
/**
|
||||
* Constructs a new instance of this class.
|
||||
*
|
||||
* Tested with [MySQL 5.0.x](http://mysql.com), [PostgreSQL](http://postgresql.com), and
|
||||
* [SQLite 3.x](http://sqlite.org). SQLite 2.x is assumed to work. No other PDO-supported databases have
|
||||
* been tested (e.g. Oracle, Microsoft SQL Server, IBM DB2, ODBC, Sybase, Firebird). Feel free to send
|
||||
* patches for additional database support.
|
||||
*
|
||||
* See <http://php.net/pdo> for more information.
|
||||
*
|
||||
* @param string $name (Required) A name to uniquely identify the cache object.
|
||||
* @param string $location (Optional) The location to store the cache object in. This may vary by cache method. The default value is NULL.
|
||||
* @param integer $expires (Optional) The number of seconds until a cache object is considered stale. The default value is 0.
|
||||
* @param boolean $gzip (Optional) Whether data should be gzipped before being stored. The default value is true.
|
||||
* @return object Reference to the cache object.
|
||||
*/
|
||||
public function __construct($name, $location = null, $expires = 0, $gzip = true)
|
||||
{
|
||||
// Make sure the name is no longer than 40 characters.
|
||||
$name = sha1($name);
|
||||
|
||||
// Call parent constructor and set id.
|
||||
parent::__construct($name, $location, $expires, $gzip);
|
||||
$this->id = $this->name;
|
||||
$options = array();
|
||||
|
||||
// Check if the location contains :// (e.g. mysql://user:pass@hostname:port/table)
|
||||
if (stripos($location, '://') === false)
|
||||
{
|
||||
// No? Just pass it through.
|
||||
$this->dsn = parse_url($location);
|
||||
$this->dsn_string = $location;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Yes? Parse and set the DSN
|
||||
$this->dsn = parse_url($location);
|
||||
$this->dsn_string = $this->dsn['scheme'] . ':host=' . $this->dsn['host'] . ((isset($this->dsn['port'])) ? ';port=' . $this->dsn['port'] : '') . ';dbname=' . substr($this->dsn['path'], 1);
|
||||
}
|
||||
|
||||
// Make sure that user/pass are defined.
|
||||
$user = isset($this->dsn['user']) ? $this->dsn['user'] : null;
|
||||
$pass = isset($this->dsn['pass']) ? $this->dsn['pass'] : null;
|
||||
|
||||
// Set persistence for databases that support it.
|
||||
switch ($this->dsn['scheme'])
|
||||
{
|
||||
case 'mysql': // MySQL
|
||||
case 'pgsql': // PostgreSQL
|
||||
$options[PDO::ATTR_PERSISTENT] = true;
|
||||
break;
|
||||
}
|
||||
|
||||
// Instantiate a new PDO object with a persistent connection.
|
||||
$this->pdo = new PDO($this->dsn_string, $user, $pass, $options);
|
||||
|
||||
// Define prepared statements for improved performance.
|
||||
$this->create = $this->pdo->prepare("INSERT INTO cache (id, expires, data) VALUES (:id, :expires, :data)");
|
||||
$this->read = $this->pdo->prepare("SELECT id, expires, data FROM cache WHERE id = :id");
|
||||
$this->reset = $this->pdo->prepare("UPDATE cache SET expires = :expires WHERE id = :id");
|
||||
$this->delete = $this->pdo->prepare("DELETE FROM cache WHERE id = :id");
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new cache.
|
||||
*
|
||||
* @param mixed $data (Required) The data to cache.
|
||||
* @return boolean Whether the operation was successful.
|
||||
*/
|
||||
public function create($data)
|
||||
{
|
||||
$data = serialize($data);
|
||||
$data = $this->gzip ? gzcompress($data) : $data;
|
||||
|
||||
$this->create->bindParam(':id', $this->id);
|
||||
$this->create->bindParam(':data', $data);
|
||||
$this->create->bindParam(':expires', $this->generate_timestamp());
|
||||
|
||||
return (bool) $this->create->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a cache.
|
||||
*
|
||||
* @return mixed Either the content of the cache object, or boolean `false`.
|
||||
*/
|
||||
public function read()
|
||||
{
|
||||
if (!$this->store_read)
|
||||
{
|
||||
$this->read->bindParam(':id', $this->id);
|
||||
$this->read->execute();
|
||||
$this->store_read = $this->read->fetch(PDO::FETCH_ASSOC);
|
||||
}
|
||||
|
||||
if ($this->store_read)
|
||||
{
|
||||
$data = $this->store_read['data'];
|
||||
$data = $this->gzip ? gzuncompress($data) : $data;
|
||||
|
||||
return unserialize($data);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates an existing cache.
|
||||
*
|
||||
* @param mixed $data (Required) The data to cache.
|
||||
* @return boolean Whether the operation was successful.
|
||||
*/
|
||||
public function update($data)
|
||||
{
|
||||
$this->delete();
|
||||
return $this->create($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a cache.
|
||||
*
|
||||
* @return boolean Whether the operation was successful.
|
||||
*/
|
||||
public function delete()
|
||||
{
|
||||
$this->delete->bindParam(':id', $this->id);
|
||||
return $this->delete->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the cache object is expired or not.
|
||||
*
|
||||
* @return boolean Whether the cache is expired or not.
|
||||
*/
|
||||
public function is_expired()
|
||||
{
|
||||
if ($this->timestamp() + $this->expires < time())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the timestamp of the cache.
|
||||
*
|
||||
* @return mixed Either the Unix time stamp of the cache creation, or boolean `false`.
|
||||
*/
|
||||
public function timestamp()
|
||||
{
|
||||
if (!$this->store_read)
|
||||
{
|
||||
$this->read->bindParam(':id', $this->id);
|
||||
$this->read->execute();
|
||||
$this->store_read = $this->read->fetch(PDO::FETCH_ASSOC);
|
||||
}
|
||||
|
||||
if ($this->store_read)
|
||||
{
|
||||
$value = $this->store_read['expires'];
|
||||
|
||||
// If 'expires' isn't yet an integer, convert it into one.
|
||||
if (!is_numeric($value))
|
||||
{
|
||||
$value = strtotime($value);
|
||||
}
|
||||
|
||||
$this->timestamp = date('U', $value);
|
||||
return $this->timestamp;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the freshness of the cache.
|
||||
*
|
||||
* @return boolean Whether the operation was successful.
|
||||
*/
|
||||
public function reset()
|
||||
{
|
||||
$this->reset->bindParam(':id', $this->id);
|
||||
$this->reset->bindParam(':expires', $this->generate_timestamp());
|
||||
return (bool) $this->reset->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of supported PDO database drivers. Identical to <PDO::getAvailableDrivers()>.
|
||||
*
|
||||
* @return array The list of supported database drivers.
|
||||
* @link http://php.net/pdo.getavailabledrivers PHP Method
|
||||
*/
|
||||
public function get_drivers()
|
||||
{
|
||||
return PDO::getAvailableDrivers();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a timestamp value apropriate to the current database type.
|
||||
*
|
||||
* @return mixed Timestamp for MySQL and PostgreSQL, integer value for SQLite.
|
||||
*/
|
||||
protected function generate_timestamp()
|
||||
{
|
||||
// Define 'expires' settings differently.
|
||||
switch ($this->dsn['scheme'])
|
||||
{
|
||||
// These support timestamps.
|
||||
case 'mysql': // MySQL
|
||||
case 'pgsql': // PostgreSQL
|
||||
$expires = date(DATE_FORMAT_MYSQL, time());
|
||||
break;
|
||||
|
||||
// These support integers.
|
||||
case 'sqlite': // SQLite 3
|
||||
case 'sqlite2': // SQLite 2
|
||||
$expires = time();
|
||||
break;
|
||||
}
|
||||
|
||||
return $expires;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*%******************************************************************************************%*/
|
||||
// EXCEPTIONS
|
||||
|
||||
class CachePDO_Exception extends CacheCore_Exception {}
|
|
@ -0,0 +1,129 @@
|
|||
<?php
|
||||
/**
|
||||
* Container for all XCache-based cache methods. Inherits additional methods from <CacheCore>. Adheres
|
||||
* to the ICacheCore interface.
|
||||
*
|
||||
* @version 2012.04.17
|
||||
* @copyright 2006-2012 Ryan Parman
|
||||
* @copyright 2006-2010 Foleeo, Inc.
|
||||
* @copyright 2012 Amazon.com, Inc. or its affiliates.
|
||||
* @copyright 2008-2010 Contributors
|
||||
* @license http://opensource.org/licenses/bsd-license.php Simplified BSD License
|
||||
* @link http://github.com/skyzyx/cachecore CacheCore
|
||||
* @link http://getcloudfusion.com CloudFusion
|
||||
* @link http://xcache.lighttpd.net XCache
|
||||
*/
|
||||
class CacheXCache extends CacheCore implements ICacheCore
|
||||
{
|
||||
|
||||
/*%******************************************************************************************%*/
|
||||
// CONSTRUCTOR
|
||||
|
||||
/**
|
||||
* Constructs a new instance of this class.
|
||||
*
|
||||
* @param string $name (Required) A name to uniquely identify the cache object.
|
||||
* @param string $location (Optional) The location to store the cache object in. This may vary by cache method. The default value is NULL.
|
||||
* @param integer $expires (Optional) The number of seconds until a cache object is considered stale. The default value is 0.
|
||||
* @param boolean $gzip (Optional) Whether data should be gzipped before being stored. The default value is true.
|
||||
* @return object Reference to the cache object.
|
||||
*/
|
||||
public function __construct($name, $location = null, $expires = 0, $gzip = true)
|
||||
{
|
||||
parent::__construct($name, null, $expires, $gzip);
|
||||
$this->id = $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new cache.
|
||||
*
|
||||
* @param mixed $data (Required) The data to cache.
|
||||
* @return boolean Whether the operation was successful.
|
||||
*/
|
||||
public function create($data)
|
||||
{
|
||||
$data = serialize($data);
|
||||
$data = $this->gzip ? gzcompress($data) : $data;
|
||||
|
||||
return xcache_set($this->id, $data, $this->expires);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a cache.
|
||||
*
|
||||
* @return mixed Either the content of the cache object, or boolean `false`.
|
||||
*/
|
||||
public function read()
|
||||
{
|
||||
if ($data = xcache_get($this->id))
|
||||
{
|
||||
$data = $this->gzip ? gzuncompress($data) : $data;
|
||||
return unserialize($data);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates an existing cache.
|
||||
*
|
||||
* @param mixed $data (Required) The data to cache.
|
||||
* @return boolean Whether the operation was successful.
|
||||
*/
|
||||
public function update($data)
|
||||
{
|
||||
$data = serialize($data);
|
||||
$data = $this->gzip ? gzcompress($data) : $data;
|
||||
|
||||
return xcache_set($this->id, $data, $this->expires);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a cache.
|
||||
*
|
||||
* @return boolean Whether the operation was successful.
|
||||
*/
|
||||
public function delete()
|
||||
{
|
||||
return xcache_unset($this->id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Defined here, but always returns false. XCache manages it's own expirations. It's worth
|
||||
* mentioning that if the server is configured for a long xcache.var_gc_interval then it IS
|
||||
* possible for expired data to remain in the var cache, though it is not possible to access
|
||||
* it.
|
||||
*
|
||||
* @return boolean Whether the cache is expired or not.
|
||||
*/
|
||||
public function is_expired()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implemented here, but always returns `false`. XCache manages its own expirations.
|
||||
*
|
||||
* @return mixed Either the Unix time stamp of the cache creation, or boolean `false`.
|
||||
*/
|
||||
public function timestamp()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implemented here, but always returns `false`. XCache manages its own expirations.
|
||||
*
|
||||
* @return boolean Whether the operation was successful.
|
||||
*/
|
||||
public function reset()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*%******************************************************************************************%*/
|
||||
// EXCEPTIONS
|
||||
|
||||
class CacheXCache_Exception extends CacheCore_Exception {}
|
|
@ -0,0 +1,66 @@
|
|||
<?php
|
||||
/**
|
||||
* Defines the methods that all implementing classes MUST have. Covers CRUD (create, read, update,
|
||||
* delete) methods, as well as others that are used in the base <CacheCore> class.
|
||||
*
|
||||
* @version 2009.03.22
|
||||
* @copyright 2006-2010 Ryan Parman
|
||||
* @copyright 2006-2010 Foleeo, Inc.
|
||||
* @copyright 2008-2010 Contributors
|
||||
* @license http://opensource.org/licenses/bsd-license.php Simplified BSD License
|
||||
* @link http://github.com/skyzyx/cachecore CacheCore
|
||||
* @link http://getcloudfusion.com CloudFusion
|
||||
*/
|
||||
interface ICacheCore
|
||||
{
|
||||
/**
|
||||
* Creates a new cache.
|
||||
*
|
||||
* @param mixed $data (Required) The data to cache.
|
||||
* @return boolean Whether the operation was successful.
|
||||
*/
|
||||
public function create($data);
|
||||
|
||||
/**
|
||||
* Reads a cache.
|
||||
*
|
||||
* @return mixed Either the content of the cache object, or boolean `false`.
|
||||
*/
|
||||
public function read();
|
||||
|
||||
/**
|
||||
* Updates an existing cache.
|
||||
*
|
||||
* @param mixed $data (Required) The data to cache.
|
||||
* @return boolean Whether the operation was successful.
|
||||
*/
|
||||
public function update($data);
|
||||
|
||||
/**
|
||||
* Deletes a cache.
|
||||
*
|
||||
* @return boolean Whether the operation was successful.
|
||||
*/
|
||||
public function delete();
|
||||
|
||||
/**
|
||||
* Checks whether the cache object is expired or not.
|
||||
*
|
||||
* @return boolean Whether the cache is expired or not.
|
||||
*/
|
||||
public function is_expired();
|
||||
|
||||
/**
|
||||
* Retrieves the timestamp of the cache.
|
||||
*
|
||||
* @return mixed Either the Unix time stamp of the cache creation, or boolean `false`.
|
||||
*/
|
||||
public function timestamp();
|
||||
|
||||
/**
|
||||
* Resets the freshness of the cache.
|
||||
*
|
||||
* @return boolean Whether the operation was successful.
|
||||
*/
|
||||
public function reset();
|
||||
}
|
|
@ -0,0 +1,181 @@
|
|||
<?php
|
||||
/**
|
||||
* @author Omer Hassan
|
||||
* @author Ryan Parman
|
||||
* @license MIT
|
||||
*/
|
||||
class Array2DOM
|
||||
{
|
||||
const ATTRIBUTES = '__attributes__';
|
||||
const CONTENT = '__content__';
|
||||
|
||||
/**
|
||||
* @param array $source
|
||||
* @param string $rootTagName
|
||||
* @return DOMDocument
|
||||
*/
|
||||
public static function arrayToDOMDocument(array $source, $rootTagName = 'root')
|
||||
{
|
||||
$document = new DOMDocument();
|
||||
$document->appendChild(self::createDOMElement($source, $rootTagName, $document));
|
||||
|
||||
return $document;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $source
|
||||
* @param string $rootTagName
|
||||
* @param bool $formatOutput
|
||||
* @return string
|
||||
*/
|
||||
public static function arrayToXMLString(array $source, $rootTagName = 'root', $formatOutput = true)
|
||||
{
|
||||
$document = self::arrayToDOMDocument($source, $rootTagName);
|
||||
$document->formatOutput = $formatOutput;
|
||||
|
||||
return $document->saveXML();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param DOMDocument $document
|
||||
* @return array
|
||||
*/
|
||||
public static function domDocumentToArray(DOMDocument $document)
|
||||
{
|
||||
return self::createArray($document->documentElement);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $xmlString
|
||||
* @return array
|
||||
*/
|
||||
public static function xmlStringToArray($xmlString)
|
||||
{
|
||||
$document = new DOMDocument();
|
||||
|
||||
return $document->loadXML($xmlString) ? self::domDocumentToArray($document) : array();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $source
|
||||
* @param string $tagName
|
||||
* @param DOMDocument $document
|
||||
* @return DOMNode
|
||||
*/
|
||||
private static function createDOMElement($source, $tagName, DOMDocument $document)
|
||||
{
|
||||
if (!is_array($source))
|
||||
{
|
||||
$element = $document->createElement($tagName);
|
||||
$element->appendChild($document->createCDATASection($source));
|
||||
|
||||
return $element;
|
||||
}
|
||||
|
||||
$element = $document->createElement($tagName);
|
||||
|
||||
foreach ($source as $key => $value)
|
||||
{
|
||||
if (is_string($key) && !is_numeric($key))
|
||||
{
|
||||
if ($key === self::ATTRIBUTES)
|
||||
{
|
||||
foreach ($value as $attributeName => $attributeValue)
|
||||
{
|
||||
$element->setAttribute($attributeName, $attributeValue);
|
||||
}
|
||||
}
|
||||
elseif ($key === self::CONTENT)
|
||||
{
|
||||
$element->appendChild($document->createCDATASection($value));
|
||||
}
|
||||
elseif (is_string($value) && !is_numeric($value))
|
||||
{
|
||||
$element->appendChild(self::createDOMElement($value, $key, $document));
|
||||
}
|
||||
elseif (is_array($value) && count($value))
|
||||
{
|
||||
$keyNode = $document->createElement($key);
|
||||
|
||||
foreach ($value as $elementKey => $elementValue)
|
||||
{
|
||||
if (is_string($elementKey) && !is_numeric($elementKey))
|
||||
{
|
||||
$keyNode->appendChild(self::createDOMElement($elementValue, $elementKey, $document));
|
||||
}
|
||||
else
|
||||
{
|
||||
$element->appendChild(self::createDOMElement($elementValue, $key, $document));
|
||||
}
|
||||
}
|
||||
|
||||
if ($keyNode->hasChildNodes())
|
||||
{
|
||||
$element->appendChild($keyNode);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (is_bool($value))
|
||||
{
|
||||
$value = $value ? 'true' : 'false';
|
||||
}
|
||||
|
||||
$element->appendChild(self::createDOMElement($value, $key, $document));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$element->appendChild(self::createDOMElement($value, $tagName, $document));
|
||||
}
|
||||
}
|
||||
|
||||
return $element;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param DOMNode $domNode
|
||||
* @return array
|
||||
*/
|
||||
private static function createArray(DOMNode $domNode)
|
||||
{
|
||||
$array = array();
|
||||
|
||||
for ($i = 0; $i < $domNode->childNodes->length; $i++)
|
||||
{
|
||||
$item = $domNode->childNodes->item($i);
|
||||
|
||||
if ($item->nodeType === XML_ELEMENT_NODE)
|
||||
{
|
||||
$arrayElement = array();
|
||||
|
||||
for ($attributeIndex = 0; !is_null($attribute = $item->attributes->item($attributeIndex)); $attributeIndex++)
|
||||
{
|
||||
if ($attribute->nodeType === XML_ATTRIBUTE_NODE)
|
||||
{
|
||||
$arrayElement[self::ATTRIBUTES][$attribute->nodeName] = $attribute->nodeValue;
|
||||
}
|
||||
}
|
||||
|
||||
$children = self::createArray($item);
|
||||
|
||||
if (is_array($children))
|
||||
{
|
||||
$arrayElement = array_merge($arrayElement, $children);
|
||||
}
|
||||
else
|
||||
{
|
||||
$arrayElement[self::CONTENT] = $children;
|
||||
}
|
||||
|
||||
$array[$item->nodeName][] = $arrayElement;
|
||||
}
|
||||
elseif ($item->nodeType === XML_CDATA_SECTION_NODE || ($item->nodeType === XML_TEXT_NODE && trim($item->nodeValue) !== ''))
|
||||
{
|
||||
return $item->nodeValue;
|
||||
}
|
||||
}
|
||||
|
||||
return $array;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
Copyright (c) 2006-2010 Ryan Parman, Foleeo Inc., and contributors. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are
|
||||
permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this list of
|
||||
conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
of conditions and the following disclaimer in the documentation and/or other materials
|
||||
provided with the distribution.
|
||||
|
||||
* Neither the name of Ryan Parman, Foleeo Inc. nor the names of its contributors may be used to
|
||||
endorse or promote products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
|
||||
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
|
||||
AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
|
@ -0,0 +1,15 @@
|
|||
# RequestCore
|
||||
|
||||
RequestCore is a lightweight cURL-based HTTP request/response class that leverages MultiCurl for parallel requests.
|
||||
|
||||
### PEAR HTTP_Request?
|
||||
|
||||
RequestCore was written as a replacement for [PEAR HTTP_Request](http://pear.php.net/http_request/). While PEAR HTTP_Request is full-featured and heavy, RequestCore features only the essentials and is very lightweight. It also leverages the batch request support in cURL's `curl_multi_exec()` to enable multi-threaded requests that fire in parallel.
|
||||
|
||||
### Reference and Download
|
||||
|
||||
You can find the class reference at <http://skyzyx.github.com/requestcore/>. You can get the code from <http://github.com/skyzyx/requestcore>.
|
||||
|
||||
### License and Copyright
|
||||
|
||||
This code is Copyright (c) 2008-2010, Ryan Parman. However, I'm licensing this code for others to use under the [Simplified BSD license](http://www.opensource.org/licenses/bsd-license.php).
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,19 @@
|
|||
Copyright (c) 2008-2009 Fabien Potencier
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is furnished
|
||||
to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
|
@ -0,0 +1,15 @@
|
|||
Symfony YAML: A PHP library that speaks YAML
|
||||
============================================
|
||||
|
||||
Symfony YAML is a PHP library that parses YAML strings and converts them to
|
||||
PHP arrays. It can also converts PHP arrays to YAML strings. Its official
|
||||
website is at http://components.symfony-project.org/yaml/.
|
||||
|
||||
The documentation is to be found in the `doc/` directory.
|
||||
|
||||
Symfony YAML is licensed under the MIT license (see LICENSE file).
|
||||
|
||||
The Symfony YAML library is developed and maintained by the
|
||||
[symfony](http://www.symfony-project.org/) project team. It has been extracted
|
||||
from symfony to be used as a standalone library. Symfony YAML is part of the
|
||||
[symfony components project](http://components.symfony-project.org/).
|
|
@ -0,0 +1,135 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the symfony package.
|
||||
* (c) 2004-2006 Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* sfYaml offers convenience methods to load and dump YAML.
|
||||
*
|
||||
* @package symfony
|
||||
* @subpackage yaml
|
||||
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
* @version SVN: $Id: sfYaml.class.php 8988 2008-05-15 20:24:26Z fabien $
|
||||
*/
|
||||
class sfYaml
|
||||
{
|
||||
static protected
|
||||
$spec = '1.2';
|
||||
|
||||
/**
|
||||
* Sets the YAML specification version to use.
|
||||
*
|
||||
* @param string $version The YAML specification version
|
||||
*/
|
||||
static public function setSpecVersion($version)
|
||||
{
|
||||
if (!in_array($version, array('1.1', '1.2')))
|
||||
{
|
||||
throw new InvalidArgumentException(sprintf('Version %s of the YAML specifications is not supported', $version));
|
||||
}
|
||||
|
||||
self::$spec = $version;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the YAML specification version to use.
|
||||
*
|
||||
* @return string The YAML specification version
|
||||
*/
|
||||
static public function getSpecVersion()
|
||||
{
|
||||
return self::$spec;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads YAML into a PHP array.
|
||||
*
|
||||
* The load method, when supplied with a YAML stream (string or file),
|
||||
* will do its best to convert YAML in a file into a PHP array.
|
||||
*
|
||||
* Usage:
|
||||
* <code>
|
||||
* $array = sfYaml::load('config.yml');
|
||||
* print_r($array);
|
||||
* </code>
|
||||
*
|
||||
* @param string $input Path of YAML file or string containing YAML
|
||||
*
|
||||
* @return array The YAML converted to a PHP array
|
||||
*
|
||||
* @throws InvalidArgumentException If the YAML is not valid
|
||||
*/
|
||||
public static function load($input)
|
||||
{
|
||||
$file = '';
|
||||
|
||||
// if input is a file, process it
|
||||
if (strpos($input, "\n") === false && is_file($input))
|
||||
{
|
||||
$file = $input;
|
||||
|
||||
ob_start();
|
||||
$retval = include($input);
|
||||
$content = ob_get_clean();
|
||||
|
||||
// if an array is returned by the config file assume it's in plain php form else in YAML
|
||||
$input = is_array($retval) ? $retval : $content;
|
||||
}
|
||||
|
||||
// if an array is returned by the config file assume it's in plain php form else in YAML
|
||||
if (is_array($input))
|
||||
{
|
||||
return $input;
|
||||
}
|
||||
|
||||
require_once dirname(__FILE__).'/sfYamlParser.php';
|
||||
|
||||
$yaml = new sfYamlParser();
|
||||
|
||||
try
|
||||
{
|
||||
$ret = $yaml->parse($input);
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
throw new InvalidArgumentException(sprintf('Unable to parse %s: %s', $file ? sprintf('file "%s"', $file) : 'string', $e->getMessage()));
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dumps a PHP array to a YAML string.
|
||||
*
|
||||
* The dump method, when supplied with an array, will do its best
|
||||
* to convert the array into friendly YAML.
|
||||
*
|
||||
* @param array $array PHP array
|
||||
* @param integer $inline The level where you switch to inline YAML
|
||||
*
|
||||
* @return string A YAML string representing the original PHP array
|
||||
*/
|
||||
public static function dump($array, $inline = 2)
|
||||
{
|
||||
require_once dirname(__FILE__).'/sfYamlDumper.php';
|
||||
|
||||
$yaml = new sfYamlDumper();
|
||||
|
||||
return $yaml->dump($array, $inline);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps echo to automatically provide a newline.
|
||||
*
|
||||
* @param string $string The string to echo with new line
|
||||
*/
|
||||
function echoln($string)
|
||||
{
|
||||
echo $string."\n";
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the symfony package.
|
||||
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
require_once(dirname(__FILE__).'/sfYamlInline.php');
|
||||
|
||||
/**
|
||||
* sfYamlDumper dumps PHP variables to YAML strings.
|
||||
*
|
||||
* @package symfony
|
||||
* @subpackage yaml
|
||||
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
* @version SVN: $Id: sfYamlDumper.class.php 10575 2008-08-01 13:08:42Z nicolas $
|
||||
*/
|
||||
class sfYamlDumper
|
||||
{
|
||||
/**
|
||||
* Dumps a PHP value to YAML.
|
||||
*
|
||||
* @param mixed $input The PHP value
|
||||
* @param integer $inline The level where you switch to inline YAML
|
||||
* @param integer $indent The level o indentation indentation (used internally)
|
||||
*
|
||||
* @return string The YAML representation of the PHP value
|
||||
*/
|
||||
public function dump($input, $inline = 0, $indent = 0)
|
||||
{
|
||||
$output = '';
|
||||
$prefix = $indent ? str_repeat(' ', $indent) : '';
|
||||
|
||||
if ($inline <= 0 || !is_array($input) || empty($input))
|
||||
{
|
||||
$output .= $prefix.sfYamlInline::dump($input);
|
||||
}
|
||||
else
|
||||
{
|
||||
$isAHash = array_keys($input) !== range(0, count($input) - 1);
|
||||
|
||||
foreach ($input as $key => $value)
|
||||
{
|
||||
$willBeInlined = $inline - 1 <= 0 || !is_array($value) || empty($value);
|
||||
|
||||
$output .= sprintf('%s%s%s%s',
|
||||
$prefix,
|
||||
$isAHash ? sfYamlInline::dump($key).':' : '-',
|
||||
$willBeInlined ? ' ' : "\n",
|
||||
$this->dump($value, $inline - 1, $willBeInlined ? 0 : $indent + 2)
|
||||
).($willBeInlined ? "\n" : '');
|
||||
}
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,442 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the symfony package.
|
||||
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
require_once dirname(__FILE__).'/sfYaml.php';
|
||||
|
||||
/**
|
||||
* sfYamlInline implements a YAML parser/dumper for the YAML inline syntax.
|
||||
*
|
||||
* @package symfony
|
||||
* @subpackage yaml
|
||||
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
* @version SVN: $Id: sfYamlInline.class.php 16177 2009-03-11 08:32:48Z fabien $
|
||||
*/
|
||||
class sfYamlInline
|
||||
{
|
||||
const REGEX_QUOTED_STRING = '(?:"([^"\\\\]*(?:\\\\.[^"\\\\]*)*)"|\'([^\']*(?:\'\'[^\']*)*)\')';
|
||||
|
||||
/**
|
||||
* Convert a YAML string to a PHP array.
|
||||
*
|
||||
* @param string $value A YAML string
|
||||
*
|
||||
* @return array A PHP array representing the YAML string
|
||||
*/
|
||||
static public function load($value)
|
||||
{
|
||||
$value = trim($value);
|
||||
|
||||
if (0 == strlen($value))
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
if (function_exists('mb_internal_encoding') && ((int) ini_get('mbstring.func_overload')) & 2)
|
||||
{
|
||||
$mbEncoding = mb_internal_encoding();
|
||||
mb_internal_encoding('ASCII');
|
||||
}
|
||||
|
||||
switch ($value[0])
|
||||
{
|
||||
case '[':
|
||||
$result = self::parseSequence($value);
|
||||
break;
|
||||
case '{':
|
||||
$result = self::parseMapping($value);
|
||||
break;
|
||||
default:
|
||||
$result = self::parseScalar($value);
|
||||
}
|
||||
|
||||
if (isset($mbEncoding))
|
||||
{
|
||||
mb_internal_encoding($mbEncoding);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dumps a given PHP variable to a YAML string.
|
||||
*
|
||||
* @param mixed $value The PHP variable to convert
|
||||
*
|
||||
* @return string The YAML string representing the PHP array
|
||||
*/
|
||||
static public function dump($value)
|
||||
{
|
||||
if ('1.1' === sfYaml::getSpecVersion())
|
||||
{
|
||||
$trueValues = array('true', 'on', '+', 'yes', 'y');
|
||||
$falseValues = array('false', 'off', '-', 'no', 'n');
|
||||
}
|
||||
else
|
||||
{
|
||||
$trueValues = array('true');
|
||||
$falseValues = array('false');
|
||||
}
|
||||
|
||||
switch (true)
|
||||
{
|
||||
case is_resource($value):
|
||||
throw new InvalidArgumentException('Unable to dump PHP resources in a YAML file.');
|
||||
case is_object($value):
|
||||
return '!!php/object:'.serialize($value);
|
||||
case is_array($value):
|
||||
return self::dumpArray($value);
|
||||
case null === $value:
|
||||
return 'null';
|
||||
case true === $value:
|
||||
return 'true';
|
||||
case false === $value:
|
||||
return 'false';
|
||||
case ctype_digit($value):
|
||||
return is_string($value) ? "'$value'" : (int) $value;
|
||||
case is_numeric($value):
|
||||
return is_infinite($value) ? str_ireplace('INF', '.Inf', strval($value)) : (is_string($value) ? "'$value'" : $value);
|
||||
case false !== strpos($value, "\n") || false !== strpos($value, "\r"):
|
||||
return sprintf('"%s"', str_replace(array('"', "\n", "\r"), array('\\"', '\n', '\r'), $value));
|
||||
case preg_match('/[ \s \' " \: \{ \} \[ \] , & \* \# \?] | \A[ - ? | < > = ! % @ ` ]/x', $value):
|
||||
return sprintf("'%s'", str_replace('\'', '\'\'', $value));
|
||||
case '' == $value:
|
||||
return "''";
|
||||
case preg_match(self::getTimestampRegex(), $value):
|
||||
return "'$value'";
|
||||
case in_array(strtolower($value), $trueValues):
|
||||
return "'$value'";
|
||||
case in_array(strtolower($value), $falseValues):
|
||||
return "'$value'";
|
||||
case in_array(strtolower($value), array('null', '~')):
|
||||
return "'$value'";
|
||||
default:
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Dumps a PHP array to a YAML string.
|
||||
*
|
||||
* @param array $value The PHP array to dump
|
||||
*
|
||||
* @return string The YAML string representing the PHP array
|
||||
*/
|
||||
static protected function dumpArray($value)
|
||||
{
|
||||
// array
|
||||
$keys = array_keys($value);
|
||||
if (
|
||||
(1 == count($keys) && '0' == $keys[0])
|
||||
||
|
||||
(count($keys) > 1 && array_reduce($keys, create_function('$v,$w', 'return (integer) $v + $w;'), 0) == count($keys) * (count($keys) - 1) / 2))
|
||||
{
|
||||
$output = array();
|
||||
foreach ($value as $val)
|
||||
{
|
||||
$output[] = self::dump($val);
|
||||
}
|
||||
|
||||
return sprintf('[%s]', implode(', ', $output));
|
||||
}
|
||||
|
||||
// mapping
|
||||
$output = array();
|
||||
foreach ($value as $key => $val)
|
||||
{
|
||||
$output[] = sprintf('%s: %s', self::dump($key), self::dump($val));
|
||||
}
|
||||
|
||||
return sprintf('{ %s }', implode(', ', $output));
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a scalar to a YAML string.
|
||||
*
|
||||
* @param scalar $scalar
|
||||
* @param string $delimiters
|
||||
* @param array $stringDelimiter
|
||||
* @param integer $i
|
||||
* @param boolean $evaluate
|
||||
*
|
||||
* @return string A YAML string
|
||||
*/
|
||||
static public function parseScalar($scalar, $delimiters = null, $stringDelimiters = array('"', "'"), &$i = 0, $evaluate = true)
|
||||
{
|
||||
if (in_array($scalar[$i], $stringDelimiters))
|
||||
{
|
||||
// quoted scalar
|
||||
$output = self::parseQuotedScalar($scalar, $i);
|
||||
}
|
||||
else
|
||||
{
|
||||
// "normal" string
|
||||
if (!$delimiters)
|
||||
{
|
||||
$output = substr($scalar, $i);
|
||||
$i += strlen($output);
|
||||
|
||||
// remove comments
|
||||
if (false !== $strpos = strpos($output, ' #'))
|
||||
{
|
||||
$output = rtrim(substr($output, 0, $strpos));
|
||||
}
|
||||
}
|
||||
else if (preg_match('/^(.+?)('.implode('|', $delimiters).')/', substr($scalar, $i), $match))
|
||||
{
|
||||
$output = $match[1];
|
||||
$i += strlen($output);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new InvalidArgumentException(sprintf('Malformed inline YAML string (%s).', $scalar));
|
||||
}
|
||||
|
||||
$output = $evaluate ? self::evaluateScalar($output) : $output;
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a quoted scalar to YAML.
|
||||
*
|
||||
* @param string $scalar
|
||||
* @param integer $i
|
||||
*
|
||||
* @return string A YAML string
|
||||
*/
|
||||
static protected function parseQuotedScalar($scalar, &$i)
|
||||
{
|
||||
if (!preg_match('/'.self::REGEX_QUOTED_STRING.'/A', substr($scalar, $i), $match))
|
||||
{
|
||||
throw new InvalidArgumentException(sprintf('Malformed inline YAML string (%s).', substr($scalar, $i)));
|
||||
}
|
||||
|
||||
$output = substr($match[0], 1, strlen($match[0]) - 2);
|
||||
|
||||
if ('"' == $scalar[$i])
|
||||
{
|
||||
// evaluate the string
|
||||
$output = str_replace(array('\\"', '\\n', '\\r'), array('"', "\n", "\r"), $output);
|
||||
}
|
||||
else
|
||||
{
|
||||
// unescape '
|
||||
$output = str_replace('\'\'', '\'', $output);
|
||||
}
|
||||
|
||||
$i += strlen($match[0]);
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a sequence to a YAML string.
|
||||
*
|
||||
* @param string $sequence
|
||||
* @param integer $i
|
||||
*
|
||||
* @return string A YAML string
|
||||
*/
|
||||
static protected function parseSequence($sequence, &$i = 0)
|
||||
{
|
||||
$output = array();
|
||||
$len = strlen($sequence);
|
||||
$i += 1;
|
||||
|
||||
// [foo, bar, ...]
|
||||
while ($i < $len)
|
||||
{
|
||||
switch ($sequence[$i])
|
||||
{
|
||||
case '[':
|
||||
// nested sequence
|
||||
$output[] = self::parseSequence($sequence, $i);
|
||||
break;
|
||||
case '{':
|
||||
// nested mapping
|
||||
$output[] = self::parseMapping($sequence, $i);
|
||||
break;
|
||||
case ']':
|
||||
return $output;
|
||||
case ',':
|
||||
case ' ':
|
||||
break;
|
||||
default:
|
||||
$isQuoted = in_array($sequence[$i], array('"', "'"));
|
||||
$value = self::parseScalar($sequence, array(',', ']'), array('"', "'"), $i);
|
||||
|
||||
if (!$isQuoted && false !== strpos($value, ': '))
|
||||
{
|
||||
// embedded mapping?
|
||||
try
|
||||
{
|
||||
$value = self::parseMapping('{'.$value.'}');
|
||||
}
|
||||
catch (InvalidArgumentException $e)
|
||||
{
|
||||
// no, it's not
|
||||
}
|
||||
}
|
||||
|
||||
$output[] = $value;
|
||||
|
||||
--$i;
|
||||
}
|
||||
|
||||
++$i;
|
||||
}
|
||||
|
||||
throw new InvalidArgumentException(sprintf('Malformed inline YAML string %s', $sequence));
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a mapping to a YAML string.
|
||||
*
|
||||
* @param string $mapping
|
||||
* @param integer $i
|
||||
*
|
||||
* @return string A YAML string
|
||||
*/
|
||||
static protected function parseMapping($mapping, &$i = 0)
|
||||
{
|
||||
$output = array();
|
||||
$len = strlen($mapping);
|
||||
$i += 1;
|
||||
|
||||
// {foo: bar, bar:foo, ...}
|
||||
while ($i < $len)
|
||||
{
|
||||
switch ($mapping[$i])
|
||||
{
|
||||
case ' ':
|
||||
case ',':
|
||||
++$i;
|
||||
continue 2;
|
||||
case '}':
|
||||
return $output;
|
||||
}
|
||||
|
||||
// key
|
||||
$key = self::parseScalar($mapping, array(':', ' '), array('"', "'"), $i, false);
|
||||
|
||||
// value
|
||||
$done = false;
|
||||
while ($i < $len)
|
||||
{
|
||||
switch ($mapping[$i])
|
||||
{
|
||||
case '[':
|
||||
// nested sequence
|
||||
$output[$key] = self::parseSequence($mapping, $i);
|
||||
$done = true;
|
||||
break;
|
||||
case '{':
|
||||
// nested mapping
|
||||
$output[$key] = self::parseMapping($mapping, $i);
|
||||
$done = true;
|
||||
break;
|
||||
case ':':
|
||||
case ' ':
|
||||
break;
|
||||
default:
|
||||
$output[$key] = self::parseScalar($mapping, array(',', '}'), array('"', "'"), $i);
|
||||
$done = true;
|
||||
--$i;
|
||||
}
|
||||
|
||||
++$i;
|
||||
|
||||
if ($done)
|
||||
{
|
||||
continue 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
throw new InvalidArgumentException(sprintf('Malformed inline YAML string %s', $mapping));
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluates scalars and replaces magic values.
|
||||
*
|
||||
* @param string $scalar
|
||||
*
|
||||
* @return string A YAML string
|
||||
*/
|
||||
static protected function evaluateScalar($scalar)
|
||||
{
|
||||
$scalar = trim($scalar);
|
||||
|
||||
if ('1.1' === sfYaml::getSpecVersion())
|
||||
{
|
||||
$trueValues = array('true', 'on', '+', 'yes', 'y');
|
||||
$falseValues = array('false', 'off', '-', 'no', 'n');
|
||||
}
|
||||
else
|
||||
{
|
||||
$trueValues = array('true');
|
||||
$falseValues = array('false');
|
||||
}
|
||||
|
||||
switch (true)
|
||||
{
|
||||
case 'null' == strtolower($scalar):
|
||||
case '' == $scalar:
|
||||
case '~' == $scalar:
|
||||
return null;
|
||||
case 0 === strpos($scalar, '!str'):
|
||||
return (string) substr($scalar, 5);
|
||||
case 0 === strpos($scalar, '! '):
|
||||
return intval(self::parseScalar(substr($scalar, 2)));
|
||||
case 0 === strpos($scalar, '!!php/object:'):
|
||||
return unserialize(substr($scalar, 13));
|
||||
case ctype_digit($scalar):
|
||||
$raw = $scalar;
|
||||
$cast = intval($scalar);
|
||||
return '0' == $scalar[0] ? octdec($scalar) : (((string) $raw == (string) $cast) ? $cast : $raw);
|
||||
case in_array(strtolower($scalar), $trueValues):
|
||||
return true;
|
||||
case in_array(strtolower($scalar), $falseValues):
|
||||
return false;
|
||||
case is_numeric($scalar):
|
||||
return '0x' == $scalar[0].$scalar[1] ? hexdec($scalar) : floatval($scalar);
|
||||
case 0 == strcasecmp($scalar, '.inf'):
|
||||
case 0 == strcasecmp($scalar, '.NaN'):
|
||||
return -log(0);
|
||||
case 0 == strcasecmp($scalar, '-.inf'):
|
||||
return log(0);
|
||||
case preg_match('/^(-|\+)?[0-9,]+(\.[0-9]+)?$/', $scalar):
|
||||
return floatval(str_replace(',', '', $scalar));
|
||||
case preg_match(self::getTimestampRegex(), $scalar):
|
||||
return strtotime($scalar);
|
||||
default:
|
||||
return (string) $scalar;
|
||||
}
|
||||
}
|
||||
|
||||
static protected function getTimestampRegex()
|
||||
{
|
||||
return <<<EOF
|
||||
~^
|
||||
(?P<year>[0-9][0-9][0-9][0-9])
|
||||
-(?P<month>[0-9][0-9]?)
|
||||
-(?P<day>[0-9][0-9]?)
|
||||
(?:(?:[Tt]|[ \t]+)
|
||||
(?P<hour>[0-9][0-9]?)
|
||||
:(?P<minute>[0-9][0-9])
|
||||
:(?P<second>[0-9][0-9])
|
||||
(?:\.(?P<fraction>[0-9]*))?
|
||||
(?:[ \t]*(?P<tz>Z|(?P<tz_sign>[-+])(?P<tz_hour>[0-9][0-9]?)
|
||||
(?::(?P<tz_minute>[0-9][0-9]))?))?)?
|
||||
$~x
|
||||
EOF;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,612 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the symfony package.
|
||||
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
require_once(dirname(__FILE__).'/sfYamlInline.php');
|
||||
|
||||
if (!defined('PREG_BAD_UTF8_OFFSET_ERROR'))
|
||||
{
|
||||
define('PREG_BAD_UTF8_OFFSET_ERROR', 5);
|
||||
}
|
||||
|
||||
/**
|
||||
* sfYamlParser parses YAML strings to convert them to PHP arrays.
|
||||
*
|
||||
* @package symfony
|
||||
* @subpackage yaml
|
||||
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
* @version SVN: $Id: sfYamlParser.class.php 10832 2008-08-13 07:46:08Z fabien $
|
||||
*/
|
||||
class sfYamlParser
|
||||
{
|
||||
protected
|
||||
$offset = 0,
|
||||
$lines = array(),
|
||||
$currentLineNb = -1,
|
||||
$currentLine = '',
|
||||
$refs = array();
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param integer $offset The offset of YAML document (used for line numbers in error messages)
|
||||
*/
|
||||
public function __construct($offset = 0)
|
||||
{
|
||||
$this->offset = $offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a YAML string to a PHP value.
|
||||
*
|
||||
* @param string $value A YAML string
|
||||
*
|
||||
* @return mixed A PHP value
|
||||
*
|
||||
* @throws InvalidArgumentException If the YAML is not valid
|
||||
*/
|
||||
public function parse($value)
|
||||
{
|
||||
$value = str_replace("\t", ' ', $value); // Convert tabs to spaces.
|
||||
|
||||
$this->currentLineNb = -1;
|
||||
$this->currentLine = '';
|
||||
$this->lines = explode("\n", $this->cleanup($value));
|
||||
|
||||
if (function_exists('mb_internal_encoding') && ((int) ini_get('mbstring.func_overload')) & 2)
|
||||
{
|
||||
$mbEncoding = mb_internal_encoding();
|
||||
mb_internal_encoding('ASCII');
|
||||
}
|
||||
|
||||
$data = array();
|
||||
while ($this->moveToNextLine())
|
||||
{
|
||||
if ($this->isCurrentLineEmpty())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// tab?
|
||||
if (preg_match('#^\t+#', $this->currentLine))
|
||||
{
|
||||
throw new InvalidArgumentException(sprintf('A YAML file cannot contain tabs as indentation at line %d (%s).', $this->getRealCurrentLineNb() + 1, $this->currentLine));
|
||||
}
|
||||
|
||||
$isRef = $isInPlace = $isProcessed = false;
|
||||
if (preg_match('#^\-((?P<leadspaces>\s+)(?P<value>.+?))?\s*$#', $this->currentLine, $values))
|
||||
{
|
||||
if (isset($values['value']) && preg_match('#^&(?P<ref>[^ ]+) *(?P<value>.*)#', $values['value'], $matches))
|
||||
{
|
||||
$isRef = $matches['ref'];
|
||||
$values['value'] = $matches['value'];
|
||||
}
|
||||
|
||||
// array
|
||||
if (!isset($values['value']) || '' == trim($values['value'], ' ') || 0 === strpos(ltrim($values['value'], ' '), '#'))
|
||||
{
|
||||
$c = $this->getRealCurrentLineNb() + 1;
|
||||
$parser = new sfYamlParser($c);
|
||||
$parser->refs =& $this->refs;
|
||||
$data[] = $parser->parse($this->getNextEmbedBlock());
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isset($values['leadspaces'])
|
||||
&& ' ' == $values['leadspaces']
|
||||
&& preg_match('#^(?P<key>'.sfYamlInline::REGEX_QUOTED_STRING.'|[^ \'"\{].*?) *\:(\s+(?P<value>.+?))?\s*$#', $values['value'], $matches))
|
||||
{
|
||||
// this is a compact notation element, add to next block and parse
|
||||
$c = $this->getRealCurrentLineNb();
|
||||
$parser = new sfYamlParser($c);
|
||||
$parser->refs =& $this->refs;
|
||||
|
||||
$block = $values['value'];
|
||||
if (!$this->isNextLineIndented())
|
||||
{
|
||||
$block .= "\n".$this->getNextEmbedBlock($this->getCurrentLineIndentation() + 2);
|
||||
}
|
||||
|
||||
$data[] = $parser->parse($block);
|
||||
}
|
||||
else
|
||||
{
|
||||
$data[] = $this->parseValue($values['value']);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (preg_match('#^(?P<key>'.sfYamlInline::REGEX_QUOTED_STRING.'|[^ \'"].*?) *\:(\s+(?P<value>.+?))?\s*$#', $this->currentLine, $values))
|
||||
{
|
||||
$key = sfYamlInline::parseScalar($values['key']);
|
||||
|
||||
if ('<<' === $key)
|
||||
{
|
||||
if (isset($values['value']) && '*' === substr($values['value'], 0, 1))
|
||||
{
|
||||
$isInPlace = substr($values['value'], 1);
|
||||
if (!array_key_exists($isInPlace, $this->refs))
|
||||
{
|
||||
throw new InvalidArgumentException(sprintf('Reference "%s" does not exist at line %s (%s).', $isInPlace, $this->getRealCurrentLineNb() + 1, $this->currentLine));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isset($values['value']) && $values['value'] !== '')
|
||||
{
|
||||
$value = $values['value'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$value = $this->getNextEmbedBlock();
|
||||
}
|
||||
$c = $this->getRealCurrentLineNb() + 1;
|
||||
$parser = new sfYamlParser($c);
|
||||
$parser->refs =& $this->refs;
|
||||
$parsed = $parser->parse($value);
|
||||
|
||||
$merged = array();
|
||||
if (!is_array($parsed))
|
||||
{
|
||||
throw new InvalidArgumentException(sprintf("YAML merge keys used with a scalar value instead of an array at line %s (%s)", $this->getRealCurrentLineNb() + 1, $this->currentLine));
|
||||
}
|
||||
else if (isset($parsed[0]))
|
||||
{
|
||||
// Numeric array, merge individual elements
|
||||
foreach (array_reverse($parsed) as $parsedItem)
|
||||
{
|
||||
if (!is_array($parsedItem))
|
||||
{
|
||||
throw new InvalidArgumentException(sprintf("Merge items must be arrays at line %s (%s).", $this->getRealCurrentLineNb() + 1, $parsedItem));
|
||||
}
|
||||
$merged = array_merge($parsedItem, $merged);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Associative array, merge
|
||||
$merged = array_merge($merge, $parsed);
|
||||
}
|
||||
|
||||
$isProcessed = $merged;
|
||||
}
|
||||
}
|
||||
else if (isset($values['value']) && preg_match('#^&(?P<ref>[^ ]+) *(?P<value>.*)#', $values['value'], $matches))
|
||||
{
|
||||
$isRef = $matches['ref'];
|
||||
$values['value'] = $matches['value'];
|
||||
}
|
||||
|
||||
if ($isProcessed)
|
||||
{
|
||||
// Merge keys
|
||||
$data = $isProcessed;
|
||||
}
|
||||
// hash
|
||||
else if (!isset($values['value']) || '' == trim($values['value'], ' ') || 0 === strpos(ltrim($values['value'], ' '), '#'))
|
||||
{
|
||||
// if next line is less indented or equal, then it means that the current value is null
|
||||
if ($this->isNextLineIndented())
|
||||
{
|
||||
$data[$key] = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
$c = $this->getRealCurrentLineNb() + 1;
|
||||
$parser = new sfYamlParser($c);
|
||||
$parser->refs =& $this->refs;
|
||||
$data[$key] = $parser->parse($this->getNextEmbedBlock());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($isInPlace)
|
||||
{
|
||||
$data = $this->refs[$isInPlace];
|
||||
}
|
||||
else
|
||||
{
|
||||
$data[$key] = $this->parseValue($values['value']);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 1-liner followed by newline
|
||||
if (2 == count($this->lines) && empty($this->lines[1]))
|
||||
{
|
||||
$value = sfYamlInline::load($this->lines[0]);
|
||||
if (is_array($value))
|
||||
{
|
||||
$first = reset($value);
|
||||
if ('*' === substr($first, 0, 1))
|
||||
{
|
||||
$data = array();
|
||||
foreach ($value as $alias)
|
||||
{
|
||||
$data[] = $this->refs[substr($alias, 1)];
|
||||
}
|
||||
$value = $data;
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($mbEncoding))
|
||||
{
|
||||
mb_internal_encoding($mbEncoding);
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
switch (preg_last_error())
|
||||
{
|
||||
case PREG_INTERNAL_ERROR:
|
||||
$error = 'Internal PCRE error on line';
|
||||
break;
|
||||
case PREG_BACKTRACK_LIMIT_ERROR:
|
||||
$error = 'pcre.backtrack_limit reached on line';
|
||||
break;
|
||||
case PREG_RECURSION_LIMIT_ERROR:
|
||||
$error = 'pcre.recursion_limit reached on line';
|
||||
break;
|
||||
case PREG_BAD_UTF8_ERROR:
|
||||
$error = 'Malformed UTF-8 data on line';
|
||||
break;
|
||||
case PREG_BAD_UTF8_OFFSET_ERROR:
|
||||
$error = 'Offset doesn\'t correspond to the begin of a valid UTF-8 code point on line';
|
||||
break;
|
||||
default:
|
||||
$error = 'Unable to parse line';
|
||||
}
|
||||
|
||||
throw new InvalidArgumentException(sprintf('%s %d (%s).', $error, $this->getRealCurrentLineNb() + 1, $this->currentLine));
|
||||
}
|
||||
|
||||
if ($isRef)
|
||||
{
|
||||
$this->refs[$isRef] = end($data);
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($mbEncoding))
|
||||
{
|
||||
mb_internal_encoding($mbEncoding);
|
||||
}
|
||||
|
||||
return empty($data) ? null : $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current line number (takes the offset into account).
|
||||
*
|
||||
* @return integer The current line number
|
||||
*/
|
||||
protected function getRealCurrentLineNb()
|
||||
{
|
||||
return $this->currentLineNb + $this->offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current line indentation.
|
||||
*
|
||||
* @return integer The current line indentation
|
||||
*/
|
||||
protected function getCurrentLineIndentation()
|
||||
{
|
||||
return strlen($this->currentLine) - strlen(ltrim($this->currentLine, ' '));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the next embed block of YAML.
|
||||
*
|
||||
* @param integer $indentation The indent level at which the block is to be read, or null for default
|
||||
*
|
||||
* @return string A YAML string
|
||||
*/
|
||||
protected function getNextEmbedBlock($indentation = null)
|
||||
{
|
||||
$this->moveToNextLine();
|
||||
|
||||
if (null === $indentation)
|
||||
{
|
||||
$newIndent = $this->getCurrentLineIndentation();
|
||||
|
||||
if (!$this->isCurrentLineEmpty() && 0 == $newIndent)
|
||||
{
|
||||
throw new InvalidArgumentException(sprintf('Indentation problem at line %d (%s)', $this->getRealCurrentLineNb() + 1, $this->currentLine));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$newIndent = $indentation;
|
||||
}
|
||||
|
||||
$data = array(substr($this->currentLine, $newIndent));
|
||||
|
||||
while ($this->moveToNextLine())
|
||||
{
|
||||
if ($this->isCurrentLineEmpty())
|
||||
{
|
||||
if ($this->isCurrentLineBlank())
|
||||
{
|
||||
$data[] = substr($this->currentLine, $newIndent);
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
$indent = $this->getCurrentLineIndentation();
|
||||
|
||||
if (preg_match('#^(?P<text> *)$#', $this->currentLine, $match))
|
||||
{
|
||||
// empty line
|
||||
$data[] = $match['text'];
|
||||
}
|
||||
else if ($indent >= $newIndent)
|
||||
{
|
||||
$data[] = substr($this->currentLine, $newIndent);
|
||||
}
|
||||
else if (0 == $indent)
|
||||
{
|
||||
$this->moveToPreviousLine();
|
||||
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new InvalidArgumentException(sprintf('Indentation problem at line %d (%s)', $this->getRealCurrentLineNb() + 1, $this->currentLine));
|
||||
}
|
||||
}
|
||||
|
||||
return implode("\n", $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves the parser to the next line.
|
||||
*/
|
||||
protected function moveToNextLine()
|
||||
{
|
||||
if ($this->currentLineNb >= count($this->lines) - 1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->currentLine = $this->lines[++$this->currentLineNb];
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves the parser to the previous line.
|
||||
*/
|
||||
protected function moveToPreviousLine()
|
||||
{
|
||||
$this->currentLine = $this->lines[--$this->currentLineNb];
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a YAML value.
|
||||
*
|
||||
* @param string $value A YAML value
|
||||
*
|
||||
* @return mixed A PHP value
|
||||
*/
|
||||
protected function parseValue($value)
|
||||
{
|
||||
if ('*' === substr($value, 0, 1))
|
||||
{
|
||||
if (false !== $pos = strpos($value, '#'))
|
||||
{
|
||||
$value = substr($value, 1, $pos - 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
$value = substr($value, 1);
|
||||
}
|
||||
|
||||
if (!array_key_exists($value, $this->refs))
|
||||
{
|
||||
throw new InvalidArgumentException(sprintf('Reference "%s" does not exist (%s).', $value, $this->currentLine));
|
||||
}
|
||||
return $this->refs[$value];
|
||||
}
|
||||
|
||||
if (preg_match('/^(?P<separator>\||>)(?P<modifiers>\+|\-|\d+|\+\d+|\-\d+|\d+\+|\d+\-)?(?P<comments> +#.*)?$/', $value, $matches))
|
||||
{
|
||||
$modifiers = isset($matches['modifiers']) ? $matches['modifiers'] : '';
|
||||
|
||||
return $this->parseFoldedScalar($matches['separator'], preg_replace('#\d+#', '', $modifiers), intval(abs($modifiers)));
|
||||
}
|
||||
else
|
||||
{
|
||||
return sfYamlInline::load($value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a folded scalar.
|
||||
*
|
||||
* @param string $separator The separator that was used to begin this folded scalar (| or >)
|
||||
* @param string $indicator The indicator that was used to begin this folded scalar (+ or -)
|
||||
* @param integer $indentation The indentation that was used to begin this folded scalar
|
||||
*
|
||||
* @return string The text value
|
||||
*/
|
||||
protected function parseFoldedScalar($separator, $indicator = '', $indentation = 0)
|
||||
{
|
||||
$separator = '|' == $separator ? "\n" : ' ';
|
||||
$text = '';
|
||||
|
||||
$notEOF = $this->moveToNextLine();
|
||||
|
||||
while ($notEOF && $this->isCurrentLineBlank())
|
||||
{
|
||||
$text .= "\n";
|
||||
|
||||
$notEOF = $this->moveToNextLine();
|
||||
}
|
||||
|
||||
if (!$notEOF)
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
if (!preg_match('#^(?P<indent>'.($indentation ? str_repeat(' ', $indentation) : ' +').')(?P<text>.*)$#', $this->currentLine, $matches))
|
||||
{
|
||||
$this->moveToPreviousLine();
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
$textIndent = $matches['indent'];
|
||||
$previousIndent = 0;
|
||||
|
||||
$text .= $matches['text'].$separator;
|
||||
while ($this->currentLineNb + 1 < count($this->lines))
|
||||
{
|
||||
$this->moveToNextLine();
|
||||
|
||||
if (preg_match('#^(?P<indent> {'.strlen($textIndent).',})(?P<text>.+)$#', $this->currentLine, $matches))
|
||||
{
|
||||
if (' ' == $separator && $previousIndent != $matches['indent'])
|
||||
{
|
||||
$text = substr($text, 0, -1)."\n";
|
||||
}
|
||||
$previousIndent = $matches['indent'];
|
||||
|
||||
$text .= str_repeat(' ', $diff = strlen($matches['indent']) - strlen($textIndent)).$matches['text'].($diff ? "\n" : $separator);
|
||||
}
|
||||
else if (preg_match('#^(?P<text> *)$#', $this->currentLine, $matches))
|
||||
{
|
||||
$text .= preg_replace('#^ {1,'.strlen($textIndent).'}#', '', $matches['text'])."\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->moveToPreviousLine();
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (' ' == $separator)
|
||||
{
|
||||
// replace last separator by a newline
|
||||
$text = preg_replace('/ (\n*)$/', "\n$1", $text);
|
||||
}
|
||||
|
||||
switch ($indicator)
|
||||
{
|
||||
case '':
|
||||
$text = preg_replace('#\n+$#s', "\n", $text);
|
||||
break;
|
||||
case '+':
|
||||
break;
|
||||
case '-':
|
||||
$text = preg_replace('#\n+$#s', '', $text);
|
||||
break;
|
||||
}
|
||||
|
||||
return $text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the next line is indented.
|
||||
*
|
||||
* @return Boolean Returns true if the next line is indented, false otherwise
|
||||
*/
|
||||
protected function isNextLineIndented()
|
||||
{
|
||||
$currentIndentation = $this->getCurrentLineIndentation();
|
||||
$notEOF = $this->moveToNextLine();
|
||||
|
||||
while ($notEOF && $this->isCurrentLineEmpty())
|
||||
{
|
||||
$notEOF = $this->moveToNextLine();
|
||||
}
|
||||
|
||||
if (false === $notEOF)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
$ret = false;
|
||||
if ($this->getCurrentLineIndentation() <= $currentIndentation)
|
||||
{
|
||||
$ret = true;
|
||||
}
|
||||
|
||||
$this->moveToPreviousLine();
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the current line is blank or if it is a comment line.
|
||||
*
|
||||
* @return Boolean Returns true if the current line is empty or if it is a comment line, false otherwise
|
||||
*/
|
||||
protected function isCurrentLineEmpty()
|
||||
{
|
||||
return $this->isCurrentLineBlank() || $this->isCurrentLineComment();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the current line is blank.
|
||||
*
|
||||
* @return Boolean Returns true if the current line is blank, false otherwise
|
||||
*/
|
||||
protected function isCurrentLineBlank()
|
||||
{
|
||||
return '' == trim($this->currentLine, ' ');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the current line is a comment line.
|
||||
*
|
||||
* @return Boolean Returns true if the current line is a comment line, false otherwise
|
||||
*/
|
||||
protected function isCurrentLineComment()
|
||||
{
|
||||
//checking explicitly the first char of the trim is faster than loops or strpos
|
||||
$ltrimmedLine = ltrim($this->currentLine, ' ');
|
||||
return $ltrimmedLine[0] === '#';
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleanups a YAML string to be parsed.
|
||||
*
|
||||
* @param string $value The input YAML string
|
||||
*
|
||||
* @return string A cleaned up YAML string
|
||||
*/
|
||||
protected function cleanup($value)
|
||||
{
|
||||
$value = str_replace(array("\r\n", "\r"), "\n", $value);
|
||||
|
||||
if (!preg_match("#\n$#", $value))
|
||||
{
|
||||
$value .= "\n";
|
||||
}
|
||||
|
||||
// strip YAML header
|
||||
$count = 0;
|
||||
$value = preg_replace('#^\%YAML[: ][\d\.]+.*\n#s', '', $value, -1, $count);
|
||||
$this->offset += $count;
|
||||
|
||||
// remove leading comments and/or ---
|
||||
$trimmedValue = preg_replace('#^((\#.*?\n)|(\-\-\-.*?\n))*#s', '', $value, -1, $count);
|
||||
if ($count == 1)
|
||||
{
|
||||
// items have been removed, update the offset
|
||||
$this->offset += substr_count($value, "\n") - substr_count($trimmedValue, "\n");
|
||||
$value = $trimmedValue;
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,312 @@
|
|||
<?php
|
||||
/*
|
||||
* Copyright 2010-2012 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
* A copy of the License is located at
|
||||
*
|
||||
* http://aws.amazon.com/apache2.0
|
||||
*
|
||||
* or in the "license" file accompanying this file. This file is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
* express or implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/*%******************************************************************************************%*/
|
||||
// CLASS
|
||||
|
||||
/**
|
||||
* The <CFArray> object extends PHP's built-in <php:ArrayObject> object by providing convenience methods for
|
||||
* rapidly manipulating array data. Specifically, the `CFArray` object is intended for working with
|
||||
* <CFResponse> and <CFSimpleXML> objects that are returned by AWS services.
|
||||
*
|
||||
* @version 2012.01.17
|
||||
* @license See the included NOTICE.md file for more information.
|
||||
* @copyright See the included NOTICE.md file for more information.
|
||||
* @link http://aws.amazon.com/php/ PHP Developer Center
|
||||
* @link http://php.net/ArrayObject ArrayObject
|
||||
*/
|
||||
class CFArray extends ArrayObject
|
||||
{
|
||||
/**
|
||||
* Constructs a new instance of <CFArray>.
|
||||
*
|
||||
* @param mixed $input (Optional) The input parameter accepts an array or an Object. The default value is an empty array.
|
||||
* @param integer $flags (Optional) Flags to control the behavior of the ArrayObject object. Defaults to <STD_PROP_LIST>.
|
||||
* @param string $iterator_class (Optional) Specify the class that will be used for iteration of the <php:ArrayObject> object. <php:ArrayIterator> is the default class used.
|
||||
* @return mixed Either an array of matches, or a single <CFSimpleXML> element.
|
||||
*/
|
||||
public function __construct($input = array(), $flags = self::STD_PROP_LIST, $iterator_class = 'ArrayIterator')
|
||||
{
|
||||
// Provide a default value
|
||||
$input = $input ? $input : array();
|
||||
|
||||
try {
|
||||
return parent::__construct($input, $flags, $iterator_class);
|
||||
}
|
||||
catch (InvalidArgumentException $e)
|
||||
{
|
||||
throw new CFArray_Exception($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Alternate approach to constructing a new instance. Supports chaining.
|
||||
*
|
||||
* @param mixed $input (Optional) The input parameter accepts an array or an Object. The default value is an empty array.
|
||||
* @param integer $flags (Optional) Flags to control the behavior of the ArrayObject object. Defaults to <STD_PROP_LIST>.
|
||||
* @param string $iterator_class (Optional) Specify the class that will be used for iteration of the <php:ArrayObject> object. <php:ArrayIterator> is the default class used.
|
||||
* @return mixed Either an array of matches, or a single <CFSimpleXML> element.
|
||||
*/
|
||||
public static function init($input = array(), $flags = self::STD_PROP_LIST, $iterator_class = 'ArrayIterator')
|
||||
{
|
||||
if (version_compare(PHP_VERSION, '5.3.0', '<'))
|
||||
{
|
||||
throw new Exception('PHP 5.3 or newer is required to instantiate a new class with CLASS::init().');
|
||||
}
|
||||
|
||||
$self = get_called_class();
|
||||
return new $self($input, $flags, $iterator_class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles how the object is rendered when cast as a string.
|
||||
*
|
||||
* @return string The word "Array".
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return 'Array';
|
||||
}
|
||||
|
||||
|
||||
/*%******************************************************************************************%*/
|
||||
// REFORMATTING
|
||||
|
||||
/**
|
||||
* Maps each element in the <CFArray> object as an integer.
|
||||
*
|
||||
* @return array The contents of the <CFArray> object mapped as integers.
|
||||
*/
|
||||
public function map_integer()
|
||||
{
|
||||
return array_map('intval', $this->getArrayCopy());
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps each element in the CFArray object as a string.
|
||||
*
|
||||
* @param string $pcre (Optional) A Perl-Compatible Regular Expression (PCRE) to filter the names against.
|
||||
* @return array The contents of the <CFArray> object mapped as strings. If there are no results, the method will return an empty array.
|
||||
*/
|
||||
public function map_string($pcre = null)
|
||||
{
|
||||
$list = array_map('strval', $this->getArrayCopy());
|
||||
$dlist = array();
|
||||
|
||||
if ($pcre)
|
||||
{
|
||||
foreach ($list as $item)
|
||||
{
|
||||
$dlist[] = preg_match($pcre, $item) ? $item : null;
|
||||
}
|
||||
|
||||
$list = array_values(array_filter($dlist));
|
||||
}
|
||||
|
||||
return $list;
|
||||
}
|
||||
|
||||
|
||||
/*%******************************************************************************************%*/
|
||||
// CONFIRMATION
|
||||
|
||||
/**
|
||||
* Verifies that _all_ responses were successful. A single failed request will cause <areOK()> to return false. Equivalent to <CFResponse::isOK()>, except it applies to all responses.
|
||||
*
|
||||
* @return boolean Whether _all_ requests were successful or not.
|
||||
*/
|
||||
public function areOK()
|
||||
{
|
||||
$dlist = array();
|
||||
$list = $this->getArrayCopy();
|
||||
|
||||
foreach ($list as $response)
|
||||
{
|
||||
if ($response instanceof CFResponse)
|
||||
{
|
||||
$dlist[] = $response->isOK();
|
||||
}
|
||||
}
|
||||
|
||||
return (array_search(false, $dlist, true) !== false) ? false : true;
|
||||
}
|
||||
|
||||
|
||||
/*%******************************************************************************************%*/
|
||||
// ITERATING AND EXECUTING
|
||||
|
||||
/**
|
||||
* Iterates over a <CFArray> object, and executes a function for each matched element.
|
||||
*
|
||||
* The callback function takes three parameters: <ul>
|
||||
* <li><code>$item</code> - <code>mixed</code> - Optional - The individual node in the array.</li>
|
||||
* <li><code>$key</code> - <code>mixed</code> - Optional - The key for the array node.</li>
|
||||
* <li><code>$bind</code> - <code>mixed</code> - Optional - The variable that was passed into the $bind parameter.</li></ul>
|
||||
*
|
||||
* @param string|function $callback (Required) The callback function to execute. PHP 5.3 or newer can use an anonymous function.
|
||||
* @param mixed $bind (Optional) A variable from the calling scope to pass-by-reference into the local scope of the callback function.
|
||||
* @return CFArray The original <CFArray> object.
|
||||
*/
|
||||
public function each($callback, &$bind = null)
|
||||
{
|
||||
$items = $this->getArrayCopy();
|
||||
|
||||
foreach ($items as $key => &$item)
|
||||
{
|
||||
$callback($item, $key, $bind);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Passes each element in the current <CFArray> object through a function, and produces a new <CFArray> object containing the return values.
|
||||
*
|
||||
* The callback function takes three parameters: <ul>
|
||||
* <li><code>$item</code> - <code>mixed</code> - Optional - The individual node in the array.</li>
|
||||
* <li><code>$key</code> - <code>mixed</code> - Optional - The key for the array node.</li>
|
||||
* <li><code>$bind</code> - <code>mixed</code> - Optional - The variable that was passed into the $bind parameter.</li></ul>
|
||||
*
|
||||
* @param string|function $callback (Required) The callback function to execute. PHP 5.3 or newer can use an anonymous function.
|
||||
* @param mixed $bind (Optional) A variable from the calling scope to pass-by-reference into the local scope of the callback function.
|
||||
* @return CFArray A new <CFArray> object containing the return values.
|
||||
*/
|
||||
public function map($callback, &$bind = null)
|
||||
{
|
||||
$items = $this->getArrayCopy();
|
||||
$collect = array();
|
||||
|
||||
foreach ($items as $key => &$item)
|
||||
{
|
||||
$collect[] = $callback($item, $key, $bind);
|
||||
}
|
||||
|
||||
return new CFArray($collect);
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the list of nodes by passing each value in the current <CFArray> object through a function. The node will be removed if the function returns `false`.
|
||||
*
|
||||
* The callback function takes three parameters: <ul>
|
||||
* <li><code>$item</code> - <code>mixed</code> - Optional - The individual node in the array.</li>
|
||||
* <li><code>$key</code> - <code>mixed</code> - Optional - The key for the array node.</li>
|
||||
* <li><code>$bind</code> - <code>mixed</code> - Optional - The variable that was passed into the $bind parameter.</li></ul>
|
||||
*
|
||||
* @param string|function $callback (Required) The callback function to execute. PHP 5.3 or newer can use an anonymous function.
|
||||
* @param mixed $bind (Optional) A variable from the calling scope to pass-by-reference into the local scope of the callback function.
|
||||
* @return CFArray A new <CFArray> object containing the return values.
|
||||
*/
|
||||
public function filter($callback, &$bind = null)
|
||||
{
|
||||
$items = $this->getArrayCopy();
|
||||
$collect = array();
|
||||
|
||||
foreach ($items as $key => &$item)
|
||||
{
|
||||
if ($callback($item, $key, $bind) !== false)
|
||||
{
|
||||
$collect[] = $item;
|
||||
}
|
||||
}
|
||||
|
||||
return new CFArray($collect);
|
||||
}
|
||||
|
||||
/**
|
||||
* Alias for <filter()>. This functionality was incorrectly named _reduce_ in earlier versions of the SDK.
|
||||
*
|
||||
* @param string|function $callback (Required) The callback function to execute. PHP 5.3 or newer can use an anonymous function.
|
||||
* @param mixed $bind (Optional) A variable from the calling scope to pass-by-reference into the local scope of the callback function.
|
||||
* @return CFArray A new <CFArray> object containing the return values.
|
||||
*/
|
||||
public function reduce($callback, &$bind = null)
|
||||
{
|
||||
return $this->filter($callback, $bind);
|
||||
}
|
||||
|
||||
|
||||
/*%******************************************************************************************%*/
|
||||
// TRAVERSAL
|
||||
|
||||
/**
|
||||
* Gets the first result in the array.
|
||||
*
|
||||
* @return mixed The first result in the <CFArray> object. Returns `false` if there are no items in the array.
|
||||
*/
|
||||
public function first()
|
||||
{
|
||||
$items = $this->getArrayCopy();
|
||||
return count($items) ? $items[0] : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the last result in the array.
|
||||
*
|
||||
* @return mixed The last result in the <CFArray> object. Returns `false` if there are no items in the array.
|
||||
*/
|
||||
public function last()
|
||||
{
|
||||
$items = $this->getArrayCopy();
|
||||
return count($items) ? end($items) : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all `null` values from an array.
|
||||
*
|
||||
* @return CFArray A new <CFArray> object containing the non-null values.
|
||||
*/
|
||||
public function compress()
|
||||
{
|
||||
return new CFArray(array_filter($this->getArrayCopy()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Reindexes the array, starting from zero.
|
||||
*
|
||||
* @return CFArray A new <CFArray> object with indexes starting at zero.
|
||||
*/
|
||||
public function reindex()
|
||||
{
|
||||
return new CFArray(array_values($this->getArrayCopy()));
|
||||
}
|
||||
|
||||
|
||||
/*%******************************************************************************************%*/
|
||||
// ALTERNATE FORMATS
|
||||
|
||||
/**
|
||||
* Gets the current XML node as a JSON string.
|
||||
*
|
||||
* @return string The current XML node as a JSON string.
|
||||
*/
|
||||
public function to_json()
|
||||
{
|
||||
return json_encode($this->getArrayCopy());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current XML node as a YAML string.
|
||||
*
|
||||
* @return string The current XML node as a YAML string.
|
||||
*/
|
||||
public function to_yaml()
|
||||
{
|
||||
return sfYaml::dump($this->getArrayCopy(), 5);
|
||||
}
|
||||
}
|
||||
|
||||
class CFArray_Exception extends Exception {}
|
|
@ -0,0 +1,126 @@
|
|||
<?php
|
||||
/*
|
||||
* Copyright 2010-2012 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
* A copy of the License is located at
|
||||
*
|
||||
* http://aws.amazon.com/apache2.0
|
||||
*
|
||||
* or in the "license" file accompanying this file. This file is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
* express or implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/*%******************************************************************************************%*/
|
||||
// EXCEPTIONS
|
||||
|
||||
/**
|
||||
* Default CFBatchRequest Exception.
|
||||
*/
|
||||
class CFBatchRequest_Exception extends Exception {}
|
||||
|
||||
|
||||
/*%******************************************************************************************%*/
|
||||
// CLASS
|
||||
|
||||
/**
|
||||
* Simplifies the flow involved with managing and executing a batch request queue. Batch requesting is the
|
||||
* ability to queue up a series of requests and execute them all in parallel. This allows for faster
|
||||
* application performance when a lot of requests are involved.
|
||||
*
|
||||
* @version 2011.12.02
|
||||
* @license See the included NOTICE.md file for more information.
|
||||
* @copyright See the included NOTICE.md file for more information.
|
||||
* @link http://aws.amazon.com/php/ PHP Developer Center
|
||||
*/
|
||||
class CFBatchRequest extends CFRuntime
|
||||
{
|
||||
/**
|
||||
* Stores the cURL handles that are to be processed.
|
||||
*/
|
||||
public $queue;
|
||||
|
||||
/**
|
||||
* Stores the size of the request window.
|
||||
*/
|
||||
public $limit;
|
||||
|
||||
/**
|
||||
* The proxy to use for connecting.
|
||||
*/
|
||||
public $proxy = null;
|
||||
|
||||
/**
|
||||
* The helpers to use when connecting.
|
||||
*/
|
||||
public $helpers = null;
|
||||
|
||||
/**
|
||||
* The active credential set.
|
||||
*/
|
||||
public $credentials;
|
||||
|
||||
|
||||
/*%******************************************************************************************%*/
|
||||
// CONSTRUCTOR
|
||||
|
||||
/**
|
||||
* Constructs a new instance of this class.
|
||||
*
|
||||
* @param integer $limit (Optional) The size of the request window. Defaults to unlimited.
|
||||
* @return boolean `false` if no valid values are set, otherwise `true`.
|
||||
*/
|
||||
public function __construct($limit = null)
|
||||
{
|
||||
$this->queue = array();
|
||||
$this->limit = $limit ? $limit : -1;
|
||||
$this->credentials = new CFCredential(array());
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the AWS credentials to use for the batch request.
|
||||
*
|
||||
* @param CFCredential $credentials (Required) The credentials to use for signing and making requests.
|
||||
* @return $this A reference to the current instance.
|
||||
*/
|
||||
public function use_credentials(CFCredential $credentials)
|
||||
{
|
||||
$this->credentials = $credentials;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new cURL handle to the request queue.
|
||||
*
|
||||
* @param resource $handle (Required) A cURL resource to add to the queue.
|
||||
* @return $this A reference to the current instance.
|
||||
*/
|
||||
public function add($handle)
|
||||
{
|
||||
$this->queue[] = $handle;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the batch request queue.
|
||||
*
|
||||
* @param array $opt (DO NOT USE) Enabled for compatibility with the method this overrides, although any values passed will be ignored.
|
||||
* @return array An indexed array of <CFResponse> objects.
|
||||
*/
|
||||
public function send($opt = null)
|
||||
{
|
||||
$http = new $this->request_class(null, $this->proxy, null, $this->credentials);
|
||||
|
||||
// Make the request
|
||||
$response = $http->send_multi_request($this->queue, array(
|
||||
'limit' => $this->limit
|
||||
));
|
||||
|
||||
return $response;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,123 @@
|
|||
<?php
|
||||
/*
|
||||
* Copyright 2010-2012 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
* A copy of the License is located at
|
||||
*
|
||||
* http://aws.amazon.com/apache2.0
|
||||
*
|
||||
* or in the "license" file accompanying this file. This file is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
* express or implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/*%******************************************************************************************%*/
|
||||
// CLASS
|
||||
|
||||
/**
|
||||
* Contains utility methods used for converting array, JSON, and YAML data types into query string keys.
|
||||
*
|
||||
* @version 2010.11.11
|
||||
* @license See the included NOTICE.md file for more information.
|
||||
* @copyright See the included NOTICE.md file for more information.
|
||||
* @link http://aws.amazon.com/php/ PHP Developer Center
|
||||
*/
|
||||
class CFComplexType
|
||||
{
|
||||
/**
|
||||
* Takes a JSON object, as a string, to convert to query string keys.
|
||||
*
|
||||
* @param string $json (Required) A JSON object. The JSON string should use canonical rules (e.g., double quotes, quoted keys) as is required by PHP's <php:json_encode()> function.
|
||||
* @param string $member (Optional) The name of the "member" property that AWS uses for lists in certain services. Defaults to an empty string.
|
||||
* @param string $default_key (Optional) The default key to use when the value for `$data` is a string. Defaults to an empty string.
|
||||
* @return array The option group parameters to merge into another method's `$opt` parameter.
|
||||
*/
|
||||
public static function json($json, $member = '', $default_key = '')
|
||||
{
|
||||
return self::option_group(json_decode($json, true), $member, $default_key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes a YAML object, as a string, to convert to query string keys.
|
||||
*
|
||||
* @param string $yaml (Required) A YAML object.
|
||||
* @param string $member (Optional) The name of the "member" property that AWS uses for lists in certain services. Defaults to an empty string.
|
||||
* @param string $default_key (Optional) The default key to use when the value for `$data` is a string. Defaults to an empty string.
|
||||
* @return array The option group parameters to merge into another method's `$opt` parameter.
|
||||
*/
|
||||
public static function yaml($yaml, $member = '', $default_key = '')
|
||||
{
|
||||
return self::option_group(sfYaml::load($yaml), $member, $default_key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes an associative array to convert to query string keys.
|
||||
*
|
||||
* @param array $map (Required) An associative array.
|
||||
* @param string $member (Optional) The name of the "member" property that AWS uses for lists in certain services. Defaults to an empty string.
|
||||
* @param string $default_key (Optional) The default key to use when the value for `$data` is a string. Defaults to an empty string.
|
||||
* @return array The option group parameters to merge into another method's `$opt` parameter.
|
||||
*/
|
||||
public static function map($map, $member = '', $default_key = '')
|
||||
{
|
||||
return self::option_group($map, $member, $default_key);
|
||||
}
|
||||
|
||||
/**
|
||||
* A protected method that is used by <json()>, <yaml()> and <map()>.
|
||||
*
|
||||
* @param string|array $data (Required) The data to iterate over.
|
||||
* @param string $member (Optional) The name of the "member" property that AWS uses for lists in certain services. Defaults to an empty string.
|
||||
* @param string $key (Optional) The default key to use when the value for `$data` is a string. Defaults to an empty string.
|
||||
* @param array $out (Optional) INTERNAL ONLY. The array that contains the calculated values up to this point.
|
||||
* @return array The option group parameters to merge into another method's `$opt` parameter.
|
||||
*/
|
||||
public static function option_group($data, $member = '', $key = '', &$out = array())
|
||||
{
|
||||
$reset = $key;
|
||||
|
||||
if (is_array($data))
|
||||
{
|
||||
foreach ($data as $k => $v)
|
||||
{
|
||||
// Avoid 0-based indexes.
|
||||
if (is_int($k))
|
||||
{
|
||||
$k = $k + 1;
|
||||
|
||||
if ($member !== '')
|
||||
{
|
||||
$key .= '.' . $member;
|
||||
}
|
||||
}
|
||||
|
||||
$key .= ($key === '' ? $k : '.' . $k);
|
||||
|
||||
if (is_array($v))
|
||||
{
|
||||
self::option_group($v, $member, $key, $out);
|
||||
}
|
||||
elseif ($v instanceof CFStepConfig)
|
||||
{
|
||||
self::option_group($v->get_config(), $member, $key, $out);
|
||||
}
|
||||
else
|
||||
{
|
||||
$out[$key] = $v;
|
||||
}
|
||||
|
||||
$key = $reset;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$out[$key] = $data;
|
||||
}
|
||||
|
||||
return $out;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,157 @@
|
|||
<?php
|
||||
/*
|
||||
* Copyright 2010-2012 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
* A copy of the License is located at
|
||||
*
|
||||
* http://aws.amazon.com/apache2.0
|
||||
*
|
||||
* or in the "license" file accompanying this file. This file is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
* express or implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/*%******************************************************************************************%*/
|
||||
// CLASS
|
||||
|
||||
/**
|
||||
* The <CFCredential> class represents an individual credential set.
|
||||
*
|
||||
* @version 2011.11.15
|
||||
* @license See the included NOTICE.md file for more information.
|
||||
* @copyright See the included NOTICE.md file for more information.
|
||||
* @link http://aws.amazon.com/php/ PHP Developer Center
|
||||
*/
|
||||
class CFCredential implements ArrayAccess
|
||||
{
|
||||
/**
|
||||
* Stores the internal <php:ArrayObject> representation of the collection.
|
||||
*/
|
||||
private $collection;
|
||||
|
||||
/**
|
||||
* Default getter. Enables syntax such as $object->method->chained_method();. Also supports
|
||||
* $object->key. Matching methods are prioritized over matching keys.
|
||||
*
|
||||
* @param string $name (Required) The name of the method to execute or key to retrieve.
|
||||
* @return mixed The results of calling the function <code>$name()</code>, or the value of the key <code>$object[$name]</code>.
|
||||
*/
|
||||
public function __get($name)
|
||||
{
|
||||
return $this[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* Default setter.
|
||||
*
|
||||
* @param string $name (Required) The name of the method to execute.
|
||||
* @param string $value (Required) The value to pass to the method.
|
||||
* @return mixed The results of calling the function, <code>$name</code>.
|
||||
*/
|
||||
public function __set($name, $value)
|
||||
{
|
||||
$this[$name] = $value;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a clone of the object.
|
||||
*
|
||||
* @return CFCredential A clone of the current instance.
|
||||
*/
|
||||
public function __clone()
|
||||
{
|
||||
$this->collection = clone $this->collection;
|
||||
}
|
||||
|
||||
|
||||
/*%******************************************************************************************%*/
|
||||
// CONSTRUCTOR
|
||||
|
||||
/**
|
||||
* Constructs a new instance of the <CFCredential> class.
|
||||
*/
|
||||
public function __construct($value = array())
|
||||
{
|
||||
$this->collection = new ArrayObject($value, ArrayObject::ARRAY_AS_PROPS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether or not a specific offset exists.
|
||||
*
|
||||
* @param integer $offset (Required) The location in the collection to verify the existence of.
|
||||
* @return boolean A value of <code>true</code> indicates that the collection offset exists. A value of <code>false</code> indicates that it does not.
|
||||
*/
|
||||
public function offsetExists($offset)
|
||||
{
|
||||
return $this->collection->offsetExists($offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value for a specific offset.
|
||||
*
|
||||
* @param integer $offset (Required) The location in the collection to retrieve the value for.
|
||||
* @return mixed The value of the collection offset. <code>NULL</code> is returned if the offset does not exist.
|
||||
*/
|
||||
public function offsetGet($offset)
|
||||
{
|
||||
if ($this->collection->offsetExists($offset))
|
||||
{
|
||||
return $this->collection->offsetGet($offset);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value for a specific offset.
|
||||
*
|
||||
* @param integer $offset (Required) The location in the collection to set a new value for.
|
||||
* @param mixed $value (Required) The new value for the collection location.
|
||||
* @return CFCredential A reference to the current collection.
|
||||
*/
|
||||
public function offsetSet($offset, $value)
|
||||
{
|
||||
$this->collection->offsetSet($offset, $value);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unset the value for a specific offset.
|
||||
*
|
||||
* @param integer $offset (Required) The location in the collection to unset.
|
||||
* @return CFCredential A reference to the current collection.
|
||||
*/
|
||||
public function offsetUnset($offset)
|
||||
{
|
||||
$this->collection->offsetUnset($offset);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge another instance of <CFCredential> onto this one.
|
||||
*
|
||||
* @param CFCredential $credential (Required) Another instance of <CFCredential>.
|
||||
* @return CFCredential A reference to the current collection.
|
||||
*/
|
||||
public function merge(CFCredential $credential)
|
||||
{
|
||||
$merged = array_merge($this->to_array(), $credential->to_array());
|
||||
$this->collection->exchangeArray($merged);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the data as a standard array.
|
||||
*
|
||||
* @return array The data as an array.
|
||||
*/
|
||||
public function to_array()
|
||||
{
|
||||
return $this->collection->getArrayCopy();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,125 @@
|
|||
<?php
|
||||
/*
|
||||
* Copyright 2010-2012 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
* A copy of the License is located at
|
||||
*
|
||||
* http://aws.amazon.com/apache2.0
|
||||
*
|
||||
* or in the "license" file accompanying this file. This file is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
* express or implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/*%******************************************************************************************%*/
|
||||
// CLASS
|
||||
|
||||
/**
|
||||
* The <CFCredentials> class enables developers to easily switch between multiple sets of credentials.
|
||||
*
|
||||
* @version 2011.11.15
|
||||
* @license See the included NOTICE.md file for more information.
|
||||
* @copyright See the included NOTICE.md file for more information.
|
||||
* @link http://aws.amazon.com/php/ PHP Developer Center
|
||||
*/
|
||||
class CFCredentials
|
||||
{
|
||||
/**
|
||||
* The key used to specify the default credential set
|
||||
*/
|
||||
const DEFAULT_KEY = '@default';
|
||||
|
||||
/**
|
||||
* The key used to identify inherited credentials
|
||||
*/
|
||||
const INHERIT_KEY = '@inherit';
|
||||
|
||||
/**
|
||||
* Stores the credentials
|
||||
*/
|
||||
protected static $credentials = array();
|
||||
|
||||
/**
|
||||
* Prevents this class from being constructed
|
||||
*/
|
||||
final private function __construct() {}
|
||||
|
||||
/**
|
||||
* Stores the credentials for re-use.
|
||||
*
|
||||
* @param array $credential_sets (Required) The named credential sets that should be made available to the application.
|
||||
* @return void
|
||||
*/
|
||||
public static function set(array $credential_sets)
|
||||
{
|
||||
// Make sure a default credential set is specified or can be inferred
|
||||
if (count($credential_sets) === 1)
|
||||
{
|
||||
$credential_sets[self::DEFAULT_KEY] = reset($credential_sets);
|
||||
}
|
||||
elseif (!isset($credential_sets[self::DEFAULT_KEY]))
|
||||
{
|
||||
throw new CFCredentials_Exception('If more than one credential set is provided, a default credential set (identified by the key "' . self::DEFAULT_KEY . '") must be specified.');
|
||||
}
|
||||
|
||||
// Resolve any @inherit tags
|
||||
foreach ($credential_sets as $credential_name => &$credential_set)
|
||||
{
|
||||
if (is_array($credential_set))
|
||||
{
|
||||
foreach ($credential_set as $credential_key => &$credential_value)
|
||||
{
|
||||
if ($credential_key === self::INHERIT_KEY)
|
||||
{
|
||||
if (!isset($credential_sets[$credential_value]))
|
||||
{
|
||||
throw new CFCredentials_Exception('The credential set, "' . $credential_value . '", does not exist and cannot be inherited.');
|
||||
}
|
||||
|
||||
$credential_set = array_merge($credential_sets[$credential_value], $credential_set);
|
||||
unset($credential_set[self::INHERIT_KEY]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Normalize the value of the @default credential set
|
||||
$default = $credential_sets[self::DEFAULT_KEY];
|
||||
if (is_string($default))
|
||||
{
|
||||
if (!isset($credential_sets[$default]))
|
||||
{
|
||||
throw new CFCredentials_Exception('The credential set, "' . $default . '", does not exist and cannot be used as the default credential set.');
|
||||
}
|
||||
|
||||
$credential_sets[self::DEFAULT_KEY] = $credential_sets[$default];
|
||||
}
|
||||
|
||||
// Store the credentials
|
||||
self::$credentials = $credential_sets;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the requested credentials from the internal credential store.
|
||||
*
|
||||
* @param string $credential_set (Optional) The name of the credential set to retrieve. The default value is set in DEFAULT_KEY.
|
||||
* @return stdClass A stdClass object where the properties represent the keys that were provided.
|
||||
*/
|
||||
public static function get($credential_name = self::DEFAULT_KEY)
|
||||
{
|
||||
// Make sure the credential set exists
|
||||
if (!isset(self::$credentials[$credential_name]))
|
||||
{
|
||||
throw new CFCredentials_Exception('The credential set, "' . $credential_name . '", does not exist and cannot be retrieved.');
|
||||
}
|
||||
|
||||
// Return the credential set as an object
|
||||
return new CFCredential(self::$credentials[$credential_name]);
|
||||
}
|
||||
}
|
||||
|
||||
class CFCredentials_Exception extends Exception {}
|
|
@ -0,0 +1,377 @@
|
|||
<?php
|
||||
/*
|
||||
* Copyright 2011-2012 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
* A copy of the License is located at
|
||||
*
|
||||
* http://aws.amazon.com/apache2.0
|
||||
*
|
||||
* or in the "license" file accompanying this file. This file is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
* express or implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* SimplePie
|
||||
*
|
||||
* A PHP-Based RSS and Atom Feed Framework.
|
||||
* Takes the hard work out of managing a complete RSS/Atom solution.
|
||||
*
|
||||
* Copyright (c) 2004-2010, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* * Neither the name of the SimplePie Team nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
|
||||
* AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* @package SimplePie
|
||||
* @version 1.3-dev
|
||||
* @copyright 2004-2010 Ryan Parman, Geoffrey Sneddon, Ryan McCue
|
||||
* @author Ryan Parman
|
||||
* @author Geoffrey Sneddon
|
||||
* @author Ryan McCue
|
||||
* @link http://simplepie.org/ SimplePie
|
||||
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
|
||||
* @todo phpDoc comments
|
||||
*/
|
||||
|
||||
|
||||
/*%******************************************************************************************%*/
|
||||
// CLASS
|
||||
|
||||
/**
|
||||
* Handles a variety of primary and edge cases around gzip/deflate decoding in PHP.
|
||||
*
|
||||
* @version 2011.02.21
|
||||
* @license See the included NOTICE.md file for more information.
|
||||
* @copyright See the included NOTICE.md file for more information.
|
||||
* @link http://aws.amazon.com/php/ PHP Developer Center
|
||||
* @link https://github.com/simplepie/simplepie/blob/master/SimplePie/gzdecode.php SimplePie_gzdecode
|
||||
*/
|
||||
class CFGzipDecode
|
||||
{
|
||||
/**
|
||||
* Compressed data
|
||||
*
|
||||
* @access private
|
||||
* @see gzdecode::$data
|
||||
*/
|
||||
public $compressed_data;
|
||||
|
||||
/**
|
||||
* Size of compressed data
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
public $compressed_size;
|
||||
|
||||
/**
|
||||
* Minimum size of a valid gzip string
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
public $min_compressed_size = 18;
|
||||
|
||||
/**
|
||||
* Current position of pointer
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
public $position = 0;
|
||||
|
||||
/**
|
||||
* Flags (FLG)
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
public $flags;
|
||||
|
||||
/**
|
||||
* Uncompressed data
|
||||
*
|
||||
* @access public
|
||||
* @see gzdecode::$compressed_data
|
||||
*/
|
||||
public $data;
|
||||
|
||||
/**
|
||||
* Modified time
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public $MTIME;
|
||||
|
||||
/**
|
||||
* Extra Flags
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public $XFL;
|
||||
|
||||
/**
|
||||
* Operating System
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public $OS;
|
||||
|
||||
/**
|
||||
* Subfield ID 1
|
||||
*
|
||||
* @access public
|
||||
* @see gzdecode::$extra_field
|
||||
* @see gzdecode::$SI2
|
||||
*/
|
||||
public $SI1;
|
||||
|
||||
/**
|
||||
* Subfield ID 2
|
||||
*
|
||||
* @access public
|
||||
* @see gzdecode::$extra_field
|
||||
* @see gzdecode::$SI1
|
||||
*/
|
||||
public $SI2;
|
||||
|
||||
/**
|
||||
* Extra field content
|
||||
*
|
||||
* @access public
|
||||
* @see gzdecode::$SI1
|
||||
* @see gzdecode::$SI2
|
||||
*/
|
||||
public $extra_field;
|
||||
|
||||
/**
|
||||
* Original filename
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public $filename;
|
||||
|
||||
/**
|
||||
* Human readable comment
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public $comment;
|
||||
|
||||
/**
|
||||
* Don't allow anything to be set
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function __set($name, $value)
|
||||
{
|
||||
trigger_error("Cannot write property $name", E_USER_ERROR);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the compressed string and related properties
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function __construct($data)
|
||||
{
|
||||
$this->compressed_data = $data;
|
||||
$this->compressed_size = strlen($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode the GZIP stream
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function parse()
|
||||
{
|
||||
if ($this->compressed_size >= $this->min_compressed_size)
|
||||
{
|
||||
// Check ID1, ID2, and CM
|
||||
if (substr($this->compressed_data, 0, 3) !== "\x1F\x8B\x08")
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get the FLG (FLaGs)
|
||||
$this->flags = ord($this->compressed_data[3]);
|
||||
|
||||
// FLG bits above (1 << 4) are reserved
|
||||
if ($this->flags > 0x1F)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Advance the pointer after the above
|
||||
$this->position += 4;
|
||||
|
||||
// MTIME
|
||||
$mtime = substr($this->compressed_data, $this->position, 4);
|
||||
// Reverse the string if we're on a big-endian arch because l is the only signed long and is machine endianness
|
||||
if (current(unpack('S', "\x00\x01")) === 1)
|
||||
{
|
||||
$mtime = strrev($mtime);
|
||||
}
|
||||
$this->MTIME = current(unpack('l', $mtime));
|
||||
$this->position += 4;
|
||||
|
||||
// Get the XFL (eXtra FLags)
|
||||
$this->XFL = ord($this->compressed_data[$this->position++]);
|
||||
|
||||
// Get the OS (Operating System)
|
||||
$this->OS = ord($this->compressed_data[$this->position++]);
|
||||
|
||||
// Parse the FEXTRA
|
||||
if ($this->flags & 4)
|
||||
{
|
||||
// Read subfield IDs
|
||||
$this->SI1 = $this->compressed_data[$this->position++];
|
||||
$this->SI2 = $this->compressed_data[$this->position++];
|
||||
|
||||
// SI2 set to zero is reserved for future use
|
||||
if ($this->SI2 === "\x00")
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get the length of the extra field
|
||||
$len = current(unpack('v', substr($this->compressed_data, $this->position, 2)));
|
||||
$position += 2;
|
||||
|
||||
// Check the length of the string is still valid
|
||||
$this->min_compressed_size += $len + 4;
|
||||
if ($this->compressed_size >= $this->min_compressed_size)
|
||||
{
|
||||
// Set the extra field to the given data
|
||||
$this->extra_field = substr($this->compressed_data, $this->position, $len);
|
||||
$this->position += $len;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Parse the FNAME
|
||||
if ($this->flags & 8)
|
||||
{
|
||||
// Get the length of the filename
|
||||
$len = strcspn($this->compressed_data, "\x00", $this->position);
|
||||
|
||||
// Check the length of the string is still valid
|
||||
$this->min_compressed_size += $len + 1;
|
||||
if ($this->compressed_size >= $this->min_compressed_size)
|
||||
{
|
||||
// Set the original filename to the given string
|
||||
$this->filename = substr($this->compressed_data, $this->position, $len);
|
||||
$this->position += $len + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Parse the FCOMMENT
|
||||
if ($this->flags & 16)
|
||||
{
|
||||
// Get the length of the comment
|
||||
$len = strcspn($this->compressed_data, "\x00", $this->position);
|
||||
|
||||
// Check the length of the string is still valid
|
||||
$this->min_compressed_size += $len + 1;
|
||||
if ($this->compressed_size >= $this->min_compressed_size)
|
||||
{
|
||||
// Set the original comment to the given string
|
||||
$this->comment = substr($this->compressed_data, $this->position, $len);
|
||||
$this->position += $len + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Parse the FHCRC
|
||||
if ($this->flags & 2)
|
||||
{
|
||||
// Check the length of the string is still valid
|
||||
$this->min_compressed_size += $len + 2;
|
||||
if ($this->compressed_size >= $this->min_compressed_size)
|
||||
{
|
||||
// Read the CRC
|
||||
$crc = current(unpack('v', substr($this->compressed_data, $this->position, 2)));
|
||||
|
||||
// Check the CRC matches
|
||||
if ((crc32(substr($this->compressed_data, 0, $this->position)) & 0xFFFF) === $crc)
|
||||
{
|
||||
$this->position += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Decompress the actual data
|
||||
if (($this->data = gzinflate(substr($this->compressed_data, $this->position, -8))) === false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->position = $this->compressed_size - 8;
|
||||
}
|
||||
|
||||
// Check CRC of data
|
||||
$crc = current(unpack('V', substr($this->compressed_data, $this->position, 4)));
|
||||
$this->position += 4;
|
||||
/*if (extension_loaded('hash') && sprintf('%u', current(unpack('V', hash('crc32b', $this->data)))) !== sprintf('%u', $crc))
|
||||
{
|
||||
return false;
|
||||
}*/
|
||||
|
||||
// Check ISIZE of data
|
||||
$isize = current(unpack('V', substr($this->compressed_data, $this->position, 4)));
|
||||
$this->position += 4;
|
||||
if (sprintf('%u', strlen($this->data) & 0xFFFFFFFF) !== sprintf('%u', $isize))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Wow, against all odds, we've actually got a valid gzip string
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
<?php
|
||||
/*
|
||||
* Copyright 2010-2012 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
* A copy of the License is located at
|
||||
*
|
||||
* http://aws.amazon.com/apache2.0
|
||||
*
|
||||
* or in the "license" file accompanying this file. This file is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
* express or implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/*%******************************************************************************************%*/
|
||||
// CLASS
|
||||
|
||||
/**
|
||||
* Contains core functionality for Hadoop helpers.
|
||||
*
|
||||
* @version 2011.05.03
|
||||
* @license See the included NOTICE.md file for more information.
|
||||
* @copyright See the included NOTICE.md file for more information.
|
||||
* @link http://aws.amazon.com/php/ PHP Developer Center
|
||||
* @link http://hadoop.apache.org Apache Hadoop
|
||||
*/
|
||||
class CFHadoopBase
|
||||
{
|
||||
/**
|
||||
* Runs a specified script on the master node of your cluster.
|
||||
*
|
||||
* @param string $script (Required) The script to run with `script-runner.jar`.
|
||||
* @param array $args (Optional) An indexed array of arguments to pass to the script.
|
||||
* @return array A standard array that is intended to be passed into a <CFStepConfig> object.
|
||||
*/
|
||||
public static function script_runner($script, $args = null)
|
||||
{
|
||||
if (!$args) $args = array();
|
||||
array_unshift($args, $script);
|
||||
|
||||
return array(
|
||||
'Jar' => 's3://us-east-1.elasticmapreduce/libs/script-runner/script-runner.jar',
|
||||
'Args' => $args
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares a Hive or Pig script before passing it to the script runner.
|
||||
*
|
||||
* @param string $type (Required) The type of script to run. [Allowed values: `hive`, `pig`].
|
||||
* @param array $args (Optional) An indexed array of arguments to pass to the script.
|
||||
* @return array A standard array that is intended to be passed into a <CFStepConfig> object.
|
||||
* @link http://hive.apache.org Apache Hive
|
||||
* @link http://pig.apache.org Apache Pig
|
||||
*/
|
||||
public static function hive_pig_script($type, $args = null)
|
||||
{
|
||||
if (!$args) $args = array();
|
||||
$args = is_array($args) ? $args : array($args);
|
||||
$args = array_merge(array('--base-path', 's3://us-east-1.elasticmapreduce/libs/' . $type . '/'), $args);
|
||||
|
||||
return self::script_runner('s3://us-east-1.elasticmapreduce/libs/' . $type . '/' . $type . '-script', $args);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,127 @@
|
|||
<?php
|
||||
/*
|
||||
* Copyright 2010-2012 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
* A copy of the License is located at
|
||||
*
|
||||
* http://aws.amazon.com/apache2.0
|
||||
*
|
||||
* or in the "license" file accompanying this file. This file is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
* express or implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/*%******************************************************************************************%*/
|
||||
// CLASS
|
||||
|
||||
/**
|
||||
* Contains a set of pre-built Amazon EMR Hadoop Bootstrap Actions.
|
||||
*
|
||||
* @version 2011.05.03
|
||||
* @license See the included NOTICE.md file for more information.
|
||||
* @copyright See the included NOTICE.md file for more information.
|
||||
* @link http://aws.amazon.com/php/ PHP Developer Center
|
||||
* @link http://hadoop.apache.org Apache Hadoop
|
||||
*/
|
||||
class CFHadoopBootstrap extends CFHadoopBase
|
||||
{
|
||||
// Config file types
|
||||
const CONFIG_SITE = 'S';
|
||||
const CONFIG_DEFAULT = 'D';
|
||||
const CONFIG_CORE = 'C';
|
||||
const CONFIG_HDFS = 'H';
|
||||
const CONFIG_MAPREDUCE = 'M';
|
||||
|
||||
// Daemon types
|
||||
const DAEMON_NAME_NODE = 'namenode';
|
||||
const DAEMON_DATA_NODE = 'datanode';
|
||||
const DAEMON_JOB_TRACKER = 'jobtracker';
|
||||
const DAEMON_TASK_TRACKER = 'tasktracker';
|
||||
const DAEMON_CLIENT = 'client';
|
||||
|
||||
/**
|
||||
* Create a new run-if bootstrap action which lets you conditionally run bootstrap actions.
|
||||
*
|
||||
* @param string $condition (Required) The condition to evaluate. If <code>true</code>, the bootstrap action executes.
|
||||
* @param array $args (Optional) An indexed array of arguments to pass to the script.
|
||||
* @return array A configuration set to be provided when running a job flow.
|
||||
*/
|
||||
public static function run_if($condition, $args = null)
|
||||
{
|
||||
if (!$args) $args = array();
|
||||
$args = is_array($args) ? $args : array($args);
|
||||
|
||||
return self::script_runner('s3://us-east-1.elasticmapreduce/bootstrap-actions/run-if', $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify options to merge with Hadoop's default configuration.
|
||||
*
|
||||
* @param string $file (Required) The Hadoop configuration file to merge with. [Allowed values: <code>CFHadoopBootstrap::CONFIG_SITE</code>, <code>CFHadoopBootstrap::CONFIG_DEFAULT</code>, <code>CFHadoopBootstrap::CONFIG_CORE</code>, <code>CFHadoopBootstrap::CONFIG_HDFS</code>, <code>CFHadoopBootstrap::CONFIG_MAPREDUCE</code>]
|
||||
* @param string|array $config (Required) This can either be an XML file in S3 (as <code>s3://bucket/path</code>), or an associative array of key-value pairs.
|
||||
* @return array A configuration set to be provided when running a job flow.
|
||||
*/
|
||||
public static function configure($file, $config)
|
||||
{
|
||||
$args = array();
|
||||
$file_arg = '-' . $file;
|
||||
|
||||
if (is_string($config))
|
||||
{
|
||||
$args[] = $file_arg;
|
||||
$args[] = $config;
|
||||
}
|
||||
elseif (is_array($config))
|
||||
{
|
||||
foreach ($config as $key => $value)
|
||||
{
|
||||
$args[] = $file_arg;
|
||||
$args[] = $key . '=' . $value;
|
||||
}
|
||||
}
|
||||
|
||||
return self::script_runner('s3://us-east-1.elasticmapreduce/bootstrap-actions/configure-hadoop', $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new bootstrap action which lets you configure Hadoop's daemons. The options are written to
|
||||
* the <code>hadoop-user-env.sh</code> file.
|
||||
*
|
||||
* @param string $daemon_type (Required) The Hadoop daemon to configure.
|
||||
* @param array $opt (Optional) An associative array of parameters that can have the following keys: <ul>
|
||||
* <li><code>HeapSize</code> - <code>integer</code> - Optional - The requested heap size of the daemon, in megabytes.</li>
|
||||
* <li><code>CLIOptions</code> - <code>string</code> - Optional - Additional Java command line arguments to pass to the daemon.</li>
|
||||
* <li><code>Replace</code> - <code>boolean</code> - Optional - Whether or not the file should be replaced. A value of <code>true</code> will replace the existing configuration file. A value of <code>false</code> will append the options to the configuration file.</li></ul>
|
||||
* @return array A configuration set to be provided when running a job flow.
|
||||
*/
|
||||
public static function daemon($daemon_type, $opt = null)
|
||||
{
|
||||
if (!$opt) $opt = array();
|
||||
$args = array();
|
||||
|
||||
foreach ($opt as $key => $value)
|
||||
{
|
||||
switch ($key)
|
||||
{
|
||||
case 'HeapSize':
|
||||
$args[] = '--' . $daemon_type . '-heap-size=' . $value;
|
||||
break;
|
||||
case 'CLIOptions':
|
||||
$args[] = '--' . $daemon_type . '-opts="' . $value . '"';
|
||||
break;
|
||||
case 'Replace':
|
||||
if ((is_string($value) && $value === 'true') || (is_bool($value) && $value === true))
|
||||
{
|
||||
$args[] = '--replace';
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return self::script_runner('s3://us-east-1.elasticmapreduce/bootstrap-actions/configure-daemons', $args);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,98 @@
|
|||
<?php
|
||||
/*
|
||||
* Copyright 2010-2012 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
* A copy of the License is located at
|
||||
*
|
||||
* http://aws.amazon.com/apache2.0
|
||||
*
|
||||
* or in the "license" file accompanying this file. This file is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
* express or implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/*%******************************************************************************************%*/
|
||||
// CLASS
|
||||
|
||||
/**
|
||||
* Contains a set of pre-built Amazon EMR Hadoop steps.
|
||||
*
|
||||
* @version 2011.05.03
|
||||
* @license See the included NOTICE.md file for more information.
|
||||
* @copyright See the included NOTICE.md file for more information.
|
||||
* @link http://aws.amazon.com/php/ PHP Developer Center
|
||||
* @link http://hadoop.apache.org Apache Hadoop
|
||||
*/
|
||||
class CFHadoopStep extends CFHadoopBase
|
||||
{
|
||||
/**
|
||||
* When ran as the first step in your job flow, enables the Hadoop debugging UI in the AWS
|
||||
* Management Console.
|
||||
*
|
||||
* @return array A standard array that is intended to be passed into a <CFStepConfig> object.
|
||||
*/
|
||||
public static function enable_debugging()
|
||||
{
|
||||
return self::script_runner('s3://us-east-1.elasticmapreduce/libs/state-pusher/0.1/fetch');
|
||||
}
|
||||
|
||||
/**
|
||||
* Step that installs Hive on your job flow.
|
||||
*
|
||||
* @return array A standard array that is intended to be passed into a <CFStepConfig> object.
|
||||
* @link http://hive.apache.org Apache Hive
|
||||
*/
|
||||
public static function install_hive()
|
||||
{
|
||||
return self::hive_pig_script('hive', '--install-hive');
|
||||
}
|
||||
|
||||
/**
|
||||
* Step that runs a Hive script on your job flow.
|
||||
*
|
||||
* @param string $script (Required) The script to run with `script-runner.jar`.
|
||||
* @param array $args (Optional) An indexed array of arguments to pass to the script.
|
||||
* @return array A standard array that is intended to be passed into a <CFStepConfig> object.
|
||||
* @link http://hive.apache.org Apache Hive
|
||||
*/
|
||||
public static function run_hive_script($script, $args = null)
|
||||
{
|
||||
if (!$args) $args = array();
|
||||
$args = is_array($args) ? $args : array($args);
|
||||
$args = array_merge(array('--run-hive-script', '--args', '-f', $script), $args);
|
||||
|
||||
return self::hive_pig_script('hive', $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Step that installs Pig on your job flow.
|
||||
*
|
||||
* @return array A standard array that is intended to be passed into a <CFStepConfig> object.
|
||||
* @link http://pig.apache.org Apache Pig
|
||||
*/
|
||||
public static function install_pig()
|
||||
{
|
||||
return self::hive_pig_script('pig', '--install-pig');
|
||||
}
|
||||
|
||||
/**
|
||||
* Step that runs a Pig script on your job flow.
|
||||
*
|
||||
* @param string $script (Required) The script to run with `script-runner.jar`.
|
||||
* @param array $args (Optional) An indexed array of arguments to pass to the script.
|
||||
* @return array A standard array that is intended to be passed into a <CFStepConfig> object.
|
||||
* @link http://pig.apache.org Apache Pig
|
||||
*/
|
||||
public static function run_pig_script($script, $args = null)
|
||||
{
|
||||
if (!$args) $args = array();
|
||||
$args = is_array($args) ? $args : array($args);
|
||||
$args = array_merge(array('--run-pig-script', '--args', '-f', $script), $args);
|
||||
|
||||
return self::hive_pig_script('pig', $args);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
<?php
|
||||
/*
|
||||
* Copyright 2010-2012 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
* A copy of the License is located at
|
||||
*
|
||||
* http://aws.amazon.com/apache2.0
|
||||
*
|
||||
* or in the "license" file accompanying this file. This file is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
* express or implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/*%******************************************************************************************%*/
|
||||
// CLASS
|
||||
|
||||
/**
|
||||
* Contains a series of methods that provide information about the SDK.
|
||||
*
|
||||
* @version 2010.10.01
|
||||
* @license See the included NOTICE.md file for more information.
|
||||
* @copyright See the included NOTICE.md file for more information.
|
||||
* @link http://aws.amazon.com/php/ PHP Developer Center
|
||||
*/
|
||||
class CFInfo
|
||||
{
|
||||
/**
|
||||
* Gets information about the web service APIs that the SDK supports.
|
||||
*
|
||||
* @return array An associative array containing service classes and API versions.
|
||||
*/
|
||||
public static function api_support()
|
||||
{
|
||||
$existing_classes = get_declared_classes();
|
||||
|
||||
foreach (glob(dirname(dirname(__FILE__)) . '/services/*.class.php') as $file)
|
||||
{
|
||||
include $file;
|
||||
}
|
||||
|
||||
$with_sdk_classes = get_declared_classes();
|
||||
$new_classes = array_diff($with_sdk_classes, $existing_classes);
|
||||
$filtered_classes = array();
|
||||
$collect = array();
|
||||
|
||||
foreach ($new_classes as $class)
|
||||
{
|
||||
if (strpos($class, 'Amazon') !== false)
|
||||
{
|
||||
$filtered_classes[] = $class;
|
||||
}
|
||||
}
|
||||
|
||||
$filtered_classes = array_values($filtered_classes);
|
||||
|
||||
foreach ($filtered_classes as $class)
|
||||
{
|
||||
$obj = new $class();
|
||||
$collect[get_class($obj)] = $obj->api_version;
|
||||
unset($obj);
|
||||
}
|
||||
|
||||
return $collect;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,89 @@
|
|||
<?php
|
||||
/*
|
||||
* Copyright 2010-2012 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
* A copy of the License is located at
|
||||
*
|
||||
* http://aws.amazon.com/apache2.0
|
||||
*
|
||||
* or in the "license" file accompanying this file. This file is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
* express or implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/*%******************************************************************************************%*/
|
||||
// CLASS
|
||||
|
||||
/**
|
||||
* Handles the conversion of data from JSON to other formats.
|
||||
*
|
||||
* @version 2012.01.27
|
||||
* @license See the included NOTICE.md file for more information.
|
||||
* @copyright See the included NOTICE.md file for more information.
|
||||
* @link http://aws.amazon.com/php/ PHP Developer Center
|
||||
*/
|
||||
class CFJSON
|
||||
{
|
||||
/**
|
||||
* Converts a JSON string to a CFSimpleXML object.
|
||||
*
|
||||
* @param string|array $json (Required) Pass either a valid JSON-formatted string, or an associative array.
|
||||
* @param string $parser (Optional) The name of the class to use to parse the XML. This class should extend <code>SimpleXMLElement</code>. Has a default value of <code>CFSimpleXML</code>.
|
||||
* @return CFSimpleXML An XML representation of the data.
|
||||
*/
|
||||
public static function to_xml($json, $parser = 'CFSimpleXML')
|
||||
{
|
||||
// If we haven't parsed the JSON, do it
|
||||
if (!is_array($json))
|
||||
{
|
||||
// Handle the case of JSON-encoded NULL value
|
||||
if ($json === 'null')
|
||||
{
|
||||
$json = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
$json = json_decode($json, true);
|
||||
|
||||
if (function_exists('json_last_error'))
|
||||
{
|
||||
// Did we encounter an error?
|
||||
switch (json_last_error())
|
||||
{
|
||||
case JSON_ERROR_DEPTH:
|
||||
throw new JSON_Exception('Maximum stack depth exceeded.');
|
||||
|
||||
case JSON_ERROR_CTRL_CHAR:
|
||||
throw new JSON_Exception('Unexpected control character found.');
|
||||
|
||||
case JSON_ERROR_SYNTAX:
|
||||
throw new JSON_Exception('Syntax error; Malformed JSON.');
|
||||
|
||||
case JSON_ERROR_STATE_MISMATCH:
|
||||
throw new JSON_Exception('Invalid or malformed JSON.');
|
||||
}
|
||||
}
|
||||
// json_last_error() not available?
|
||||
elseif ($json === null)
|
||||
{
|
||||
throw new JSON_Exception('Unknown JSON error. Be sure to validate your JSON and read the notes on http://php.net/json_decode.');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Hand off for the recursive work
|
||||
$string = Array2DOM::arrayToXMLString($json, 'rootElement', true);
|
||||
|
||||
return simplexml_load_string($string, $parser, LIBXML_NOCDATA);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Default JSON Exception.
|
||||
*/
|
||||
class JSON_Exception extends Exception {}
|
|
@ -0,0 +1,54 @@
|
|||
<?php
|
||||
/*
|
||||
* Copyright 2010-2012 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
* A copy of the License is located at
|
||||
*
|
||||
* http://aws.amazon.com/apache2.0
|
||||
*
|
||||
* or in the "license" file accompanying this file. This file is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
* express or implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/*%******************************************************************************************%*/
|
||||
// CLASS
|
||||
|
||||
/**
|
||||
* Simplifies the process of generating manifests for the AWS Import/Export service.
|
||||
*
|
||||
* @version 2010.11.22
|
||||
* @license See the included NOTICE.md file for more information.
|
||||
* @copyright See the included NOTICE.md file for more information.
|
||||
* @link http://aws.amazon.com/php/ PHP Developer Center
|
||||
*/
|
||||
class CFManifest
|
||||
{
|
||||
|
||||
/**
|
||||
* Takes a JSON object as a string to convert to a YAML manifest.
|
||||
*
|
||||
* @param string $json (Required) A JSON object. The JSON string should use canonical rules (e.g., double quotes, quoted keys) as is required by PHP's <php:json_encode()> function.
|
||||
* @return string A YAML manifest document.
|
||||
*/
|
||||
public static function json($json)
|
||||
{
|
||||
$map = json_decode($json, true);
|
||||
return sfYaml::dump($map);
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes an associative array to convert to a YAML manifest.
|
||||
*
|
||||
* @param array $map (Required) An associative array.
|
||||
* @return string A YAML manifest document.
|
||||
*/
|
||||
public static function map($map)
|
||||
{
|
||||
return sfYaml::dump($map);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,223 @@
|
|||
<?php
|
||||
/*
|
||||
* Copyright 2010-2012 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
* A copy of the License is located at
|
||||
*
|
||||
* http://aws.amazon.com/apache2.0
|
||||
*
|
||||
* or in the "license" file accompanying this file. This file is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
* express or implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/*%******************************************************************************************%*/
|
||||
// CLASS
|
||||
|
||||
/**
|
||||
* Simplifies the process of looking up the content-types for a variety of file extensions.
|
||||
*
|
||||
* @version 2010.07.20
|
||||
* @license See the included NOTICE.md file for more information.
|
||||
* @copyright See the included NOTICE.md file for more information.
|
||||
* @link http://aws.amazon.com/php/ PHP Developer Center
|
||||
*/
|
||||
class CFMimeTypes
|
||||
{
|
||||
/**
|
||||
* Map of the extension-to-mime-types that we support.
|
||||
*/
|
||||
public static $mime_types = array(
|
||||
'3gp' => 'video/3gpp',
|
||||
'ai' => 'application/postscript',
|
||||
'aif' => 'audio/x-aiff',
|
||||
'aifc' => 'audio/x-aiff',
|
||||
'aiff' => 'audio/x-aiff',
|
||||
'asc' => 'text/plain',
|
||||
'atom' => 'application/atom+xml',
|
||||
'au' => 'audio/basic',
|
||||
'avi' => 'video/x-msvideo',
|
||||
'bcpio' => 'application/x-bcpio',
|
||||
'bin' => 'application/octet-stream',
|
||||
'bmp' => 'image/bmp',
|
||||
'cdf' => 'application/x-netcdf',
|
||||
'cgm' => 'image/cgm',
|
||||
'class' => 'application/octet-stream',
|
||||
'cpio' => 'application/x-cpio',
|
||||
'cpt' => 'application/mac-compactpro',
|
||||
'csh' => 'application/x-csh',
|
||||
'css' => 'text/css',
|
||||
'dcr' => 'application/x-director',
|
||||
'dif' => 'video/x-dv',
|
||||
'dir' => 'application/x-director',
|
||||
'djv' => 'image/vnd.djvu',
|
||||
'djvu' => 'image/vnd.djvu',
|
||||
'dll' => 'application/octet-stream',
|
||||
'dmg' => 'application/octet-stream',
|
||||
'dms' => 'application/octet-stream',
|
||||
'doc' => 'application/msword',
|
||||
'dtd' => 'application/xml-dtd',
|
||||
'dv' => 'video/x-dv',
|
||||
'dvi' => 'application/x-dvi',
|
||||
'dxr' => 'application/x-director',
|
||||
'eps' => 'application/postscript',
|
||||
'etx' => 'text/x-setext',
|
||||
'exe' => 'application/octet-stream',
|
||||
'ez' => 'application/andrew-inset',
|
||||
'flv' => 'video/x-flv',
|
||||
'gif' => 'image/gif',
|
||||
'gram' => 'application/srgs',
|
||||
'grxml' => 'application/srgs+xml',
|
||||
'gtar' => 'application/x-gtar',
|
||||
'gz' => 'application/x-gzip',
|
||||
'hdf' => 'application/x-hdf',
|
||||
'hqx' => 'application/mac-binhex40',
|
||||
'htm' => 'text/html',
|
||||
'html' => 'text/html',
|
||||
'ice' => 'x-conference/x-cooltalk',
|
||||
'ico' => 'image/x-icon',
|
||||
'ics' => 'text/calendar',
|
||||
'ief' => 'image/ief',
|
||||
'ifb' => 'text/calendar',
|
||||
'iges' => 'model/iges',
|
||||
'igs' => 'model/iges',
|
||||
'jnlp' => 'application/x-java-jnlp-file',
|
||||
'jp2' => 'image/jp2',
|
||||
'jpe' => 'image/jpeg',
|
||||
'jpeg' => 'image/jpeg',
|
||||
'jpg' => 'image/jpeg',
|
||||
'js' => 'application/x-javascript',
|
||||
'kar' => 'audio/midi',
|
||||
'latex' => 'application/x-latex',
|
||||
'lha' => 'application/octet-stream',
|
||||
'lzh' => 'application/octet-stream',
|
||||
'm3u' => 'audio/x-mpegurl',
|
||||
'm4a' => 'audio/mp4a-latm',
|
||||
'm4p' => 'audio/mp4a-latm',
|
||||
'm4u' => 'video/vnd.mpegurl',
|
||||
'm4v' => 'video/x-m4v',
|
||||
'mac' => 'image/x-macpaint',
|
||||
'man' => 'application/x-troff-man',
|
||||
'mathml' => 'application/mathml+xml',
|
||||
'me' => 'application/x-troff-me',
|
||||
'mesh' => 'model/mesh',
|
||||
'mid' => 'audio/midi',
|
||||
'midi' => 'audio/midi',
|
||||
'mif' => 'application/vnd.mif',
|
||||
'mov' => 'video/quicktime',
|
||||
'movie' => 'video/x-sgi-movie',
|
||||
'mp2' => 'audio/mpeg',
|
||||
'mp3' => 'audio/mpeg',
|
||||
'mp4' => 'video/mp4',
|
||||
'mpe' => 'video/mpeg',
|
||||
'mpeg' => 'video/mpeg',
|
||||
'mpg' => 'video/mpeg',
|
||||
'mpga' => 'audio/mpeg',
|
||||
'ms' => 'application/x-troff-ms',
|
||||
'msh' => 'model/mesh',
|
||||
'mxu' => 'video/vnd.mpegurl',
|
||||
'nc' => 'application/x-netcdf',
|
||||
'oda' => 'application/oda',
|
||||
'ogg' => 'application/ogg',
|
||||
'ogv' => 'video/ogv',
|
||||
'pbm' => 'image/x-portable-bitmap',
|
||||
'pct' => 'image/pict',
|
||||
'pdb' => 'chemical/x-pdb',
|
||||
'pdf' => 'application/pdf',
|
||||
'pgm' => 'image/x-portable-graymap',
|
||||
'pgn' => 'application/x-chess-pgn',
|
||||
'pic' => 'image/pict',
|
||||
'pict' => 'image/pict',
|
||||
'png' => 'image/png',
|
||||
'pnm' => 'image/x-portable-anymap',
|
||||
'pnt' => 'image/x-macpaint',
|
||||
'pntg' => 'image/x-macpaint',
|
||||
'ppm' => 'image/x-portable-pixmap',
|
||||
'ppt' => 'application/vnd.ms-powerpoint',
|
||||
'ps' => 'application/postscript',
|
||||
'qt' => 'video/quicktime',
|
||||
'qti' => 'image/x-quicktime',
|
||||
'qtif' => 'image/x-quicktime',
|
||||
'ra' => 'audio/x-pn-realaudio',
|
||||
'ram' => 'audio/x-pn-realaudio',
|
||||
'ras' => 'image/x-cmu-raster',
|
||||
'rdf' => 'application/rdf+xml',
|
||||
'rgb' => 'image/x-rgb',
|
||||
'rm' => 'application/vnd.rn-realmedia',
|
||||
'roff' => 'application/x-troff',
|
||||
'rtf' => 'text/rtf',
|
||||
'rtx' => 'text/richtext',
|
||||
'sgm' => 'text/sgml',
|
||||
'sgml' => 'text/sgml',
|
||||
'sh' => 'application/x-sh',
|
||||
'shar' => 'application/x-shar',
|
||||
'silo' => 'model/mesh',
|
||||
'sit' => 'application/x-stuffit',
|
||||
'skd' => 'application/x-koan',
|
||||
'skm' => 'application/x-koan',
|
||||
'skp' => 'application/x-koan',
|
||||
'skt' => 'application/x-koan',
|
||||
'smi' => 'application/smil',
|
||||
'smil' => 'application/smil',
|
||||
'snd' => 'audio/basic',
|
||||
'so' => 'application/octet-stream',
|
||||
'spl' => 'application/x-futuresplash',
|
||||
'src' => 'application/x-wais-source',
|
||||
'sv4cpio' => 'application/x-sv4cpio',
|
||||
'sv4crc' => 'application/x-sv4crc',
|
||||
'svg' => 'image/svg+xml',
|
||||
'swf' => 'application/x-shockwave-flash',
|
||||
't' => 'application/x-troff',
|
||||
'tar' => 'application/x-tar',
|
||||
'tcl' => 'application/x-tcl',
|
||||
'tex' => 'application/x-tex',
|
||||
'texi' => 'application/x-texinfo',
|
||||
'texinfo' => 'application/x-texinfo',
|
||||
'tif' => 'image/tiff',
|
||||
'tiff' => 'image/tiff',
|
||||
'tr' => 'application/x-troff',
|
||||
'tsv' => 'text/tab-separated-values',
|
||||
'txt' => 'text/plain',
|
||||
'ustar' => 'application/x-ustar',
|
||||
'vcd' => 'application/x-cdlink',
|
||||
'vrml' => 'model/vrml',
|
||||
'vxml' => 'application/voicexml+xml',
|
||||
'wav' => 'audio/x-wav',
|
||||
'wbmp' => 'image/vnd.wap.wbmp',
|
||||
'wbxml' => 'application/vnd.wap.wbxml',
|
||||
'webm' => 'video/webm',
|
||||
'wml' => 'text/vnd.wap.wml',
|
||||
'wmlc' => 'application/vnd.wap.wmlc',
|
||||
'wmls' => 'text/vnd.wap.wmlscript',
|
||||
'wmlsc' => 'application/vnd.wap.wmlscriptc',
|
||||
'wmv' => 'video/x-ms-wmv',
|
||||
'wrl' => 'model/vrml',
|
||||
'xbm' => 'image/x-xbitmap',
|
||||
'xht' => 'application/xhtml+xml',
|
||||
'xhtml' => 'application/xhtml+xml',
|
||||
'xls' => 'application/vnd.ms-excel',
|
||||
'xml' => 'application/xml',
|
||||
'xpm' => 'image/x-xpixmap',
|
||||
'xsl' => 'application/xml',
|
||||
'xslt' => 'application/xslt+xml',
|
||||
'xul' => 'application/vnd.mozilla.xul+xml',
|
||||
'xwd' => 'image/x-xwindowdump',
|
||||
'xyz' => 'chemical/x-xyz',
|
||||
'zip' => 'application/zip',
|
||||
);
|
||||
|
||||
/**
|
||||
* Attempt to match the file extension to a known mime-type.
|
||||
*
|
||||
* @param string $ext (Required) The file extension to attempt to map.
|
||||
* @return string The mime-type to use for the file extension.
|
||||
*/
|
||||
public static function get_mimetype($ext)
|
||||
{
|
||||
return (isset(self::$mime_types[$ext]) ? self::$mime_types[$ext] : 'application/octet-stream');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,134 @@
|
|||
<?php
|
||||
/*
|
||||
* Copyright 2010-2012 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
* A copy of the License is located at
|
||||
*
|
||||
* http://aws.amazon.com/apache2.0
|
||||
*
|
||||
* or in the "license" file accompanying this file. This file is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
* express or implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/*%******************************************************************************************%*/
|
||||
// CLASS
|
||||
|
||||
/**
|
||||
* Simplifies the process of signing JSON policy documents.
|
||||
*
|
||||
* @version 2011.04.25
|
||||
* @license See the included NOTICE.md file for more information.
|
||||
* @copyright See the included NOTICE.md file for more information.
|
||||
* @link http://aws.amazon.com/php/ PHP Developer Center
|
||||
*/
|
||||
class CFPolicy
|
||||
{
|
||||
/**
|
||||
* Stores the object that contains the authentication credentials.
|
||||
*/
|
||||
public $auth;
|
||||
|
||||
/**
|
||||
* Stores the policy object that we're working with.
|
||||
*/
|
||||
public $json_policy;
|
||||
|
||||
/**
|
||||
* Constructs a new instance of this class.
|
||||
*
|
||||
* @param CFRuntime $auth (Required) An instance of any authenticated AWS object that is an instance of <CFRuntime> (e.g. <AmazonEC2>, <AmazonS3>).
|
||||
* @param string|array $policy (Required) The associative array representing the S3 policy to use, or a string of JSON content.
|
||||
* @return $this A reference to the current instance.
|
||||
* @link http://docs.amazonwebservices.com/AmazonS3/2006-03-01/dev/index.html?HTTPPOSTForms.html S3 Policies
|
||||
* @link http://docs.amazonwebservices.com/AmazonS3/latest/dev/index.html?AccessPolicyLanguage.html Access Policy Language
|
||||
*/
|
||||
public function __construct($auth, $policy)
|
||||
{
|
||||
$this->auth = $auth;
|
||||
|
||||
if (is_array($policy)) // We received an associative array...
|
||||
{
|
||||
$this->json_policy = json_encode($policy);
|
||||
}
|
||||
else // We received a valid, parseable JSON string...
|
||||
{
|
||||
$this->json_policy = json_encode(json_decode($policy, true));
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Alternate approach to constructing a new instance. Supports chaining.
|
||||
*
|
||||
* @param CFRuntime $auth (Required) An instance of any authenticated AWS object that is an instance of <CFRuntime> (e.g. <AmazonEC2>, <AmazonS3>).
|
||||
* @param string|array $policy (Required) The associative array representing the S3 policy to use, or a string of JSON content.
|
||||
* @return $this A reference to the current instance.
|
||||
*/
|
||||
public static function init($auth, $policy)
|
||||
{
|
||||
if (version_compare(PHP_VERSION, '5.3.0', '<'))
|
||||
{
|
||||
throw new Exception('PHP 5.3 or newer is required to instantiate a new class with CLASS::init().');
|
||||
}
|
||||
|
||||
$self = get_called_class();
|
||||
return new $self($auth, $policy);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the key from the authenticated instance.
|
||||
*
|
||||
* @return string The key from the authenticated instance.
|
||||
*/
|
||||
public function get_key()
|
||||
{
|
||||
return $this->auth->key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Base64-encodes the JSON string.
|
||||
*
|
||||
* @return string The Base64-encoded version of the JSON string.
|
||||
*/
|
||||
public function get_policy()
|
||||
{
|
||||
return base64_encode($this->json_policy);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the JSON string with the whitespace removed.
|
||||
*
|
||||
* @return string The JSON string without extraneous whitespace.
|
||||
*/
|
||||
public function get_json()
|
||||
{
|
||||
return $this->json_policy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the JSON string with the whitespace removed.
|
||||
*
|
||||
* @return string The Base64-encoded, signed JSON string.
|
||||
*/
|
||||
public function get_policy_signature()
|
||||
{
|
||||
return base64_encode(hash_hmac('sha1', $this->get_policy(), $this->auth->secret_key));
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode a policy that was returned from the service.
|
||||
*
|
||||
* @param string $response (Required) The policy returned by AWS that you want to decode into an object.
|
||||
* @return string The Base64-encoded, signed JSON string.
|
||||
*/
|
||||
public static function decode_policy($response)
|
||||
{
|
||||
return json_decode(urldecode($response), true);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
<?php
|
||||
/*
|
||||
* Copyright 2010-2012 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
* A copy of the License is located at
|
||||
*
|
||||
* http://aws.amazon.com/apache2.0
|
||||
*
|
||||
* or in the "license" file accompanying this file. This file is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
* express or implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/*%******************************************************************************************%*/
|
||||
// CLASS
|
||||
|
||||
/**
|
||||
* Wraps the underlying `RequestCore` class with some AWS-specific customizations.
|
||||
*
|
||||
* @version 2011.12.02
|
||||
* @license See the included NOTICE.md file for more information.
|
||||
* @copyright See the included NOTICE.md file for more information.
|
||||
* @link http://aws.amazon.com/php/ PHP Developer Center
|
||||
*/
|
||||
class CFRequest extends RequestCore
|
||||
{
|
||||
/**
|
||||
* The default class to use for HTTP Requests (defaults to <CFRequest>).
|
||||
*/
|
||||
public $request_class = 'CFRequest';
|
||||
|
||||
/**
|
||||
* The default class to use for HTTP Responses (defaults to <CFResponse>).
|
||||
*/
|
||||
public $response_class = 'CFResponse';
|
||||
|
||||
/**
|
||||
* The active credential set.
|
||||
*/
|
||||
public $credentials;
|
||||
|
||||
|
||||
/*%******************************************************************************************%*/
|
||||
// CONSTRUCTOR
|
||||
|
||||
/**
|
||||
* Constructs a new instance of this class.
|
||||
*
|
||||
* @param string $url (Optional) The URL to request or service endpoint to query.
|
||||
* @param string $proxy (Optional) The faux-url to use for proxy settings. Takes the following format: `proxy://user:pass@hostname:port`
|
||||
* @param array $helpers (Optional) An associative array of classnames to use for request, and response functionality. Gets passed in automatically by the calling class.
|
||||
* @param CFCredential $credentials (Required) The credentials to use for signing and making requests.
|
||||
* @return $this A reference to the current instance.
|
||||
*/
|
||||
public function __construct($url = null, $proxy = null, $helpers = null, CFCredential $credentials = null)
|
||||
{
|
||||
parent::__construct($url, $proxy, $helpers);
|
||||
|
||||
// Standard settings for all requests
|
||||
$this->set_useragent(CFRUNTIME_USERAGENT);
|
||||
$this->credentials = $credentials;
|
||||
$this->cacert_location = ($this->credentials['certificate_authority'] ? $this->credentials['certificate_authority'] : false);
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
<?php
|
||||
/*
|
||||
* Copyright 2010-2012 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
* A copy of the License is located at
|
||||
*
|
||||
* http://aws.amazon.com/apache2.0
|
||||
*
|
||||
* or in the "license" file accompanying this file. This file is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
* express or implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/*%******************************************************************************************%*/
|
||||
// CLASS
|
||||
|
||||
/**
|
||||
* Wraps the underlying `ResponseCore` class with some AWS-specific customizations.
|
||||
*
|
||||
* @version 2010.10.11
|
||||
* @license See the included NOTICE.md file for more information.
|
||||
* @copyright See the included NOTICE.md file for more information.
|
||||
* @link http://aws.amazon.com/php/ PHP Developer Center
|
||||
*/
|
||||
class CFResponse extends ResponseCore {}
|
|
@ -0,0 +1,248 @@
|
|||
<?php
|
||||
/*
|
||||
* Copyright 2010-2012 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
* A copy of the License is located at
|
||||
*
|
||||
* http://aws.amazon.com/apache2.0
|
||||
*
|
||||
* or in the "license" file accompanying this file. This file is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
* express or implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/*%******************************************************************************************%*/
|
||||
// CLASS
|
||||
|
||||
/**
|
||||
* Wraps the underlying `SimpleXMLIterator` class with enhancements for rapidly traversing the DOM tree,
|
||||
* converting types, and comparisons.
|
||||
*
|
||||
* @version 2012.01.17
|
||||
* @license See the included NOTICE.md file for more information.
|
||||
* @copyright See the included NOTICE.md file for more information.
|
||||
* @link http://aws.amazon.com/php/ PHP Developer Center
|
||||
* @link http://php.net/SimpleXML SimpleXML
|
||||
*/
|
||||
class CFSimpleXML extends SimpleXMLIterator
|
||||
{
|
||||
/**
|
||||
* Stores the namespace name to use in XPath queries.
|
||||
*/
|
||||
public $xml_ns;
|
||||
|
||||
/**
|
||||
* Stores the namespace URI to use in XPath queries.
|
||||
*/
|
||||
public $xml_ns_url;
|
||||
|
||||
/**
|
||||
* Catches requests made to methods that don't exist. Specifically, looks for child nodes via XPath.
|
||||
*
|
||||
* @param string $name (Required) The name of the method.
|
||||
* @param array $arguments (Required) The arguments passed to the method.
|
||||
* @return mixed Either an array of matches, or a single <CFSimpleXML> element.
|
||||
*/
|
||||
public function __call($name, $arguments)
|
||||
{
|
||||
// Remap $this
|
||||
$self = $this;
|
||||
|
||||
// Re-base the XML
|
||||
$self = new CFSimpleXML($self->asXML());
|
||||
|
||||
// Determine XPath query
|
||||
$self->xpath_expression = 'descendant-or-self::' . $name;
|
||||
|
||||
// Get the results and augment with CFArray
|
||||
$results = $self->xpath($self->xpath_expression);
|
||||
if (!count($results)) return false;
|
||||
$results = new CFArray($results);
|
||||
|
||||
// If an integer was passed, return only that result
|
||||
if (isset($arguments[0]) && is_int($arguments[0]))
|
||||
{
|
||||
if (isset($results[$arguments[0]]))
|
||||
{
|
||||
return $results[$arguments[0]];
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Alternate approach to constructing a new instance. Supports chaining.
|
||||
*
|
||||
* @param string $data (Required) A well-formed XML string or the path or URL to an XML document if $data_is_url is <code>true</code>.
|
||||
* @param integer $options (Optional) Used to specify additional LibXML parameters. The default value is <code>0</code>.
|
||||
* @param boolean $data_is_url (Optional) Specify a value of <code>true</code> to specify that data is a path or URL to an XML document instead of string data. The default value is <code>false</code>.
|
||||
* @param string $ns (Optional) The XML namespace to return values for.
|
||||
* @param boolean $is_prefix (Optional) (No description provided by PHP.net.)
|
||||
* @return CFSimpleXML Creates a new <CFSimpleXML> element.
|
||||
*/
|
||||
public static function init($data, $options = 0, $data_is_url, $ns, $is_prefix = false)
|
||||
{
|
||||
if (version_compare(PHP_VERSION, '5.3.0', '<'))
|
||||
{
|
||||
throw new Exception('PHP 5.3 or newer is required to instantiate a new class with CLASS::init().');
|
||||
}
|
||||
|
||||
$self = get_called_class();
|
||||
return new $self($data, $options, $data_is_url, $ns, $is_prefix);
|
||||
}
|
||||
|
||||
|
||||
/*%******************************************************************************************%*/
|
||||
// TRAVERSAL
|
||||
|
||||
/**
|
||||
* Wraps the results of an XPath query in a <CFArray> object.
|
||||
*
|
||||
* @param string $expr (Required) The XPath expression to use to query the XML response.
|
||||
* @return CFArray A <CFArray> object containing the results of the XPath query.
|
||||
*/
|
||||
public function query($expr)
|
||||
{
|
||||
return new CFArray($this->xpath($expr));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the parent or a preferred ancestor of the current element.
|
||||
*
|
||||
* @param string $node (Optional) Name of the ancestor element to match and return.
|
||||
* @return CFSimpleXML A <CFSimpleXML> object containing the requested node.
|
||||
*/
|
||||
public function parent($node = null)
|
||||
{
|
||||
if ($node)
|
||||
{
|
||||
$parents = $this->xpath('ancestor-or-self::' . $node);
|
||||
}
|
||||
else
|
||||
{
|
||||
$parents = $this->xpath('parent::*');
|
||||
}
|
||||
|
||||
return $parents[0];
|
||||
}
|
||||
|
||||
|
||||
/*%******************************************************************************************%*/
|
||||
// ALTERNATE FORMATS
|
||||
|
||||
/**
|
||||
* Gets the current XML node as a true string.
|
||||
*
|
||||
* @return string The current XML node as a true string.
|
||||
*/
|
||||
public function to_string()
|
||||
{
|
||||
return (string) $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current XML node as <CFArray>, a child class of PHP's <php:ArrayObject> class.
|
||||
*
|
||||
* @return CFArray The current XML node as a <CFArray> object.
|
||||
*/
|
||||
public function to_array()
|
||||
{
|
||||
return new CFArray(json_decode(json_encode($this), true));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current XML node as a stdClass object.
|
||||
*
|
||||
* @return array The current XML node as a stdClass object.
|
||||
*/
|
||||
public function to_stdClass()
|
||||
{
|
||||
return json_decode(json_encode($this));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current XML node as a JSON string.
|
||||
*
|
||||
* @return string The current XML node as a JSON string.
|
||||
*/
|
||||
public function to_json()
|
||||
{
|
||||
return json_encode($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current XML node as a YAML string.
|
||||
*
|
||||
* @return string The current XML node as a YAML string.
|
||||
*/
|
||||
public function to_yaml()
|
||||
{
|
||||
return sfYaml::dump(json_decode(json_encode($this), true), 5);
|
||||
}
|
||||
|
||||
|
||||
/*%******************************************************************************************%*/
|
||||
// COMPARISONS
|
||||
|
||||
/**
|
||||
* Whether or not the current node exactly matches the compared value.
|
||||
*
|
||||
* @param string $value (Required) The value to compare the current node to.
|
||||
* @return boolean Whether or not the current node exactly matches the compared value.
|
||||
*/
|
||||
public function is($value)
|
||||
{
|
||||
return ((string) $this === $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not the current node contains the compared value.
|
||||
*
|
||||
* @param string $value (Required) The value to use to determine whether it is contained within the node.
|
||||
* @return boolean Whether or not the current node contains the compared value.
|
||||
*/
|
||||
public function contains($value)
|
||||
{
|
||||
return (stripos((string) $this, $value) !== false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not the current node matches the regular expression pattern.
|
||||
*
|
||||
* @param string $pattern (Required) The pattern to match the current node against.
|
||||
* @return boolean Whether or not the current node matches the pattern.
|
||||
*/
|
||||
public function matches($pattern)
|
||||
{
|
||||
return (bool) preg_match($pattern, (string) $this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not the current node starts with the compared value.
|
||||
*
|
||||
* @param string $value (Required) The value to compare the current node to.
|
||||
* @return boolean Whether or not the current node starts with the compared value.
|
||||
*/
|
||||
public function starts_with($value)
|
||||
{
|
||||
return $this->matches("@^$value@u");
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not the current node ends with the compared value.
|
||||
*
|
||||
* @param string $value (Required) The value to compare the current node to.
|
||||
* @return boolean Whether or not the current node ends with the compared value.
|
||||
*/
|
||||
public function ends_with($value)
|
||||
{
|
||||
return $this->matches("@$value$@u");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
<?php
|
||||
/*
|
||||
* Copyright 2010-2012 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
* A copy of the License is located at
|
||||
*
|
||||
* http://aws.amazon.com/apache2.0
|
||||
*
|
||||
* or in the "license" file accompanying this file. This file is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
* express or implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/*%******************************************************************************************%*/
|
||||
// CLASS
|
||||
|
||||
/**
|
||||
* Simplifies the process of preparing JSON stack templates.
|
||||
*
|
||||
* @version 2011.02.03
|
||||
* @license See the included NOTICE.md file for more information.
|
||||
* @copyright See the included NOTICE.md file for more information.
|
||||
* @link http://aws.amazon.com/php/ PHP Developer Center
|
||||
*/
|
||||
class CFStackTemplate
|
||||
{
|
||||
/**
|
||||
* Removes whitespace from a JSON template.
|
||||
*
|
||||
* @param string $template (Required) A JSON representation of the stack template. Must have <a href="http://docs.php.net/manual/en/function.json-decode.php#refsect1-function.json-decode-examples">strict JSON-specific formatting</a>.
|
||||
* @return string A JSON representation of the template.
|
||||
*/
|
||||
public static function json($template)
|
||||
{
|
||||
return json_encode(json_decode($template, true));
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an associative array (map) of the template into a JSON string.
|
||||
*
|
||||
* @param array $template (Required) An associative array that maps directly to its JSON counterpart.
|
||||
* @return string A JSON representation of the template.
|
||||
*/
|
||||
public static function map($template)
|
||||
{
|
||||
return json_encode($template);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,91 @@
|
|||
<?php
|
||||
/*
|
||||
* Copyright 2010-2012 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
* A copy of the License is located at
|
||||
*
|
||||
* http://aws.amazon.com/apache2.0
|
||||
*
|
||||
* or in the "license" file accompanying this file. This file is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
* express or implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/*%******************************************************************************************%*/
|
||||
// CLASS
|
||||
|
||||
/**
|
||||
* Contains functionality for simplifying Amazon EMR Hadoop steps.
|
||||
*
|
||||
* @version 2010.11.16
|
||||
* @license See the included NOTICE.md file for more information.
|
||||
* @copyright See the included NOTICE.md file for more information.
|
||||
* @link http://aws.amazon.com/php/ PHP Developer Center
|
||||
*/
|
||||
class CFStepConfig
|
||||
{
|
||||
|
||||
/**
|
||||
* Stores the configuration map.
|
||||
*/
|
||||
public $config;
|
||||
|
||||
/**
|
||||
* Constructs a new instance of this class.
|
||||
*
|
||||
* @param array $config (Required) An associative array representing the Hadoop step configuration.
|
||||
* @return $this A reference to the current instance.
|
||||
*/
|
||||
public function __construct($config)
|
||||
{
|
||||
// Handle Hadoop jar arguments
|
||||
if (isset($config['HadoopJarStep']['Args']) && $args = $config['HadoopJarStep']['Args'])
|
||||
{
|
||||
$config['HadoopJarStep']['Args'] = is_array($args) ? $args : array($args);
|
||||
}
|
||||
|
||||
$this->config = $config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new instance of this class, and allows chaining.
|
||||
*
|
||||
* @param array $config (Required) An associative array representing the Hadoop step configuration.
|
||||
* @return $this A reference to the current instance.
|
||||
*/
|
||||
public static function init($config)
|
||||
{
|
||||
if (version_compare(PHP_VERSION, '5.3.0', '<'))
|
||||
{
|
||||
throw new Exception('PHP 5.3 or newer is required to instantiate a new class with CLASS::init().');
|
||||
}
|
||||
|
||||
$self = get_called_class();
|
||||
return new $self($config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a JSON representation of the object when typecast as a string.
|
||||
*
|
||||
* @return string A JSON representation of the object.
|
||||
* @link http://www.php.net/manual/en/language.oop5.magic.php#language.oop5.magic.tostring PHP Magic Methods
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return json_encode($this->config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the configuration data.
|
||||
*
|
||||
* @return array The configuration data.
|
||||
*/
|
||||
public function get_config()
|
||||
{
|
||||
return $this->config;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,399 @@
|
|||
<?php
|
||||
/*
|
||||
* Copyright 2010-2012 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
* A copy of the License is located at
|
||||
*
|
||||
* http://aws.amazon.com/apache2.0
|
||||
*
|
||||
* or in the "license" file accompanying this file. This file is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
* express or implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/*%******************************************************************************************%*/
|
||||
// CLASS
|
||||
|
||||
/**
|
||||
* Contains a set of utility methods for connecting to, and working with, AWS.
|
||||
*
|
||||
* @version 2010.09.30
|
||||
* @license See the included NOTICE.md file for more information.
|
||||
* @copyright See the included NOTICE.md file for more information.
|
||||
* @link http://aws.amazon.com/php/ PHP Developer Center
|
||||
*/
|
||||
class CFUtilities
|
||||
{
|
||||
|
||||
/*%******************************************************************************************%*/
|
||||
// CONSTANTS
|
||||
|
||||
/**
|
||||
* Define the RFC 2616-compliant date format.
|
||||
*/
|
||||
const DATE_FORMAT_RFC2616 = 'D, d M Y H:i:s \G\M\T';
|
||||
|
||||
/**
|
||||
* Define the ISO-8601-compliant date format.
|
||||
*/
|
||||
const DATE_FORMAT_ISO8601 = 'Y-m-d\TH:i:s\Z';
|
||||
|
||||
/**
|
||||
* Define the MySQL-compliant date format.
|
||||
*/
|
||||
const DATE_FORMAT_MYSQL = 'Y-m-d H:i:s';
|
||||
|
||||
/**
|
||||
* Define the Signature v4 date format.
|
||||
*/
|
||||
const DATE_FORMAT_SIGV4 = 'Ymd\THis\Z';
|
||||
|
||||
|
||||
/*%******************************************************************************************%*/
|
||||
// METHODS
|
||||
|
||||
/**
|
||||
* Constructs a new instance of this class.
|
||||
*
|
||||
* @return $this A reference to the current instance.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the value of a class constant, while avoiding the `T_PAAMAYIM_NEKUDOTAYIM` error. Misspelled because `const` is a reserved word.
|
||||
*
|
||||
* @param object $class (Required) An instance of the class containing the constant.
|
||||
* @param string $const (Required) The name of the constant to retrieve.
|
||||
* @return mixed The value of the class constant.
|
||||
*/
|
||||
public function konst($class, $const)
|
||||
{
|
||||
if (is_string($class))
|
||||
{
|
||||
$ref = new ReflectionClass($class);
|
||||
}
|
||||
else
|
||||
{
|
||||
$ref = new ReflectionObject($class);
|
||||
}
|
||||
|
||||
return $ref->getConstant($const);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a HEX value to Base64.
|
||||
*
|
||||
* @param string $str (Required) Value to convert.
|
||||
* @return string Base64-encoded string.
|
||||
*/
|
||||
public function hex_to_base64($str)
|
||||
{
|
||||
$raw = '';
|
||||
|
||||
for ($i = 0; $i < strlen($str); $i += 2)
|
||||
{
|
||||
$raw .= chr(hexdec(substr($str, $i, 2)));
|
||||
}
|
||||
|
||||
return base64_encode($raw);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert an associative array into a query string.
|
||||
*
|
||||
* @param array $array (Required) Array to convert.
|
||||
* @return string URL-friendly query string.
|
||||
*/
|
||||
public function to_query_string($array)
|
||||
{
|
||||
$temp = array();
|
||||
|
||||
foreach ($array as $key => $value)
|
||||
{
|
||||
if (is_string($key) && !is_array($value))
|
||||
{
|
||||
$temp[] = rawurlencode($key) . '=' . rawurlencode($value);
|
||||
}
|
||||
}
|
||||
|
||||
return implode('&', $temp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert an associative array into a sign-able string.
|
||||
*
|
||||
* @param array $array (Required) Array to convert.
|
||||
* @return string URL-friendly sign-able string.
|
||||
*/
|
||||
public function to_signable_string($array)
|
||||
{
|
||||
$t = array();
|
||||
|
||||
foreach ($array as $k => $v)
|
||||
{
|
||||
$t[] = $this->encode_signature2($k) . '=' . $this->encode_signature2($v);
|
||||
}
|
||||
|
||||
return implode('&', $t);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode the value according to RFC 3986.
|
||||
*
|
||||
* @param string $string (Required) String to convert.
|
||||
* @return string URL-friendly sign-able string.
|
||||
*/
|
||||
public function encode_signature2($string)
|
||||
{
|
||||
$string = rawurlencode($string);
|
||||
return str_replace('%7E', '~', $string);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a query string into an associative array. Multiple, identical keys will become an indexed array.
|
||||
*
|
||||
* @param string $qs (Required) Query string to convert.
|
||||
* @return array Associative array of keys and values.
|
||||
*/
|
||||
public function query_to_array($qs)
|
||||
{
|
||||
$query = explode('&', $qs);
|
||||
$data = array();
|
||||
|
||||
foreach ($query as $q)
|
||||
{
|
||||
$q = explode('=', $q);
|
||||
|
||||
if (isset($data[$q[0]]) && is_array($data[$q[0]]))
|
||||
{
|
||||
$data[$q[0]][] = urldecode($q[1]);
|
||||
}
|
||||
else if (isset($data[$q[0]]) && !is_array($data[$q[0]]))
|
||||
{
|
||||
$data[$q[0]] = array($data[$q[0]]);
|
||||
$data[$q[0]][] = urldecode($q[1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
$data[urldecode($q[0])] = urldecode($q[1]);
|
||||
}
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return human readable file sizes.
|
||||
*
|
||||
* @author Aidan Lister <aidan@php.net>
|
||||
* @author Ryan Parman <ryan@getcloudfusion.com>
|
||||
* @license http://www.php.net/license/3_01.txt PHP License
|
||||
* @param integer $size (Required) Filesize in bytes.
|
||||
* @param string $unit (Optional) The maximum unit to use. Defaults to the largest appropriate unit.
|
||||
* @param string $default (Optional) The format for the return string. Defaults to `%01.2f %s`.
|
||||
* @return string The human-readable file size.
|
||||
* @link http://aidanlister.com/repos/v/function.size_readable.php Original Function
|
||||
*/
|
||||
public function size_readable($size, $unit = null, $default = null)
|
||||
{
|
||||
// Units
|
||||
$sizes = array('B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB');
|
||||
$mod = 1024;
|
||||
$ii = count($sizes) - 1;
|
||||
|
||||
// Max unit
|
||||
$unit = array_search((string) $unit, $sizes);
|
||||
if ($unit === null || $unit === false)
|
||||
{
|
||||
$unit = $ii;
|
||||
}
|
||||
|
||||
// Return string
|
||||
if ($default === null)
|
||||
{
|
||||
$default = '%01.2f %s';
|
||||
}
|
||||
|
||||
// Loop
|
||||
$i = 0;
|
||||
while ($unit != $i && $size >= 1024 && $i < $ii)
|
||||
{
|
||||
$size /= $mod;
|
||||
$i++;
|
||||
}
|
||||
|
||||
return sprintf($default, $size, $sizes[$i]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a number of seconds into Hours:Minutes:Seconds.
|
||||
*
|
||||
* @param integer $seconds (Required) The number of seconds to convert.
|
||||
* @return string The formatted time.
|
||||
*/
|
||||
public function time_hms($seconds)
|
||||
{
|
||||
$time = '';
|
||||
|
||||
// First pass
|
||||
$hours = (int) ($seconds / 3600);
|
||||
$seconds = $seconds % 3600;
|
||||
$minutes = (int) ($seconds / 60);
|
||||
$seconds = $seconds % 60;
|
||||
|
||||
// Cleanup
|
||||
$time .= ($hours) ? $hours . ':' : '';
|
||||
$time .= ($minutes < 10 && $hours > 0) ? '0' . $minutes : $minutes;
|
||||
$time .= ':';
|
||||
$time .= ($seconds < 10) ? '0' . $seconds : $seconds;
|
||||
|
||||
return $time;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the first value that is set. Based on [Try.these()](http://api.prototypejs.org/language/Try/these/) from [Prototype](http://prototypejs.org).
|
||||
*
|
||||
* @param array $attrs (Required) The attributes to test, as strings. Intended for testing properties of the $base object, but also works with variables if you place an @ symbol at the beginning of the command.
|
||||
* @param object $base (Optional) The base object to use, if any.
|
||||
* @param mixed $default (Optional) What to return if there are no matches. Defaults to `null`.
|
||||
* @return mixed Either a matching property of a given object, boolean `false`, or any other data type you might choose.
|
||||
*/
|
||||
public function try_these($attrs, $base = null, $default = null)
|
||||
{
|
||||
if ($base)
|
||||
{
|
||||
foreach ($attrs as $attr)
|
||||
{
|
||||
if (isset($base->$attr))
|
||||
{
|
||||
return $base->$attr;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach ($attrs as $attr)
|
||||
{
|
||||
if (isset($attr))
|
||||
{
|
||||
return $attr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* Can be removed once all calls are updated.
|
||||
*
|
||||
* @deprecated Use <php:json_encode()> instead.
|
||||
* @param mixed $obj (Required) The PHP object to convert into a JSON string.
|
||||
* @return string A JSON string.
|
||||
*/
|
||||
public function json_encode($obj)
|
||||
{
|
||||
return json_encode($obj);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a SimpleXML response to an array structure.
|
||||
*
|
||||
* @param ResponseCore $response (Required) A response value.
|
||||
* @return array The response value as a standard, multi-dimensional array.
|
||||
*/
|
||||
public function convert_response_to_array(ResponseCore $response)
|
||||
{
|
||||
return json_decode(json_encode($response), true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to see if a date stamp is ISO-8601 formatted, and if not, makes it so.
|
||||
*
|
||||
* @param string $datestamp (Required) A date stamp, or a string that can be parsed into a date stamp.
|
||||
* @return string An ISO-8601 formatted date stamp.
|
||||
*/
|
||||
public function convert_date_to_iso8601($datestamp)
|
||||
{
|
||||
if (!preg_match('/\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}((\+|-)\d{2}:\d{2}|Z)/m', $datestamp))
|
||||
{
|
||||
return gmdate(self::DATE_FORMAT_ISO8601, strtotime($datestamp));
|
||||
}
|
||||
|
||||
return $datestamp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether the data is Base64 encoded or not.
|
||||
*
|
||||
* @license http://us.php.net/manual/en/function.base64-decode.php#81425 PHP License
|
||||
* @param string $s (Required) The string to test.
|
||||
* @return boolean Whether the string is Base64 encoded or not.
|
||||
*/
|
||||
public function is_base64($s)
|
||||
{
|
||||
return (bool) preg_match('/^[a-zA-Z0-9\/\r\n+]*={0,2}$/', $s);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether the data is a JSON string or not.
|
||||
*
|
||||
* @param string $s (Required) The string to test.
|
||||
* @return boolean Whether the string is a valid JSON object or not.
|
||||
*/
|
||||
public function is_json($s)
|
||||
{
|
||||
return !!(json_decode($s) instanceof stdClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes `\uXXXX` entities into their real unicode character equivalents.
|
||||
*
|
||||
* @param string $s (Required) The string to decode.
|
||||
* @return string The decoded string.
|
||||
*/
|
||||
public function decode_uhex($s)
|
||||
{
|
||||
preg_match_all('/\\\u([0-9a-f]{4})/i', $s, $matches);
|
||||
$matches = $matches[count($matches) - 1];
|
||||
$map = array();
|
||||
|
||||
foreach ($matches as $match)
|
||||
{
|
||||
if (!isset($map[$match]))
|
||||
{
|
||||
$map['\u' . $match] = html_entity_decode('&#' . hexdec($match) . ';', ENT_NOQUOTES, 'UTF-8');
|
||||
}
|
||||
}
|
||||
|
||||
return str_replace(array_keys($map), $map, $s);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a random GUID.
|
||||
*
|
||||
* @author Alix Axel <http://www.php.net/manual/en/function.com-create-guid.php#99425>
|
||||
* @license http://www.php.net/license/3_01.txt PHP License
|
||||
* @return string A random GUID.
|
||||
*/
|
||||
public function generate_guid()
|
||||
{
|
||||
return sprintf(
|
||||
'%04X%04X-%04X-%04X-%04X-%04X%04X%04X',
|
||||
mt_rand(0, 65535),
|
||||
mt_rand(0, 65535),
|
||||
mt_rand(0, 65535),
|
||||
mt_rand(16384, 20479),
|
||||
mt_rand(32768, 49151),
|
||||
mt_rand(0, 65535),
|
||||
mt_rand(0, 65535),
|
||||
mt_rand(0, 65535)
|
||||
);
|
||||
}
|
||||
}
|
|
@ -172,7 +172,6 @@ class CSSMin {
|
|||
$type = self::getMimeType( $file );
|
||||
// Detect when URLs were preceeded with embed tags, and also verify file size is
|
||||
// below the limit
|
||||
var_dump($match['embed'], $file, filesize($file));
|
||||
if (
|
||||
$type
|
||||
&& $match['embed'][1] > 0
|
||||
|
|
|
@ -48,7 +48,7 @@ class PasswordHash {
|
|||
function get_random_bytes($count)
|
||||
{
|
||||
$output = '';
|
||||
if (is_readable('/dev/urandom') &&
|
||||
if (@is_readable('/dev/urandom') &&
|
||||
($fh = @fopen('/dev/urandom', 'rb'))) {
|
||||
$output = fread($fh, $count);
|
||||
fclose($fh);
|
||||
|
|
|
@ -586,7 +586,7 @@ class When
|
|||
}
|
||||
}
|
||||
}
|
||||
elseif($this->gobyday || $interval == "month")
|
||||
elseif($this->gobyday && $interval == "month")
|
||||
{
|
||||
$_mdays = range(1, date('t',mktime(0,0,0,$month,1,$year)));
|
||||
foreach($_mdays as $_mday)
|
||||
|
@ -621,7 +621,13 @@ class When
|
|||
|
||||
if($interval == "month")
|
||||
{
|
||||
$this->try_date->modify('last day of ' . $this->interval . ' ' . $interval);
|
||||
|
||||
$this->try_date->modify('first day of next month');
|
||||
if((int) date('t', $this->try_date->format('U')) > (int) $this->start_date->format('j')){
|
||||
$this->try_date->modify('+' . (int) $this->start_date->format('j') - 1 . ' day');
|
||||
}else{
|
||||
$this->try_date->modify('+' . (int) date('t', $this->try_date->format('U')) - 1 . ' day');
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -28,6 +28,6 @@ OCP\User::checkLoggedIn();
|
|||
OCP\App::checkAppEnabled('bookmarks');
|
||||
|
||||
require_once('bookmarksHelper.php');
|
||||
addBookmark($_GET['url'], '', 'Read-Later');
|
||||
addBookmark($_POST['url'], '', 'Read-Later');
|
||||
|
||||
include 'templates/addBm.php';
|
||||
|
|
|
@ -30,7 +30,7 @@ $RUNTIME_NOSETUPFS=true;
|
|||
OCP\JSON::checkLoggedIn();
|
||||
OCP\JSON::checkAppEnabled('bookmarks');
|
||||
|
||||
$id = $_GET['id'];
|
||||
$id = $_POST['id'];
|
||||
if (!OC_Bookmarks_Bookmarks::deleteUrl($id)){
|
||||
OC_JSON::error();
|
||||
exit();
|
||||
|
|
|
@ -39,7 +39,7 @@ if( $CONFIG_DBTYPE == 'sqlite' or $CONFIG_DBTYPE == 'sqlite3' ){
|
|||
$_ut = "UNIX_TIMESTAMP()";
|
||||
}
|
||||
|
||||
$bookmark_id = (int)$_GET["id"];
|
||||
$bookmark_id = (int)$_POST["id"];
|
||||
|
||||
$query = OCP\DB::prepare("
|
||||
UPDATE *PREFIX*bookmarks
|
||||
|
@ -48,8 +48,8 @@ $query = OCP\DB::prepare("
|
|||
");
|
||||
|
||||
$params=array(
|
||||
htmlspecialchars_decode($_GET["url"]),
|
||||
htmlspecialchars_decode($_GET["title"]),
|
||||
htmlspecialchars_decode($_POST["url"]),
|
||||
htmlspecialchars_decode($_POST["title"]),
|
||||
);
|
||||
$query->execute($params);
|
||||
|
||||
|
@ -67,7 +67,7 @@ $query = OCP\DB::prepare("
|
|||
VALUES (?, ?)
|
||||
");
|
||||
|
||||
$tags = explode(' ', urldecode($_GET["tags"]));
|
||||
$tags = explode(' ', urldecode($_POST["tags"]));
|
||||
foreach ($tags as $tag) {
|
||||
if(empty($tag)) {
|
||||
//avoid saving blankspaces
|
||||
|
|
|
@ -37,7 +37,7 @@ $query = OCP\DB::prepare("
|
|||
AND url LIKE ?
|
||||
");
|
||||
|
||||
$params=array(OCP\USER::getUser(), htmlspecialchars_decode($_GET["url"]));
|
||||
$params=array(OCP\USER::getUser(), htmlspecialchars_decode($_POST["url"]));
|
||||
$bookmarks = $query->execute($params);
|
||||
|
||||
header( "HTTP/1.1 204 No Content" );
|
||||
|
|
|
@ -33,11 +33,11 @@ OCP\JSON::checkAppEnabled('bookmarks');
|
|||
|
||||
|
||||
//Filter for tag?
|
||||
$filterTag = isset($_GET['tag']) ? htmlspecialchars_decode($_GET['tag']) : false;
|
||||
$filterTag = isset($_POST['tag']) ? htmlspecialchars_decode($_POST['tag']) : false;
|
||||
|
||||
$offset = isset($_GET['page']) ? intval($_GET['page']) * 10 : 0;
|
||||
$offset = isset($_POST['page']) ? intval($_POST['page']) * 10 : 0;
|
||||
|
||||
$sort = isset($_GET['sort']) ? ($_GET['sort']) : 'bookmarks_sorting_recent';
|
||||
$sort = isset($_POST['sort']) ? ($_POST['sort']) : 'bookmarks_sorting_recent';
|
||||
if($sort == 'bookmarks_sorting_clicks') {
|
||||
$sqlSortColumn = 'clickcount';
|
||||
} else {
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<name>*dbname*</name>
|
||||
<create>true</create>
|
||||
<overwrite>false</overwrite>
|
||||
<charset>latin1</charset>
|
||||
<charset>utf8</charset>
|
||||
<table>
|
||||
<name>*dbprefix*bookmarks</name>
|
||||
<declaration>
|
||||
|
|
|
@ -6,6 +6,7 @@ function addBookmark(event) {
|
|||
var url = $('#bookmark_add_url').val();
|
||||
var tags = $('#bookmark_add_tags').val();
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: 'ajax/addBookmark.php',
|
||||
data: 'url=' + encodeURI(url) + '&tags=' + encodeURI(tags),
|
||||
success: function(data){
|
||||
|
|
|
@ -20,6 +20,7 @@ function getBookmarks() {
|
|||
}
|
||||
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: OC.filePath('bookmarks', 'ajax', 'updateList.php'),
|
||||
data: 'tag=' + encodeURIComponent($('#bookmarkFilterTag').val()) + '&page=' + bookmarks_page + '&sort=' + bookmarks_sorting,
|
||||
success: function(bookmarks){
|
||||
|
@ -70,6 +71,7 @@ function addOrEditBookmark(event) {
|
|||
}
|
||||
if (id == 0) {
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: OC.filePath('bookmarks', 'ajax', 'addBookmark.php'),
|
||||
data: 'url=' + encodeURIComponent(url) + '&title=' + encodeURIComponent(title) + '&tags=' + encodeURIComponent(tags),
|
||||
success: function(response){
|
||||
|
@ -82,6 +84,7 @@ function addOrEditBookmark(event) {
|
|||
}
|
||||
else {
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: OC.filePath('bookmarks', 'ajax', 'editBookmark.php'),
|
||||
data: 'id=' + id + '&url=' + encodeURIComponent(url) + '&title=' + encodeURIComponent(title) + '&tags=' + encodeURIComponent(tags),
|
||||
success: function(){
|
||||
|
@ -99,6 +102,7 @@ function addOrEditBookmark(event) {
|
|||
function delBookmark(event) {
|
||||
var record = $(this).parent().parent();
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: OC.filePath('bookmarks', 'ajax', 'delBookmark.php'),
|
||||
data: 'id=' + record.data('id'),
|
||||
success: function(data){
|
||||
|
@ -177,6 +181,7 @@ function updateOnBottom() {
|
|||
|
||||
function recordClick(event) {
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: OC.filePath('bookmarks', 'ajax', 'recordClick.php'),
|
||||
data: 'url=' + encodeURIComponent($(this).attr('href')),
|
||||
});
|
||||
|
|
|
@ -16,6 +16,7 @@ function recordClick(event) {
|
|||
var jsFileLocation = $('script[src*=bookmarksearch]').attr('src');
|
||||
jsFileLocation = jsFileLocation.replace('js/bookmarksearch.js', '');
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: jsFileLocation + 'ajax/recordClick.php',
|
||||
data: 'url=' + encodeURI($(this).attr('href')),
|
||||
});
|
||||
|
|
|
@ -11,7 +11,7 @@ OCP\JSON::checkLoggedIn();
|
|||
OCP\JSON::checkAppEnabled('calendar');
|
||||
|
||||
$calendarcolor_options = OC_Calendar_Calendar::getCalendarColorOptions();
|
||||
$calendar = OC_Calendar_App::getCalendar($_GET['calendarid']);
|
||||
$calendar = OC_Calendar_App::getCalendar($_POST['calendarid']);
|
||||
$tmpl = new OCP\Template("calendar", "part.editcalendar");
|
||||
$tmpl->assign('new', false);
|
||||
$tmpl->assign('calendarcolor_options', $calendarcolor_options);
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
*/
|
||||
OCP\JSON::checkLoggedIn();
|
||||
OCP\JSON::checkAppEnabled('calendar');
|
||||
$view = $_GET['v'];
|
||||
$view = $_POST['v'];
|
||||
switch($view){
|
||||
case 'agendaWeek':
|
||||
case 'month';
|
||||
|
|
|
@ -13,7 +13,7 @@ if(!OCP\User::isLoggedIn()) {
|
|||
}
|
||||
OCP\JSON::checkAppEnabled('calendar');
|
||||
|
||||
$id = $_GET['id'];
|
||||
$id = $_POST['id'];
|
||||
$data = OC_Calendar_App::getEventObject($id, true, true);
|
||||
|
||||
if(!$data){
|
||||
|
|
|
@ -27,7 +27,6 @@ else {
|
|||
$start = (version_compare(PHP_VERSION, '5.3.0', '>='))?DateTime::createFromFormat('U', $_GET['start']):new DateTime('@' . $_GET['start']);
|
||||
$end = (version_compare(PHP_VERSION, '5.3.0', '>='))?DateTime::createFromFormat('U', $_GET['end']):new DateTime('@' . $_GET['end']);
|
||||
$events = OC_Calendar_App::getrequestedEvents($calendar_id, $start, $end);
|
||||
|
||||
$output = array();
|
||||
foreach($events as $event){
|
||||
$output = array_merge($output, OC_Calendar_App::generateEventOutput($event, $start, $end));
|
||||
|
|
|
@ -16,9 +16,9 @@ $nl="\r\n";
|
|||
$comps = array('VEVENT'=>true, 'VTODO'=>true, 'VJOURNAL'=>true);
|
||||
|
||||
global $progresskey;
|
||||
$progresskey = 'calendar.import-' . $_GET['progresskey'];
|
||||
$progresskey = 'calendar.import-' . $_POST['progresskey'];
|
||||
|
||||
if (isset($_GET['progress']) && $_GET['progress']) {
|
||||
if (isset($_POST['progress']) && $_POST['progress']) {
|
||||
echo OC_Cache::get($progresskey);
|
||||
die;
|
||||
}
|
||||
|
|
|
@ -12,8 +12,8 @@ OCP\JSON::checkAppEnabled('calendar');
|
|||
|
||||
$l = OC_L10N::get('calendar');
|
||||
|
||||
$lat = $_GET['lat'];
|
||||
$lng = $_GET['long'];
|
||||
$lat = $_POST['lat'];
|
||||
$lng = $_POST['lng'];
|
||||
|
||||
$timezone = OC_Geo::timezone($lat, $lng);
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue