/** * This method calls the next Callable in the list. All of the method arguments * coming into this method are substituted into the original method argument of * call in the chain. * * If the original method call has these parameters * <code> * $originalobject->dyExampleMethod('param1', 'param2', 'param3') * </code> * <code> * $callchain->dyExampleMethod('alt1', 'alt2') * </code> * then the next call in the call chain will recieve the parameters as if this were called * <code> * $behavior->dyExampleMethod('alt1', 'alt2', 'param3', $callchainobject) * </code> * * When dealing with {@link IClassBehaviors}, the first parameter of the stored argument * list in 'dy' event calls is always the object containing the behavior. This modifies * the parameter replacement mechanism slightly to leave the object containing the behavior * alone and only replacing the other parameters in the argument list. As per {@link __call}, * any calls to a 'dy' event do not need the object containing the behavior as the addition of * the object to the argument list as the first element is automatic for IClassBehaviors. * * The last parameter of the method parameter list for any callable in the call chain * will be the TCallChain object itself. This is so that any behavior implementing * these calls will have access to the call chain. Each callable should either call * the TCallChain call method internally for direct chaining or call the method being * chained (in which case the dynamic handler will pass through to this call method). * * If the dynamic intra object/behavior event is not called in the behavior implemented * dynamic method, it will return to this method and call the following behavior * implementation so as no behavior with an implementation of the dynamic event is left * uncalled. This does break the call chain though and will not act as a "parameter filter". * * When there are no handlers or no handlers left, it returns the first parameter of the * argument list. * */ public function call() { $args = func_get_args(); if ($this->getCount() === 0) { return isset($args[0]) ? $args[0] : null; } if (!$this->_iterator) { $chain_array = array_reverse($this->toArray()); $this->_iterator = new TListIterator($chain_array); } if ($this->_iterator->valid()) { do { $handler = $this->_iterator->current(); $this->_iterator->next(); if (is_array($handler[0]) && $handler[0][0] instanceof IClassBehavior) { array_splice($handler[1], 1, count($args), $args); } else { array_splice($handler[1], 0, count($args), $args); } $handler[1][] = $this; $result = call_user_func_array($handler[0], $handler[1]); } while ($this->_iterator->valid()); } else { $result = $args[0]; } return $result; }
/** * Constructs an Image object. * * @param string $url URL of the query for the data that should be returned based on Picasa's API documentation. * See {@link http://code.google.com/apis/picasaweb/gdata.html} for instructions on how to formulate * the URL. The URL parameter can be left blank, which will still produce a populated Image * object as long as the $albums parameter contains XML from the Picasa Atom feed for an image. * @param SimpleXMLElement $albums XML describing a Picasa image. This can be left blank as long as a URL is specified in the * url parameter that returns valid XML for a Picasa image. If both are null, a * {@link Picasa_Exception} is thrown. * @param array $contextArray An array that can be passed to stream_context_create() to generate * a PHP context. See * {@link http://us2.php.net/manual/en/function.stream-context-create.php} * @param boolean $useCache You can decide not to cache a specific request by passing false here. You may * want to do this, for instance, if you're requesting a private feed. * @throws {@link Picasa_Exception} If the XML suppled through either parameter does not contain valid XML. */ public function __construct($url = null, SimpleXMLElement $albums = null, $contextArray = null, $useCache = true) { if ($url != null) { Picasa_Logger::getLogger()->logIfEnabled('Request string: ' . $url); $context = null; $xmldata = false; if ($contextArray != null) { $context = stream_context_create($contextArray); } if ($useCache === true) { $xmldata = Picasa_Cache::getCache()->getIfCached($url); } if ($xmldata === false) { Picasa_Logger::getLogger()->logIfEnabled('Cached copy not available, requesting image freshly for URL: ' . $url); $xmldata = @file_get_contents($url, false, $context); if ($useCache === true && $xmldata !== false) { Picasa_Logger::getLogger()->logIfEnabled('Saving account to cache.'); Picasa_Cache::getCache()->setInCache($url, $xmldata); } } else { Picasa_Logger::getLogger()->logIfEnabled('Image retreived from cache.'); } if ($xmldata == false) { throw Picasa::getExceptionFromInvalidQuery($url, $contextArray); } try { // Load the XML file into a SimpleXMLElement $albums = new SimpleXMLElement($xmldata); } catch (Exception $e) { throw new Picasa_Exception($e->getMessage(), null, $url); } } $this->contextArray = $contextArray; if ($albums != null) { foreach ($albums->link as $plink) { if ($plink['rel'] == 'alternate') { $this->weblink = $plink['href']; } } $namespaces = $albums->getNamespaces(true); if (array_key_exists("media", $namespaces)) { $media_ns = $albums->children($namespaces["media"]); $this->description = $media_ns->group->description; $this->keywords = $media_ns->group->keywords; $this->thumbUrlMap = array(); $this->thumbHeightMap = array(); $this->previous = null; $this->next = null; $i = 0; $this->thumbnails = array(); $thumb = $media_ns->group->thumbnail[$i]; while ($thumb != null) { $thumbAtt = $thumb->attributes(); $width = "" . $thumbAtt['width']; $height = $thumbAtt['height']; $url = $thumbAtt['url']; // These fields are deprecated but included for backwards compatibility $this->thumbUrlMap[$width] = $url; $this->thumbHeightMap[$width] = $height; $this->thumbnails[$i] = new Picasa_Thumbnail($url, $thumbAtt['width'], $thumbAtt['height']); $i++; $thumb = $media_ns->group->thumbnail[$i]; } /* This is to support the previous implementation. It may seem inefficiant to loop * through twice, but typically there will be 1-3 iterations, so it is inconsequential. */ $thumb = $media_ns->group->thumbnail[0]; if ($thumb != null) { $thumbAtt = $media_ns->group->thumbnail[0]->attributes(); $this->smallThumb = $thumbAtt['url']; } else { $this->smallThumb = null; } $thumb = $media_ns->group->thumbnail[1]; if ($thumb != null) { $thumbAtt = $thumb->attributes(); $this->mediumThumb = $thumbAtt['url']; } else { $this->mediumThumb = null; } $thumb = $media_ns->group->thumbnail[2]; if ($thumb != null) { $thumbAtt = $thumb->attributes(); $this->largeThumb = $thumbAtt['url']; } else { $this->largeThumb = null; } $this->contentUrlMap = array(); $this->contentHeightMap = array(); $i = 0; $thumb = $media_ns->group->content[$i]; while ($thumb != null) { $thumbAtt = $thumb->attributes(); $width = "" . $thumbAtt['width']; $height = $thumbAtt['height']; $url = $thumbAtt['url']; $this->contentUrlMap[$width] = $url; $this->contentHeightMap[$width] = $height; $i++; $thumb = $media_ns->group->content[$i]; } $this->content = $thumbAtt['url']; $this->imageType = $thumbAtt['type']; // Pull and parse the tags if ($media_ns->group->keywords != null || strcmp($media_ns->group->keywords, "") != 0) { // Make an array for to hold all of a photo's tags $this->tags = array(); /* Tags are stored as a comma-delimited list. * Tokenize the list on comma and strip it to get just the tag. */ $tok = strtok($media_ns->group->keywords, ","); $i = 0; while ($tok != false) { // Set the tag in the array $this->tags[$i] = trim($tok); $tok = strtok(","); $i++; } } else { $this->tags = null; } } else { $this->description = null; $this->keywords = null; $this->smallThumb = null; $this->mediumThumb = null; $this->largeThumb = null; $this->content = null; } if (array_key_exists("gphoto", $namespaces)) { $gphoto_ns = $albums->children($namespaces["gphoto"]); $this->idnum = $gphoto_ns->id; $this->width = $gphoto_ns->width; $this->height = $gphoto_ns->height; $this->albumid = $gphoto_ns->albumid; $this->albumTitle = $gphoto_ns->albumtitle; $this->albumDescription = $gphoto_ns->albumdesc; $this->version = $gphoto_ns->version; $this->timestamp = $gphoto_ns->timestamp; $this->commentingEnabled = $gphoto_ns->commentingEnabled; if (strcmp($gphoto_ns->commentCount, "") == 0 || $gphoto_ns->commentCount === null) { $this->commentCount = null; } else { $this->commentCount = intval($gphoto_ns->commentCount); } } else { $this->idnum = null; $this->width = null; $this->height = null; $this->albumid = null; $this->commentCount = null; $this->version = null; $this->timestamp = null; } if (array_key_exists("exif", $namespaces)) { $exif_ns = $albums->children($namespaces["exif"]); $this->flash = $exif_ns->tags->flash; $this->fstop = $exif_ns->tags->fstop; $this->cameraMake = $exif_ns->tags->make; $this->cameraModel = $exif_ns->tags->model; $this->exposure = $exif_ns->tags->exposure; $this->focalLength = $exif_ns->tags->focallength; $this->iso = $exif_ns->tags->iso; } else { $this->flash = null; $this->fstop = null; $this->cameraMake = null; $this->cameraModel = null; $this->exposure = null; $this->focalLength = null; $this->iso = null; } if (array_key_exists("georss", $namespaces)) { $georss_ns = $albums->children($namespaces["georss"]); $gml_ns = @$georss_ns->children($namespaces["gml"]); if ($gml_ns !== null || $gml_ns !== false) { $this->gmlPosition = @$gml_ns->Point->pos; } else { $this->gmlPosition = null; } } else { $this->gmlPosition = null; } // Set the basic attributes $this->id = $albums->id; $this->title = $albums->title; $this->updated = $albums->updated; if ($albums->author != null && strcmp($albums->author, "") != 0) { $this->author = new Picasa_Author($albums->author); } else { $this->author = new Picasa_Author(); } // The user is not a field in the XML for an image like it is for an album. Thus, we parse. if ($this->author->getUser() == null || strcmp($this->author->getUser(), "") == 0) { $startUser = strpos($this->id, '/user/') + 6; $endUser = strpos($this->id, '/', $startUser); $this->author->setUser(substr($this->id, $startUser, $endUser - $startUser)); } // If there are comments, retrieve them and put them into the comments field of the object if ($this->commentCount === null) { $this->comments = null; } else { if ($this->commentCount === 0) { $this->comments = array(); } else { $this->comments = array(); $i = 0; // Grab each comment and make it into an object foreach ($albums->entry as $comment) { $this->comments[$i] = new Picasa_Comment($comment); $i++; } } } } }
/** * Constructs an Album object. * When called, this method will fill out each private member * of the Album object based on XML returned from Picasa's Atom feed. It will also create * a Picasa_Image object for each image in the Album by passing XML for each image into * the Picasa_Image constructor. * * @param string $url The URL of the Picasa query to retrieve the XML from. See * http://code.google.com/apis/picasaweb/gdata.html for information on * how to format the URL. If null, it is assumed that $albums param * has been supplied. * @param SimpleXMLElement $albums XML for constructing the object. If null, it is assumed that the * URL to the Atom feed has been supplied. If both are null, a * {@link Picasa_Exception} is thrown. * @param array $contextArray An array that can be passed to stream_context_create() to generate * a PHP context. See * {@link http://us2.php.net/manual/en/function.stream-context-create.php} * @param boolean $useCache You can decide not to cache a specific request by passing false here. You may * want to do this, for instance, if you're requesting a private feed. * @throws {@link Picasa_Exception} If the XML suppled through either parameter does not contain valid XML. */ public function __construct($url = null, SimpleXMLElement $albums = null, $contextArray = null, $useCache = true) { if ($url != null) { $xmldata = false; $context = null; Picasa_Logger::getLogger()->logIfEnabled('Request string: ' . $url); if ($contextArray !== null) { $context = stream_context_create($contextArray); } if ($useCache === true) { $xmldata = Picasa_Cache::getCache()->getIfCached($url); } if ($xmldata === false) { Picasa_Logger::getLogger()->logIfEnabled("Not using cached entry for " . $url); $xmldata = @file_get_contents($url, false, $context); if ($useCache === true && $xmldata !== false) { Picasa_Logger::getLogger()->logIfEnabled("Refreshing cache entry for key " . $url); Picasa_Cache::getCache()->setInCache($url, $xmldata); } } if ($xmldata === false) { throw Picasa::getExceptionFromInvalidQuery($url, $contextArray); } try { // Load the XML file into a SimpleXMLElement $albums = new SimpleXMLElement($xmldata); } catch (Exception $e) { throw new Picasa_Exception($e->getMessage(), null, $url); } // I'm not sure why there's a difference, but the icon is given in different ways // depending on if the document is just for an Album or if it's part of a larger document $this->icon = $albums->icon; } // Whether or not the contextArray is null, it should be set. $this->contextArray = $contextArray; if ($albums != null) { $namespaces = $albums->getNamespaces(true); $this->picasaAuthor = new Picasa_Author($albums->author); $this->editLink = null; $link = $albums->link[0]; $i = 0; while ($link != null) { $attributes = $albums->link[$i]->attributes(); if (strcmp($attributes["rel"], "edit") == 0) { $this->editLink = $attributes["href"]; break; } else { if (strcmp($attributes["rel"], "alternate") == 0) { $this->weblink = $attributes["href"]; } } $i++; $link = $albums->link[$i]; } if (array_key_exists("gphoto", $namespaces)) { $gphoto_ns = $albums->children($namespaces["gphoto"]); $this->location = $gphoto_ns->location; $this->idnum = $gphoto_ns->id; $this->numphotos = $gphoto_ns->numphotos; $this->photosRemaining = $gphoto_ns->numphotosremaining; $this->bytesUsed = $gphoto_ns->bytesUsed; $this->commentingEnabled = $gphoto_ns->commentingEnabled; $this->numComments = $gphoto_ns->commentCount; $this->timestamp = $gphoto_ns->timestamp; // The picasaAuthor field must be set before this line is executed if ($this->picasaAuthor->getUser() == null || strcmp($this->picasaAuthor->getUser(), "") == 0) { $this->picasaAuthor->setUser($gphoto_ns->user); } } if (array_key_exists("media", $namespaces)) { $media_ns = $albums->children($namespaces["media"]); // As stated above, this is to account for the different placement of icon if ($url === null) { $thumbAtt = $media_ns->group->thumbnail->attributes(); $this->icon = $thumbAtt["url"]; } } if (array_key_exists("georss", $namespaces)) { $georss_ns = $albums->children($namespaces["georss"]); $gml_ns = $georss_ns->children($namespaces["gml"]); $this->gmlPosition = @$gml_ns->Point->pos; } $this->id = $albums->id; $this->title = $albums->title; $this->updated = $albums->updated; $this->published = $albums->published; $this->summary = $albums->summary; $this->rights = $albums->rights; $this->author = $albums->author->name; $this->subtitle = $albums->subtitle; $this->comments = null; $this->images = array(); $i = 0; //Create a new Image object for each Image element foreach ($albums->entry as $images) { $this->images[$i] = new Picasa_Image(null, $images); $i++; } } }
/** * @todo document this method * @param array $config */ public function configure(array $config) { if (!isset($config['connection']) || !is_array($config['connection'])) { throw new Exception('The \'connection\' configuration parameter is required and this has to be an array'); } $this->_dbConnectionOptions = $config['connection']; $this->_ormConfig = new \Doctrine\ORM\Configuration(); //Create ORM Mapping driver to use if (isset($config['mappingDriver'])) { $driverMappingConfig = $config['mappingDriver']; if (!isset($driverMappingConfig['type']) || !isset($driverMappingConfig['mappingDocsPath'])) { throw new Exception('\'type\' and \'mappingDocsPath\' parameters are required by mapping driver configuration'); } //Get full path to mapping documents if (is_array($driverMappingConfig['mappingDocsPath'])) { foreach ($driverMappingConfig['mappingDocsPath'] as &$path) { $path = \ifc\util\zend\Config::prepareAbsolutePath(APPLICATION_PATH, $path); } } else { $driverMappingConfig['mappingDocsPath'] = \ifc\util\zend\Config::prepareAbsolutePath(APPLICATION_PATH, $driverMappingConfig['mappingDocsPath']); } $driverMappingConfig['type'] = strtolower($driverMappingConfig['type']); switch ($driverMappingConfig['type']) { case 'xml': $driverImpl = new Doctrine\ORM\Mapping\Driver\XmlDriver($driverMappingConfig['mappingDocsPath']); break; case 'yml': $driverImpl = new Doctrine\ORM\Mapping\Driver\YamlDriver($driverMappingConfig['mappingDocsPath']); break; case 'annotation': $driverImpl = $this->_ormConfig->newDefaultAnnotationDriver($driverMappingConfig['mappingDocsPath']); break; case 'php': $driverImpl = new Doctrine\ORM\Mapping\Driver\PHPDriver($driverMappingConfig['mappingDocsPath']); break; default: throw new Exception('Unrecognized ORM driver mapping'); } $this->_ormConfig->setMetadataDriverImpl($driverImpl); } else { throw new Exception('The \'mappingDriver\' configuration parameter is required'); } //Parametrize configuration object if (isset($config['configuration'])) { //Each defined parameters of the {@link \Doctrine\ORM\Configuration} is //the name of one setters methods of the that only receive one parameter // of a simple type /* foreach ($config['configuration'] as $param => $value) { $method = 'set' . $param; if (method_exists($this->_ormConfig, $method)) { $this->_ormConfig->$method($value); } else { throw new Exception($param . ' is is not a correct parameter for ORM Configuration; the accepted parameters to configure the \\Doctrine\\ORM\\Configuration are the name of the setter methods without the \'set\' prefix that accept one parameter of a basic type.'); } }/* */ $configParams = $config['configuration']; // If exist ProxyDir parameter, set the Proxy directori if (isset($configParams['proxyDir'])) { $this->_ormConfig->setProxyDir($path = \ifc\util\zend\Config::prepareAbsolutePath(APPLICATION_PATH, $configParams['proxyDir'])); } // If exist ProxyNamespace parameter, set the Proxy namespace if (isset($configParams['proxyNamespace'])) { $this->_ormConfig->setProxyNamespace($configParams['proxyNamespace']); } // If exist AutoGenerateProxyClasses parameter, set the flag if // the proxy classess have to be autogenerated if (isset($configParams['autoGenerateProxyClasses'])) { $this->_ormConfig->setAutoGenerateProxyClasses($path = \ifc\util\zend\Config::prepareAbsolutePath(APPLICATION_PATH, $configParams['autoGenerateProxyClasses'])); } } //Configure cache if (isset($config['cache'])) { $cacheConfig = $config['cache']; if (!isset($cacheConfig['class'])) { throw new Exception('The \'class\' configuration parameter is required to configure ORM cache'); } if (!class_exists($cacheConfig['class'])) { throw new Exception($cacheConfig['class'] . ' not found'); } $cache = new $cacheConfig['class'](); if (isset($cacheConfig['uses'])) { /* foreach ($cacheConfig['uses'] as $use => $flag) { if ($flag) { $method = 'set' . $use; if (method_exists($this->_ormConfig, $method)) { $this->_ormConfig->$method($cache); } else { throw new Exception($use . ' is is not a correct cache use for ORM Configuration; the accepted parameters to configure the cache of \\Doctrine\\ORM\\Configuration are the name of the setter methods without the \'set\' prefix that accept one parameter of a class that implements \\Doctrine\\Common\\Cache interface.'); } } }/* */ $cacheUseConfig = $cacheConfig['uses']; //Puts the Metadata cache if this is required if (isset($cacheUseConfig['metadata']) && $cacheUseConfig['metadata']) { $this->_ormConfig->setMetadataCacheImpl($cache); } //Puts the Query cache if this is required if (isset($cacheUseConfig['query']) && $cacheUseConfig['query']) { $this->_ormConfig->setQueryCacheImpl($cache); } //Puts the Result cache if this is required if (isset($cacheUseConfig['result']) && $cacheUseConfig['result']) { $this->_ormConfig->setResultCacheImpl($cache); } } } $this->_entityManager = \Doctrine\ORM\EntityManager::create($this->_dbConnectionOptions, $this->_ormConfig, new \Doctrine\Common\EventManager()); }