Configuration: "global" settings are set here. * See the setConfiguration() method to see how they * can be set, and the config() and hasConfig() methods to see * how configuration might be checked. * - Stream Wrappers: This class can initialize a set of stream * wrappers which will make certain HPCloud services available * through the core PHP stream support. * - Autoloader: It provides a special-purpose autoloader that can * load the HPCloud classes, but which will not interfere with * other autoloading facilities. * * Configuration * * Configuration directives can be merged into the existing confiuration * using the setConfiguration method. * * @code * '\HPCloud\Transport\CURLTransport', * // Set the HTTP max wait time to 500. * 'transport.timeout' => 500, * ); * Bootstrap::setConfiguration($config); * * // Check and get params. * if (Bootstrap::hasConf('transport.timeout') { * $to = Bootstrap::conf('transport.timeout'); * } * * // Or get a param with a default value: * $val = Bootstrap::conf('someval', 'default value'); * * // $val will be set to 'default value' because there * // is no 'someval' configuration param. * * ?> * @endcode * * AUTOLOADING * * HPCloud comes with a built-in autoloader that can be called like this: * * @code * Bootstrap::useAutoloader(); * @endcode * * @attention * The structure of the HPCloud file hierarchy is PSR-0 compliant. * This means that you can use any standard PSR-0 classloader to * load all of the classes here. * * That said, many projects rely upon packages to handle their own * class loading. To provide this, this package contains a custom * classloader that will load JUST the HPCloud classes. See * the Bootstrap::useAutoloader() static method. * * See https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md * * STREAM WRAPPERS * * Stream wrappers allow you to use the built-in file manipulation * functions in PHP to interact with other services. Specifically, * the HPCloud stream wrappers allow you to use built-in file commands * to access Object Storage (Swift) and other HPCloud services using * commands like file_get_contents() and fopen(). * * It's awesome. Trust me. * */ class Bootstrap { /** * The directory where HPCloud is located. */ public static $basedir = __DIR__; public static $config = array( // The transport implementation. By default, we use the PHP stream // wrapper's HTTP mechanism to process transactions. //'transport' => '\HPCloud\Transport\PHPStreamTransport', // This is the default transport while a bug persists in the // Identity Services REST service. 'transport' => '\HPCloud\Transport\CURLTransport', ); /** * An identity services object created from the global settings. * @var object HPCloud::Services::IdentityServices */ public static $identity = NULL; /** * Add the autoloader to PHP's autoloader list. * * This will add the internal special-purpose * autoloader to the list of autoloaders that PHP will * leverage to resolve class paths. * * Because HPCloud is PSR-0 compliant, any * full PSR-0 classloader should be capable of loading * these classes witout issue. You may prefer to use * a standard PSR-0 loader instead of this one. * * @see https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md */ public static function useAutoloader() { spl_autoload_register(__NAMESPACE__ . '\Bootstrap::autoload'); } /** * Register stream wrappers for HPCloud. * * This register the ObjectStorage stream wrappers, which allow you to access * ObjectStorage through standard file access mechanisms. * * @code * // Enable stream wrapper. * Bootstrap::useStreamWrappers(); * * // Create a context resource. * $cxt = stream_context_create(array( * 'tenantid' => '12de21', * 'account' => '123454321', * 'secret' => 'f78saf7hhlll', * 'endpoint' => 'https://identity.hpcloud.com' // <-- not real URL! * )); * * // Get the contents of a Swift object. * $content = file_get_contents('swift://public/notes.txt', 'r', FALSE, $cxt); * @endcode */ public static function useStreamWrappers() { $swift = stream_wrapper_register( \HPCloud\Storage\ObjectStorage\StreamWrapper::DEFAULT_SCHEME, '\HPCloud\Storage\ObjectStorage\StreamWrapper' ); $swiftfs = stream_wrapper_register( \HPCloud\Storage\ObjectStorage\StreamWrapperFS::DEFAULT_SCHEME, '\HPCloud\Storage\ObjectStorage\StreamWrapperFS' ); return ($swift && $swiftfs); } /** * Set configuration directives for HPCloud. * * This merges the provided associative array into the existing * configuration parameters (Bootstrap::$config). * * All of the HPCloud classes share the same configuration. This * ensures that a stable runtime environment is maintained. * * Common configuration directives: * * - 'transport': The namespaced classname for the transport that * should be used. Example: @code \HPCloud\Transport\CURLTransport @endcode * - 'transport.debug': The integer 1 for enabling debug, 0 for * disabling. Enabling will turn on verbose debugging output * for any transport that supports it. * - 'transport.timeout': An integer value indicating how long * the transport layer should wait for an HTTP request. A * transport MAY ignore this parameter, but the ones included * with the library honor it. * - 'account' and 'secret' * - 'username' and 'password' * - 'tenantid' * - 'endpoint': The full URL to identity services. This is used by stream * wrappers. * * @param array $array * An associative array of configuration directives. */ public static function setConfiguration($array) { self::$config = $array + self::$config; } /** * HPCloud autoloader. * * An implementation of a PHP autoload function. Use * HPCloud::useAutoloader() if you want PHP to automatically * load classes using this autoloader. * * @code * // Enable the autoloader. * Bootstrap::useAutoloader(); * @endcode * * This is a special-purpose autoloader for loading * only the HPCloud classes. It will not attempt to * autoload anything outside of the HPCloud namespace. * * Because this is a special-purpose autoloader, it * should be safe to use with other special-purpose * autoloaders (and also projects that don't * rely upon autoloaders). * * @param string $klass * The fully qualified name of the class to be autoloaded. */ public static function autoload($klass) { $components = explode('\\', $klass); if (empty($components[0])) { array_shift($components); } // This class loader ONLY loads // our classes. A general purpose // classloader should be used for // more sophisticated needs. if ($components[0] != 'HPCloud') { return; } // We need the path up to, but not including, the root HPCloud dir: $local_path = substr(self::$basedir, 0, strrpos(self::$basedir, '/HPCloud')); array_unshift($components, $local_path); $path = implode(DIRECTORY_SEPARATOR, $components) . '.php'; if (file_exists($path)) { require $path; return; } } /** * Get a configuration option. * * Get a configuration option by name, with an optional default. * * @param string $name * The name of the configuration option to get. * @param mixed $default * The default value to return if the name is not found. * @retval mixed * The value, if found; or the default, if set; or NULL. */ public static function config($name = NULL, $default = NULL) { // If no name is specified, return the entire config array. if (empty($name)) { return self::$config; } // If the config value exists, return that. if (isset(self::$config[$name])) { return self::$config[$name]; } // Otherwise, just return the default value. return $default; } /** * Check whether the given configuration option is set. * * @code * if (Bootstrap::hasConfig('transport')) { * syslog(LOG_INFO, 'An alternate transport is supplied.'); * } * @endcode * * @param string $name * The name of the item to check for. * @retval boolean * TRUE if the named option is set, FALSE otherwise. Note that the value may * be falsey (FALSE, 0, etc.), but if the value is NULL, this will return * false. */ public static function hasConfig($name) { return isset(self::$config[$name]); } /** * Get a HPCloud::Services::IdentityService object from the bootstrap config. * * A factory helper function that uses the bootstrap configuration to create * a ready to use HPCloud::Services::IdentityService object. * * @param bool $force * Whether to force the generation of a new object even if one is already * cached. * @retval HPCloud::Services::IdentityService * An authenticated ready to use HPCloud::Services::IdentityService object. * @throws HPCloud::Exception * When the needed configuration to authenticate is not available. */ public static function identity($force = FALSE) { // If we already have an identity make sure the token is not expired. if ($force || is_null(self::$identity) || self::$identity->isExpired()) { // Make sure we have an endpoint to use if (!self::hasConfig('endpoint')) { throw new Exception('Unable to authenticate. No endpoint supplied.'); } // Neither user nor account can be an empty string, so we need // to do more checking than self::hasConfig(), which returns TRUE // if an item exists and is an empty string. $user = self::config('username', NULL); $account = self::config('account', NULL); // Check if we have a username/password if (!empty($user) && self::hasConfig('password')) { $is = new IdentityServices(self::config('endpoint')); $is->authenticateAsUser($user, self::config('password'), self::config('tenantid', NULL), self::config('tenantname', NULL)); self::$identity = $is; } // Otherwise we go with access/secret keys elseif (!empty($account) && self::hasConfig('secret')) { $is = new IdentityServices(self::config('endpoint')); $is->authenticateAsAccount($account, self::config('secret'), self::config('tenantid', NULL), self::config('tenantname', NULL)); self::$identity = $is; } else { throw new Exception('Unable to authenticate. No account credentials supplied.'); } } return self::$identity; } }