railpage/railpagecore

View on GitHub
lib/Gallery/Album.php

Summary

Maintainability
F
5 days
Test Coverage
<?php

/**
 * Old Gallery1-migrated user album
 * @since Version 3.8.7
 * @package Railpage
 * @author Michael Greenhill
 */

namespace Railpage\Gallery;

use Exception;
use DateTime;
use Railpage\Users\User;
use Railpage\Users\Factory as UserFactory;
use Railpage\Module;
use Railpage\Url;
use Railpage\AppCore;
use Railpage\ContentUtility;

/**
 * Album
 */

class Album extends AppCore {
    
    /**
     * On-disk root path
     * @since Version 3.10.0
     * @const string ALBUMS_DIR
     */
    
    const ALBUMS_DIR = "/srv/railpage.com.au/old.www/public_html/modules/gallery/albums/";
    
    /**
     * Do we need to update these photos or not?
     * @since Version 3.8.7
     * @const boolean UPDATE_PHOTO
     */
    
    const UPDATE_PHOTO = true;
    
    /**
     * Album ID
     * @since Version 3.8.7
     * @var int $id
     */
    
    public $id;
    
    /**
     * Album name
     * @since Version 3.8.7
     * @var string $name
     */
    
    public $name;
    
    /**
     * URL slug
     * @since Version 3.8.7
     * @var string $slug
     */
    
    public $slug;
    
    /**
     * Album meta data
     * @since Version 3.8.7
     * @var array $meta
     */
    
    public $meta;
    
    /**
     * Album owner
     * @since Version 3.8.7
     * @var \Railpage\Users\User $Owner
     */
    
    public $Owner;
    
    /**
     * Featured image
     * @since Version 3.8.7
     * @var \Railpage\Gallery\Image $FeaturedImage
     */
    
    public $FeaturedImage;
    
    /**
     * The parent album
     * @since Version 3.10.0
     * @var \Railpage\Gallery\Album $ParentAlbum
     */
    
    private $ParentAlbum;
    
    /**
     * Constructor
     * @since Version 3.8.7
     * @param int|string $id
     */
    
    public function __construct($id = null) {
        
        parent::__construct();
        
        $this->Module = new Module("Gallery");
        
        // Rewrite - some album titles can be all numbers (eg 639, 8203)
        if ($id != null) {
            // First, assume that the album ID is a string. Let's try to get the ID from that
            $query = "SELECT id FROM gallery_mig_album WHERE name = ?";
            $this->id = $this->db->fetchOne($query, $id);
            
            // If the value returned from the database is false, there's no album 
            // by that name so let's assume the name provided is actually an ID
            if (!$this->id) {
                $this->id = $id;
            }
        }
        
        if (filter_var($this->id, FILTER_VALIDATE_INT)) {
            $this->mckey = sprintf("railpage:gallery.album=%d", $this->id);
            
            if (!$data = $this->Memcached->fetch($this->mckey)) {
                $query = "SELECT * FROM gallery_mig_album WHERE id = ?";
                
                $data = $this->db->fetchRow($query, $this->id);
                
                $this->Memcached->save($this->mckey, $data, strtotime("+1 year"));
            }
            
            $this->name = $data['title'];
            $this->meta = json_decode($data['meta'], true);
            $this->owner = $data['owner'];
            $this->slug = $data['name'];
            $this->featured_photo_id = $data['featured_photo'];
            
            $this->url = new Url(sprintf("%s?album=%s", $this->Module->url, $data['name']));
            $this->url->edit = sprintf("%s?album=%s&mode=album.edit", $this->Module->url, $data['name']);
            $this->url->new = sprintf("%s?mode=album.edit&parent_id=%d", $this->Module->url, $this->id);
            $this->url->upload = sprintf("%s?album=%s&mode=album.upload", $this->Module->url, $data['name']);
            
            if (self::UPDATE_PHOTO) {
                $data['featured_photo'] = $this->updateFeaturedImage(); 
                $this->Memcached->save($this->mckey, $data, strtotime("+1 year"));
            }
        
            if (isset($data['featured_photo']) && filter_var($data['featured_photo'], FILTER_VALIDATE_INT)) {
                $this->FeaturedImage = new Image($data['featured_photo']);
            }
        }
        
        if (!empty($this->id) && !preg_match("/([a-zA-Z]+)/", $this->id)) {
            $this->id = intval($this->id);
        }
    }
    
    /**
     * List photos in this album
     * @since Version 3.8.7
     * @yield new \Railpage\Gallery\Image
     */
    
