client = $client; }else{ $this->client = new April_Client(); } } /** * Helper object cache * * When a service requests a resource-helper, it's cached here * * @var array */ protected static $cachedHelpers = array(); /** * Provides an interface to call ($url, $resource [, $extra...]) functions. * * Eg:- * * $this->getObject($url); * $this->putObject($url, $obj, $meta); * $this->deleteObject($url); * $this->headBucket($url); * * * @param string $method * @param array() $args * @return April_Response */ public function __call($method, $args) { // split camelCase method name: getMyObject => array('get', 'MyObject') $parts = preg_split('/(:?[a-z]+)([A-Z].*)/', $method, null, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE ); $verb = strtoupper(array_shift($parts)); $resourceType = array_shift($parts); $url = array_shift($args); $resource = array_shift($args); // get a helper for this serivce/resource combination $this->helper = April_Service::getHelper($this->getClass(), $resourceType); // build request $request = $this->buildRequest($verb, $resourceType, $url, $resource, $args); // return response $response = $this->client->request($request); $response->setHelper($this->helper); return $response; } /** * Return a helper object for a given service/resource * * @param string $service className of service * @param string $resource name of resource * @return April_ResourceHelper $helper */ protected static function getHelper($service, $resource) { // Eg: April_S3_Bucket_Helper $helperClass = $service . '_' . $resource . '_' . 'Helper'; // check cache if(isset(self::$cachedHelpers[$helperClass])){ return self::$cachedHelpers[$helperClass]; } // else instantiate a new helper... $classFile = str_replace('_', DIRECTORY_SEPARATOR, $helperClass) . '.php'; // try to include the classfile $paths = explode(PATH_SEPARATOR, get_include_path()); foreach ($paths as $path) { if(file_exists($path . DIRECTORY_SEPARATOR . $classFile)){ require_once $classFile; break; } } // if the class now exists, use it, else default to Aprile_ResourceHelper if(class_exists($helperClass)){ $helper = new $helperClass(); }else{ $helper = new April_ResourceHelper(); // the default // could look at caching a single default instance, but leaving for now } self::$cachedHelpers[$helperClass] = $helper; return $helper; } /** * Build the April_Request object * * @param string $verb HTTP method * @param string $resourceType Resource Type * @param string|April_Url $url URL for resource * @param string $resource The resource object * @param array $args Any additional arguments */ protected function buildRequest($verb, $resourceType, $url, $resource = null, $args = array()) { $request = new April_Request($url); $request->setMethod($verb); // populate the request with the resource $this->helper->populateRequest($resource, $request); // return the request object return $request; } protected function getClass() { return __CLASS__; } }