railpage/railpagecore

View on GitHub
lib/Railcams/Storage.php

Summary

Maintainability
D
1 day
Test Coverage
<?php

/**
 * Railcam footage storage class
 * @since Version 3.10.0
 * @package Railpage
 * @author Michael Greenhill
 */

namespace Railpage\Railcams;

use Exception;
use InvalidArgumentException;
use DateTime;
use DateTimeZone;
use Railpage\AppCore;
use Railpage\Debug;
use Railpage\Url;
use Zend_Db_Expr;

class Storage {
    
    /**
     * Railcam storage ID
     * @since Version 3.10.0
     * @var int $id
     */
    
    public $id; 
    
    /**
     * Is this the primary storage destination for this railcam?
     * @since Version 3.10.0
     * @var bool $primary
     */
    
    private $primary = false;
    
    /**
     * Railcam object
     * @since Version 3.10.0
     * @var \Railpage\Railcams\Camera $cameraObject
     */
    
    private $cameraObject; 
    
    /**
     * Database object
     * @since Version 3.10.0
     * @var object $db
     */
    
    private $db;
    
    /**
     * Storage type
     * @since Version 3.10.0
     * @var string $type
     */
    
    private $type;
    
    /**
     * Storage configuration
     * @since Version 3.10.0
     * @var array $config
     */
    
    private $config;
    
    /**
     * Constructor
     * @since Version 3.10.0
     * @return \Railpage\Railcams\Storage
     */
    
    public function __construct($id = null) {
        
        $this->db = AppCore::GetDatabase(); 
        
        if (filter_var($id, FILTER_VALIDATE_INT)) {
            $this->id = $id; 
            $this->getConfig();
        }
        
    }
    
    /**
     * Set our railcam object
     * @since Version 3.10.0
     * @param \Railpage\Railcams\Camera $cameraObject
     * @return \Railpage\Railcams\Storage
     */
    
    public function setCamera(Camera $cameraObject) {
        
        $this->cameraObject = $cameraObject; 
        
        return $this;
        
    }
    
    /**
     * Set the image capture time
     * @since Version 3.10.0
     * @param \DateTime $timeStamp
     * @return \Railpage\Railcams\Storage
     */
    
    public function setTimestamp(DateTime $timeStamp) {
        
        $this->timeStamp = $timeStamp; 
        
        return $this;
        
    }
    
    /**
     * Set our storage type
     * @since Version 3.10.0
     * @param string $type
     * @return \Railpage\Railcams\Storage
     */
    
    public function setType($type = null) {
        
        $class = sprintf("\\Railpage\\Railcams\\Storage\\%s", $type); 
        
        if (!class_exists($class)) {
            throw new InvalidArgumentException("The desired storage type " . $type . " is invalid"); 
        }
        
        $this->type = $type; 
        
        return $this;
        
    }
    
    /**
     * Set our storage type configuration
     * @since Version 3.10.0
     * @param array $config
     * @return \Railpage\Railcams\Storage
     */
    
    public function setConfig($config = null) {
        
        if ($this->type == "LocalFS") {
            if (substr($config['storageRoot'], -1) != "/") {
                $config['storageRoot'] .= "/"; 
            }
            
            if (substr($config['storageRoot'], -3) != $this->cameraObject->id . "/") {
               $config['storageRoot'] .= $this->cameraObject->id . "/"; 
            }
            
            if (substr($config['webRoot'], -1) != "/") {
                $config['webRoot'] .= "/"; 
            }
            
            if (substr($config['webRoot'], -3) != $this->cameraObject->id . "/") {
               $config['webRoot'] .= $this->cameraObject->id . "/"; 
            }
            
        }
        
        $this->config = $config; 
        
        $data = [
            "camera_id" => $this->cameraObject->id,
            "type" => $this->type, 
            "config" => json_encode($this->config)
        ];
        
        if (filter_var($this->id, FILTER_VALIDATE_INT)) {
            $where = [ "id = ?" => $this->id ]; 
            $this->db->update("railcam_storage", $data, $where);
            
            return $this;
        }
        
        $this->db->insert("railcam_storage", $data, $where); 
        $this->id = $this->db->lastInsertId();
        
        return $this;
        
    }
    
    /**
     * Get the configuration for this storage destination
     * @since Version 3.10.0
     * @return array
     */
    