    public function getImages() {
        $query = "SELECT id FROM gallery_mig_image WHERE album_id = ? AND hidden = ? ORDER BY id";
        
        $results = $this->db->fetchAll($query, array($this->id, 0));
        
        foreach ($results as $image) {
            yield new Image($image['id']);
        }
    }
    
    /**
     * Get a single image from this album
     * @since Version 3.9
     * @yield new \Railpage\Gallery\Image
     * @param string $imageId
     */
    
    public function getImage($imageId) {
        if (!filter_var($imageId, FILTER_VALIDATE_INT)) {
            $query = "SELECT id FROM gallery_mig_image WHERE album_id = ? AND meta LIKE ?";
            
            $imageId = $this->db->fetchOne($query, array($this->id, "%" . $imageId . "%"));
        }
        
        return new Image($imageId);
    }
    
    /**
     * List the albums available
     * @since Version 3.8.7
     * @yield \Railpage\Gallery\Album
     */
    
    public function yieldAlbums() {
        $query = "SELECT id FROM gallery_mig_album WHERE parent_id = ? ORDER BY title";
        
        foreach ($this->db->fetchAll($query, $this->id) as $album) {
            yield new Album($album['id']);
        }
    }
    
    /**
     * Get all child albums as an array
     * @since Version 3.8.7
     * @return array
     */
    
    public function getAlbums($page, $limit = 25) {
        if (!$return = $this->Memcached->fetch(sprintf("railpage:gallery.old.album=%d.subalbums.page=%d.perpage=%d", $this->id, $page, $limit))) {
            $Sphinx = $this->getSphinx(); 
            
            $query = $Sphinx->select("*")
                    ->from("idx_gallery_album")
                    ->where("parent_id", "=", $this->id)
                    ->orderBy("album_title", "ASC")
                    ->limit(($page - 1) * $limit, $limit);
            
            $matches = $query->execute(); 
            
            $meta = $Sphinx->query("SHOW META");
            $meta = $meta->execute();
            
            foreach ($matches as $id => $row) {
                $row['album_meta'] = json_decode($row['album_meta'], true);
                
                $matches[$id] = $row;
            }
            
            $return = array(
                "total" => $meta[1]['Value'],
                "page" => $page,
                "perpage" => $limit,
                "albums" => $matches
            );
            
            $this->Memcached->save(sprintf("railpage:gallery.old.album=%d.subalbums.page=%d.perpage=%d", $this->id, $page, $limit), $return);
        }
        
        return $return;
    }
    
    /**
     * Get the parent album
     * @since Version 3.8.7
     * @return \Railpage\Gallery\Album
     */
    
    public function getParent() {
        
        if ($this->ParentAlbum instanceof Album) {
            return $this->ParentAlbum;
        }
        
        $query = "SELECT parent_id FROM gallery_mig_album WHERE id = ?";
        
        $id = $this->db->fetchOne($query, $this->id);
        
        if (filter_var($id, FILTER_VALIDATE_INT) && $id > 0) {
            return new Album($id);
        }
        
        return false;
        
    }
    
    /**
     * Set the parent album
     * @since Version 3.10.0
     * @param \Railpage\Gallery\Album $albumObject
     * @return \Railpage\Gallery\Album $this
     */
    
    public function setParent(Album $albumObject) {
        
        $this->ParentAlbum = $albumObject;
        
        return $this;
        
    }
    
    /**
     * Load the owner of this album
     * @since Version 3.8.7
     * @return \Railpage\Users\User
     */
    
    public function getOwner() {
        
        if ($this->Owner instanceof User) {
            return $this->Owner;
        }
        
        if (filter_var($this->owner, FILTER_VALIDATE_INT)) {
            try {
                return UserFactory::CreateUser($this->owner);
            } catch (Exception $e) {
                // Don't care
            }
        
        }
        
    }
    
    /**
     * Set the album owner
     * @since Version 3.10.0
     * @param \Railpage\Users\User $userObject
     * @return \Railpage\Gallery\Album
     */
    
    public function setOwner(User $userObject) {
        
        $this->Owner = $userObject; 
        
        return $this;
        
    }
    
    /**
     * Update the featured image for this album
     * @since Version 3.8.7
     * @return int
     */
    
