/wp-content/plugins/backwpup/vendor/rackspace/php-opencloud/lib/OpenCloud/Common/Base.php
PHP | 437 lines | 235 code | 49 blank | 153 comment | 34 complexity | 43f71d2174ef6d042739d91f3eecbd55 MD5 | raw file
Possible License(s): BSD-3-Clause, MIT
- <?php
- /**
- * Copyright 2012-2014 Rackspace US, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- namespace OpenCloud\Common;
- use OpenCloud\Common\Collection\ResourceIterator;
- use OpenCloud\Common\Constants\Header as HeaderConst;
- use OpenCloud\Common\Constants\Mime as MimeConst;
- use OpenCloud\Common\Exceptions\JsonError;
- use Psr\Log\LoggerInterface;
- /**
- * The root class for all other objects used or defined by this SDK.
- *
- * It contains common code for error handling as well as service functions that
- * are useful. Because it is an abstract class, it cannot be called directly,
- * and it has no publicly-visible properties.
- */
- abstract class Base
- {
- const PATCH_CONTENT_TYPE = MimeConst::JSON_PATCH;
- /**
- * Holds all the properties added by overloading.
- *
- * @var array
- */
- private $properties = array();
- /**
- * The logger instance
- *
- * @var LoggerInterface
- */
- private $logger;
- /**
- * The aliases configure for the properties of the instance.
- *
- * @var array
- */
- protected $aliases = array();
- /**
- * @return static
- */
- public static function getInstance()
- {
- return new static();
- }
- /**
- * Intercept non-existent method calls for dynamic getter/setter functionality.
- *
- * @param $method
- * @param $args
- * @throws Exceptions\RuntimeException
- */
- public function __call($method, $args)
- {
- $prefix = substr($method, 0, 3);
- // Get property - convert from camel case to underscore
- $property = lcfirst(substr($method, 3));
- // Only do these methods on properties which exist
- if ($this->propertyExists($property) && $prefix == 'get') {
- return $this->getProperty($property);
- }
- // Do setter
- if ($this->propertyExists($property) && $prefix == 'set') {
- return $this->setProperty($property, $args[0]);
- }
- throw new Exceptions\RuntimeException(sprintf(
- 'No method %s::%s()',
- get_class($this),
- $method
- ));
- }
- /**
- * We can set a property under three conditions:
- *
- * 1. If it has a concrete setter: setProperty()
- * 2. If the property exists
- * 3. If the property name's prefix is in an approved list
- *
- * @param mixed $property
- * @param mixed $value
- * @return mixed
- */
- protected function setProperty($property, $value)
- {
- $setter = 'set' . $this->toCamel($property);
- if (method_exists($this, $setter)) {
- return call_user_func(array($this, $setter), $value);
- } elseif (false !== ($propertyVal = $this->propertyExists($property))) {
- // Are we setting a public or private property?
- if ($this->isAccessible($propertyVal)) {
- $this->$propertyVal = $value;
- } else {
- $this->properties[$propertyVal] = $value;
- }
- return $this;
- } else {
- $this->getLogger()->warning(
- 'Attempted to set {property} with value {value}, but the'
- . ' property has not been defined. Please define first.',
- array(
- 'property' => $property,
- 'value' => print_r($value, true)
- )
- );
- }
- }
- /**
- * Basic check to see whether property exists.
- *
- * @param string $property The property name being investigated.
- * @param bool $allowRetry If set to TRUE, the check will try to format the name in underscores because
- * there are sometimes discrepancies between camelCaseNames and underscore_names.
- * @return bool
- */
- protected function propertyExists($property, $allowRetry = true)
- {
- if (!property_exists($this, $property) && !$this->checkAttributePrefix($property)) {
- // Convert to under_score and retry
- if ($allowRetry) {
- return $this->propertyExists($this->toUnderscores($property), false);
- } else {
- $property = false;
- }
- }
- return $property;
- }
- /**
- * Convert a string to camelCase format.
- *
- * @param $string
- * @param bool $capitalise Optional flag which allows for word capitalization.
- * @return mixed
- */
- public function toCamel($string, $capitalise = true)
- {
- if ($capitalise) {
- $string = ucfirst($string);
- }
- return preg_replace_callback('/_([a-z])/', function ($char) {
- return strtoupper($char[1]);
- }, $string);
- }
- /**
- * Convert string to underscore format.
- *
- * @param $string
- * @return mixed
- */
- public function toUnderscores($string)
- {
- $string = lcfirst($string);
- return preg_replace_callback('/([A-Z])/', function ($char) {
- return "_" . strtolower($char[1]);
- }, $string);
- }
- /**
- * Does the property exist in the object variable list (i.e. does it have public or protected visibility?)
- *
- * @param $property
- * @return bool
- */
- private function isAccessible($property)
- {
- return array_key_exists($property, get_object_vars($this));
- }
- /**
- * Checks the attribute $property and only permits it if the prefix is
- * in the specified $prefixes array
- *
- * This is to support extension namespaces in some services.
- *
- * @param string $property the name of the attribute
- * @return boolean
- */
- private function checkAttributePrefix($property)
- {
- if (!method_exists($this, 'getService')) {
- return false;
- }
- $prefix = strstr($property, ':', true);
- return in_array($prefix, $this->getService()->namespaces());
- }
- /**
- * Grab value out of the data array.
- *
- * @param string $property
- * @return mixed
- */
- protected function getProperty($property)
- {
- if (array_key_exists($property, $this->properties)) {
- return $this->properties[$property];
- } elseif (array_key_exists($this->toUnderscores($property), $this->properties)) {
- return $this->properties[$this->toUnderscores($property)];
- } elseif (method_exists($this, 'get' . ucfirst($property))) {
- return call_user_func(array($this, 'get' . ucfirst($property)));
- } elseif (false !== ($propertyVal = $this->propertyExists($property)) && $this->isAccessible($propertyVal)) {
- return $this->$propertyVal;
- }
- return null;
- }
- /**
- * Sets the logger.
- *
- * @param LoggerInterface $logger
- *
- * @return $this
- */
- public function setLogger(LoggerInterface $logger = null)
- {
- $this->logger = $logger;
- return $this;
- }
- /**
- * Returns the Logger object.
- *
- * @return LoggerInterface
- */
- public function getLogger()
- {
- if (null === $this->logger) {
- $this->setLogger(new Log\Logger);
- }
- return $this->logger;
- }
- /**
- * @return bool
- */
- public function hasLogger()
- {
- return (null !== $this->logger);
- }
- /**
- * @deprecated
- */
- public function url($path = null, array $query = array())
- {
- return $this->getUrl($path, $query);
- }
- /**
- * Populates the current object based on an unknown data type.
- *
- * @param mixed $info
- * @param bool
- * @throws Exceptions\InvalidArgumentError
- */
- public function populate($info, $setObjects = true)
- {
- if (is_string($info) || is_integer($info)) {
- $this->setProperty($this->primaryKeyField(), $info);
- $this->refresh($info);
- } elseif (is_object($info) || is_array($info)) {
- foreach ($info as $key => $value) {
- if ($key == 'metadata' || $key == 'meta') {
- // Try retrieving existing value
- if (null === ($metadata = $this->getProperty($key))) {
- // If none exists, create new object
- $metadata = new Metadata;
- }
- // Set values for metadata
- $metadata->setArray($value);
- // Set object property
- $this->setProperty($key, $metadata);
- } elseif (!empty($this->associatedResources[$key]) && $setObjects === true) {
- // Associated resource
- try {
- $resource = $this->getService()->resource($this->associatedResources[$key], $value);
- $resource->setParent($this);
- $this->setProperty($key, $resource);
- } catch (Exception\ServiceException $e) {
- }
- } elseif (!empty($this->associatedCollections[$key]) && $setObjects === true) {
- // Associated collection
- try {
- $className = $this->associatedCollections[$key];
- $options = $this->makeResourceIteratorOptions($className);
- $iterator = ResourceIterator::factory($this, $options, $value);
- $this->setProperty($key, $iterator);
- } catch (Exception\ServiceException $e) {
- }
- } elseif (!empty($this->aliases[$key])) {
- // Sometimes we might want to preserve camelCase
- // or covert `rax-bandwidth:bandwidth` to `raxBandwidth`
- $this->setProperty($this->aliases[$key], $value);
- } else {
- // Normal key/value pair
- $this->setProperty($key, $value);
- }
- }
- } elseif (null !== $info) {
- throw new Exceptions\InvalidArgumentError(sprintf(
- Lang::translate('Argument for [%s] must be string or object'),
- get_class()
- ));
- }
- }
- /**
- * Checks the most recent JSON operation for errors.
- *
- * @throws Exceptions\JsonError
- * @codeCoverageIgnore
- */
- public static function checkJsonError()
- {
- switch (json_last_error()) {
- case JSON_ERROR_NONE:
- return;
- case JSON_ERROR_DEPTH:
- $jsonError = 'JSON error: The maximum stack depth has been exceeded';
- break;
- case JSON_ERROR_STATE_MISMATCH:
- $jsonError = 'JSON error: Invalid or malformed JSON';
- break;
- case JSON_ERROR_CTRL_CHAR:
- $jsonError = 'JSON error: Control character error, possibly incorrectly encoded';
- break;
- case JSON_ERROR_SYNTAX:
- $jsonError = 'JSON error: Syntax error';
- break;
- case JSON_ERROR_UTF8:
- $jsonError = 'JSON error: Malformed UTF-8 characters, possibly incorrectly encoded';
- break;
- default:
- $jsonError = 'Unexpected JSON error';
- break;
- }
- if (isset($jsonError)) {
- throw new JsonError(Lang::translate($jsonError));
- }
- }
- public static function generateUuid()
- {
- return sprintf('%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
- // 32 bits for "time_low"
- mt_rand(0, 0xffff), mt_rand(0, 0xffff),
- // 16 bits for "time_mid"
- mt_rand(0, 0xffff),
- // 16 bits for "time_hi_and_version",
- // four most significant bits holds version number 4
- mt_rand(0, 0x0fff) | 0x4000,
- // 16 bits, 8 bits for "clk_seq_hi_res",
- // 8 bits for "clk_seq_low",
- // two most significant bits holds zero and one for variant DCE1.1
- mt_rand(0, 0x3fff) | 0x8000,
- // 48 bits for "node"
- mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff)
- );
- }
- public function makeResourceIteratorOptions($resource)
- {
- $options = array('resourceClass' => $this->stripNamespace($resource));
- if (method_exists($resource, 'jsonCollectionName')) {
- $options['key.collection'] = $resource::jsonCollectionName();
- }
- if (method_exists($resource, 'jsonCollectionElement')) {
- $options['key.collectionElement'] = $resource::jsonCollectionElement();
- }
- return $options;
- }
- public function stripNamespace($namespace)
- {
- $array = explode('\\', $namespace);
- return end($array);
- }
- protected static function getJsonHeader()
- {
- return array(HeaderConst::CONTENT_TYPE => MimeConst::JSON);
- }
- protected static function getPatchHeaders()
- {
- return array(HeaderConst::CONTENT_TYPE => static::PATCH_CONTENT_TYPE);
- }
- }