<?php

    include_once( PLOG_CLASS_PATH."class/plugin/pluginbase.class.php" );
    include_once( PLOG_CLASS_PATH."class/plugin/pluginmanager.class.php" );
    include_once( PLOG_CLASS_PATH."class/net/rawrequestgenerator.class.php" );
    include_once( PLOG_CLASS_PATH."plugins/flickr/class/xml/XMLParser.class.php" );

    //Used as the root for building the img URLs
    define ('FLICKR_PHOTO_ROOT', 'http://www.flickr.com/photos/'); 
    define ('FLICKR_SLIDESHOW_ROOT', 'http://www.flickr.com/slideShow/'); 
    
    //Used as the root for Flickr API service URLs
    define ('FLICKR_GET_PHOTOLIST', 'http://www.flickr.com/services/rest/?method=flickr.photosets.getList&api_key='); 
    define ('FLICKR_GET_PHOTOS', 'http://www.flickr.com/services/rest/?method=flickr.photosets.getPhotos&api_key='); 
    define ('FLICKR_GET_PHOTOINFO', 'http://www.flickr.com/services/rest/?method=flickr.photos.getInfo&api_key=');

    //DO NOT CHANGE OR STEAL THIS
    //This is the API key that was assigned to this plog plugin by Flickr.  
    //If you need an API key for your own project 
    //goto http://flickr.com/services/api/misc.api_keys.html
    define ('FLICKR_API_KEY', '642d5965f8ecba92fb78ff5d83993a02'); 

    /**
     * Plugin that offers features to integrate the Flickr Photo Gallery Service
     */
    class PluginFlickr extends PluginBase
    {
        var $cacheFolder;           //pLog Temp Folder
        var $pluginEnabled;
        var $email;                 //Your Flickr account logon (email address you registered with)
        var $password;              //Your Flickr account password
        var $aliasName;             //Your Flickr alias name
        var $albumThumbnailSize;    //Size of the thumbnail you want to appear in the album thumbnail page
        var $photoThumbnailSize;    //Size of the thumbnail you want to appear in the album thumbnail page
        var $showPrivate;           //Whether or not to show your "private" Flickr photos
        var $showNote;              //Whether or not to show your "notes" of photo
        var $expiredTime;           //Duration for cache expired 
        var $userRoot;              //Root for links in the output

        function PluginFlickr()
        {
            $this->PluginBase();
            
            $this->id = "flickr";
            $this->author = "Mark Wu";
            $this->desc = 'This plugin let you integrate your Flickr with pLog. It is inspired by <a href="http://www.worrad.com/archives/2004/11/23/flickr-gallery-wp-plugin/">Wordpress Flickr Gallery Plugin</a> written by Ray.';

            $this->locales = Array( "en_UK" , "zh_TW" , "zh_CN", "de_DE" );
            
            $this->init();                     
        }

		function init()
		{
            $this->registerAdminAction( "flickr", "PluginFlickrConfigAction" );
			$this->registerAdminAction( "updateFlickrConfig", "PluginFlickrUpdateConfigAction" );
			$this->registerBlogAction( "FlickrShow", "PluginFlickrShowAction" );
			
			$menu =& Menu::getMenu();
			if( !$menu->entryExists( "/menu/controlCenter/manageIntegrationPlugins" ))						
				$this->addMenuEntry( "/menu/controlCenter", "manageIntegrationPlugins", "", "", true, false );			
            $this->addMenuEntry( "/menu/controlCenter/manageIntegrationPlugins", "Flickr", "?op=flickr", "" );            
		}
 
		function register()
		{
            $config =& Config::getConfig();
            $this->cacheFolder = $config->getValue('temp_folder');
			$this->cacheFolder = $this->cacheFolder.'/flickr/'.$this->blogInfo->getId();
			if( !File::exists( $this->cacheFolder )) {
				File::createDir( $this->cacheFolder );
			}
		    
		    $blogSettings = $this->blogInfo->getSettings();
			$this->pluginEnabled = $blogSettings->getValue( "plugin_flickr_enabled" );
			$this->email = $blogSettings->getValue( "plugin_flickr_email" );
            $this->password = $blogSettings->getValue( "plugin_flickr_password" );
            $this->aliasName = $blogSettings->getValue( "plugin_flickr_aliasname" );
            $this->albumThumbnailSize = $blogSettings->getValue( "plugin_flickr_albumthumbnailsize" );
            $this->photoThumbnailSize = $blogSettings->getValue( "plugin_flickr_photothumbnailsize" );
            $this->showPrivate = $blogSettings->getValue( "plugin_flickr_showprivate" );
            $this->showNote = $blogSettings->getValue( "plugin_flickr_shownote" );
            $this->expiredTime = $blogSettings->getValue( "plugin_flickr_expiredtime" );
		}

	    function isEnabled()
	    {
	        return $this->pluginEnabled;
	    }
		
        function pluginTemplatePage()
        {
 			$rg = new RawRequestGenerator($this->blogInfo);
            
        	$rg->addParameter( "op", "FlickrShow" );
            $rg->addParameter( "blogId", $this->blogInfo->getId());

            $templatePage = $rg->getIndexUrl().$rg->getRequest();

            return $templatePage;
        }

        /**
         * Get the photo albums from specific user
         */
        function getPhotoList()
        {
            $apiUrl = FLICKR_GET_PHOTOLIST.FLICKR_API_KEY;
            $apiUrl .= '&email=' . $this->email . '&password=' . $this->password;    

            $this->userRoot = $this->pluginTemplatePage();

            $data = $this->cached_get_file_contents($apiUrl, 'r', $this->expiredTime, $this->cacheFolder);
            $parser =& new XMLParser($data, 'raw', 1);
            $tree = $parser->getTree();
            
            $total_albums = count($tree['RSP']['PHOTOSETS']['PHOTOSET']);
            $albums = Array();
            
            if ($tree['RSP']['PHOTOSETS']['PHOTOSET'][0] != NULL) {
                for ($i = 0; $i < $total_albums; $i++) {
                    $album = Array();
    
                    $albumId = $tree['RSP']['PHOTOSETS']['PHOTOSET'][$i]['ATTRIBUTES']['ID'];
                    $albumPrimary = $tree['RSP']['PHOTOSETS']['PHOTOSET'][$i]['ATTRIBUTES']['PRIMARY'];
                    $albumSecret =$tree['RSP']['PHOTOSETS']['PHOTOSET'][$i]['ATTRIBUTES']['SECRET'];
    
                    $album['title'] = $tree['RSP']['PHOTOSETS']['PHOTOSET'][$i]['TITLE']['VALUE'];
                    $album['description'] = $tree['RSP']['PHOTOSETS']['PHOTOSET'][$i]['DESCRIPTION']['VALUE'];
                    $album['photos'] =$tree['RSP']['PHOTOSETS']['PHOTOSET'][$i]['ATTRIBUTES']['PHOTOS'];
                    $album['thumbnailUrl'] = FLICKR_PHOTO_ROOT.$albumPrimary."_".$albumSecret."_".$this->albumThumbnailSize.".jpg";
                    $album['flickrUrl'] = FLICKR_PHOTO_ROOT.$this->aliasName."/sets/".$albumId;
                    $album['albumUrl'] = $this->userRoot."&album=".$albumId;
                    
                    array_push( $albums, $album);
                }
            } else {
                $album = Array();
    
                $albumId = $tree['RSP']['PHOTOSETS']['PHOTOSET']['ATTRIBUTES']['ID'];
                $albumPrimary = $tree['RSP']['PHOTOSETS']['PHOTOSET']['ATTRIBUTES']['PRIMARY'];
                $albumSecret =$tree['RSP']['PHOTOSETS']['PHOTOSET']['ATTRIBUTES']['SECRET'];
    
                $album['title'] = $tree['RSP']['PHOTOSETS']['PHOTOSET']['TITLE']['VALUE'];
                $album['description'] = $tree['RSP']['PHOTOSETS']['PHOTOSET']['DESCRIPTION']['VALUE'];
                $album['photos'] =$tree['RSP']['PHOTOSETS']['PHOTOSET']['ATTRIBUTES']['PHOTOS'];
                $album['thumbnailUrl'] = FLICKR_PHOTO_ROOT.$albumPrimary."_".$albumSecret."_".$this->albumThumbnailSize.".jpg";
                $album['flickrUrl'] = FLICKR_PHOTO_ROOT.$this->aliasName."/sets/".$albumId;
                $album['albumUrl'] = $this->userRoot."&album=".$albumId;
                    
                array_push( $albums, $album);
            }
            return $albums;
        }

        /**
         * Get the photos from specific photo album
         */
        function getPhotos($albumId)
        {
            $apiUrl = FLICKR_GET_PHOTOS.FLICKR_API_KEY;
            if ($this->showPrivate == 1)
                $apiUrl .= '&photoset_id=' . $albumId;
            else
                $apiUrl .= '&email=' . $this->email . '&password=' . $this->password . '&photoset_id=' . $albumId;
            
            $data = $this->cached_get_file_contents($apiUrl, 'r', $this->expiredTime, $this->cacheFolder);
            $parser =& new XMLParser($data, 'raw', 1);
            $tree = $parser->getTree();

            $this->userRoot = $this->pluginTemplatePage();

            $totalPhotos = count($tree['RSP']['PHOTOSET']['PHOTO']);
            $photos = Array();
            
            if ($tree['RSP']['PHOTOSET']['PHOTO'][0] != NULL) {
                for ($i = 0; $i < $totalPhotos; $i++) {
                    $photo = Array();
    
                    $photoId = $tree['RSP']['PHOTOSET']['PHOTO'][$i]['ATTRIBUTES']['ID'];
                    $photoSecret =$tree['RSP']['PHOTOSET']['PHOTO'][$i]['ATTRIBUTES']['SECRET'];
    
                    $photo['thumbnailUrl'] = FLICKR_PHOTO_ROOT.$photoId."_".$photoSecret."_".$this->photoThumbnailSize.".jpg";
                    $photo['flickrUrl'] = FLICKR_PHOTO_ROOT.$this->aliasName."/".$photoId."/in/set".$albumId;
                    $photo['photoUrl'] = $this->userRoot."&album=".$albumId."&photo=".$photoId."&secret=".$photoSecret;
                    
                    array_push( $photos, $photo);
                }
            } else {
                $photo = Array();
    
                $photoId = $tree['RSP']['PHOTOSET']['PHOTO']['ATTRIBUTES']['ID'];
                $photoSecret =$tree['RSP']['PHOTOSET']['PHOTO']['ATTRIBUTES']['SECRET'];
    
                $photo['thumbnailUrl'] = FLICKR_PHOTO_ROOT.$photoId."_".$photoSecret."_".$this->photoThumbnailSize.".jpg";
                $photo['flickrUrl'] = FLICKR_PHOTO_ROOT.$this->aliasName."/".$photoId."/in/set".$albumId;
                $photo['photoUrl'] = $this->userRoot."&album=".$albumId."&photo=".$photoId."&secret=".$photoSecret;
                    
                array_push( $photos, $photo);
            }
            return $photos;
        }

        /**
         * Get the photo info from specific photo
         */
        function getPhotoInfo($photoId, $photoSecret)
        {
            $apiUrl = FLICKR_GET_PHOTOINFO.FLICKR_API_KEY;
            if ($this->showPrivate == 1)
                $apiUrl .= '&photo_id=' . $photoId;
            else
                $apiUrl .= '&email=' . $this->email . '&password=' . $this->password . '&photo_id=' . $photoId;
            
            $this->userRoot = $this->pluginTemplatePage(); 
 
            $data = $this->cached_get_file_contents($apiUrl, 'r', $this->expiredTime, $this->cacheFolder);
            $parser =& new XMLParser($data, 'raw', 1);
            $tree = $parser->getTree();
            
            $photo = Array();

            $photo['date'] = $tree['RSP']['PHOTO']['ATTRIBUTES']['DATEUPLOADED'];
            $photo['title'] = $tree['RSP']['PHOTO']['TITLE']['VALUE'];
            $photo['description'] = $tree['RSP']['PHOTO']['DESCRIPTION']['VALUE'];
            $photo['comments'] = $tree['RSP']['PHOTO']['COMMENTS']['VALUE'];
            
            $photo['resizeimageUrl'] = FLICKR_PHOTO_ROOT.$photoId."_".$photoSecret.".jpg";
            $photo['originalimageUrl'] = FLICKR_PHOTO_ROOT.$photoId."_".$photoSecret."_o.jpg";
            $photo['flickrUrl'] = FLICKR_PHOTO_ROOT.$this->aliasName."/".$photoId;

            $tagCount = count($tree['RSP']['PHOTO']['TAGS']['TAG']);
            
            if ($tree['RSP']['PHOTO']['TAGS']['TAG'][0] != NULL) {
                for ($i = 0; $i < $tagCount; $i=$i+1) {
                    $photo['tags'][$i]['tagName'] = $tree['RSP']['PHOTO']['TAGS']['TAG'][$i]['VALUE'];
                    $photo['tags'][$i]['tagUrl'] = FLICKR_PHOTO_ROOT."tags/".$tree['RSP']['PHOTO']['TAGS']['TAG'][$i]['VALUE'];
                }
            } else {
                $photo['tags'][0]['tagName'] = $tree['RSP']['PHOTO']['TAGS']['TAG']['VALUE'];
                $photo['tags'][0]['tagUrl'] = FLICKR_PHOTO_ROOT."tags/".$tree['RSP']['PHOTO']['TAGS']['TAG']['VALUE'];
            }
                
            $noteCount = count($tree['RSP']['PHOTO']['NOTES']['NOTE']);
            
            if ($this->showNote) {
                if ($tree['RSP']['PHOTO']['NOTES']['NOTE'][0] != NULL) {
                    for ($i = 0; $i < $noteCount; $i=$i+1) {
                        $photo['notes'][$i]['noteDesc'] = $tree['RSP']['PHOTO']['NOTES']['NOTE'][$i]['VALUE'];
                        $photo['notes'][$i]['noteX'] = $tree['RSP']['PHOTO']['NOTES']['NOTE'][$i]['ATTRIBUTES']['X'];
                        $photo['notes'][$i]['noteY'] = $tree['RSP']['PHOTO']['NOTES']['NOTE'][$i]['ATTRIBUTES']['Y'];
                        $photo['notes'][$i]['noteW'] = $tree['RSP']['PHOTO']['NOTES']['NOTE'][$i]['ATTRIBUTES']['W'];
                        $photo['notes'][$i]['noteH'] = $tree['RSP']['PHOTO']['NOTES']['NOTE'][$i]['ATTRIBUTES']['H'];
                    }
                } else {
                    $photo['notes'][0]['noteDesc'] = $tree['RSP']['PHOTO']['NOTES']['NOTE']['VALUE'];
                    $photo['notes'][0]['noteX'] = $tree['RSP']['PHOTO']['NOTES']['NOTE']['ATTRIBUTES']['X'];
                    $photo['notes'][0]['noteY'] = $tree['RSP']['PHOTO']['NOTES']['NOTE']['ATTRIBUTES']['Y'];
                    $photo['notes'][0]['noteW'] = $tree['RSP']['PHOTO']['NOTES']['NOTE']['ATTRIBUTES']['W'];
                    $photo['notes'][0]['noteH'] = $tree['RSP']['PHOTO']['NOTES']['NOTE']['ATTRIBUTES']['H'];
                }
            }

            return $photo;
        }

        /**
         * Get the photo navigation from specific photo album
         */
        function getPhotoNavigation($albumId, $currentPhotoId)
        {
            $apiUrl = FLICKR_GET_PHOTOS.FLICKR_API_KEY;
            if ($this->showPrivate == 1)
                $apiUrl .= '&photoset_id=' . $albumId;
            else
                $apiUrl .= '&email=' . $this->email . '&password=' . $this->password . '&photoset_id=' . $albumId;
            
            $data = $this->cached_get_file_contents($apiUrl, 'r', $this->expiredTime, $this->cacheFolder);
            $parser =& new XMLParser($data, 'raw', 1);
            $tree = $parser->getTree();

            $this->userRoot = $this->pluginTemplatePage();

            $totalPhotos = count($tree['RSP']['PHOTOSET']['PHOTO']);
            
            $navigationUrl = Array();
            
            if ($tree['RSP']['PHOTOSET']['PHOTO'][0] != NULL) {
                for ($i = 0; $i < $totalPhotos; $i++) {
                    $photoId = $tree['RSP']['PHOTOSET']['PHOTO'][$i]['ATTRIBUTES']['ID'];
                    if ( $photoId == $currentPhotoId ) {
                        if ($i == 0) {
                            $prevPhotoUrl = '';
                            
                            $nextPhotoId = $tree['RSP']['PHOTOSET']['PHOTO'][$i+1]['ATTRIBUTES']['ID'];
                            $nextPhotoSecret =$tree['RSP']['PHOTOSET']['PHOTO'][$i+1]['ATTRIBUTES']['SECRET'];
                            $nextPhotoUrl = $this->userRoot."&album=".$albumId."&photo=".$nextPhotoId."&secret=".$nextPhotoSecret;
                        } elseif ($i < $totalPhotos-1) {
                            $prevPhotoId = $tree['RSP']['PHOTOSET']['PHOTO'][$i-1]['ATTRIBUTES']['ID'];
                            $prevPhotoSecret =$tree['RSP']['PHOTOSET']['PHOTO'][$i-1]['ATTRIBUTES']['SECRET'];
                            $prevPhotoUrl = $this->userRoot."&album=".$albumId."&photo=".$prevPhotoId."&secret=".$prevPhotoSecret;
                            
                            $nextPhotoId = $tree['RSP']['PHOTOSET']['PHOTO'][$i+1]['ATTRIBUTES']['ID'];
                            $nextPhotoSecret =$tree['RSP']['PHOTOSET']['PHOTO'][$i+1]['ATTRIBUTES']['SECRET'];
                            $nextPhotoUrl = $this->userRoot."&album=".$albumId."&photo=".$nextPhotoId."&secret=".$nextPhotoSecret;
                        } else {
                            $prevPhotoId = $tree['RSP']['PHOTOSET']['PHOTO'][$i-1]['ATTRIBUTES']['ID'];
                            $prevPhotoSecret =$tree['RSP']['PHOTOSET']['PHOTO'][$i-1]['ATTRIBUTES']['SECRET'];
                            $prevPhotoUrl = $this->userRoot."&album=".$albumId."&photo=".$prevPhotoId."&secret=".$prevPhotoSecret;
                            
                            $nextPhotoUrl = '';
                        }
                        $navigationUrl['prevPhotoUrl'] = $prevPhotoUrl;
                        $navigationUrl['nextPhotoUrl'] = $nextPhotoUrl;
                        return $navigationUrl;
                    }
                }
            } else {
                $navigationUrl['prevPhotoUrl'] = '';
                $navigationUrl['nextPhotoUrl'] = '';
                return $navigationUrl;
            }
        }        

        /**
         * Get the slide show of specific photo album
         */
        function getSlideShowUrl($albumId)
        {
            return FLICKR_SLIDESHOW_ROOT."index.gne?set_id=".$albumId;
        }
        
        function getAlbumUrl($albumId)
        {
            return $this->pluginTemplatePage()."&album=".$albumId;
        }        

        /**
         * Function that reads file from the cache if it is younger than a certain age 
         * and otherwise grabs a fresh copy of it from remote source 
         */
        function cached_get_file_contents ($file, $file_mode, $cache_timeout = 3600, $cache_path = '../', $debug = false)
        {
        	// Clear file stats so we get an accurate file creation time for cache files
        	clearstatcache();
        	
        	$encode_file = "%%Flickr%%".md5($file);
        	
        	// Path to cached file
        	$cache_filename = $cache_path .'/' . $encode_file . ".cached";
        
        	if ($debug)
        	{
        		print "local_cache creation_time =" . @filemtime($cache_filename) . " actual time = " . time() . " timeout = " . $timeout_seconds ."\n";
        	}
        
        	if (( @file_exists($cache_filename) && (( @filemtime($cache_filename) + $cache_timeout) > ( time())))) // If file exists and is young enough then do nothing because it will return file contents of cache
        	{
        		if ($debug)
        		{
        			print "using cached file ($cache_filename)\n";
        		}
        	} 
        	else // If file doesn't exist or is too old get a fresh copy from remote source
        	{
        		if ($debug)
        		{
        			print "cacheing file ($file) to local ($cache_filename)\n";
        		}
        
        		$f = @fopen($file,"r"); // Open remote source file
        		if (!$f) // Remote file couldn't be opened
        		{
        			return @file_get_contents ($cache_filename); // Return the file contents from the cache
        		}
        		$f2 = @fopen($cache_filename,"w+"); // Open local cache file
        		while ($r = @fread($f,8192)) // Loop through remote source file
        		{
        			@fwrite($f2,$r); // Write to the local cache
        		}
        		@fclose($f2);
        		@fclose($f);
        	}
        
        	return file_get_contents ($cache_filename); // Return the file contents from the cache
        }
    }
?>