    public function updateFeaturedImage() {
        
        $data = array(
            "featured_photo" => $this->featured_photo_id
        );
        
        /*
         * Update the featured photo by album images
         */
        
        if (!isset($data['featured_photo']) || !filter_var($data['featured_photo'], FILTER_VALIDATE_INT) || $data['featured_photo'] == 1) {
            foreach ($this->getImages() as $Image) {
                if (!$Image->hidden) {
                    $data['featured_photo'] = $Image->id;
                    
                    $this->db->update("gallery_mig_album", $data, array("id = ?" => $this->id));
                    $this->Memcached->delete($this->mckey);
                    #$this->Memcached->save($this->mckey, $data, strtotime("+1 year"));
                    break;
                }
            }
        }
        
        /**
         * Update the featured photo by sub-album images
         */
        
        if (!isset($data['featured_photo']) || !filter_var($data['featured_photo'], FILTER_VALIDATE_INT) || $data['featured_photo'] == 1) {
            foreach ($this->yieldAlbums() as $Album) {
                foreach ($Album->getImages() as $Image) {
                    if (!$Image->hidden) {
                        $data['featured_photo'] = $Image->id;
                        
                        $this->db->update("gallery_mig_album", $data, array("id = ?" => $this->id));
                        $this->Memcached->delete($this->mckey);
                        #$this->Memcached->save($this->mckey, $data, strtotime("+1 year"));
                        break;
                    }
                }
                
                if (isset($data['featured_photo']) && filter_var($data['featured_photo'], FILTER_VALIDATE_INT)) {
                    break;
                }
            }
        }
        
        return $data['featured_photo'];
    }
    
    /**
     * Get this album as an array
     * @since Version 3.10.0
     * @return array
     */
    
    public function getArray() {
        
        $album = array(
            "id" => $this->id,
            "name" => $this->name,
            "url" => $this->url instanceof Url ? $this->url->getUrls() : array(),
            "num_photos" => $this->meta['fields']['cached_photo_count'],
            "num_albums" => 0,
            "mckey" => urlencode($this->mckey)
        );
        
        $AlbumOwner = $this->getOwner();
        
        if ($AlbumOwner instanceof User) {
            $album['owner'] = array(
                "id" => $AlbumOwner->id,
                "username" => $AlbumOwner->username,
                "url" => $AlbumOwner->url->getUrls(),
                "avatar" => array(
                    "small" => format_avatar($AlbumOwner->avatar, 40),
                    "large" => format_avatar($AlbumOwner->avatar, 120)
                )
            );
        }
        
        return $album;
        
    }
    
    /**
     * Validate changes to this album
     * @since Version 3.10.0
     * @return boolean
     * @throws \Exception if $this->name is empty
     * @throws \Exception if $this->Author is empty
     */
    
    private function validate() {
        
        if (empty($this->name)) {
            throw new Exception("Album name is empty"); 
        }
        
        if (empty($this->slug)) {
            $this->slug = ContentUtility::generateUrlSlug($this->name, 30);
            
            $query = "SELECT id FROM gallery_mig_album WHERE name = ?";
            $rs = $this->db->fetchAll($query, $this->slug); 
            
            if (count($rs)) {
                $this->slug .= count($rs); 
            }
        }
        
        if (!$this->Owner instanceof User) {
            $this->Owner = $this->getOwner();
        }
        
        if (!$this->Owner instanceof User) {
            throw new Exception("No valid album owner has been set"); 
        }
        
        return true;
        
    }
    
    /**
     * Flush the cache for this album
     * @since Version 3.10.0
     * @return \Railpage\Gallery\Album
     */
    
    public function flushCache() {
        
        $this->Memcached->delete($this->mckey); 
        
        for ($i = 1; $i < 10; $i++) {
            $this->Memcached->delete(sprintf("railpage:gallery.old.album=%d.subalbums.page=%d.perpage=%d", $this->id, $i, 25));
        }
        
        return $this;
        
    }
    
    /**
     * Commit changes
     * @since Version 3.10.0
     * @return \Railpage\Gallery\Album
     */
    
    public function commit() {
        
        $this->validate(); 
        
        $data = [
            "title" => $this->name,
            "meta" => json_encode($this->meta),
            "owner" => $this->Owner->id,
            "owner_id" => $this->Owner->id,
            "name" => $this->slug,
            "featured_photo" => $this->featured_photo_id,
        ];
        
        if ($Album = $this->getParent()) {
            $data['parent_id'] = $Album->id;
            $data['parent'] = $Album->slug;
        }
        
        if (filter_var($this->id, FILTER_VALIDATE_INT)) {
            $where = [ "id = ?" => $this->id ];
            $this->db->update("gallery_mig_album", $data, $where); 
        }
        
        
        if (!filter_var($this->id, FILTER_VALIDATE_INT)) {
            $this->db->insert("gallery_mig_album", $data); 
            $this->id = $this->db->lastInsertId(); 
        }
        
        $this->flushCache(); 
        $this->getParent()->flushCache(); 
        
        return $this;
        
    }
}