    public function getConfig() {
        
        if (!count($this->config)) {
            $query = "SELECT * FROM railcam_storage WHERE id = ?"; 
            $row = $this->db->fetchRow($query, $this->id); 
            $this->type = $row['type']; 
            $this->config = json_decode($row['config'], true); 
            $this->primary = (bool) $row['camera_primary']; 
            
            $this->setCamera(new Camera($row['camera_id']));
        }
        
        return $this->config; 
        
    }
    
    /**
     * Set this as the primary storage destination for our railcam
     * @since Version 3.10.0
     * @throws \Exception if $this->cameraObject has not been set
     * @return \Railpage\Railcams\Storage
     */
    
    public function setPrimary() {
        
        if (!$this->cameraObject instanceof Camera) {
            throw new Exception("Cannot set as primary storage destination, as no railcam has been set"); 
        }
        
        if (!filter_var($this->id, FILTER_VALIDATE_INT)) {
            throw new Exception("Cannot set this as the primary storage destination as it has not been saved to database yet"); 
        }
        
        $data = [ "camera_primary" => 0 ];
        $where = [ "camera_id = ?" => $this->cameraObject->id ]; 
        
        $this->db->update("railcam_storage", $data, $where); 
        
        $data = [ "camera_primary" => 1 ];
        $where = [ "id = ?" => $this->id ];
        
        $this->db->update("railcam_storage", $data, $where); 
        $this->primary = true; 
        
        return $this;
        
    }
    
    /**
     * Is this storage destination the primary destination for this railcam?
     * @since Version 3.10.0
     * @return boolean
     */
    
    public function isPrimary() {
        
        return $this->primary; 
        
    }
    
    /**
     * Get the primary storage destination for this railcam
     * @since Version 3.10.0
     * @return \Railpage\Railcams\Storage
     */
    
    public function getPrimary() {
        
        if ($this->isPrimary()) {
            return $this;
        }
        
        $query = "SELECT id FROM railcam_storage WHERE camera_id = ? AND camera_primary = 1"; 
        if ($id = $this->db->fetchOne($query, $this->cameraObject->id)) {
            return new Storage($id); 
        }
        
        $this->setPrimary(); 
        
        return $this;
        
    }
    
    /**
     * Put new railcam footage in our storage destination
     * @since Version 3.10.0
     * @param string $tmpFile
     * @param string $origFile
     * @return int 
     */
    
    public function putFootage($tmpFile = null, $origFile = null) {
        
        if (count($this->config) === 0) {
            throw new Exception("Cannot put railcam footage - storage configuration has not been set"); 
        }
        
        if ($this->type == null) {
            throw new Exception("Cannot put railcam footage - storage type has not been set"); 
        }
        
        $storageType = sprintf("\\Railpage\\Railcams\\Storage\\%s", $this->type); 
        $storageType = new $storageType; 
        $storageType->setConfig($this->getConfig())->putFile($tmpFile, $origFile); 
        
        $fileInfo = $storageType->getFileInfo(); 
        
        // insert
        $data = [
            "datestored" => $this->timeStamp->format("Y-m-d H:i:s"),
            "railcam_id" => $this->cameraObject->id,
            "type" => $fileInfo['type'],
            "duration" => $fileInfo['duration'],
            "remote_id" => $fileInfo['remote_id'],
            "storage_id" => $this->id,
            "fileinfo" => json_encode($fileInfo)
        ];
        
        $this->db->insert("railcam_footage", $data); 
        
        $this->footageId = $this->db->lastInsertId();
        
    }
    
    /**
     * Get information about a piece of railcam footage from the database
     * @since Version 3.10.0
     * @param int $id
     * @return \Railpage\Railcams\Footage
     */
    
    public function getFootage($id = null) {
        
        $query = "SELECT * FROM railcam_footage WHERE id = ?"; 
        
        return $this->db->fetchRow($query, $id); 
        
    }
    
    /**
     * Get the footage type from the mime type
     * @since Version 3.10.0
     * @param string $mime
     * @return string
     */
    
    public static function getTypeFromMime($mime) {
        
        if (strpos($mime, "image") !== false) {
            return "image";
        }
        
        return "video";
        
    }
    
    /**
     * Get the web URL for a piece of footage
     * @since Version 3.10.0
     * @param array $fileInfo
     * @return string
     */
    
    public function getWebUrl($fileInfo) {
        
        return $this->config['webRoot'] . $fileInfo['path'];
        
    }
    
}