Merge branch 'master' into calendar_repeat
This commit is contained in:
commit
e83e30a8a9
|
@ -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,83 @@
|
|||
<?php if (!class_exists('CFRuntime')) die('No direct access allowed.');
|
||||
/**
|
||||
* Stores your AWS account information. Add your account information, and then rename this file
|
||||
* to 'config.inc.php'.
|
||||
*
|
||||
* @version 2011.12.14
|
||||
* @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://aws.amazon.com/security-credentials AWS Security Credentials
|
||||
*/
|
||||
|
||||
|
||||
/*###################################################################################################
|
||||
|
||||
As of version 1.5, the AWS SDK for PHP uses the CFCredentials class to handle credentials.
|
||||
This class has the advantage of being able to support multiple sets of credentials at a time,
|
||||
including the ability for credential sets to inherit settings from other credential sets.
|
||||
|
||||
Some example uses are noted at https://gist.github.com/1478912
|
||||
|
||||
Notes:
|
||||
|
||||
* You can define one or more credential sets.
|
||||
|
||||
* Credential sets can be named anything that PHP allows for an associative array key;
|
||||
"production", "staging", etc., are just sample values. Feel free to rename them.
|
||||
|
||||
* A credential set only has four required entries: key, secret, default_cache_config and
|
||||
certificate_authority. Aside from these, you can add any additional bits of information
|
||||
you'd like to keep easily accessible (e.g., multi-factor authentication device key, your
|
||||
AWS Account ID, your canonical identifiers).
|
||||
|
||||
* Additional credential sets can inherit the properties of another credential set using the
|
||||
@inherit keyword.
|
||||
|
||||
* If more than one credential set is provided, a default credential set must be specified
|
||||
using the @default keyword.
|
||||
|
||||
* If you only have one credential set, you can set it to the @default keyword.
|
||||
|
||||
* View the documentation for the CFCredentials::set() method to view usage examples.
|
||||
|
||||
###################################################################################################*/
|
||||
|
||||
|
||||
/**
|
||||
* Create a list of credential sets that can be used with the SDK.
|
||||
*/
|
||||
CFCredentials::set(array(
|
||||
|
||||
// Credentials for the development environment.
|
||||
'development' => array(
|
||||
|
||||
// Amazon Web Services Key. Found in the AWS Security Credentials. You can also pass
|
||||
// this value as the first parameter to a service constructor.
|
||||
'key' => 'development-key',
|
||||
|
||||
// Amazon Web Services Secret Key. Found in the AWS Security Credentials. You can also
|
||||
// pass this value as the second parameter to a service constructor.
|
||||
'secret' => 'development-secret',
|
||||
|
||||
// This option allows you to configure a preferred storage type to use for caching by
|
||||
// default. This can be changed later using the set_cache_config() method.
|
||||
//
|
||||
// Valid values are: `apc`, `xcache`, or a file system path such as `./cache` or
|
||||
// `/tmp/cache/`.
|
||||
'default_cache_config' => '',
|
||||
|
||||
// Determines which Cerificate Authority file to use.
|
||||
//
|
||||
// A value of boolean `false` will use the Certificate Authority file available on the
|
||||
// system. A value of boolean `true` will use the Certificate Authority provided by the
|
||||
// SDK. Passing a file system path to a Certificate Authority file (chmodded to `0755`)
|
||||
// will use that.
|
||||
//
|
||||
// Leave this set to `false` if you're not sure.
|
||||
'certificate_authority' => false
|
||||
),
|
||||
|
||||
// Specify a default credential set to use if there are more than one.
|
||||
'@default' => 'development'
|
||||
));
|
|
@ -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)
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
|
||||
OCP\JSON::checkAppEnabled('files_external');
|
||||
if ($_POST['isPersonal'] == 'true') {
|
||||
OCP\JSON::checkLoggedIn();
|
||||
$isPersonal = true;
|
||||
} else {
|
||||
OCP\JSON::checkAdminUser();
|
||||
$isPersonal = false;
|
||||
}
|
||||
OC_Mount_Config::addMountPoint($_POST['mountPoint'], $_POST['class'], $_POST['classOptions'], $_POST['mountType'], $_POST['applicable'], $isPersonal);
|
||||
|
||||
?>
|
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
|
||||
OCP\JSON::checkAppEnabled('files_external');
|
||||
if ($_POST['isPersonal'] == 'true') {
|
||||
OCP\JSON::checkLoggedIn();
|
||||
$isPersonal = true;
|
||||
} else {
|
||||
OCP\JSON::checkAdminUser();
|
||||
$isPersonal = false;
|
||||
}
|
||||
OC_Mount_Config::removeMountPoint($_POST['mountPoint'], $_POST['mountType'], $_POST['applicable'], $isPersonal);
|
||||
|
||||
?>
|
|
@ -6,11 +6,16 @@
|
|||
* See the COPYING-README file.
|
||||
*/
|
||||
|
||||
OC::$CLASSPATH['OC_FileStorage_StreamWrapper']='apps/files_external/lib/streamwrapper.php';
|
||||
OC::$CLASSPATH['OC_FileStorage_StreamWrapper']='apps/files_external/lib/streamwrapper.php';
|
||||
OC::$CLASSPATH['OC_Filestorage_FTP']='apps/files_external/lib/ftp.php';
|
||||
OC::$CLASSPATH['OC_Filestorage_DAV']='apps/files_external/lib/webdav.php';
|
||||
OC::$CLASSPATH['OC_Filestorage_Google']='apps/files_external/lib/google.php';
|
||||
OC::$CLASSPATH['OC_Filestorage_SWIFT']='apps/files_external/lib/swift.php';
|
||||
OC::$CLASSPATH['OC_Filestorage_SMB']='apps/files_external/lib/smb.php';
|
||||
OC::$CLASSPATH['OC_Filestorage_AmazonS3']='apps/files_external/lib/amazons3.php';
|
||||
OC::$CLASSPATH['OC_Mount_Config']='apps/files_external/lib/config.php';
|
||||
|
||||
OCP\App::registerAdmin('files_external', 'settings');
|
||||
if (OCP\Config::getAppValue('files_external', 'allow_user_mounting', 'yes') == 'yes') {
|
||||
OCP\App::registerPersonal('files_external', 'personal');
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
.error { color: #FF3B3B; }
|
||||
td.type { width:8em; }
|
||||
td.mount, td.options, td.applicable { width:10em; }
|
||||
#addStorage>td { border:none; }
|
||||
#addStorage>td:not(.selectStorage) { visibility:hidden; }
|
||||
#selectStorage { margin-left:-10px; }
|
||||
td.mountPoint, td.backend { width:10em; }
|
||||
#addMountPoint>td { border:none; }
|
||||
#addMountPoint>td.applicable { visibility:hidden; }
|
||||
#selectBackend { margin-left:-10px; }
|
|
@ -1,59 +1,143 @@
|
|||
$(document).ready(function(){
|
||||
$(document).ready(function() {
|
||||
|
||||
function applicableChange(applicable) {
|
||||
if (applicable == 'Global') {
|
||||
|
||||
}
|
||||
console.log(applicable);
|
||||
}
|
||||
|
||||
$('#selectStorage').live('change', function() {
|
||||
$('.chzn-select').chosen();
|
||||
|
||||
$('#selectBackend').live('change', function() {
|
||||
var tr = $(this).parent().parent();
|
||||
$('#externalStorage tbody').last().append($(tr).clone());
|
||||
var selected = $(this).val();
|
||||
var selected = $(this).find('option:selected').text();
|
||||
var backendClass = $(this).val();
|
||||
$(this).parent().text(selected);
|
||||
var backends = $(this).data('configurations').split(';');
|
||||
var configuration = [];
|
||||
// Find selected backend configuration parameters
|
||||
$.each(backends, function(index, backend) {
|
||||
if (backend.split(':')[0] == selected) {
|
||||
configuration = backend.split(':')[1].split(',');
|
||||
// break;
|
||||
}
|
||||
});
|
||||
$(tr).find('.backend').data('class', $(this).val());
|
||||
var configurations = $(this).data('configurations');
|
||||
var td = $(tr).find('td.configuration');
|
||||
$.each(configuration, function(index, config) {
|
||||
if (config.indexOf('*') != -1) {
|
||||
td.append('<input type="password" placeholder="'+config.substring(1)+'" />');
|
||||
} else {
|
||||
td.append('<input type="text" placeholder="'+config+'" />');
|
||||
$.each(configurations, function(backend, parameters) {
|
||||
if (backend == backendClass) {
|
||||
$.each(parameters['configuration'], function(parameter, placeholder) {
|
||||
if (placeholder.indexOf('*') != -1) {
|
||||
td.append('<input type="password" data-parameter="'+parameter+'" placeholder="'+placeholder.substring(1)+'" />');
|
||||
} else if (placeholder.indexOf('!') != -1) {
|
||||
td.append('<label><input type="checkbox" data-parameter="'+parameter+'" />'+placeholder.substring(1)+'</label>');
|
||||
} else if (placeholder.indexOf('&') != -1) {
|
||||
td.append('<input type="text" class="optional" data-parameter="'+parameter+'" placeholder="'+placeholder.substring(1)+'" />');
|
||||
} else {
|
||||
td.append('<input type="text" data-parameter="'+parameter+'" placeholder="'+placeholder+'" />');
|
||||
}
|
||||
});
|
||||
return false;
|
||||
}
|
||||
});
|
||||
$('.chz-select').chosen();
|
||||
$(tr).find('td').last().attr('class', 'remove');
|
||||
$(tr).removeAttr('id');
|
||||
$(this).remove();
|
||||
});
|
||||
|
||||
$('td.remove>img').live('click', function() {
|
||||
$(this).parent().parent().remove();
|
||||
// TODO remove storage
|
||||
});
|
||||
|
||||
$('#externalStorage select[multiple]').each(function(index,element){
|
||||
applyMultiplySelect($(element));
|
||||
});
|
||||
|
||||
function applyMultiplySelect(element) {
|
||||
var checkHandeler=false;
|
||||
element.multiSelect({
|
||||
oncheck:applicableChange,
|
||||
onuncheck:applicableChange,
|
||||
minWidth: 120,
|
||||
$('#externalStorage td').live('change', function() {
|
||||
var tr = $(this).parent();
|
||||
var mountPoint = $(tr).find('.mountPoint input').val();
|
||||
if (mountPoint == '') {
|
||||
return false;
|
||||
}
|
||||
var backendClass = $(tr).find('.backend').data('class');
|
||||
var configuration = $(tr).find('.configuration input');
|
||||
var addMountPoint = true;
|
||||
if (configuration.length < 1) {
|
||||
return false;
|
||||
}
|
||||
var classOptions = {};
|
||||
$.each(configuration, function(index, input) {
|
||||
if ($(input).val() == '' && !$(input).hasClass('optional')) {
|
||||
addMountPoint = false;
|
||||
return false;
|
||||
}
|
||||
if ($(input).is(':checkbox')) {
|
||||
if ($(input).is(':checked')) {
|
||||
classOptions[$(input).data('parameter')] = true;
|
||||
} else {
|
||||
classOptions[$(input).data('parameter')] = false;
|
||||
}
|
||||
} else {
|
||||
classOptions[$(input).data('parameter')] = $(input).val();
|
||||
}
|
||||
});
|
||||
}
|
||||
if (addMountPoint) {
|
||||
if ($('#externalStorage').data('admin')) {
|
||||
var isPersonal = false;
|
||||
var multiselect = $(tr).find('.chzn-select').val();
|
||||
var oldGroups = $(tr).find('.applicable').data('applicable-groups');
|
||||
var oldUsers = $(tr).find('.applicable').data('applicable-users');
|
||||
$.each(multiselect, function(index, value) {
|
||||
var pos = value.indexOf('(group)');
|
||||
if (pos != -1) {
|
||||
var mountType = 'group';
|
||||
var applicable = value.substr(0, pos);
|
||||
if ($.inArray(applicable, oldGroups) != -1) {
|
||||
oldGroups.splice($.inArray(applicable, oldGroups), 1);
|
||||
}
|
||||
} else {
|
||||
var mountType = 'user';
|
||||
var applicable = value;
|
||||
if ($.inArray(applicable, oldUsers) != -1) {
|
||||
oldUsers.splice($.inArray(applicable, oldUsers), 1);
|
||||
}
|
||||
}
|
||||
$.post(OC.filePath('files_external', 'ajax', 'addMountPoint.php'), { mountPoint: mountPoint, class: backendClass, classOptions: classOptions, mountType: mountType, applicable: applicable, isPersonal: isPersonal });
|
||||
});
|
||||
var mountType = 'group';
|
||||
$.each(oldGroups, function(index, applicable) {
|
||||
$.post(OC.filePath('files_external', 'ajax', 'removeMountPoint.php'), { mountPoint: mountPoint, mountType: mountType, applicable: applicable, isPersonal: isPersonal });
|
||||
});
|
||||
var mountType = 'user';
|
||||
$.each(oldUsers, function(index, applicable) {
|
||||
$.post(OC.filePath('files_external', 'ajax', 'removeMountPoint.php'), { mountPoint: mountPoint, mountType: mountType, applicable: applicable, isPersonal: isPersonal });
|
||||
});
|
||||
} else {
|
||||
var isPersonal = true;
|
||||
var mountType = 'user';
|
||||
var applicable = OC.currentUser;
|
||||
$.post(OC.filePath('files_external', 'ajax', 'addMountPoint.php'), { mountPoint: mountPoint, class: backendClass, classOptions: classOptions, mountType: mountType, applicable: applicable, isPersonal: isPersonal });
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$('td.remove>img').live('click', function() {
|
||||
var tr = $(this).parent().parent();
|
||||
var mountPoint = $(tr).find('.mountPoint input').val();
|
||||
if (mountPoint == '') {
|
||||
return false;
|
||||
}
|
||||
if ($('#externalStorage').data('admin')) {
|
||||
var isPersonal = false;
|
||||
var multiselect = $(tr).find('.chzn-select').val();
|
||||
$.each(multiselect, function(index, value) {
|
||||
var pos = value.indexOf('(group)');
|
||||
if (pos != -1) {
|
||||
var mountType = 'group';
|
||||
var applicable = value.substr(0, pos);
|
||||
} else {
|
||||
var mountType = 'user';
|
||||
var applicable = value;
|
||||
}
|
||||
$.post(OC.filePath('files_external', 'ajax', 'removeMountPoint.php'), { mountPoint: mountPoint, mountType: mountType, applicable: applicable, isPersonal: isPersonal });
|
||||
});
|
||||
} else {
|
||||
var mountType = 'user';
|
||||
var applicable = OC.currentUser;
|
||||
var isPersonal = true;
|
||||
}
|
||||
$.post(OC.filePath('files_external', 'ajax', 'removeMountPoint.php'), { mountPoint: mountPoint, mountType: mountType, applicable: applicable, isPersonal: isPersonal });
|
||||
$(tr).remove();
|
||||
});
|
||||
|
||||
|
||||
|
||||
$('#allowUserMounting').bind('change', function() {
|
||||
// TODO save setting
|
||||
if (this.checked) {
|
||||
OC.AppConfig.setValue('files_external', 'allow_user_mounting', 'yes');
|
||||
} else {
|
||||
OC.AppConfig.setValue('files_external', 'allow_user_mounting', 'no');
|
||||
}
|
||||
});
|
||||
|
||||
});
|
|
@ -20,7 +20,7 @@
|
|||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
require_once 'aws-sdk-1.5.5/sdk.class.php';
|
||||
require_once 'aws-sdk/sdk.class.php';
|
||||
|
||||
class OC_Filestorage_AmazonS3 extends OC_Filestorage_Common {
|
||||
|
||||
|
|
|
@ -0,0 +1,231 @@
|
|||
<?php
|
||||
/**
|
||||
* ownCloud
|
||||
*
|
||||
* @author Michael Gapczynski
|
||||
* @copyright 2012 Michael Gapczynski mtgap@owncloud.com
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class to configure the config/mount.php and data/$user/mount.php files
|
||||
*/
|
||||
class OC_Mount_Config {
|
||||
|
||||
const MOUNT_TYPE_GLOBAL = 'global';
|
||||
const MOUNT_TYPE_GROUP = 'group';
|
||||
const MOUNT_TYPE_USER = 'user';
|
||||
|
||||
/**
|
||||
* Get details on each of the external storage backends, used for the mount config UI
|
||||
* If the configuration parameter should be secret, add a '*' to the beginning of the value
|
||||
* If the configuration parameter is a boolean, add a '!' to the beginning of the value
|
||||
* If the configuration parameter is optional, add a '&' to the beginning of the value
|
||||
* @return array
|
||||
*/
|
||||
public static function getBackends() {
|
||||
return array(
|
||||
'OC_Filestorage_Local' => array('backend' => 'Local', 'configuration' => array('datadir' => 'Location')),
|
||||
'OC_Filestorage_AmazonS3' => array('backend' => 'Amazon S3', 'configuration' => array('key' => 'Key', 'secret' => '*Secret', 'bucket' => 'Bucket')),
|
||||
'OC_Filestorage_FTP' => array('backend' => 'FTP', 'configuration' => array('host' => 'URL', 'user' => 'Username', 'password' => '*Password', 'root' => '&Root', 'secure' => '!Secure ftps://')),
|
||||
'OC_Filestorage_SWIFT' => array('backend' => 'OpenStack Swift', 'configuration' => array('host' => 'URL', 'user' => 'Username', 'token' => '*Token', 'root' => '&Root', 'secure' => '!Secure ftps://')),
|
||||
'OC_Filestorage_SMB' => array('backend' => 'SMB', 'configuration' => array('host' => 'URL', 'user' => 'Username', 'password' => '*Password', 'root' => '&Root')),
|
||||
'OC_Filestorage_DAV' => array('backend' => 'WebDAV', 'configuration' => array('host' => 'URL', 'user' => 'Username', 'password' => '*Password', 'root' => '&Root', 'secure' => '!Secure https://'))
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the system mount points
|
||||
* The returned array is not in the same format as getUserMountPoints()
|
||||
* @return array
|
||||
*/
|
||||
public static function getSystemMountPoints() {
|
||||
$mountPoints = self::readData(false);
|
||||
$backends = self::getBackends();
|
||||
$system = array();
|
||||
if (isset($mountPoints[self::MOUNT_TYPE_GROUP])) {
|
||||
foreach ($mountPoints[self::MOUNT_TYPE_GROUP] as $group => $mounts) {
|
||||
foreach ($mounts as $mountPoint => $mount) {
|
||||
// Remove '/$user/files/' from mount point
|
||||
$mountPoint = substr($mountPoint, 13);
|
||||
// Merge the mount point into the current mount points
|
||||
if (isset($system[$mountPoint]) && $system[$mountPoint]['configuration'] == $mount['options']) {
|
||||
$system[$mountPoint]['applicable']['groups'] = array_merge($system[$mountPoint]['applicable']['groups'], array($group));
|
||||
} else {
|
||||
$system[$mountPoint] = array('class' => $mount['class'], 'backend' => $backends[$mount['class']]['backend'], 'configuration' => $mount['options'], 'applicable' => array('groups' => array($group), 'users' => array()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isset($mountPoints[self::MOUNT_TYPE_USER])) {
|
||||
foreach ($mountPoints[self::MOUNT_TYPE_USER] as $user => $mounts) {
|
||||
foreach ($mounts as $mountPoint => $mount) {
|
||||
// Remove '/$user/files/' from mount point
|
||||
$mountPoint = substr($mountPoint, 13);
|
||||
// Merge the mount point into the current mount points
|
||||
if (isset($system[$mountPoint]) && $system[$mountPoint]['configuration'] == $mount['options']) {
|
||||
$system[$mountPoint]['applicable']['users'] = array_merge($system[$mountPoint]['applicable']['users'], array($user));
|
||||
} else {
|
||||
$system[$mountPoint] = array('class' => $mount['class'], 'backend' => $backends[$mount['class']]['backend'], 'configuration' => $mount['options'], 'applicable' => array('groups' => array(), 'users' => array($user)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $system;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the personal mount points of the current user
|
||||
* The returned array is not in the same format as getUserMountPoints()
|
||||
* @return array
|
||||
*/
|
||||
public static function getPersonalMountPoints() {
|
||||
$mountPoints = self::readData(true);
|
||||
$backends = self::getBackends();
|
||||
$uid = OCP\User::getUser();
|
||||
$personal = array();
|
||||
if (isset($mountPoints[self::MOUNT_TYPE_USER][$uid])) {
|
||||
foreach ($mountPoints[self::MOUNT_TYPE_USER][$uid] as $mountPoint => $mount) {
|
||||
// Remove '/$user/files/' from mount point
|
||||
$personal[substr($mountPoint, 13)] = array('class' => $mount['class'], 'backend' => $backends[$mount['class']]['backend'], 'configuration' => $mount['options']);
|
||||
}
|
||||
}
|
||||
return $personal;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add a mount point to the filesystem
|
||||
* @param string Mount point
|
||||
* @param string Backend class
|
||||
* @param array Backend parameters for the class
|
||||
* @param string MOUNT_TYPE_GROUP | MOUNT_TYPE_USER
|
||||
* @param string User or group to apply mount to
|
||||
* @param bool Personal or system mount point i.e. is this being called from the personal or admin page
|
||||
* @return bool
|
||||
*/
|
||||
public static function addMountPoint($mountPoint, $class, $classOptions, $mountType, $applicable, $isPersonal = false) {
|
||||
if ($isPersonal) {
|
||||
// Verify that the mount point applies for the current user
|
||||
// Prevent non-admin users from mounting local storage
|
||||
if ($applicable != OCP\User::getUser() || $class == 'OC_Filestorage_Local') {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
$mount = array($applicable => array('/$user/files/'.$mountPoint => array('class' => $class, 'options' => $classOptions)));
|
||||
$mountPoints = self::readData($isPersonal);
|
||||
// Merge the new mount point into the current mount points
|
||||
if (isset($mountPoints[$mountType])) {
|
||||
if (isset($mountPoints[$mountType][$applicable])) {
|
||||
$mountPoints[$mountType][$applicable] = array_merge($mountPoints[$mountType][$applicable], $mount[$applicable]);
|
||||
} else {
|
||||
$mountPoints[$mountType] = array_merge($mountPoints[$mountType], $mount);
|
||||
}
|
||||
} else {
|
||||
$mountPoints[$mountType] = $mount;
|
||||
}
|
||||
self::writeData($isPersonal, $mountPoints);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param string Mount point
|
||||
* @param string MOUNT_TYPE_GROUP | MOUNT_TYPE_USER
|
||||
* @param string User or group to remove mount from
|
||||
* @param bool Personal or system mount point
|
||||
* @return bool
|
||||
*/
|
||||
public static function removeMountPoint($mountPoint, $mountType, $applicable, $isPersonal = false) {
|
||||
// Verify that the mount point applies for the current user
|
||||
if ($isPersonal && $applicable != OCP\User::getUser()) {
|
||||
return false;
|
||||
}
|
||||
$mountPoints = self::readData($isPersonal);
|
||||
// Remove mount point
|
||||
unset($mountPoints[$mountType][$applicable]['/$user/files/'.$mountPoint]);
|
||||
// Unset parent arrays if empty
|
||||
if (empty($mountPoints[$mountType][$applicable])) {
|
||||
unset($mountPoints[$mountType][$applicable]);
|
||||
if (empty($mountPoints[$mountType])) {
|
||||
unset($mountPoints[$mountType]);
|
||||
}
|
||||
}
|
||||
self::writeData($isPersonal, $mountPoints);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the mount points in the config file into an array
|
||||
* @param bool Personal or system config file
|
||||
* @return array
|
||||
*/
|
||||
private static function readData($isPersonal) {
|
||||
if ($isPersonal) {
|
||||
$file = OC::$SERVERROOT.'/data/'.OCP\User::getUser().'/mount.php';
|
||||
} else {
|
||||
$file = OC::$SERVERROOT.'/config/mount.php';
|
||||
}
|
||||
if (is_file($file)) {
|
||||
$mountPoints = include($file);
|
||||
if (is_array($mountPoints)) {
|
||||
return $mountPoints;
|
||||
}
|
||||
}
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the mount points to the config file
|
||||
* @param bool Personal or system config file
|
||||
* @param array Mount points
|
||||
*/
|
||||
private static function writeData($isPersonal, $data) {
|
||||
if ($isPersonal) {
|
||||
$file = OC::$SERVERROOT.'/data/'.OCP\User::getUser().'/mount.php';
|
||||
} else {
|
||||
$file = OC::$SERVERROOT.'/config/mount.php';
|
||||
}
|
||||
$content = "<?php return array (\n";
|
||||
if (isset($data[self::MOUNT_TYPE_GROUP])) {
|
||||
$content .= "\t'group' => array (\n";
|
||||
foreach ($data[self::MOUNT_TYPE_GROUP] as $group => $mounts) {
|
||||
$content .= "\t\t'".$group."' => array (\n";
|
||||
foreach ($mounts as $mountPoint => $mount) {
|
||||
$content .= "\t\t\t'".$mountPoint."' => ".str_replace("\n", '', var_export($mount, true)).",\n";
|
||||
|
||||
}
|
||||
$content .= "\t\t),\n";
|
||||
}
|
||||
$content .= "\t),\n";
|
||||
}
|
||||
if (isset($data[self::MOUNT_TYPE_USER])) {
|
||||
$content .= "\t'user' => array (\n";
|
||||
foreach ($data[self::MOUNT_TYPE_USER] as $user => $mounts) {
|
||||
$content .= "\t\t'".$user."' => array (\n";
|
||||
foreach ($mounts as $mountPoint => $mount) {
|
||||
$content .= "\t\t\t'".$mountPoint."' => ".str_replace("\n", '', var_export($mount, true)).",\n";
|
||||
}
|
||||
$content .= "\t\t),\n";
|
||||
}
|
||||
$content .= "\t),\n";
|
||||
}
|
||||
$content .= ");\n?>";
|
||||
@file_put_contents($file, $content);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* ownCloud
|
||||
*
|
||||
* @author Michael Gapczynski
|
||||
* @copyright 2012 Michael Gapczynski mtgap@owncloud.com
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
OCP\Util::addScript('files_external', 'settings');
|
||||
OCP\Util::addStyle('files_external', 'settings');
|
||||
$backends = OC_Mount_Config::getBackends();
|
||||
// Remove local storage
|
||||
unset($backends['OC_Filestorage_Local']);
|
||||
$tmpl = new OCP\Template('files_external', 'settings');
|
||||
$tmpl->assign('isAdminPage', false);
|
||||
$tmpl->assign('mounts', OC_Mount_Config::getPersonalMountPoints());
|
||||
$tmpl->assign('backends', $backends);
|
||||
return $tmpl->fetchPage();
|
||||
|
||||
?>
|
|
@ -20,16 +20,15 @@
|
|||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
OCP\Util::addscript('files_external', 'settings');
|
||||
OCP\Util::addstyle('files_external', 'settings');
|
||||
OCP\Util::addScript('files_external', 'settings');
|
||||
OCP\Util::addStyle('files_external', 'settings');
|
||||
$tmpl = new OCP\Template('files_external', 'settings');
|
||||
$tmpl->assign('allowUserMounting', 'yes');
|
||||
$tmpl->assign('isAdminPage', true);
|
||||
$tmpl->assign('storage', array());
|
||||
$tmpl->assign('mounts', OC_Mount_Config::getSystemMountPoints());
|
||||
$tmpl->assign('backends', OC_Mount_Config::getBackends());
|
||||
$tmpl->assign('groups', OC_Group::getGroups());
|
||||
$tmpl->assign('backends', array('Amazon S3', 'FTP', 'Google Drive', 'SWIFT', 'WebDAV'));
|
||||
$tmpl->assign('configurations', '');
|
||||
$tmpl->assign('options', array('Encrypt', 'Version control', 'Allow sharing'));
|
||||
$tmpl->assign('users', OCP\User::getUsers());
|
||||
$tmpl->assign('allowUserMounting', OCP\Config::getAppValue('files_external', 'allow_user_mounting', 'yes'));
|
||||
return $tmpl->fetchPage();
|
||||
|
||||
?>
|
|
@ -1,70 +1,82 @@
|
|||
<form id="files_external">
|
||||
<fieldset class="personalblock">
|
||||
<legend><strong><?php echo $l->t('External Storage'); ?></strong></legend>
|
||||
<?php if (isset($_['storage'])): ?>
|
||||
<table id="externalStorage">
|
||||
<table id="externalStorage" data-admin="<?php echo json_encode($_['isAdminPage']); ?>">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><?php echo $l->t('Type'); ?></th>
|
||||
<th><?php echo $l->t('Mount point'); ?></th>
|
||||
<th><?php echo $l->t('Backend'); ?></th>
|
||||
<th><?php echo $l->t('Configuration'); ?></th>
|
||||
<th><?php echo $l->t('Mount Location'); ?></th>
|
||||
<th><?php echo $l->t('Options'); ?></th>
|
||||
<?php if ($_['isAdminPage'] == true) echo '<th>'.$l->t('Applicable').'</th>'; ?>
|
||||
<!--<th><?php echo $l->t('Options'); ?></th> -->
|
||||
<?php if ($_['isAdminPage']) echo '<th>'.$l->t('Applicable').'</th>'; ?>
|
||||
<th> </th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php $_['storage'] = array_merge($_['storage'], array(array('id' => 'addStorage', 'mount' => ''))); ?>
|
||||
<?php foreach($_['storage'] as $storage): ?>
|
||||
<tr <?php if ($storage['id'] == 'addStorage') echo 'id="addStorage"'; ?> data-storage-id="<?php echo $storage['id']; ?>">
|
||||
<?php if ($storage['id'] == 'addStorage'): ?>
|
||||
<td class="selectStorage">
|
||||
<select id="selectStorage" data-configurations="<?php echo $_['configurations']; ?>">
|
||||
<option value="" disabled selected style="display:none;"><?php echo $l->t('Add storage'); ?></option>
|
||||
<?php foreach($_['backends'] as $backend): ?>
|
||||
<option value="<?php echo $backend; ?>"><?php echo $backend; ?></option>
|
||||
<tbody width="100%">
|
||||
<?php $_['mounts'] = array_merge($_['mounts'], array('' => array())); ?>
|
||||
<?php foreach ($_['mounts'] as $mountPoint => $mount): ?>
|
||||
<tr <?php if ($mountPoint == '') echo 'id="addMountPoint"'; ?>>
|
||||
<td class="mountPoint"><input type="text" name="mountPoint" value="<?php echo $mountPoint; ?>" placeholder="<?php echo $l->t('Mount point'); ?>" /></td>
|
||||
<?php if ($mountPoint == ''): ?>
|
||||
<td class="backend">
|
||||
<select id="selectBackend" data-configurations='<?php echo json_encode($_['backends']); ?>'>
|
||||
<option value="" disabled selected style="display:none;"><?php echo $l->t('Add mount point'); ?></option>
|
||||
<?php foreach ($_['backends'] as $class => $backend): ?>
|
||||
<option value="<?php echo $class; ?>"><?php echo $backend['backend']; ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</td>
|
||||
<?php else: ?>
|
||||
<td class="type" <?php if ($storage['status'] == 'error') echo 'class="error"'; ?>><?php echo $storage['type']; ?></td>
|
||||
<?php endif; ?>
|
||||
<td class ="configuration">
|
||||
<?php if (isset($storage['configuration'])): ?>
|
||||
<?php foreach($storage['configuration'] as $parameter => $value): ?>
|
||||
<?php if (strpos($parameter, '*') !== false): ?>
|
||||
<input type="password" value="<?php echo $value; ?>" placeholder="<?php echo $l->t(substr($parameter, 1)); ?>" />
|
||||
<?php else: ?>
|
||||
<input type="text" value="<?php echo $value; ?>" placeholder="<?php echo $l->t($parameter); ?>" />
|
||||
<?php endif; ?>
|
||||
<?php endforeach; ?>
|
||||
<td class="backend" data-class="<?php echo $mount['class']; ?>"><?php echo $mount['backend']; ?></td>
|
||||
<?php endif; ?>
|
||||
<td class ="configuration" width="100%">
|
||||
<?php if (isset($mount['configuration'])): ?>
|
||||
<?php foreach ($mount['configuration'] as $parameter => $value): ?>
|
||||
<?php if (isset($_['backends'][$mount['class']]['configuration'][$parameter])): ?>
|
||||
<?php $placeholder = $_['backends'][$mount['class']]['configuration'][$parameter]; ?>
|
||||
<?php if (strpos($placeholder, '*') !== false): ?>
|
||||
<input type="password" data-parameter="<?php echo $parameter; ?>" value="<?php echo $value; ?>" placeholder="<?php echo substr($placeholder, 1); ?>" />
|
||||
<?php elseif(strpos($placeholder, '!') !== false): ?>
|
||||
<label><input type="checkbox" data-parameter="<?php echo $parameter; ?>" <?php if ($value == 'true') echo ' checked="checked"'; ?> /><?php echo substr($placeholder, 1); ?></label>
|
||||
<?php elseif (strpos($placeholder, '&') !== false): ?>
|
||||
<input type="text" class="optional" data-parameter="<?php echo $parameter; ?>" value="<?php echo $value; ?>" placeholder="<?php echo substr($placeholder, 1); ?>" />
|
||||
<?php else: ?>
|
||||
<input type="text" data-parameter="<?php echo $parameter; ?>" value="<?php echo $value; ?>" placeholder="<?php echo $placeholder; ?>" />
|
||||
<?php endif; ?>
|
||||
<?php endif; ?>
|
||||
<?php endforeach; ?>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td class="mount"><input type="text" name="storageMountLocation" value="<?php echo $storage['mount']; ?>" placeholder="<?php echo $l->t('Mount Location'); ?>" /></td>
|
||||
<td class="options">
|
||||
<select class="selectOptions" title="<?php echo $l->t('None set')?>" multiple="multiple">
|
||||
<!--<td class="options">
|
||||
<select class="selectOptions" title="<?php echo $l->t('None set')?>" multiple="multiple" disabled>
|
||||
<?php if (OCP\App::isEnabled('files_encryption')) echo '<option value="Encrypt">Encrypt</option>'; ?>
|
||||
<?php if (OCP\App::isEnabled('files_versions')) echo '<option value="Version control">Version control</option>'; ?>
|
||||
<?php if (OCP\App::isEnabled('files_sharing')) echo '<option value="Allow sharing">Allow sharing</option>'; ?>
|
||||
</select>
|
||||
</td>
|
||||
<?php if ($_['isAdminPage'] == true): ?>
|
||||
<td class="applicable">
|
||||
<select class="selectApplicable" data-storage-applicable="<?php echo $storage['applicable']; ?>" title="<?php echo $l->t('None set'); ?>" multiple="multiple">
|
||||
<option value="Global"><?php echo $l->t('Global'); ?></option>
|
||||
<?php foreach($_['groups'] as $group): ?>
|
||||
<option value="<?php echo $group; ?>"><?php echo $group; ?></option>
|
||||
<?php endforeach; ?>
|
||||
</td>-->
|
||||
<?php if ($_['isAdminPage']): ?>
|
||||
<td class="applicable" align="right" data-applicable-groups='<?php if (isset($mount['applicable']['groups'])) echo json_encode($mount['applicable']['groups']); ?>' data-applicable-users='<?php if (isset($mount['applicable']['users'])) echo json_encode($mount['applicable']['users']); ?>'>
|
||||
<select class="chzn-select" multiple style="width:20em;" data-placeholder="<?php echo $l->t('None set'); ?>">
|
||||
<option value="all"><?php echo $l->t('All Users'); ?></option>
|
||||
<optgroup label="<?php echo $l->t('Groups'); ?>">
|
||||
<?php foreach ($_['groups'] as $group): ?>
|
||||
<option value="<?php echo $group; ?>(group)" <?php if (isset($mount['applicable']['groups']) && in_array($group, $mount['applicable']['groups'])) echo 'selected="selected"'; ?>><?php echo $group; ?></option>
|
||||
<?php endforeach; ?>
|
||||
</optgroup>
|
||||
<optgroup label="<?php echo $l->t('Users'); ?>">
|
||||
<?php foreach ($_['users'] as $user): ?>
|
||||
<option value="<?php echo $user; ?>" <?php if (isset($mount['applicable']['users']) && in_array($user, $mount['applicable']['users'])) echo 'selected="selected"'; ?>"><?php echo $user; ?></option>
|
||||
<?php endforeach; ?>
|
||||
</optgroup>
|
||||
</select>
|
||||
</td>
|
||||
<?php endif; ?>
|
||||
<td <?php if ($storage['id'] != 'addStorage') echo 'class="remove"'; ?>><img alt="<?php echo $l->t('Delete'); ?>" title="<?php echo $l->t('Delete'); ?>" class="svg action" src="<?php echo image_path('core', 'actions/delete.svg'); ?>" /></td>
|
||||
<td <?php if ($mountPoint != '') echo 'class="remove"'; ?>><img alt="<?php echo $l->t('Delete'); ?>" title="<?php echo $l->t('Delete'); ?>" class="svg action" src="<?php echo image_path('core', 'actions/delete.svg'); ?>" /></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
<?php endif; ?>
|
||||
<?php if ($_['isAdminPage'] == true): ?>
|
||||
<?php if ($_['isAdminPage']): ?>
|
||||
<br />
|
||||
<input type="checkbox" name="allowUserMounting" id="allowUserMounting" value="1" <?php if ($_['allowUserMounting'] == 'yes') echo ' checked="checked"'; ?> />
|
||||
<label for="allowUserMounting"><?php echo $l->t('Enable User External Storage'); ?></label><br/>
|
||||
|
|
|
@ -8,8 +8,8 @@ OCP\Util::connectHook("OC_Filesystem", "post_delete", "OC_Share", "deleteItem");
|
|||
OCP\Util::connectHook("OC_Filesystem", "post_rename", "OC_Share", "renameItem");
|
||||
OCP\Util::connectHook("OC_Filesystem", "post_write", "OC_Share", "updateItem");
|
||||
OCP\Util::connectHook('OC_User', 'post_deleteUser', 'OC_Share', 'removeUser');
|
||||
OCP\Util::connectHook('OC_User', 'post_addToGroup', 'OC_Share', 'addToGroupShare');
|
||||
OCP\Util::connectHook('OC_User', 'post_removeFromGroup', 'OC_Share', 'removeFromGroupShare');
|
||||
OCP\Util::connectHook('OC_Group', 'post_addToGroup', 'OC_Share', 'addToGroupShare');
|
||||
OCP\Util::connectHook('OC_Group', 'post_removeFromGroup', 'OC_Share', 'removeFromGroupShare');
|
||||
$dir = isset($_GET['dir']) ? $_GET['dir'] : '/';
|
||||
if ($dir != '/Shared' || OCP\Config::getAppValue('files_sharing', 'resharing', 'yes') == 'yes') {
|
||||
OCP\Util::addscript("files_sharing", "share");
|
||||
|
|
|
@ -190,7 +190,7 @@ class OC_GROUP_LDAP extends OC_Group_Backend {
|
|||
$ldap_groups = OC_LDAP::fetchListOfGroups($this->ldapGroupFilter, array(OC_LDAP::conf('ldapGroupDisplayName'), 'dn'));
|
||||
$this->_groups = OC_LDAP::ownCloudGroupNames($ldap_groups);
|
||||
}
|
||||
return $this->groups;
|
||||
return $this->_groups;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -5,61 +5,90 @@ define("DEBUG", true);
|
|||
$CONFIG = array(
|
||||
/* Flag to indicate OwnCloud is successfully installed (true = installed) */
|
||||
"installed" => false,
|
||||
|
||||
/* Type of database, can be sqlite, mysql or pgsql */
|
||||
"dbtype" => "sqlite",
|
||||
|
||||
/* Name of the OwnCloud database */
|
||||
"dbname" => "owncloud",
|
||||
|
||||
/* User to access the OwnCloud database */
|
||||
"dbuser" => "",
|
||||
|
||||
/* Password to access the OwnCloud database */
|
||||
"dbpassword" => "",
|
||||
|
||||
/* Host running the OwnCloud database */
|
||||
"dbhost" => "",
|
||||
|
||||
/* Prefix for the OwnCloud tables in the database */
|
||||
"dbtableprefix" => "",
|
||||
|
||||
/* Define the salt used to hash the user passwords. All your user passwords are lost if you lose this string. */
|
||||
"passwordsalt" => "",
|
||||
|
||||
/* Force use of HTTPS connection (true = use HTTPS) */
|
||||
"forcessl" => false,
|
||||
|
||||
/* Theme to use for OwnCloud */
|
||||
"theme" => "",
|
||||
|
||||
/* Path to the 3rdparty directory */
|
||||
"3rdpartyroot" => "",
|
||||
|
||||
/* URL to the 3rdparty directory, as seen by the browser */
|
||||
"3rdpartyurl" => "",
|
||||
|
||||
/* Default app to load on login */
|
||||
"defaultapp" => "files",
|
||||
|
||||
/* Enable the help menu item in the settings */
|
||||
"knowledgebaseenabled" => true,
|
||||
|
||||
/* URL to use for the help page, server should understand OCS */
|
||||
"knowledgebaseurl" => "http://api.apps.owncloud.com/v1",
|
||||
|
||||
/* Enable installing apps from the appstore */
|
||||
"appstoreenabled" => true,
|
||||
|
||||
/* URL of the appstore to use, server should understand OCS */
|
||||
"appstoreurl" => "http://api.apps.owncloud.com/v1",
|
||||
|
||||
/* Mode to use for sending mail, can be sendmail, smtp, qmail or php, see PHPMailer docs */
|
||||
"mail_smtpmode" => "sendmail",
|
||||
|
||||
/* Host to use for sending mail, depends on mail_smtpmode if this is used */
|
||||
"mail_smtphost" => "127.0.0.1",
|
||||
|
||||
/* authentication needed to send mail, depends on mail_smtpmode if this is used
|
||||
* (false = disable authentication)
|
||||
*/
|
||||
"mail_smtpauth" => false,
|
||||
|
||||
/* Username to use for sendmail mail, depends on mail_smtpauth if this is used */
|
||||
"mail_smtpname" => "",
|
||||
|
||||
/* Password to use for sendmail mail, depends on mail_smtpauth if this is used */
|
||||
"mail_smtppassword" => "",
|
||||
|
||||
/* Check 3rdparty apps for malicious code fragments */
|
||||
"appcodechecker" => "",
|
||||
|
||||
/* Place to log to, can be owncloud and syslog (owncloud is log menu item in admin menu) */
|
||||
"log_type" => "owncloud",
|
||||
|
||||
/* File for the owncloud logger to log to, (default is ownloud.log in the data dir */
|
||||
"logfile" => "",
|
||||
|
||||
/* Loglevel to start logging at. 0=DEBUG, 1=INFO, 2=WARN, 3=ERROR (default is WARN) */
|
||||
"loglevel" => "",
|
||||
|
||||
/* Set this to false to disable the check for writable apps dir.
|
||||
* If the apps dir is not writable, you can't download&install extra apps
|
||||
* in the admin apps menu.
|
||||
*/
|
||||
"writable_appsdir" => true,
|
||||
|
||||
/* The directory where the user data is stored, default to data in the owncloud
|
||||
* directory. The sqlite database is also stored here, when sqlite is used.
|
||||
*/
|
||||
|
|
|
@ -73,6 +73,10 @@ class OC_Setup {
|
|||
$dbtype='sqlite3';
|
||||
}
|
||||
|
||||
//generate a random salt that is used to salt the local user passwords
|
||||
$salt=mt_rand(1000,9000).mt_rand(1000,9000).mt_rand(1000,9000).mt_rand(1000,9000).mt_rand(1000,9000).mt_rand(1000,9000).mt_rand(1000,9000).mt_rand(1000,9000);
|
||||
OC_Config::setValue('passwordsalt', $salt);
|
||||
|
||||
//write the config file
|
||||
OC_Config::setValue('datadirectory', $datadir);
|
||||
OC_Config::setValue('dbtype', $dbtype);
|
||||
|
|
|
@ -69,7 +69,7 @@ class OC_User_Database extends OC_User_Backend {
|
|||
return false;
|
||||
}else{
|
||||
$hasher=$this->getHasher();
|
||||
$hash = $hasher->HashPassword($password);
|
||||
$hash = $hasher->HashPassword($password.OC_Config::getValue('passwordsalt', ''));
|
||||
$query = OC_DB::prepare( "INSERT INTO `*PREFIX*users` ( `uid`, `password` ) VALUES( ?, ? )" );
|
||||
$result = $query->execute( array( $uid, $hash));
|
||||
|
||||
|
@ -102,7 +102,7 @@ class OC_User_Database extends OC_User_Backend {
|
|||
public function setPassword( $uid, $password ){
|
||||
if( $this->userExists($uid) ){
|
||||
$hasher=$this->getHasher();
|
||||
$hash = $hasher->HashPassword($password);
|
||||
$hash = $hasher->HashPassword($password.OC_Config::getValue('passwordsalt', ''));
|
||||
$query = OC_DB::prepare( "UPDATE *PREFIX*users SET password = ? WHERE uid = ?" );
|
||||
$result = $query->execute( array( $hash, $uid ));
|
||||
|
||||
|
@ -131,7 +131,7 @@ class OC_User_Database extends OC_User_Backend {
|
|||
$storedHash=$row['password'];
|
||||
if (substr($storedHash,0,1)=='$'){//the new phpass based hashing
|
||||
$hasher=$this->getHasher();
|
||||
if($hasher->CheckPassword($password, $storedHash)){
|
||||
if($hasher->CheckPassword($password.OC_Config::getValue('passwordsalt', ''), $storedHash)){
|
||||
return $row['uid'];
|
||||
}else{
|
||||
return false;
|
||||
|
|
|
@ -34,9 +34,10 @@ li.selected { background-color:#ddd; }
|
|||
#content>table:not(.nostyle) { margin-top:3em; }
|
||||
table:not(.nostyle) { width:100%; }
|
||||
#rightcontent { padding-left: 1em; }
|
||||
td.quota { position:absolute; }
|
||||
td.quota { position:relative; }
|
||||
div.quota { float:right; display:block; position:absolute; right:25em; top:0; }
|
||||
select.quota { position:absolute; left:0; top:0; width:10em; }
|
||||
select.quota-user { position:relative; left:0; top:0; width:10em; }
|
||||
input.quota-other { display:none; position:absolute; left:0.1em; top:0.1em; width:7em; border:none; -webkit-box-shadow: none -mox-box-shadow:none ; box-shadow:none; }
|
||||
div.quota>span { position:absolute; right:0em; white-space:nowrap; top: 0.7em }
|
||||
select.quota.active { background: #fff; }
|
||||
|
|
|
@ -64,7 +64,7 @@ foreach($_["groups"] as $group) {
|
|||
</select>
|
||||
</td>
|
||||
<td class="quota">
|
||||
<select class='quota'>
|
||||
<select class='quota-user'>
|
||||
<?php foreach($_['quota_preset'] as $preset):?>
|
||||
<option <?php if($user['quota']==$preset) echo 'selected="selected"';?> value='<?php echo $preset;?>'><?php echo $preset;?></option>
|
||||
<?php endforeach;?>
|
||||
|
|
Loading…
Reference in New Issue