Merge "Object Storage directory has been converted from doxygen to PHPDoc. Partially implements blueprint phpdoc."

This commit is contained in:
Jenkins 2014-04-07 18:46:24 +00:00 committed by Gerrit Code Review
commit 38ae1ae3e8
11 changed files with 668 additions and 958 deletions

View File

@ -15,8 +15,6 @@
limitations under the License.
============================================================================ */
/**
* @file
*
* This file provides the ObjectStorage class, which is the primary
* representation of the ObjectStorage system.
*
@ -39,7 +37,7 @@ use OpenStack\Storage\ObjectStorage\ACL;
*
* There is also a stream wrapper interface that exposes ObjectStorage
* to PHP's streams system. For common use of an object store, you may
* prefer to use that system. (See OpenStack::Bootstrap).
* prefer to use that system. (@see \OpenStack\Bootstrap).
*
* When constructing a new ObjectStorage object, you will need to know
* what kind of authentication you are going to perform. Older
@ -47,8 +45,8 @@ use OpenStack\Storage\ObjectStorage\ACL;
* mechanism for Swift. You can use ObjectStorage::newFromSwiftAuth() to
* perform this type of authentication.
*
* Newer versions use the IdentityServices authentication mechanism (see
* OpenStack::Services::IdentityServices). That method is the preferred
* Newer versions use the IdentityServices authentication mechanism (@see
* \OpenStack\Services\IdentityServices). That method is the preferred
* method.
*
* Common Tasks
@ -87,7 +85,7 @@ class ObjectStorage {
* Create a new instance after getting an authenitcation token.
*
* THIS METHOD IS DEPRECATED. OpenStack now uses Keyston to authenticate.
* You should use OpenStack::Services::IdentityServices to authenticate.
* You should use \OpenStack\Services\IdentityServices to authenticate.
* Then use this class's constructor to create an object.
*
* This uses the legacy Swift authentication facility to authenticate
@ -102,18 +100,15 @@ class ObjectStorage {
* - Key: Typically this will be your password.
* - Endpoint URL: The URL given to you by your service provider.
*
* @param string $account
* Your account name.
* @param string $key
* Your secret key.
* @param string $url
* The URL to the object storage endpoint.
* @param string $account Your account name.
* @param string $key Your secret key.
* @param string $url The URL to the object storage endpoint.
*
* @throws OpenStack::Transport::AuthorizationException if the
* @throws \OpenStack\Transport\AuthorizationException if the
* authentication failed.
* @throws OpenStack::Transport::FileNotFoundException if the URL is
* @throws \OpenStack\Transport\FileNotFoundException if the URL is
* wrong.
* @throws OpenStack::Exception if some other exception occurs.
* @throws \OpenStack\Exception if some other exception occurs.
*
* @deprecated Newer versions of OpenStack use Keystone auth instead
* of Swift auth.
@ -151,14 +146,12 @@ class ObjectStorage {
* Given an IdentityServices instance, create an ObjectStorage instance.
*
* This constructs a new ObjectStorage from an authenticated instance
* of an OpenStack::Services::IdentityServices object.
* of an \OpenStack\Services\IdentityServices object.
*
* @param OpenStack::Services::IdentityServices $identity
* An identity services object that already has a valid token and a
* service catalog.
* @retval OpenStack::Storage::ObjectStorage
* @return \OpenStack\Storage\ObjectStorage
* A new ObjectStorage instance.
* @param \OpenStack\Services\IdentityServices $identity An identity services
* object that already has a valid token and a service catalog.
*
* @return \OpenStack\Storage\ObjectStorage A new ObjectStorage instance.
*/
public static function newFromIdentity($identity, $region = ObjectStorage::DEFAULT_REGION) {
$cat = $identity->serviceCatalog();
@ -175,15 +168,12 @@ class ObjectStorage {
* This builder can scan the catalog and generate a new ObjectStorage
* instance pointed to the first object storage endpoint in the catalog.
*
* @param array $catalog
* The serice catalog from IdentityServices::serviceCatalog(). This
* can be either the entire catalog or a catalog filtered to
* just ObjectStorage::SERVICE_TYPE.
* @param string $authToken
* The auth token returned by IdentityServices.
* @retval OpenStack::Storage::ObjectStorage
* @return \OpenStack\Storage\ObjectStorage
* A new ObjectStorage instance.
* @param array $catalog The serice catalog from IdentityServices::serviceCatalog().
* This can be either the entire catalog or a catalog filtered to just
* ObjectStorage::SERVICE_TYPE.
* @param string $authToken The auth token returned by IdentityServices.
*
* @return \OpenStack\Storage\ObjectStorage A new ObjectStorage instance.
*/
public static function newFromServiceCatalog($catalog, $authToken, $region = ObjectStorage::DEFAULT_REGION) {
$c = count($catalog);
@ -207,12 +197,10 @@ class ObjectStorage {
*
* Use this if newFromServiceCatalog() does not meet your needs.
*
* @param string $authToken
* A token that will be included in subsequent requests to validate
* that this client has authenticated correctly.
* @param string $url
* The URL to the endpoint. This typically is returned after
* authentication.
* @param string $authToken A token that will be included in subsequent
* requests to validate that this client has authenticated correctly.
* @param string $url The URL to the endpoint. This typically is returned
* after authentication.
*/
public function __construct($authToken, $url) {
$this->token = $authToken;
@ -222,9 +210,7 @@ class ObjectStorage {
/**
* Get the authentication token.
*
* @retval string
* @return string
* The authentication token.
* @return string The authentication token.
*/
public function token() {
return $this->token;
@ -233,9 +219,7 @@ class ObjectStorage {
/**
* Get the URL endpoint.
*
* @retval string
* @return string
* The URL that is the endpoint for this service.
* @return string The URL that is the endpoint for this service.
*/
public function url() {
return $this->url;
@ -263,20 +247,15 @@ class ObjectStorage {
* requested, it makes an additional round-trip to the server to
* fetch that data.
*
* @param int $limit
* The maximum number to return at a time. The default is -- brace
* yourself -- 10,000 (as determined by OpenStack. Implementations
* @param int $limit The maximum number to return at a time. The default is
* -- brace yourself -- 10,000 (as determined by OpenStack. Implementations
* may vary).
* @param string $marker
* The name of the last object seen. Used when paging.
* @param string $marker The name of the last object seen. Used when paging.
*
* @retval array
* @return array
* An associative array of containers, where the key is the
* container's name and the value is an
* OpenStack::Storage::ObjectStorage::Container object. Results are
* ordered in server order (the order that the remote host puts them
* in).
* @return array An associative array of containers, where the key is the
* container's name and the value is an \OpenStack\Storage\ObjectStorage\Container
* object. Results are ordered in server order (the order that the remote
* host puts them in).
*/
public function containers($limit = 0, $marker = NULL) {
@ -305,13 +284,11 @@ class ObjectStorage {
*
* This loads only the named container from the remote server.
*
* @param string $name
* The name of the container to load.
* @retval OpenStack::Storage::ObjectStorage::Container
* @return \OpenStack\Storage\ObjectStorage\Container
* A container.
* @throws OpenStack::Transport::FileNotFoundException
* if the named container is not found on the remote server.
* @param string $name The name of the container to load.
*
* @return \OpenStack\Storage\ObjectStorage\Container A container.
* @throws \OpenStack\Transport\FileNotFoundException if the named container
* is not found on the remote server.
*/
public function container($name) {
@ -332,17 +309,14 @@ class ObjectStorage {
/**
* Check to see if this container name exists.
*
* This method directly checks the remote server. Calling container()
* or containers() might be more efficient if you plan to work with
* This method directly checks the remote server. Calling container()
* or containers() might be more efficient if you plan to work with
* the resulting container.
*
* @param string $name
* The name of the container to test.
* @retval boolean
* @return boolean
* TRUE if the container exists, FALSE if it does not.
* @throws OpenStack::Exception
* If an unexpected network error occurs.
* @param string $name The name of the container to test.
*
* @return boolean TRUE if the container exists, FALSE if it does not.
* @throws \OpenStack\Exception If an unexpected network error occurs.
*/
public function hasContainer($name) {
try {
@ -373,8 +347,8 @@ class ObjectStorage {
* ACLs
*
* Swift supports an ACL stream that allows for specifying (with
* certain caveats) various levels of read and write access. However,
* there are two standard settings that cover the vast majority of
* certain caveats) various levels of read and write access. However,
* there are two standard settings that cover the vast majority of
* cases.
*
* - Make the resource private: This grants read and write access to
@ -388,34 +362,29 @@ class ObjectStorage {
* container public will allow access to ALL objects inside of the
* container.
*
* To find out whether an existing container is public, you can
* To find out whether an existing container is public, you can
* write something like this:
*
* @code
* <?php
* // Get the container.
* $container = $objectStorage->container('my_container');
* <?php
* // Get the container.
* $container = $objectStorage->container('my_container');
*
* //Check the permission on the ACL:
* $boolean = $container->acl()->isPublic();
* ?>
* @endcode
* //Check the permission on the ACL:
* $boolean = $container->acl()->isPublic();
* ?>
*
* For details on ACLs, see OpenStack::Storage::ObjectStorage::ACL.
* For details on ACLs, see \OpenStack\Storage\ObjectStorage\ACL.
*
* @param string $name
* The name of the container.
* @param object $acl OpenStack::Storage::ObjectStorage::ACL
* An access control list object. By default, a container is
* non-public (private). To change this behavior, you can add a
* custom ACL. To make the container publically readable, you can
* use this: OpenStack::Storage::ObjectStorage::ACL::makePublic().
* @param array $metadata
* An associative array of metadata to attach to the container.
* @retval boolean
* @return boolean
* TRUE if the container was created, FALSE if the container was not
* created because it already exists.
* @param string $name The name of the container.
* @param object $acl \OpenStack\Storage\ObjectStorage\ACL An access control
* list object. By default, a container is non-public (private). To change
* this behavior, you can add a custom ACL. To make the container publically
* readable, you can use this: \OpenStack\Storage\ObjectStorage\ACL::makePublic().
* @param array $metadata An associative array of metadata to attach to the
* container.
*
* @return boolean TRUE if the container was created, FALSE if the container
* was not created because it already exists.
*/
public function createContainer($name, ACL $acl = NULL, $metadata = array()) {
$url = $this->url() . '/' . rawurlencode($name);
@ -471,14 +440,11 @@ class ObjectStorage {
* implementation, which uses the same HTTP verb to create a container
* and to set the ACL.)
*
* @param string $name
* The name of the container.
* @param object $acl OpenStack::Storage::ObjectStorage::ACL
* An ACL. To make the container publically readable, use
* ACL::makePublic().
* @retval boolean
* @return boolean
* TRUE if the cointainer was created, FALSE otherwise.
* @param string $name The name of the container.
* @param object $acl \OpenStack\Storage\ObjectStorage\ACL An ACL. To make the
* container publically readable, use ACL::makePublic().
*
* @return boolean TRUE if the cointainer was created, FALSE otherwise.
*/
public function changeContainerACL($name, ACL $acl) {
// Oddly, the way to change an ACL is to issue the
@ -493,18 +459,16 @@ class ObjectStorage {
* the object storage.
*
* The container MUST be empty before it can be deleted. If it is not,
* an OpenStack::Storage::ObjectStorage::ContainerNotEmptyException will
* an \OpenStack\Storage\ObjectStorage\ContainerNotEmptyException will
* be thrown.
*
* @param string $name
* The name of the container.
* @retval boolean
* @return boolean
* TRUE if the container was deleted, FALSE if the container was not
* found (and hence, was not deleted).
* @throws OpenStack::Storage::ObjectStorage::ContainerNotEmptyException
* @param string $name The name of the container.
*
* @return boolean TRUE if the container was deleted, FALSE if the container
* was not found (and hence, was not deleted).
* @throws \OpenStack\Storage\ObjectStorage\ContainerNotEmptyException
* if the container is not empty.
* @throws OpenStack::Exception if an unexpected response code is returned.
* @throws \OpenStack\Exception if an unexpected response code is returned.
* While this should never happen on OpenStack servers, forks of
* OpenStack may choose to extend object storage in a way that
* results in a non-standard code.
@ -545,14 +509,12 @@ class ObjectStorage {
* - The total bytes used by this Object Storage instance (`bytes`).
* - The number of containers (`count`).
*
* @retval array
* @return array
* An associative array of account info. Typical keys are:
* @return array An associative array of account info. Typical keys are:
* - bytes: Bytes consumed by existing content.
* - containers: Number of containers.
* - objects: Number of objects.
* @throws OpenStack::Transport::AuthorizationException
* if the user credentials are invalid or have expired.
* @throws \OpenStack\Transport\AuthorizationException if the user credentials
* are invalid or have expired.
*/
public function accountInfo() {
$url = $this->url();

View File

@ -15,8 +15,6 @@
limitations under the License.
============================================================================ */
/**
* @file
*
* Contains the class for manipulating ObjectStorage ACL strings.
*/
@ -25,7 +23,7 @@ namespace OpenStack\Storage\ObjectStorage;
/**
* Access control list for object storage.
*
* @b EXPERIMENTAL: This is bassed on a feature of Swift that is likely to
* EXPERIMENTAL: This is bassed on a feature of Swift that is likely to
* change. Most of this is based on undocmented features of the API
* discovered both in the Python docs and in discussions by various
* members of the OpenStack community.
@ -38,63 +36,56 @@ namespace OpenStack\Storage\ObjectStorage;
* In the current implementation of Swift, access can be assigned based
* on two different factors:
*
* - @b Accounts: Access can be granted to specific accounts, and within
* - Accounts: Access can be granted to specific accounts, and within
* those accounts, can be further specified to specific users. See the
* addAccount() method for details on this.
* - @b Referrers: Access can be granted based on host names or host name
* patterns. For example, only subdomains of <tt>*.example.com</tt> may be
* - Referrers: Access can be granted based on host names or host name
* patterns. For example, only subdomains of *.example.com may be
* granted READ access to a particular object.
*
* ACLs are transmitted within the HTTP headers for an object or
* container. Two headers are used: @c X-Container-Read for READ rules, and
* @c X-Container-Write for WRITE rules. Each header may have a chain of
* container. Two headers are used: `X-Container-Read` for READ rules, and
* `X-Container-Write` for WRITE rules. Each header may have a chain of
* rules.
*
* @b Examples
* Examples
*
* For most casual cases, only the static constructor functions are
* used. For example, an ACL that does not grant any public access can
* be created with a single call:
*
* @code
* <?php
* $acl = ACL::makeNonPublic();
* ?>
* @endcode
* <?php
* $acl = ACL::makeNonPublic();
* ?>
*
* Public read access is granted like this:
*
* @code
* <?php
* $acl = ACL::makePublic();
* ?>
* @endcode
* <?php
* $acl = ACL::makePublic();
* ?>
*
* (Note that in both cases, what is returned is an instance of an ACL with
* all of the necessary configuration done.)
*
* Sometimes you will need more sophisticated access control rules. The
* following grants READ access to anyone coming from an @c example.com
* domain, but grants WRITE access only to the account @c admins:
* following grants READ access to anyone coming from an `example.com`
* domain, but grants WRITE access only to the account `admins:`
*
* @code
* <?php
* $acl = new ACL();
* <?php
* $acl = new ACL();
*
* // Grant READ to example.com users.
* $acl->addReferrer(ACL::READ, '*.example.com');
* // Grant READ to example.com users.
* $acl->addReferrer(ACL::READ, '*.example.com');
*
* // Allow only people in the account 'admins' access to
* // write.
* $acl->addAccount(ACL::WRITE, 'admins');
* // Allow only people in the account 'admins' access to
* // write.
* $acl->addAccount(ACL::WRITE, 'admins');
*
* // Allow example.com users to view the container
* // listings:
* $acl->allowListings();
*
* ?>
* @endcode
* // Allow example.com users to view the container
* // listings:
* $acl->allowListings();
*
* ?>
*
* Notes
*
@ -105,7 +96,7 @@ namespace OpenStack\Storage\ObjectStorage;
* replaced by a new mechanism.
*
* For a detailed description of the rules for ACL creation,
* see http://swift.openstack.org/misc.html#acls
* @see http://swift.openstack.org/misc.html#acls
*/
class ACL {
@ -124,7 +115,7 @@ class ACL {
/**
* Flag for READ and WRITE.
*
* This is equivalent to <tt>ACL::READ | ACL::WRITE</tt>
* This is equivalent to `ACL::READ | ACL::WRITE`
*/
const READ_WRITE = 3; // self::READ | self::WRITE;
@ -146,9 +137,8 @@ class ACL {
*
* - READ to any host, with container listings.
*
* @retval OpenStack::Storage::ObjectStorage::ACL
* @return \OpenStack\Storage\ObjectStorage\ACL
* an ACL object with the appopriate permissions set.
* @return \OpenStack\Storage\ObjectStorage\ACL an ACL object with the
* appopriate permissions set.
*/
public static function makePublic() {
$acl = new ACL();
@ -167,9 +157,8 @@ class ACL {
* This does not grant any permissions. OpenStack interprets an object
* with no permissions as a private object.
*
* @retval OpenStack::Storage::ObjectStorage::ACL
* @return \OpenStack\Storage\ObjectStorage\ACL
* an ACL object with the appopriate permissions set.
* @return \OpenStack\Storage\ObjectStorage\ACL an ACL object with the
* appopriate permissions set.
*/
public static function makeNonPublic() {
// Default ACL is private.
@ -189,11 +178,9 @@ class ACL {
* This is a utility for processing headers and discovering any ACLs embedded
* inside the headers.
*
* @param array $headers
* An associative array of headers.
* @retval OpenStack::Storage::ObjectStorage::ACL
* @return \OpenStack\Storage\ObjectStorage\ACL
* A new ACL.
* @param array $headers An associative array of headers.
*
* @return \OpenStack\Storage\ObjectStorage\ACL A new ACL.
*/
public static function newFromHeaders($headers) {
$acl = new ACL();
@ -235,13 +222,10 @@ class ACL {
* This attempts to parse an ACL rule. It is not particularly
* fault-tolerant.
*
* @param int $perm
* The permission (ACL::READ, ACL::WRITE).
* @param string $rule
* The string rule to parse.
* @retval array
* @return array
* The rule as an array.
* @param int $perm The permission (ACL::READ, ACL::WRITE).
* @param string $rule The string rule to parse.
*
* @return array The rule as an array.
*/
public static function parseRule($perm, $rule) {
// This regular expression generates the following:
@ -304,24 +288,20 @@ class ACL {
*
* If $user is an array, every user in the array will be granted
* access under the provided account. That is, for each user in the
* array, an entry of the form \c account:user will be generated in the
* array, an entry of the form `account:user` will be generated in the
* final ACL.
*
* At this time there does not seem to be a way to grant global write
* access to an object.
*
* @param int $perm
* ACL::READ, ACL::WRITE or ACL::READ_WRITE (which is the same as
* ACL::READ|ACL::WRITE).
* @param string $account
* The name of the account.
* @param mixed $user
* The name of the user, or optionally an indexed array of user
* names.
* @param int $perm ACL::READ, ACL::WRITE or ACL::READ_WRITE (which is the
* same as ACL::READ|ACL::WRITE).
* @param string $account The name of the account.
* @param mixed $user The name of the user, or optionally an indexed array of
* user names.
*
* @retval OpenStack::Storage::ObjectStorage::ACL
* @return \OpenStack\Storage\ObjectStorage\ACL
* $this for current object so the method can be used in chaining.
* @return \OpenStack\Storage\ObjectStorage\ACL $this for current object so
* the method can be used in chaining.
*/
public function addAccount($perm, $account, $user = NULL) {
$rule = array('account' => $account);
@ -351,14 +331,12 @@ class ACL {
* Note that a simple minus sign ('-') is illegal, though it seems it
* should be "disallow all hosts."
*
* @param string $perm
* The permission being granted. One of ACL:READ, ACL::WRITE, or ACL::READ_WRITE.
* @param string $host
* A host specification string as described above.
* @param string $perm The permission being granted. One of ACL:READ,
* ACL::WRITE, or ACL::READ_WRITE.
* @param string $host A host specification string as described above.
*
* @retval OpenStack::Storage::ObjectStorage::ACL
* @return \OpenStack\Storage\ObjectStorage\ACL
* $this for current object so the method can be used in chaining.
* @return \OpenStack\Storage\ObjectStorage\ACL $this for current object so
* the method can be used in chaining.
*/
public function addReferrer($perm, $host = '*') {
$this->addRule($perm, array('host' => $host));
@ -369,14 +347,11 @@ class ACL {
/**
* Add a rule to the appropriate stack of rules.
*
* @param int $perm
* One of the predefined permission constants.
* @param array $rule
* A rule array.
*
* @retval OpenStack::Storage::ObjectStorage::ACL
* @return \OpenStack\Storage\ObjectStorage\ACL
* $this for current object so the method can be used in chaining.
* @param int $perm One of the predefined permission constants.
* @param array $rule A rule array.
*
* @return \OpenStack\Storage\ObjectStorage\ACL $this for current object so
* the method can be used in chaining.
*/
protected function addRule($perm, $rule) {
$rule['mask'] = $perm;
@ -397,9 +372,8 @@ class ACL {
* In the current Swift implementation, there is no mechanism for
* allowing some hosts to get listings, while denying others.
*
* @retval OpenStack::Storage::ObjectStorage::ACL
* @return \OpenStack\Storage\ObjectStorage\ACL
* $this for current object so the method can be used in chaining.
* @return \OpenStack\Storage\ObjectStorage\ACL $this for current object so
* the method can be used in chaining.
*/
public function allowListings() {
@ -414,9 +388,7 @@ class ACL {
/**
* Get the rules array for this ACL.
*
* @retval array
* @return array
* An array of associative arrays of rules.
* @return array An array of associative arrays of rules.
*/
public function rules() {
return $this->rules;
@ -427,6 +399,8 @@ class ACL {
*
* If this is called on an empty object, an empty set of headers is
* returned.
*
* @return array Array of headers
*/
public function headers() {
$headers = array();
@ -467,10 +441,8 @@ class ACL {
/**
* Convert a rule to a string.
*
* @param int $perm
* The permission for which to generate the rule.
* @param array $rule
* A rule array.
* @param int $perm The permission for which to generate the rule.
* @param array $rule A rule array.
*/
protected function ruleToString($perm, $rule) {
@ -519,10 +491,8 @@ class ACL {
* This returns TRUE only if this ACL does not grant any permissions
* at all.
*
* @retval boolean
* @return boolean
* TRUE if this is private (non-public), FALSE if
* any permissions are granted via this ACL.
* @return boolean TRUE if this is private (non-public), FALSE if any
* permissions are granted via this ACL.
*/
public function isNonPublic() {
return empty($this->rules);
@ -544,7 +514,9 @@ class ACL {
* This checks whether the object allows public reading,
* not whether it is ONLY allowing public reads.
*
* See ACL::makePublic().
* @see ACL::makePublic().
*
* @return boolean Whether or not the object allows public reading.
*/
public function isPublic() {
$allowsAllHosts = FALSE;
@ -563,14 +535,12 @@ class ACL {
}
/**
* Implements the magic __toString() PHP function.
* Implements the magic `__toString()` PHP function.
*
* This allows you to <tt>print $acl</tt> and get back
* This allows you to `print $acl` and get back
* a pretty string.
*
* @retval string
* @return string
* The ACL represented as a string.
* @return string The ACL represented as a string.
*/
public function __toString() {
$headers = $this->headers();
@ -583,4 +553,4 @@ class ACL {
return implode("\t", $buffer);
}
}
}

View File

@ -15,8 +15,6 @@
limitations under the License.
============================================================================ */
/**
* @file
*
* Contains the class for ObjectStorage Container objects.
*/
@ -37,28 +35,26 @@ namespace OpenStack\Storage\ObjectStorage;
* They are retrieved using ObjectStorage::container() or
* ObjectStorage::containers().
*
* @code
* <?php
* use \OpenStack\Storage\ObjectStorage;
* use \OpenStack\Storage\ObjectStorage\Container;
* use \OpenStack\Storage\ObjectStorage\Object;
* <?php
* use \OpenStack\Storage\ObjectStorage;
* use \OpenStack\Storage\ObjectStorage\Container;
* use \OpenStack\Storage\ObjectStorage\Object;
*
* // Create a new ObjectStorage instance, logging in with older Swift
* // credentials.
* $store = ObjectStorage::newFromSwiftAuth('user', 'key', 'http://example.com');
* // Create a new ObjectStorage instance, logging in with older Swift
* // credentials.
* $store = ObjectStorage::newFromSwiftAuth('user', 'key', 'http://example.com');
*
* // Get the container called 'foo'.
* $container = $store->container('foo');
* // Get the container called 'foo'.
* $container = $store->container('foo');
*
* // Create an object.
* $obj = new Object('bar.txt');
* $obj->setContent('Example content.', 'text/plain');
* // Create an object.
* $obj = new Object('bar.txt');
* $obj->setContent('Example content.', 'text/plain');
*
* // Save the new object in the container.
* $container->save($obj);
* // Save the new object in the container.
* $container->save($obj);
*
* ?>
* @endcode
* ?>
*
* Once you have a Container, you manipulate objects inside of the
* container.
@ -92,16 +88,13 @@ class Container implements \Countable, \IteratorAggregate {
*
* This is used when storing an object in a container.
*
* @param array $metadata
* An associative array of metadata. Metadata is not escaped in any
* way (there is no codified spec by which to escape), so make sure
* that keys are alphanumeric (dashes allowed) and values are
* @param array $metadata An associative array of metadata. Metadata is not
* escaped in any way (there is no codified spec by which to escape), so
* make sure that keys are alphanumeric (dashes allowed) and values are
* ASCII-armored with no newlines.
* @param string $prefix
* A prefix for the metadata headers.
* @retval array
* @return array
* An array of headers.
* @param string $prefix A prefix for the metadata headers.
*
* @return array An array of headers.
* @see http://docs.openstack.org/bexar/openstack-object-storage/developer/content/ch03s03.html#d5e635
* @see http://docs.openstack.org/bexar/openstack-object-storage/developer/content/ch03s03.html#d5e700
*/
@ -124,19 +117,15 @@ class Container implements \Countable, \IteratorAggregate {
* (namely slashes (`/`)) that are normally URLencoded when they appear
* inside of path sequences.
*
* @note
* Swift does not distinguish between @c %2F and a slash character, so
* Swift does not distinguish between `%2F` and a slash character, so
* this is not strictly necessary.
*
* @param string $base
* The base URL. This is not altered; it is just prepended to
* the returned string.
* @param string $oname
* The name of the object.
* @retval string
* @return string
* The URL to the object. Characters that need escaping will be escaped,
* while slash characters are not. Thus, the URL will look pathy.
* @param string $base The base URL. This is not altered; it is just prepended
* to the returned string.
* @param string $oname The name of the object.
*
* @return string The URL to the object. Characters that need escaping will be
* escaped, while slash characters are not. Thus, the URL will look pathy.
*/
public static function objectUrl($base, $oname) {
if (strpos($oname, '/') === FALSE) {
@ -152,7 +141,6 @@ class Container implements \Countable, \IteratorAggregate {
return $base . '/' . $newname;
}
/**
* Extract object attributes from HTTP headers.
*
@ -166,13 +154,10 @@ class Container implements \Countable, \IteratorAggregate {
* value data, so it is left up to implementors to choose their own
* strategy.
*
* @param array $headers
* An associative array of HTTP headers.
* @param string $prefix
* The prefix on metadata headers.
* @retval array
* @return array
* An associative array of name/value attribute pairs.
* @param array $headers An associative array of HTTP headers.
* @param string $prefix The prefix on metadata headers.
*
* @return array An associative array of name/value attribute pairs.
*/
public static function extractHeaderAttributes($headers, $prefix = NULL) {
if (empty($prefix)) {
@ -197,17 +182,13 @@ class Container implements \Countable, \IteratorAggregate {
* This is used in lieue of a standard constructor when
* fetching containers from ObjectStorage.
*
* @param array $jsonArray
* An associative array as returned by json_decode($foo, TRUE);
* @param string $token
* The auth token.
* @param string $url
* The base URL. The container name is automatically appended to
* this at construction time.
* @param array $jsonArray An associative array as returned by
* json_decode($foo, TRUE);
* @param string $token The auth token.
* @param string $url The base URL. The container name is automatically
* appended to this at construction time.
*
* @retval OpenStack::Storage::ObjectStorage::Comtainer
* @return \OpenStack\Storage\ObjectStorage\Container
* A new container object.
* @return \OpenStack\Storage\ObjectStorage\Container A new container object.
*/
public static function newFromJSON($jsonArray, $token, $url) {
$container = new Container($jsonArray['name']);
@ -240,18 +221,14 @@ class Container implements \Countable, \IteratorAggregate {
* cases, the standard constructor is preferred for client-size
* Container initialization.
*
* @param string $name
* The name of the container.
* @param object $response OpenStack::Transport::Response
* The HTTP response object from the Transporter layer
* @param string $token
* The auth token.
* @param string $url
* The base URL. The container name is automatically appended to
* this at construction time.
* @retval OpenStack::Storage::ObjectStorage::Container
* @return \OpenStack\Storage\ObjectStorage\Container
* The Container object, initialized and ready for use.
* @param string $name The name of the container.
* @param object $response \OpenStack\Transport\Response The HTTP response object from the Transporter layer
* @param string $token The auth token.
* @param string $url The base URL. The container name is automatically
* appended to this at construction time.
*
* @return \OpenStack\Storage\ObjectStorage\Container The Container object,
* initialized and ready for use.
*/
public static function newFromResponse($name, $response, $token, $url) {
$container = new Container($name);
@ -273,7 +250,6 @@ class Container implements \Countable, \IteratorAggregate {
/**
* Construct a new Container.
*
* @attention
* Typically a container should be created by ObjectStorage::createContainer().
* Get existing containers with ObjectStorage::container() or
* ObjectStorage::containers(). Using the constructor directly has some
@ -307,13 +283,9 @@ class Container implements \Countable, \IteratorAggregate {
* - When in doubt, use the ObjectStorage methods. That is always the safer
* option.
*
* @param string $name
* The name.
* @param string $url
* The full URL to the container.
* @param string $token
* The auth token.
*
* @param string $name The name.
* @param string $url The full URL to the container.
* @param string $token The auth token.
*/
public function __construct($name , $url = NULL, $token = NULL) {
$this->name = $name;
@ -324,9 +296,7 @@ class Container implements \Countable, \IteratorAggregate {
/**
* Get the name of this container.
*
* @retval string
* @return string
* The name of the container.
* @return string The name of the container.
*/
public function name() {
return $this->name;
@ -335,9 +305,7 @@ class Container implements \Countable, \IteratorAggregate {
/**
* Get the number of bytes in this container.
*
* @retval int
* @return int
* The number of bytes in this container.
* @return int The number of bytes in this container.
*/
public function bytes() {
if (is_null($this->bytes)) {
@ -361,9 +329,7 @@ class Container implements \Countable, \IteratorAggregate {
* listings do not supply the metadata, while loading a container
* directly does.
*
* @retval array
* @return array
* An array of metadata name/value pairs.
* @return array An array of metadata name/value pairs.
*/
public function metadata() {
@ -374,7 +340,6 @@ class Container implements \Countable, \IteratorAggregate {
return $this->metadata;
}
/**
* Set the tags on the container.
*
@ -393,9 +358,8 @@ class Container implements \Countable, \IteratorAggregate {
* more than 256. UTF-8 or ASCII characters are allowed, though ASCII
* seems to be preferred.
*
* @retval OpenStack::Storage::ObjectStorage::Container
* @return \OpenStack\Storage\ObjectStorage\Container
* $this so the method can be used in chaining.
* @return \OpenStack\Storage\ObjectStorage\Container $this so the method can
* be used in chaining.
*/
public function setMetadata($metadata) {
$this->metadata = $metadata;
@ -406,18 +370,14 @@ class Container implements \Countable, \IteratorAggregate {
/**
* Get the number of items in this container.
*
* Since Container implements Countable, the PHP builtin
* count() can be used on a Container instance:
* Since Container implements Countable, the PHP builtin count() can be used
* on a Container instance:
*
* @code
* <?php
* count($container) === $container->count();
* ?>
* @endcode
* <?php
* count($container) === $container->count();
* ?>
*
* @retval int
* @return int
* The number of items in this container.
* @return int The number of items in this container.
*/
public function count() {
if (is_null($this->count)) {
@ -429,28 +389,24 @@ class Container implements \Countable, \IteratorAggregate {
/**
* Save an Object into Object Storage.
*
* This takes an OpenStack::Storage::ObjectStorage::Object
* This takes an \OpenStack\Storage\ObjectStorage\Object
* and stores it in the given container in the present
* container on the remote object store.
*
* @param object $obj OpenStack::Storage::ObjectStorage::Object
* The object to store.
* @param resource $file
* An optional file argument that, if set, will be treated as the
* contents of the object.
* @retval boolean
* @return boolean
* TRUE if the object was saved.
* @throws OpenStack::Transport::LengthRequiredException
* if the Content-Length could not be determined and chunked
* encoding was not enabled. This should not occur for this class,
* which always automatically generates Content-Length headers.
* However, subclasses could generate this error.
* @throws OpenStack::Transport::UnprocessableEntityException
* if the checksome passed here does not match the checksum
* calculated remotely.
* @throws OpenStack::Exception when an unexpected (usually
* network-related) error condition arises.
* @param object $obj \OpenStack\Storage\ObjectStorage\Object The object to
* store.
* @param resource $file An optional file argument that, if set, will be
* treated as the contents of the object.
*
* @return boolean TRUE if the object was saved.
* @throws \OpenStack\Transport\LengthRequiredException if the Content-Length
* could not be determined and chunked encoding was not enabled. This should
* not occur for this class, which always automatically generates
* Content-Length headers. However, subclasses could generate this error.
* @throws \OpenStack\Transport\UnprocessableEntityException if the checksum
* passed here does not match the checksum calculated remotely.
* @throws \OpenStack\Exception when an unexpected (usually network-related)
* error condition arises.
*/
public function save(Object $obj, $file = NULL) {
@ -555,15 +511,12 @@ class Container implements \Countable, \IteratorAggregate {
* particularly in cases where custom headers have been set.
* Use with caution.
*
* @param object $obj OpenStack::Storage::ObjectStorage::Object
* The object to update.
* @param object $obj \OpenStack\Storage\ObjectStorage\Object The object to
* update.
*
* @retval boolean
* @return boolean
* TRUE if the metadata was updated.
*
* @throws OpenStack::Transport::FileNotFoundException
* if the object does not already exist on the object storage.
* @return boolean TRUE if the metadata was updated.
* @throws \OpenStack\Transport\FileNotFoundException if the object does not
* already exist on the object storage.
*/
public function updateMetadata(Object $obj) {
//$url = $this->url . '/' . rawurlencode($obj->name());
@ -605,20 +558,16 @@ class Container implements \Countable, \IteratorAggregate {
* Note that there is no MOVE operation. You must copy and then DELETE
* in order to achieve that.
*
* @param object $obj OpenStack::Storage::ObjectStorage::Object
* The object to copy. This object MUST already be saved on the
* remote server. The body of the object is not sent. Instead, the
* copy operation is performed on the remote server. You can, and
* probably should, use a RemoteObject here.
* @param string $newName
* The new name of this object. If you are copying across
* containers, the name can be the same. If you are copying within
* @param object $obj \OpenStack\Storage\ObjectStorage::Object The object to
* copy. This object MUST already be saved on the remote server. The body of
* the object is not sent. Instead, the copy operation is performed on the
* remote server. You can, and probably should, use a RemoteObject here.
* @param string $newName The new name of this object. If you are copying a
* cross containers, the name can be the same. If you are copying within
* the same container, though, you will need to supply a new name.
* @param string $container
* The name of the alternate container. If this is set, the object
* will be saved into this container. If this is not sent, the copy
* will be performed inside of the original container.
*
* @param string $container The name of the alternate container. If this is
* set, the object will be saved into this container. If this is not sent,
* the copy will be performed inside of the original container.
*/
public function copy(Object $obj, $newName, $container = NULL) {
//$sourceUrl = $obj->url(); // This doesn't work with Object; only with RemoteObject.
@ -655,11 +604,11 @@ class Container implements \Countable, \IteratorAggregate {
* This fetches a single object with the given name. It downloads the
* entire object at once. This is useful if the object is small (under
* a few megabytes) and the content of the object will be used. For
* example, this is the right operation for accessing a text file
* example, this is the right operation for accessing a text file
* whose contents will be processed.
*
* For larger files or files whose content may never be accessed, use
* remoteObject(), which delays loading the content until one of its
* For larger files or files whose content may never be accessed, use
* remoteObject(), which delays loading the content until one of its
* content methods (e.g. RemoteObject::content()) is called.
*
* This does not yet support the following features of Swift:
@ -668,11 +617,10 @@ class Container implements \Countable, \IteratorAggregate {
* - If-Modified-Since/If-Unmodified-Since
* - If-Match/If-None-Match
*
* @param string $name
* The name of the object to load.
* @retval OpenStack::Storage::ObjectStorage::RemoteObject
* @return \OpenStack\Storage\ObjectStorage\RemoteObject
* A remote object with the content already stored locally.
* @param string $name The name of the object to load.
*
* @return \OpenStack\Storage\ObjectStorage\RemoteObject A remote object with
* the content already stored locally.
*/
public function object($name) {
@ -720,11 +668,10 @@ class Container implements \Countable, \IteratorAggregate {
* though, that calling RemoteObject::content() will initiate another
* network operation.
*
* @param string $name
* The name of the object to fetch.
* @retval OpenStack::Storage::ObjectStorage::RemoteObject
* @return \OpenStack\Storage\ObjectStorage\RemoteObject
* A remote object ready for use.
* @param string $name The name of the object to fetch.
*
* @return \OpenStack\Storage\ObjectStorage\RemoteObject A remote object ready
* for use.
*/
public function proxyObject($name) {
$url = self::objectUrl($this->url, $name);
@ -749,6 +696,7 @@ class Container implements \Countable, \IteratorAggregate {
}
/**
* This has been replaced with proxyObject().
*
* @deprecated
*/
public function remoteObject($name) {
@ -758,10 +706,9 @@ class Container implements \Countable, \IteratorAggregate {
/**
* Get a list of objects in this container.
*
* This will return a list of objects in the container. With no
* parameters, it will attempt to return a listing of <i>all</i>
* objects in the container. However, by setting contraints, you can
* retrieve only a specific subset of objects.
* This will return a list of objects in the container. With no parameters, it
* will attempt to return a listing of all objects in the container. However,
* by setting contraints, you can retrieve only a specific subset of objects.
*
* Note that OpenStacks Swift will return no more than 10,000 objects
* per request. When dealing with large datasets, you are encouraged
@ -776,15 +723,12 @@ class Container implements \Countable, \IteratorAggregate {
* will begin with the next item after the marker (assuming the marker
* is found.)
*
* @param int $limit
* An integer indicating the maximum number of items to return. This
* cannot be greater than the Swift maximum (10k).
* @param string $marker
* The name of the object to start with. The query will begin with
* the next object AFTER this one.
* @retval array
* @return array
* List of RemoteObject or Subdir instances.
* @param int $limit An integer indicating the maximum number of items to
* return. This cannot be greater than the Swift maximum (10k).
* @param string $marker The name of the object to start with. The query will
* begin with the next object AFTER this one.
*
* @return array List of RemoteObject or Subdir instances.
*/
public function objects($limit = NULL, $marker = NULL) {
$params = array();
@ -834,19 +778,15 @@ class Container implements \Countable, \IteratorAggregate {
* delimiters other than '/', you need to be very consistent with your
* usage or else you may get surprising results.
*
* @param string $prefix
* The leading prefix.
* @param string $delimiter
* The character used to delimit names. By default, this is '/'.
* @param int $limit
* An integer indicating the maximum number of items to return. This
* cannot be greater than the Swift maximum (10k).
* @param string $marker
* The name of the object to start with. The query will begin with
* the next object AFTER this one.
* @retval array
* @return array
* List of RemoteObject or Subdir instances.
* @param string $prefix The leading prefix.
* @param string $delimiter The character used to delimit names. By default,
* this is '/'.
* @param int $limit An integer indicating the maximum number of items to
* return. This cannot be greater than the Swift maximum (10k).
* @param string $marker The name of the object to start with. The query will
* begin with the next object AFTER this one.
*
* @return array List of RemoteObject or Subdir instances.
*/
public function objectsWithPrefix($prefix, $delimiter = '/', $limit = NULL, $marker = NULL) {
$params = array(
@ -867,12 +807,10 @@ class Container implements \Countable, \IteratorAggregate {
* directory-like. You create it exactly as you create any other file.
* Typically, it is 0 bytes long.
*
* @code
* <?php
* $dir = new Object('a/b/c', '');
* $container->save($dir);
* ?>
* @endcode
* <?php
* $dir = new Object('a/b/c', '');
* $container->save($dir);
* ?>
*
* Using objectsByPath() with directory markers will return a list of
* Object instances, some of which are regular files, and some of
@ -884,16 +822,13 @@ class Container implements \Countable, \IteratorAggregate {
* method was legacy. More recent versions of the documentation no
* longer indicate this.
*
* @param string $path
* The path prefix.
* @param string $delimiter
* The character used to delimit names. By default, this is '/'.
* @param int $limit
* An integer indicating the maximum number of items to return. This
* cannot be greater than the Swift maximum (10k).
* @param string $marker
* The name of the object to start with. The query will begin with
* the next object AFTER this one.
* @param string $path The path prefix.
* @param string $delimiter The character used to delimit names. By default,
* this is '/'.
* @param int $limit An integer indicating the maximum number of items to
* return. This cannot be greater than the Swift maximum (10k).
* @param string $marker The name of the object to start with. The query will
* begin with the next object AFTER this one.
*/
public function objectsByPath($path, $delimiter = '/', $limit = NULL, $marker = NULL) {
$params = array(
@ -907,12 +842,10 @@ class Container implements \Countable, \IteratorAggregate {
* Get the URL to this container.
*
* Any container that has been created will have a valid URL. If the
* Container was set to be public (See
* Container was set to be public (See
* ObjectStorage::createContainer()) will be accessible by this URL.
*
* @retval string
* @return string
* The URL.
* @return string The URL.
*/
public function url() {
return $this->url;
@ -932,9 +865,9 @@ class Container implements \Countable, \IteratorAggregate {
* ObjectStorage methods.
*
* @todo Determine how to get the ACL from JSON data.
* @retval \OpenStack\Storage\ObjectStorage\ACL
* @return OpenStack::Storage::ObjectStorage::ACL
* An ACL, or NULL if the ACL could not be retrieved.
*
* @return \OpenStack\Storage\ObjectStorage\ACL An ACL, or NULL if the ACL
* could not be retrieved.
*/
public function acl() {
if (!isset($this->acl)) {
@ -949,7 +882,6 @@ class Container implements \Countable, \IteratorAggregate {
* Not all containers come fully instantiated. This method is sometimes
* called to "fill in" missing fields.
*
* @retval OpenStack::Storage::ObjectStorage::Comtainer
* @return \OpenStack\Storage\ObjectStorage\Container
*/
protected function loadExtraData() {
@ -1039,26 +971,23 @@ class Container implements \Countable, \IteratorAggregate {
/**
* Return the iterator of contents.
*
* A Container is Iterable. This means that you can use a container in
* A Container is Iterable. This means that you can use a container in
* a `foreach` loop directly:
*
* @code
* <?php
* foreach ($container as $object) {
* print $object->name();
* }
* ?>
* @endcode
* <?php
* foreach ($container as $object) {
* print $object->name();
* }
* ?>
*
* The above is equivalent to doing the following:
* @code
* <?php
* $objects = $container->objects();
* foreach ($objects as $object) {
* print $object->name();
* }
* ?>
* @endcode
*
* <?php
* $objects = $container->objects();
* foreach ($objects as $object) {
* print $object->name();
* }
* ?>
*
* Note that there is no way to pass any constraints into an iterator.
* You cannot limit the number of items, set an marker, or add a
@ -1071,11 +1000,10 @@ class Container implements \Countable, \IteratorAggregate {
/**
* Remove the named object from storage.
*
* @param string $name
* The name of the object to remove.
* @retval boolean
* @return boolean
* TRUE if the file was deleted, FALSE if no such file is found.
* @param string $name The name of the object to remove.
*
* @return boolean TRUE if the file was deleted, FALSE if no such file is
* found.
*/
public function delete($name) {
$url = self::objectUrl($this->url, $name);

View File

@ -15,8 +15,6 @@
limitations under the License.
============================================================================ */
/**
* @file
*
* Contains exception class for ContainerNotEmptyException.
*/

View File

@ -15,8 +15,6 @@
limitations under the License.
============================================================================ */
/**
* @file
*
* Contains the ContentVerificationException object.
*/
namespace OpenStack\Storage\ObjectStorage;
@ -27,6 +25,5 @@ namespace OpenStack\Storage\ObjectStorage;
* This occurs when the server sends content whose value does
* not match the supplied checksum. See
* RemoteObject::setContentVerification().
*
*/
class ContentVerificationException extends \OpenStack\Exception {}

View File

@ -15,7 +15,6 @@
limitations under the License.
============================================================================ */
/**
* @file
* Contains the class Object for ObjectStorage.
*/
@ -40,7 +39,7 @@ namespace OpenStack\Storage\ObjectStorage;
* - Metadata: File attributes that are stored along with the file on
* object store.
*
* Objects are stored and retrieved <i>by name</i>. So it is assumed
* Objects are stored and retrieved by name. So it is assumed
* that, per container, no more than one file with a given name exists.
*
* You may create Object instance and then store them in Containers.
@ -66,6 +65,7 @@ class Object {
* as they may prefer filesystem backing.
*/
protected $content;
/**
* The content type.
*
@ -73,6 +73,7 @@ class Object {
* a generic byte stream.
*/
protected $contentType = self::DEFAULT_CONTENT_TYPE;
/**
* Associative array of stored metadata.
*/
@ -86,18 +87,14 @@ class Object {
*/
protected $additionalHeaders = array();
/**
* Construct a new object for storage.
*
* @param string $name
* A name (may be pathlike) for the object.
* @param string $content
* Optional content to store in this object. This is the same
* as calling setContent().
* @param string $type
* Optional content type for this content. This is the same as
* calling setContentType().
* @param string $name A name (may be pathlike) for the object.
* @param string $content Optional content to store in this object. This is
* the same as calling setContent().
* @param string $type Optional content type for this content. This is the
* same as calling setContentType().
*/
public function __construct($name, $content = NULL, $type = NULL) {
$this->name = $name;
@ -140,16 +137,14 @@ class Object {
* names so that the name is always given an initial capital leter.
* That is, `foo` becomes `Foo`.
*
* @param array $array
* An associative array of metadata names to values.
* @param array $array An associative array of metadata names to values.
*
* @retval OpenStack::Storage::ObjectStorage::Object
* @return \OpenStack\Storage\ObjectStorage\Object
* $this so the method can be used in chaining.
* @return \OpenStack\Storage\ObjectStorage\Object $this so the method can be
* used in chaining.
*/
public function setMetadata(array $array) {
$this->metadata = $array;
return $this;
}
@ -158,9 +153,7 @@ class Object {
*
* This returns an associative array of all metadata for this object.
*
* @retval array
* @return array
* An associative array of metadata. This may be empty.
* @return array An associative array of metadata. This may be empty.
*/
public function metadata() {
return $this->metadata;
@ -169,20 +162,18 @@ class Object {
/**
* Override (change) the name of an object.
*
* Note that this changes only the <i>local copy</i> of an object. It
* Note that this changes only the local copy of an object. It
* does not rename the remote copy. In fact, changing the local name
* and then saving it will result in a new object being created in the
* object store.
*
* To copy an object, see
* OpenStack::Storage::ObjectStorage::Container::copyObject().
* To copy an object:
* @see \OpenStack\Storage\ObjectStorage\Container::copyObject().
*
* @param string $name
* A file or object name.
* @param string $name A file or object name.
*
* @retval OpenStack::Storage::ObjectStorage::Object
* @return \OpenStack\Storage\ObjectStorage\Object
* $this so the method can be used in chaining.
* @return \OpenStack\Storage\ObjectStorage\Object $this so the method can be
* used in chaining.
*/
public function setName($name) {
$this->name = $name;
@ -195,9 +186,7 @@ class Object {
* Returns the name of an object. If the name has been overwritten
* using setName(), this will return the latest (overwritten) name.
*
* @retval string
* @return string
* The name of the object.
* @return string The name of the object.
*/
public function name() {
return $this->name;
@ -216,23 +205,19 @@ class Object {
* All HTTP type options are allowed. So, for example, you can add a
* charset to a text type:
*
* @code
* <?php
* $o = new Object('my.html');
* $o->setContentType('text/html; charset=iso-8859-13');
* ?>
* @endcode
* <?php
* $o = new Object('my.html');
* $o->setContentType('text/html; charset=iso-8859-13');
* ?>
*
* Content type is not parsed or verified locally (though it is
* remotely). It can be dangerous, too, to allow users to specify a
* content type.
*
* @param string $type
* A valid content type.
* @param string $type A valid content type.
*
* @retval OpenStack::Storage::ObjectStorage::Object
* @return \OpenStack\Storage\ObjectStorage\Object
* $this so the method can be used in chaining.
* @return \OpenStack\Storage\ObjectStorage\Object $this so the method can be
* used in chaining.
*/
public function setContentType($type) {
$this->contentType = $type;
@ -244,9 +229,7 @@ class Object {
*
* This returns the currently set content type.
*
* @retval string
* @return string
* The content type, including any additional options.
* @return string The content type, including any additional options.
*/
public function contentType() {
return $this->contentType;
@ -255,10 +238,10 @@ class Object {
/**
* Set the content for this object.
*
* Place the content into the object. Typically, this is string
* Place the content into the object. Typically, this is string
* content that will be stored remotely.
*
* PHP's string is backed by a robust system that can accomodate
* PHP's string is backed by a robust system that can accomodate
* moderately sized files. However, it is best to keep strings short
* (<2MB, for example -- test for your own system's sweet spot).
* Larger data may be better handled with file system entries or
@ -267,15 +250,12 @@ class Object {
* Note that the OpenStack will not allow files larger than 5G, and
* PHP will likely croak well before that marker. So use discretion.
*
* @param string $content
* The content of the object.
* @param string $type
* The content type (MIME type). This can be set here for
* @param string $content The content of the object.
* @param string $type The content type (MIME type). This can be set here for
* convenience, or you can call setContentType() directly.
*
* @retval OpenStack::Storage::ObjectStorage::Object
* @return \OpenStack\Storage\ObjectStorage\Object
* $this so the method can be used in chaining.
* @return \OpenStack\Storage\ObjectStorage\Object $this so the method can be
* used in chaining.
*/
public function setContent($content, $type = NULL) {
$this->content = $content;
@ -303,9 +283,7 @@ class Object {
* When extending this class, you should make sure that this function
* returns the entire contents of an object.
*
* @retval string
* @return string
* The content of the file.
* @return string The content of the file.
*/
public function content() {
return $this->content;
@ -314,7 +292,7 @@ class Object {
/**
* Calculate the content length.
*
* This returns the number of <i>bytes</i> in a piece of content (not
* This returns the number of bytes in a piece of content (not
* the number of characters). Among other things, it is used to let
* the remote object store know how big of an object to expect when
* transmitting data.
@ -322,9 +300,7 @@ class Object {
* When extending this class, you should make sure to calculate the
* content length appropriately.
*
* @retval int
* @return int
* The length of the content, in bytes.
* @return int The length of the content, in bytes.
*/
public function contentLength() {
// strlen() is binary safe (or at least it seems to be).
@ -340,9 +316,7 @@ class Object {
* When extending this class, generate an ETag by creating an MD5 of
* the entire object's content (but not the metadata or name).
*
* @retval string
* @return string
* An MD5 value as a string of 32 hex digits (0-9a-f).
* @return string An MD5 value as a string of 32 hex digits (0-9a-f).
*/
public function eTag() {
return md5($this->content);
@ -364,12 +338,10 @@ class Object {
* to "gzip". This allows many user agents to receive the compressed
* data and automatically decompress them and display them correctly.
*
* @param string $encoding
* A valid encoding type.
* @param string $encoding A valid encoding type.
*
* @retval OpenStack::Storage::ObjectStorage::Object
* @return \OpenStack\Storage\ObjectStorage\Object
* $this so the method can be used in chaining.
* @return \OpenStack\Storage\ObjectStorage\Object $this so the method can be
* used in chaining.
*/
public function setEncoding($encoding) {
$this->contentEncoding = $encoding;
@ -383,9 +355,7 @@ class Object {
* Encoding is used to indicate how a file was encoded or compressed.
* See setEncoding() for more information.
*
* @retval string
* @return string
* The encoding type.
* @return string The encoding type.
*/
public function encoding() {
return $this->contentEncoding;
@ -399,22 +369,19 @@ class Object {
* a display.
*
* The typical value for this is:
* @code
* <?php
* $object->setDisposition('attachment; filename=foo.png');
* ?>
* @endcode
*
* <?php
* $object->setDisposition('attachment; filename=foo.png');
* ?>
*
* A disposition string should not include any newline characters or
* binary data.
*
* @param string $disposition
* A valid disposition declaration. These are defined in various
* HTTP specifications.
* @param string $disposition A valid disposition declaration. These are
* defined in various HTTP specifications.
*
* @retval OpenStack::Storage::ObjectStorage::Object
* @return \OpenStack\Storage\ObjectStorage\Object
* $this so the method can be used in chaining.
* @return \OpenStack\Storage\ObjectStorage\Object $this so the method can be
* used in chaining.
*/
public function setDisposition($disposition) {
$this->contentDisposition = $disposition;
@ -427,9 +394,7 @@ class Object {
*
* See setDisposition() for discussion.
*
* @retval string
* @return string
* The disposition string, or NULL if none is set.
* @return string The disposition string, or NULL if none is set.
*/
public function disposition() {
return $this->contentDisposition;
@ -438,8 +403,8 @@ class Object {
/**
* Set additional headers for storage.
*
* @attention EXPERT: You will need to understand OpenStack
* internals to use this effectively.
* EXPERT: You will need to understand OpenStack internals to use this
* effectively.
*
* Headers set here will be added to the HTTP request during save
* operations. They are not merged into existing headers until
@ -464,14 +429,12 @@ class Object {
* checking. You must ensure that the headers are in the proper
* format.
*
* @param array $headers
* An associative array where each name is an HTTP header name, and
* each value is the HTTP header value. No encoding or escaping is
* done.
* @param array $headers An associative array where each name is an HTTP
* header name, and each value is the HTTP header value. No encoding or
* escaping is done.
*
* @retval OpenStack::Storage::ObjectStorage::Object
* @return \OpenStack\Storage\ObjectStorage\Object
* $this so the method can be used in chaining.
* @return \OpenStack\Storage\ObjectStorage\Object $this so the method can be
* used in chaining.
*/
public function setAdditionalHeaders($headers) {
$this->additionalHeaders = $headers;
@ -496,17 +459,14 @@ class Object {
* by setAdditionalHeaders() are removed from an Object.
* (RemoteObject works differently).
*
* @attention
* Many headers are generated automatically, such as
* Content-Type and Content-Length. Removing these
* will simply result in their being regenerated.
* Many headers are generated automatically, such as
* Content-Type and Content-Length. Removing these
* will simply result in their being regenerated.
*
* @param array $keys
* The header names to be removed.
* @param array $keys The header names to be removed.
*
* @retval OpenStack::Storage::ObjectStorage::Object
* @return \OpenStack\Storage\ObjectStorage\Object
* $this for the current object so it can be used in chaining methods.
* @return \OpenStack\Storage\ObjectStorage\Object $this for the current
* object so it can be used in chaining methods.
*/
public function removeHeaders($keys) {
foreach ($keys as $k) {
@ -525,16 +485,14 @@ class Object {
* This should be used when (a) the file size is large, or (b) the
* exact size of the file is unknown.
*
* If this returns TRUE, it does not <i>guarantee</i> that the data
* If this returns TRUE, it does not guarantee that the data
* will be transmitted in chunks. But it recommends that the
* underlying transport layer use chunked encoding.
*
* The contentLength() method is not called for chunked transfers. So
* if this returns TRUE, contentLength() is ignored.
*
* @retval boolean
* @return boolean
* TRUE to recommend chunked transfer, FALSE otherwise.
* @return boolean TRUE to recommend chunked transfer, FALSE otherwise.
*/
public function isChunked() {
// Currently, this value is hard-coded. The default Object

View File

@ -14,9 +14,7 @@
See the License for the specific language governing permissions and
limitations under the License.
============================================================================ */
/**
* @file
*/
namespace OpenStack\Storage\ObjectStorage;
/**
* Thrown if an object that is read only is modified.

View File

@ -15,8 +15,6 @@
limitations under the License.
============================================================================ */
/**
* @file
*
* Contains the RemoteObject class.
*/
@ -27,7 +25,7 @@ namespace OpenStack\Storage\ObjectStorage;
*
* A remote object is one whose canonical copy is stored in a remote
* object storage. It represents a local (and possibly partial) copy of
* an object. (Contrast this with OpenStack::Storage::ObjectStorage::Object)
* an object. (Contrast this with \OpenStack\Storage\ObjectStorage\Object)
*
* Depending on how the object was constructed, it may or may not have a
* local copy of the entire contents of the file. It may only have the
@ -37,8 +35,8 @@ namespace OpenStack\Storage\ObjectStorage;
*
* Remote objects can be modified locally. Simply modifying an object
* will not result in those modifications being stored on the remote
* server. The object must be saved (see
* OpenStack::Storage::ObjectStorage::Container::save()). When an
* server. The object must be saved (see
* \OpenStack\Storage\ObjectStorage\Container::save()). When an
* object is modified so that its local contents differ from the remote
* stored copy, it is marked dirty (see isDirty()).
*/
@ -65,12 +63,9 @@ class RemoteObject extends Object {
/**
* Create a new RemoteObject from JSON data.
*
* @param array $data
* The JSON data as an array.
* @param string $token
* The authentication token.
* @param $url
* The URL to the object on the remote server
* @param array $data The JSON data as an array.
* @param string $token The authentication token.
* @param $url The URL to the object on the remote server
*/
public static function newFromJSON($data, $token, $url) {
@ -96,20 +91,15 @@ class RemoteObject extends Object {
* This is used to create objects from GET and HEAD requests, which
* return all of the metadata inside of the headers.
*
* @param string $name
* The name of the object.
* @param array $headers
* An associative array of HTTP headers in the exact format
* documented by OpenStack's API docs.
* @param string $token
* The current auth token (used for issuing subsequent requests).
* @param string $url
* The URL to the object in the object storage. Used for issuing
* subsequent requests.
* @param string $name The name of the object.
* @param array $headers An associative array of HTTP headers in the exact
* format documented by OpenStack's API docs.
* @param string $token The current auth token (used for issuing subsequent
* requests).
* @param string $url The URL to the object in the object storage. Used for
* issuing subsequent requests.
*
* @retval OpenStack::Storage::ObjectStorage::RemoteObject
* @return \OpenStack\Storage\ObjectStorage\RemoteObject
* A new RemoteObject.
* @return \OpenStack\Storage\ObjectStorage\RemoteObject A new RemoteObject.
*/
public static function newFromHeaders($name, $headers, $token, $url) {
$object = new RemoteObject($name);
@ -155,7 +145,6 @@ class RemoteObject extends Object {
* If this object has been stored remotely, it will have
* a valid URL.
*
* @retval string
* @return string
* A URL to the object. The following considerations apply:
* - If the container is public, this URL can be loaded without
@ -203,9 +192,8 @@ class RemoteObject extends Object {
/**
* Set the headers
*
* @retval OpenStack::Storage::ObjectStorage::RemoteObject
* @return \OpenStack\Storage\ObjectStorage\RemoteObject
* $this for the current object so it can be used in chaining methods.
* @return \OpenStack\Storage\ObjectStorage\RemoteObject $this for the current
* object so it can be used in chaining methods.
*/
public function setHeaders($headers) {
$this->allHeaders = array();
@ -222,14 +210,12 @@ class RemoteObject extends Object {
/**
* Get the HTTP headers sent by the server.
*
* @attention EXPERT.
* EXPERT.
*
* This returns the array of minimally processed HTTP headers that
* were sent from the server.
*
* @retval array
* @return array
* An associative array of header names and values.
* @return array An associative array of header names and values.
*/
public function headers() {
return $this->allHeaders;
@ -252,7 +238,7 @@ class RemoteObject extends Object {
}
protected $reservedHeaders = array(
'etag' => TRUE, 'content-length' => TRUE,
'etag' => TRUE, 'content-length' => TRUE,
'x-auth-token' => TRUE,
'transfer-encoding' => TRUE,
'x-trans-id' => TRUE,
@ -261,9 +247,8 @@ class RemoteObject extends Object {
/**
* Filter the headers.
*
* @retval OpenStack::Storage::ObjectStorage::RemoteObject
* @return \OpenStack\Storage\ObjectStorage\RemoteObject
* $this for the current object so it can be used in chaining methods.
* @return \OpenStack\Storage\ObjectStorage\RemoteObject $this for the current
* object so it can be used in chaining methods.
*/
public function filterHeaders(&$headers) {
$unset = array();
@ -290,17 +275,14 @@ class RemoteObject extends Object {
* Note that you cannot remove metadata through this mechanism,
* as it is managed using the metadata() methods.
*
* @attention
* Many headers are generated automatically, such as
* Content-Type and Content-Length. Removing these
* will simply result in their being regenerated.
* Many headers are generated automatically, such as
* Content-Type and Content-Length. Removing these
* will simply result in their being regenerated.
*
* @param array $keys
* The header names to be removed.
* @param array $keys The header names to be removed.
*
* @retval OpenStack::Storage::ObjectStorage::RemoteObject
* @return \OpenStack\Storage\ObjectStorage\RemoteObject
* $this for the current object so it can be used in chaining methods.
* @return \OpenStack\Storage\ObjectStorage\RemoteObject $this for the current
* object so it can be used in chaining methods.
*/
public function removeHeaders($keys) {
foreach ($keys as $key) {
@ -326,15 +308,11 @@ class RemoteObject extends Object {
*
* Be wary of using this method with large files.
*
* @retval string
* @return string
* The contents of the file as a string.
* @throws \OpenStack\Transport\FileNotFoundException
* when the requested content cannot be located on the remote
* server.
* @throws \OpenStack\Exception
* when an unknown exception (usually an abnormal network condition)
* occurs.
* @return string The contents of the file as a string.
* @throws \OpenStack\Transport\FileNotFoundException when the requested
* content cannot be located on the remote server.
* @throws \OpenStack\Exception when an unknown exception (usually an abnormal
* network condition) occurs.
*/
public function content() {
@ -389,14 +367,12 @@ class RemoteObject extends Object {
*
* The stream is read-only.
*
* @param boolean $refresh
* If this is set to TRUE, any existing local modifications will be ignored
* and the content will be refreshed from the server. Any
* local changes to the object will be discarded.
* @retval resource
* @return resource
* A handle to the stream, which is already opened and positioned at
* the beginning of the stream.
* @param boolean $refresh If this is set to TRUE, any existing local
* modifications will be ignored and the content will be refreshed from the
* server. Any local changes to the object will be discarded.
*
* @return resource A handle to the stream, which is already opened and
* positioned at the beginning of the stream.
*/
public function stream($refresh = FALSE) {
@ -443,13 +419,11 @@ class RemoteObject extends Object {
* existing cached content will not be removed if caching is turned
* off.
*
* @param boolean $enabled
* If this is TRUE, caching will be enabled. If this is FALSE,
* caching will be disabled.
* @param boolean $enabled If this is TRUE, caching will be enabled. If this
* is FALSE, caching will be disabled.
*
* @retval OpenStack::Storage::ObjectStorage::RemoteObject
* @return \OpenStack\Storage\ObjectStorage\RemoteObject
* $this so the method can be used in chaining.
* @return \OpenStack\Storage\ObjectStorage\RemoteObject $this so the method
* can be used in chaining.
*/
public function setCaching($enabled) {
$this->caching = $enabled;
@ -459,12 +433,10 @@ class RemoteObject extends Object {
/**
* Indicates whether this object caches content.
*
* Importantly, this indicates whether the object <i>will</i> cache
* Importantly, this indicates whether the object will cache
* its contents, not whether anything is actually cached.
*
* @retval boolean
* @return boolean
* TRUE if caching is enabled, FALSE otherwise.
* @return boolean TRUE if caching is enabled, FALSE otherwise.
*/
public function isCaching() {
return $this->caching;
@ -488,14 +460,12 @@ class RemoteObject extends Object {
* also provide a small performance improvement on large files, but at
* the expense of security.
*
* @param boolean $enabled
* If this is TRUE, content verification is performed. The content
* is hashed and checked against a server-supplied MD5 hashcode. If
* this is FALSE, no checking is done.
* @param boolean $enabled If this is TRUE, content verification is performed.
* The content is hashed and checked against a server-supplied MD5 hashcode.
* If this is FALSE, no checking is done.
*
* @retval OpenStack::Storage::ObjectStorage::RemoteObject
* @return \OpenStack\Storage\ObjectStorage\RemoteObject
* $this so the method can be used in chaining.
* @return \OpenStack\Storage\ObjectStorage\RemoteObject $this so the method
* can be used in chaining.
*/
public function setContentVerification($enabled) {
$this->contentVerification = $enabled;
@ -510,9 +480,7 @@ class RemoteObject extends Object {
* returned by the remote server, and comparing that to the server's
* supplied ETag hash.
*
* @retval boolean
* @return boolean
* TRUE if this is verifying, FALSE otherwise.
* @return boolean TRUE if this is verifying, FALSE otherwise.
*/
public function isVerifyingContent() {
return $this->contentVerification;
@ -539,6 +507,8 @@ class RemoteObject extends Object {
* written to the remote server when desired.
*
* To replace dirty content with a clean copy, see refresh().
*
* @return boolean Whether or not there are unsaved changes.
*/
public function isDirty() {
@ -566,12 +536,11 @@ class RemoteObject extends Object {
* WARNING: This will destroy any unsaved local changes. You can use
* isDirty() to determine whether or not a local change has been made.
*
* @param boolean $fetchContent
* If this is TRUE, the content will be downloaded as well.
* @param boolean $fetchContent If this is TRUE, the content will be
* downloaded as well.
*
* @retval OpenStack::Storage::ObjectStorage::RemoteObject
* @return \OpenStack\Storage\ObjectStorage\RemoteObject
* $this for the current object so it can be used in chaining methods.
* @return \OpenStack\Storage\ObjectStorage\RemoteObject $this for the current
* object so it can be used in chaining methods.
*/
public function refresh($fetchContent = FALSE) {
@ -591,15 +560,13 @@ class RemoteObject extends Object {
/**
* Helper function for fetching an object.
*
* @param boolean $fetchContent
* If this is set to TRUE, a GET request will be issued, which will
* cause the remote host to return the object in the response body.
* The response body is not handled, though. If this is set to
* FALSE, a HEAD request is sent, and no body is returned.
* @retval OpenStack::Transport::Response
* @return \OpenStack\Transport\Response
* containing the object metadata and (depending on the
* $fetchContent flag) optionally the data.
* @param boolean $fetchContent If this is set to TRUE, a GET request will be
* issued, which will cause the remote host to return the object in the
* response body. The response body is not handled, though. If this is set
* to FALSE, a HEAD request is sent, and no body is returned.
*
* @return \OpenStack\Transport\Response containing the object metadata and
* (depending on the $fetchContent flag) optionally the data.
*/
protected function fetchObject($fetchContent = FALSE) {
$method = $fetchContent ? 'GET' : 'HEAD';
@ -625,9 +592,8 @@ class RemoteObject extends Object {
*
* This is used internally to set object properties from headers.
*
* @retval OpenStack::Storage::ObjectStorage::RemoteObject
* @return \OpenStack\Storage\ObjectStorage\RemoteObject
* $this for the current object so it can be used in chaining methods.
* @return \OpenStack\Storage\ObjectStorage\RemoteObject $this for the current
* object so it can be used in chaining methods.
*/
protected function extractFromHeaders($response) {
$this->setContentType($response->header('Content-Type', $this->contentType()));
@ -642,6 +608,5 @@ class RemoteObject extends Object {
$this->setMetadata(Container::extractHeaderAttributes($response->headers()));
return $this;
}
}

View File

@ -15,7 +15,6 @@
limitations under the License.
============================================================================ */
/**
* @file
* Contains the stream wrapper for `swift://` URLs.
*/
@ -35,15 +34,15 @@ use \OpenStack\Storage\ObjectStorage;
* unauthenticated access to files (which can be done using the HTTP
* stream wrapper -- no need for swift-specific logic).
*
* <b>URL Structure</b>
* URL Structure
*
* This takes URLs of the following form:
*
* <tt>swift://CONTAINER/FILE</tt>
* `swift://CONTAINER/FILE`
*
* Example:
*
* <tt>swift://public/example.txt</tt>
* `swift://public/example.txt`
*
* The example above would access the `public` container and attempt to
* retrieve the file named `example.txt`.
@ -51,7 +50,7 @@ use \OpenStack\Storage\ObjectStorage;
* Slashes are legal in Swift filenames, so a pathlike URL can be constructed
* like this:
*
* <tt>swift://public/path/like/file/name.txt</tt>
* `swift://public/path/like/file/name.txt`
*
* The above would attempt to find a file in object storage named
* `path/like/file/name.txt`.
@ -61,7 +60,7 @@ use \OpenStack\Storage\ObjectStorage;
* and object name (path) if there is any possibility that it will contain
* UTF-8 characters.
*
* <b>Locking</b>
* Locking
*
* This library does not support locking (e.g. flock()). This is because the
* OpenStack Object Storage implementation does not support locking. But there
@ -73,7 +72,7 @@ use \OpenStack\Storage\ObjectStorage;
* TWO COPIES of the object. This can, of course, lead to nasty race
* conditions if each copy is modified.
*
* <b>Usage</b>
* Usage
*
* The principle purpose of this wrapper is to make it easy to access and
* manipulate objects on a remote object storage instance. Managing
@ -81,46 +80,43 @@ use \OpenStack\Storage\ObjectStorage;
* the OpenStack API). Consequently, almost all actions done through the
* stream wrapper are focused on objects, not containers, servers, etc.
*
* <b>Retrieving an Existing Object</b>
* Retrieving an Existing Object
*
* Retrieving an object is done by opening a file handle to that object.
*
* <b>Writing an Object</b>
* Writing an Object
*
* Nothing is written to the remote storage until the file is closed. This
* keeps network traffic at a minimum, and respects the more-or-less stateless
* nature of ObjectStorage.
*
* <b>USING FILE/STREAM RESOURCES</b>
* USING FILE/STREAM RESOURCES
*
* In general, you should access files like this:
*
* @code
* <?php
* \OpenStack\Bootstrap::useStreamWrappers();
* // Set up the context.
* $context = stream_context_create(
* array('swift' => array(
* 'account' => ACCOUNT_NUMBER,
* 'secret' => SECRET_KEY,
* 'tenantid' => TENANT_ID,
* 'tenantname' => TENANT_NAME, // Optional instead of tenantid.
* 'endpoint' => AUTH_ENDPOINT_URL,
* )
* )
* );
* // Open the file.
* $handle = fopen('swift://mycontainer/myobject.txt', 'r+', FALSE, $context);
* <?php
* \OpenStack\Bootstrap::useStreamWrappers();
* // Set up the context.
* $context = stream_context_create(
* array('swift' => array(
* 'account' => ACCOUNT_NUMBER,
* 'secret' => SECRET_KEY,
* 'tenantid' => TENANT_ID,
* 'tenantname' => TENANT_NAME, // Optional instead of tenantid.
* 'endpoint' => AUTH_ENDPOINT_URL,
* )
* )
* );
* // Open the file.
* $handle = fopen('swift://mycontainer/myobject.txt', 'r+', FALSE, $context);
*
* // You can get the entire file, or use fread() to loop through the file.
* $contents = stream_get_contents($handle);
* // You can get the entire file, or use fread() to loop through the file.
* $contents = stream_get_contents($handle);
*
* fclose($handle);
* ?>
* @endcode
*
* @remarks
* fclose($handle);
* ?>
*
* Remarks
* - file_get_contents() works fine.
* - You can write to a stream, too. Nothing is pushed to the server until
* fflush() or fclose() is called.
@ -128,7 +124,7 @@ use \OpenStack\Storage\ObjectStorage;
* constraints are slightly relaxed to accomodate efficient local buffering.
* - Files are buffered locally.
*
* <b>USING FILE-LEVEL FUNCTIONS</b>
* USING FILE-LEVEL FUNCTIONS
*
* PHP provides a number of file-level functions that stream wrappers can
* optionally support. Here are a few such functions:
@ -147,7 +143,7 @@ use \OpenStack\Storage\ObjectStorage;
* * An auth request
* * A request for the container (to get container permissions)
* * A request for the object
* - <em>IMPORTANT:</em> Unlike the fopen()/fclose()... functions NONE of these functions
* - IMPORTANT: Unlike the fopen()/fclose()... functions NONE of these functions
* retrieves the body of the file. If you are working with large files, using
* these functions may be orders of magnitude faster than using fopen(), etc.
* (The crucial detail: These kick off a HEAD request, will fopen() does a
@ -172,13 +168,13 @@ use \OpenStack\Storage\ObjectStorage;
* - stat/fstat provide only one timestamp. Swift only tracks mtime, so mtime, atime,
* and ctime are all set to the last modified time.
*
* <b>DIRECTORIES</b>
* DIRECTORIES
*
* OpenStack Swift does not really have directories. Rather, it allows
* characters such as '/' to be used to designate namespaces on object
* names. (For simplicity, this library uses only '/' as a separator).
*
* This allows for simulated directory listings. Requesting
* This allows for simulated directory listings. Requesting
* `scandir('swift://foo/bar/')` is really a request to "find all of the items
* in the 'foo' container whose names start with 'bar/'".
*
@ -194,35 +190,33 @@ use \OpenStack\Storage\ObjectStorage;
* said markers ought to be created, they are not supported by the stream
* wrapper.
*
* As usual, the underlying OpenStack::Storage::ObjectStorage::Container class
* As usual, the underlying \OpenStack\Storage\ObjectStorage\Container class
* supports the full range of Swift features.
*
* <b>SUPPORTED CONTEXT PARAMETERS</b>
* SUPPORTED CONTEXT PARAMETERS
*
* This section details paramters that can be passed <i>either</i>
* through a stream context <i>or</i> through
* OpenStack::Bootstrap::setConfiguration().
* This section details paramters that can be passed either
* through a stream context or through
* \OpenStack\Bootstrap\setConfiguration().
*
* @attention
* PHP functions that do not allow you to pass a context may still be supported
* here <em>IF</em> you have set options using Bootstrap::setConfiguration().
* here IF you have set options using Bootstrap::setConfiguration().
*
* You are <i>required</i> to pass in authentication information. This
* You are required to pass in authentication information. This
* comes in one of three forms:
*
* -# API keys: acccount, secret, tenantid, endpoint
* -# User login: username, password, tenantid, endpoint
* -# Existing (valid) token: token, swift_endpoint
*
* @attention
* As of 1.0.0-beta6, you may use `tenantname` instead of `tenantid`.
* As of 1.0.0-beta6, you may use `tenantname` instead of `tenantid`.
*
* The third method (token) can be used when the application has already
* authenticated. In this case, a token has been generated and assigned
* to an account and tenant.
*
* The following parameters may be set either in the stream context
* or through OpenStack::Bootstrap::setConfiguration():
* or through OpenStack\Bootstrap::setConfiguration():
*
* - token: An auth token. If this is supplied, authentication is skipped and
* this token is used. NOTE: You MUST set swift_endpoint if using this
@ -297,7 +291,7 @@ class StreamWrapper {
/**
* Indicate whether the local differs from remote.
*
* When the file is modified in such a way that
* When the file is modified in such a way that
* it needs to be written remotely, the isDirty flag
* is set to TRUE.
*/
@ -337,19 +331,17 @@ class StreamWrapper {
*
* This closes a directory handle, freeing up the resources.
*
* @code
* <?php
* <?php
*
* // Assuming a valid context in $cxt...
* // Assuming a valid context in $cxt...
*
* // Get the container as if it were a directory.
* $dir = opendir('swift://mycontainer', $cxt);
* // Get the container as if it were a directory.
* $dir = opendir('swift://mycontainer', $cxt);
*
* // Do something with $dir
* // Do something with $dir
*
* closedir($dir);
* ?>
* @endcode
* closedir($dir);
* ?>
*
* NB: Some versions of PHP 5.3 don't clear all buffers when
* closing, and the handle can occasionally remain accessible for
@ -367,29 +359,24 @@ class StreamWrapper {
/**
* Open a directory for reading.
*
* @code
* <?php
* <?php
*
* // Assuming a valid context in $cxt...
* // Assuming a valid context in $cxt...
*
* // Get the container as if it were a directory.
* $dir = opendir('swift://mycontainer', $cxt);
* // Get the container as if it were a directory.
* $dir = opendir('swift://mycontainer', $cxt);
*
* // Do something with $dir
* // Do something with $dir
*
* closedir($dir);
* ?>
* @endcode
* closedir($dir);
* ?>
*
* See opendir() and scandir().
*
* @param string $path
* The URL to open.
* @param int $options
* Unused.
* @retval boolean
* @return boolean
* TRUE if the directory is opened, FALSE otherwise.
* @param string $path The URL to open.
* @param int $options Unused.
*
* @return boolean TRUE if the directory is opened, FALSE otherwise.
*/
public function dir_opendir($path, $options) {
$url = $this->parseUrl($path);
@ -427,26 +414,23 @@ class StreamWrapper {
* Read an entry from the directory.
*
* This gets a single line from the directory.
* @code
* <?php
*
* // Assuming a valid context in $cxt...
* <?php
*
* // Get the container as if it were a directory.
* $dir = opendir('swift://mycontainer', $cxt);
* // Assuming a valid context in $cxt...
*
* while (($entry = readdir($dir)) !== FALSE) {
* print $entry . PHP_EOL;
* }
* // Get the container as if it were a directory.
* $dir = opendir('swift://mycontainer', $cxt);
*
* closedir($dir);
* ?>
* @endcode
* while (($entry = readdir($dir)) !== FALSE) {
* print $entry . PHP_EOL;
* }
*
* @retval string
* @return string
* The name of the resource or FALSE when the directory has no more
* entries.
* closedir($dir);
* ?>
*
* @return string The name of the resource or FALSE when the directory has no
* more entries.
*/
public function dir_readdir() {
// If we are at the end of the listing, return FALSE.
@ -469,33 +453,30 @@ class StreamWrapper {
$fullpath = substr($fullpath, $len);
}
return $fullpath;
}
/**
* Rewind to the beginning of the listing.
*
* This repositions the read pointer at the first entry in the directory.
* @code
* <?php
*
* // Assuming a valid context in $cxt...
* <?php
*
* // Get the container as if it were a directory.
* $dir = opendir('swift://mycontainer', $cxt);
* // Assuming a valid context in $cxt...
*
* while (($entry = readdir($dir)) !== FALSE) {
* print $entry . PHP_EOL;
* }
* // Get the container as if it were a directory.
* $dir = opendir('swift://mycontainer', $cxt);
*
* rewinddir($dir);
* while (($entry = readdir($dir)) !== FALSE) {
* print $entry . PHP_EOL;
* }
*
* $first = readdir($dir);
* rewinddir($dir);
*
* closedir($dir);
* ?>
* @endcode
* $first = readdir($dir);
*
* closedir($dir);
* ?>
*/
public function dir_rewinddir() {
$this->dirIndex = 0;
@ -519,34 +500,29 @@ class StreamWrapper {
*
* This DOES support cross-container renaming.
*
* See Container::copy().
* @see Container::copy().
*
* @code
* <?php
* Bootstrap::setConfiguration(array(
* 'tenantname' => 'foo@example.com',
* // 'tenantid' => '1234', // You can use this instead of tenantname
* 'account' => '1234',
* 'secret' => '4321',
* 'endpoint' => 'https://auth.example.com',
* ));
* <?php
* Bootstrap::setConfiguration(array(
* 'tenantname' => 'foo@example.com',
* // 'tenantid' => '1234', // You can use this instead of tenantname
* 'account' => '1234',
* 'secret' => '4321',
* 'endpoint' => 'https://auth.example.com',
* ));
*
* $from = 'swift://containerOne/file.txt';
* $to = 'swift://containerTwo/file.txt';
* $from = 'swift://containerOne/file.txt';
* $to = 'swift://containerTwo/file.txt';
*
* // Rename can also take a context as a third param.
* rename($from, $to);
* // Rename can also take a context as a third param.
* rename($from, $to);
*
* ?>
* @endcode
* ?>
*
* @param string $path_from
* A swift URL that exists on the remote.
* @param string $path_to
* A swift URL to another path.
* @retval boolean
* @return boolean
* TRUE on success, FALSE otherwise.
* @param string $path_from A swift URL that exists on the remote.
* @param string $path_to A swift URL to another path.
*
* @return boolean TRUE on success, FALSE otherwise.
*/
public function rename($path_from, $path_to) {
$this->initializeObjectStorage();
@ -592,9 +568,7 @@ class StreamWrapper {
* the lower-level buffer objects, this function can have unexpected
* side effects.
*
* @retval resource
* @return resource
* this returns the underlying stream.
* @return resource this returns the underlying stream.
*/
public function stream_cast($cast_as) {
return $this->objStream;
@ -603,23 +577,21 @@ class StreamWrapper {
/**
* Close a stream, writing if necessary.
*
* @code
* <?php
* <?php
*
* // Assuming $cxt has a valid context.
* // Assuming $cxt has a valid context.
*
* $file = fopen('swift://container/file.txt', 'r', FALSE, $cxt);
* $file = fopen('swift://container/file.txt', 'r', FALSE, $cxt);
*
* fclose($file);
* fclose($file);
*
* ?>
* @endcode
*
* This will close the present stream. Importantly,
* this will also write to the remote object storage if
* any changes have been made locally.
*
* See stream_open().
* @see stream_open().
*/
public function stream_close() {
@ -642,13 +614,11 @@ class StreamWrapper {
* This checks whether the stream has reached the
* end of the object's contents.
*
* Called when \c feof() is called on a stream.
* Called when `feof()` is called on a stream.
*
* See stream_seek().
* @see stream_seek().
*
* @retval boolean
* @return boolean
* TRUE if it has reached the end, FALSE otherwise.
* @return boolean TRUE if it has reached the end, FALSE otherwise.
*/
public function stream_eof() {
return feof($this->objStream);
@ -660,7 +630,7 @@ class StreamWrapper {
* If the local copy of this object has been modified,
* it is written remotely.
*
* Called when \c fflush() is called on a stream.
* Called when `fflush()` is called on a stream.
*/
public function stream_flush() {
try {
@ -706,7 +676,7 @@ class StreamWrapper {
/*
* Locking is currently unsupported.
*
* There is no remote support for locking a
* There is no remote support for locking a
* file.
public function stream_lock($operation) {
@ -718,23 +688,21 @@ class StreamWrapper {
*
* This opens a given stream resource and prepares it for reading or writing.
*
* @code
* <?php
* $cxt = stream_context_create(array(
* 'account' => '1bc123456',
* 'tenantid' => '987654321',
* 'secret' => 'eieio',
* 'endpoint' => 'https://auth.example.com',
* ));
* ?>
* <?php
* $cxt = stream_context_create(array(
* 'account' => '1bc123456',
* 'tenantid' => '987654321',
* 'secret' => 'eieio',
* 'endpoint' => 'https://auth.example.com',
* ));
* ?>
*
* $file = fopen('swift://myContainer/myObject.csv', 'rb', FALSE, $cxt);
* while ($bytes = fread($file, 8192)) {
* print $bytes;
* }
* fclose($file);
* ?>
* @endcode
* $file = fopen('swift://myContainer/myObject.csv', 'rb', FALSE, $cxt);
* while ($bytes = fread($file, 8192)) {
* print $bytes;
* }
* fclose($file);
* ?>
*
* If a file is opened in write mode, its contents will be retrieved from the
* remote storage and cached locally for manipulation. If the file is opened
@ -744,21 +712,18 @@ class StreamWrapper {
* During this operation, the remote host may need to be contacted for
* authentication as well as for file retrieval.
*
* @param string $path
* The URL to the resource. See the class description for details, but
* typically this expects URLs in the form <tt>swift://CONTAINER/OBJECT</tt>.
* @param string $mode
* Any of the documented mode strings. See fopen(). For any file that is
* in a writing mode, the file will be saved remotely on flush or close.
* Note that there is an extra mode: 'nope'. It acts like 'c+' except
* that it is never written remotely. This is useful for debugging the
* stream locally without sending that data to object storage. (Note that
* data is still fetched -- just never written.)
* @param int $options
* An OR'd list of options. Only STREAM_REPORT_ERRORS has any meaning
* to this wrapper, as it is not working with local files.
* @param string $opened_path
* This is not used, as this wrapper deals only with remote objects.
* @param string $path The URL to the resource. See the class description for
* details, but typically this expects URLs in the form `swift://CONTAINER/OBJECT`.
* @param string $mode Any of the documented mode strings. See fopen(). For
* any file that is in a writing mode, the file will be saved remotely on
* flush or close. Note that there is an extra mode: 'nope'. It acts like
* 'c+' except that it is never written remotely. This is useful for
* debugging the stream locally without sending that data to object storage.
* (Note that data is still fetched -- just never written.)
* @param int $options An OR'd list of options. Only STREAM_REPORT_ERRORS has
* any meaning to this wrapper, as it is not working with local files.
* @param string $opened_path This is not used, as this wrapper deals only
* with remote objects.
*/
public function stream_open($path, $mode, $options, &$opened_path) {
@ -837,7 +802,7 @@ class StreamWrapper {
try{
// Now we fetch the file. Only under certain circumstances do we generate
// an error if the file is not found.
// FIXME: We should probably allow a context param that can be set to
// FIXME: We should probably allow a context param that can be set to
// mark the file as lazily fetched.
$this->obj = $this->container->object($objectName);
$stream = $this->obj->stream();
@ -915,26 +880,22 @@ class StreamWrapper {
* This will read up to the requested number of bytes. Or, upon
* hitting the end of the file, it will return NULL.
*
* See fread(), fgets(), and so on for examples.
* @see fread(), fgets(), and so on for examples.
*
* @code
* <?php
* $cxt = stream_context_create(array(
* 'tenantname' => 'me@example.com',
* 'username' => 'me@example.com',
* 'password' => 'secret',
* 'endpoint' => 'https://auth.example.com',
* ));
* <?php
* $cxt = stream_context_create(array(
* 'tenantname' => 'me@example.com',
* 'username' => 'me@example.com',
* 'password' => 'secret',
* 'endpoint' => 'https://auth.example.com',
* ));
*
* $content = file_get_contents('swift://public/myfile.txt', FALSE, $cxt);
* ?>
* @endcode
* $content = file_get_contents('swift://public/myfile.txt', FALSE, $cxt);
* ?>
*
* @param int $count
* The number of bytes to read (usually 8192).
* @retval string
* @return string
* The data read.
* @param int $count The number of bytes to read (usually 8192).
*
* @return string The data read.
*/
public function stream_read($count) {
return fread($this->objStream, $count);
@ -943,12 +904,11 @@ class StreamWrapper {
/**
* Perform a seek.
*
* This is called whenever \c fseek() or \c rewind() is called on a
* This is called whenever `fseek()` or `rewind()` is called on a
* Swift stream.
*
* @attention
* IMPORTANT: Unlike the PHP core, this library
* allows you to fseek() inside of a file opened
* allows you to `fseek()` inside of a file opened
* in append mode ('a' or 'a+').
*/
public function stream_seek($offset, $whence) {
@ -987,20 +947,16 @@ class StreamWrapper {
/**
* Perform stat()/lstat() operations.
*
* @code
* <?php
* $file = fopen('swift://foo/bar', 'r+', FALSE, $cxt);
* $stats = fstat($file);
* ?>
* @endcode
* <?php
* $file = fopen('swift://foo/bar', 'r+', FALSE, $cxt);
* $stats = fstat($file);
* ?>
*
* To use standard \c stat() on a Swift stream, you will
* To use standard `stat()` on a Swift stream, you will
* need to set account information (tenant ID, account ID, secret,
* etc.) through OpenStack::Bootstrap::setConfiguration().
* etc.) through \OpenStack\Bootstrap::setConfiguration().
*
* @retval array
* @return array
* The stats array.
* @return array The stats array.
*/
public function stream_stat() {
$stat = fstat($this->objStream);
@ -1015,11 +971,9 @@ class StreamWrapper {
/**
* Get the current position in the stream.
*
* See ftell() and fseek().
* @see `ftell()` and `fseek()`.
*
* @retval int
* @return int
* The current position in the stream.
* @return int The current position in the stream.
*/
public function stream_tell() {
return ftell($this->objStream);
@ -1029,14 +983,12 @@ class StreamWrapper {
* Write data to stream.
*
* This writes data to the local stream buffer. Data
* is not pushed remotely until stream_close() or
* is not pushed remotely until stream_close() or
* stream_flush() is called.
*
* @param string $data
* Data to write to the stream.
* @retval int
* @return int
* The number of bytes written. 0 indicates and error.
* @param string $data Data to write to the stream.
*
* @return int The number of bytes written. 0 indicates and error.
*/
public function stream_write($data) {
$this->isDirty = TRUE;
@ -1055,15 +1007,12 @@ class StreamWrapper {
* delete either one. If you are using directory markers, not that deleting
* a marker will NOT delete the contents of the "directory".
*
* @attention
* You will need to use OpenStack::Bootstrap::setConfiguration() to set the
* necessary stream configuration, since \c unlink() does not take a context.
* You will need to use \OpenStack\Bootstrap::setConfiguration() to set the
* necessary stream configuration, since `unlink()` does not take a context.
*
* @param string $path
* The URL.
* @retval boolean
* @return boolean
* TRUE if the file was deleted, FALSE otherwise.
* @param string $path The URL.
*
* @return boolean TRUE if the file was deleted, FALSE otherwise.
*/
public function unlink($path) {
$url = $this->parseUrl($path);
@ -1147,7 +1096,7 @@ class StreamWrapper {
* Get the Object.
*
* This provides low-level access to the
* PHCloud::Storage::ObjectStorage::Object instance in which the content
* \OpenStack\Storage\ObjectStorage::Object instance in which the content
* is stored.
*
* Accessing the object's payload (Object::content()) is strongly
@ -1160,13 +1109,11 @@ class StreamWrapper {
*
* To access this:
*
* @code
* <?php
* $handle = fopen('swift://container/test.txt', 'rb', $cxt);
* $md = stream_get_meta_data($handle);
* $obj = $md['wrapper_data']->object();
* ?>
* @endcode
* <?php
* $handle = fopen('swift://container/test.txt', 'rb', $cxt);
* $md = stream_get_meta_data($handle);
* $obj = $md['wrapper_data']->object();
* ?>
*/
public function object() {
return $this->obj;
@ -1175,8 +1122,7 @@ class StreamWrapper {
/**
* EXPERT: Get the ObjectStorage for this wrapper.
*
* @retval object OpenStack::ObjectStorage
* An ObjectStorage object.
* @return object \OpenStack\ObjectStorage An ObjectStorage object.
* @see object()
*/
public function objectStorage() {
@ -1186,8 +1132,7 @@ class StreamWrapper {
/**
* EXPERT: Get the auth token for this wrapper.
*
* @retval string
* A token.
* @return string A token.
* @see object()
*/
public function token() {
@ -1199,8 +1144,7 @@ class StreamWrapper {
*
* This is only available when a file is opened via fopen().
*
* @retval array
* A service catalog.
* @return array A service catalog.
* @see object()
*/
public function serviceCatalog() {
@ -1228,7 +1172,7 @@ class StreamWrapper {
* the cached stat['size'] for the underlying buffer.
*/
protected function generateStat($object, $container, $size) {
// This is not entirely accurate. Basically, if the
// This is not entirely accurate. Basically, if the
// file is marked public, it gets 100775, and if
// it is private, it gets 100770.
//
@ -1287,12 +1231,10 @@ class StreamWrapper {
/**
* Set the fopen mode.
*
* @param string $mode
* The mode string, e.g. `r+` or `wb`.
* @param string $mode The mode string, e.g. `r+` or `wb`.
*
* @retval OpenStack::Storage::ObjectStorage::StreamWrapper
* @return \OpenStack\Storage\ObjectStorage\StreamWrapper
* $this so the method can be used in chaining.
* @return \OpenStack\Storage\ObjectStorage\StreamWrapper $this so the method
* can be used in chaining.
*/
protected function setMode($mode) {
$mode = strtolower($mode);
@ -1372,14 +1314,12 @@ class StreamWrapper {
*
* @todo Should there be an option to NOT query the Bootstrap::conf()?
*
* @param string $name
* The name to look up. First look it up in the context, then look
* it up in the Bootstrap config.
* @param mixed $default
* The default value to return if no config param was found.
* @retval mixed
* @return mixed
* The discovered result, or $default if specified, or NULL if
* @param string $name The name to look up. First look it up in the context,
* then look it up in the Bootstrap config.
* @param mixed $default The default value to return if no config param was
* found.
*
* @return mixed The discovered result, or $default if specified, or NULL if
* no $default is specified.
*/
protected function cxt($name, $default = NULL) {
@ -1422,11 +1362,9 @@ class StreamWrapper {
* This parses the URL and urldecodes the container name and
* the object name.
*
* @param string $url
* A Swift URL.
* @retval array
* @return array
* An array as documented in parse_url().
* @param string $url A Swift URL.
*
* @return array An array as documented in parse_url().
*/
protected function parseUrl($url) {
$res = parse_url($url);
@ -1453,7 +1391,7 @@ class StreamWrapper {
* Based on the context, initialize the ObjectStorage.
*
* The following parameters may be set either in the stream context
* or through OpenStack::Bootstrap::setConfiguration():
* or through \OpenStack\Bootstrap::setConfiguration():
*
* - token: An auth token. If this is supplied, authentication is skipped and
* this token is used. NOTE: You MUST set swift_endpoint if using this
@ -1470,10 +1408,10 @@ class StreamWrapper {
* the deprecated swiftAuth instead of IdentityService authentication.
* In general, you should avoid using this.
*
* To find these params, the method first checks the supplied context. If the
* To find these params, the method first checks the supplied context. If the
* key is not found there, it checks the Bootstrap::conf().
*
* @fixme This should be rewritten to use ObjectStorage::newFromServiceCatalog().
* @fixme This should be rewritten to use \ObjectStorage::newFromServiceCatalog().
*/
protected function initializeObjectStorage() {

View File

@ -15,12 +15,11 @@
limitations under the License.
============================================================================ */
/**
* @file
* Contains the stream wrapper for `swiftfs://` URLs.
*
* <b>Note, this stream wrapper is in early testing.</b>
*
* The stream wrapper implemented in OpenStack\Storage\ObjectStorage\StreamWrapper
*
* Note, this stream wrapper is in early testing.
*
* The stream wrapper implemented in \OpenStack\Storage\ObjectStorage\StreamWrapper
* only supports the elements of a stream that are implemented by object
* storage. This is how the PHP documentation states a stream wrapper should be
* created. Because some features do not exist, attempting to treat a stream
@ -28,25 +27,25 @@
* while there are not directories objects have pathy names (with / separators).
* Directory calls to object storage with the default stream wrappers will not
* operate how they would for a file system.
*
*
* StreamWrapperFS is an attempt to make a filesystem like stream wrapper.
* Hence the protocol is swiftfs standing for swift file system.
*
*
* To understand how this stream wrapper works start by first reading the
* documentation on the OpenStack::Storage::ObjectStorage::StreamWrapper.
*
* <b>DIRECTORIES</b>
*
* documentation on the \OpenStack\Storage\ObjectStorage\StreamWrapper.
*
* DIRECTORIES
*
* Because OpenStack Swift does not support directories the swift:// stream
* wrapper does not support them. This stream wrapper attempts to fake them by
* faking directory stats, mkdir, and rmdir. By default (see the options below
* for how to change these) directories have permissions of 777, timestamps
* close to that of the request, and the user and group called by php. We mock
* these on the fly though information is stored in the PHP stat cache.
*
*
* In addition to the parameters supported by StreamWrapper, the following
* parameters may be set either in the stream context or through
* OpenStack::Bootstrap::setConfiguration():
* parameters may be set either in the stream context or through
* OpenStack\Bootstrap::setConfiguration():
* - swiftfs_fake_stat_mode: Directories don't exist in swift. When stat() is
* is called on a directory we mock the stat information so functions like
* is_dir will work. The default file permissions is 0777. Though this
@ -70,7 +69,6 @@ use \OpenStack\Storage\ObjectStorage;
* This provides a full stream wrapper to expose `swiftfs://` URLs to the
* PHP stream system.
*
*
* @see http://us3.php.net/manual/en/class.streamwrapper.php
*/
class StreamWrapperFS extends StreamWrapper {
@ -93,7 +91,7 @@ class StreamWrapperFS extends StreamWrapper {
/**
* Fake Remove a directory.
*
*
* ObjectStorage has pathy objects not directories. If no objects with a path
* prefix exist we can pass removing it. If objects with a path prefix exist
* removing the directory will fail.
@ -135,17 +133,15 @@ class StreamWrapperFS extends StreamWrapper {
/**
* Test if a path prefix (directory like) esits.
*
*
* ObjectStorage has pathy objects not directories. If objects exist with a
* path prefix we can consider that the directory exists. For example, if
* we have an object at foo/bar/baz.txt and test the existance of the
* directory foo/bar/ we sould see it.
*
* @param string $path
* The directory path to test.
* @retval boolean
* @return boolean
* TRUE if the directory prefix exists and FALSE otherwise.
*
* @param string $path The directory path to test.
*
* @return boolean TRUE if the directory prefix exists and FALSE otherwise.
*/
protected function testDirectoryExists($path) {
$url = $this->parseUrl($path);

View File

@ -15,7 +15,6 @@
limitations under the License.
============================================================================ */
/**
* @file
* Contains the Subdir class.
*/
@ -24,14 +23,21 @@ namespace OpenStack\Storage\ObjectStorage;
/**
* Represent a subdirectory (subdir) entry.
*
* Depending on the method with which Swift container requests are
* Depending on the method with which Swift container requests are
* executed, Swift may return subdir entries instead of Objects.
*
* Subdirs are used for things that are directory-like.
*/
class Subdir {
/**
* @var string The path string that this subdir describes
*/
protected $path;
/**
* @var string The delimiter used in this path
*/
protected $delimiter;
@ -40,10 +46,8 @@ class Subdir {
*
* This represents a remote response's tag for a subdirectory.
*
* @param string $path
* The path string that this subdir describes.
* @param string $delimiter
* The delimiter used in this path.
* @param string $path The path string that this subdir describes.
* @param string $delimiter The delimiter used in this path.
*/
public function __construct($path, $delimiter = '/') {
$this->path = $path;
@ -55,9 +59,7 @@ class Subdir {
*
* The path is delimited using the string returned by delimiter().
*
* @retval string
* @return string
* The path.
* @return string The path
*/
public function path() {
return $this->path;
@ -65,11 +67,9 @@ class Subdir {
/**
* Get the delimiter used by the server.
*
* @retval string
* @return string
* The value used as a delimiter.
* @return string The value used as a delimiter.
*/
public function delimiter() {
return $this->delimiter;
}
}
}