* @link http://getkirby.com * @copyright Bastian Allgeier * @license http://www.opensource.org/licenses/mit-license.php MIT License */ class Media { // optional url where the file is reachable public $url = null; // the full path for the file protected $root = null; // the filename including the extension protected $filename = null; // the name excluding the extension protected $name = null; // the extension of the file protected $extension = null; // the content of the file protected $content = null; // cache for various data protected $cache = array(); /** * Constructor * * @param string $root */ public function __construct($root, $url = null) { $this->url = $url; $this->root = $root === null ? $root : realpath($root); $this->filename = basename($root); $this->name = pathinfo($root, PATHINFO_FILENAME); $this->extension = strtolower(pathinfo($root, PATHINFO_EXTENSION)); } /** * Resets the internal cache */ public function reset() { $this->cache = array(); } /** * Returns the full root of the asset * * @return string */ public function root() { return $this->root; } /** * Returns the url * * @return string */ public function url() { return $this->url; } /** * Returns a md5 hash of the root */ public function hash() { return md5($this->root); } /** * Returns the parent directory path * * @return string */ public function dir() { return dirname($this->root); } /** * Returns the filename of the file * i.e. somefile.jpg * * @return string */ public function filename() { return $this->filename; } /** * Returns the name of the file without extension * * @return string */ public function name() { return $this->name; } /** * Returns the filename as safe name * * @return string */ public function safeName() { return f::safeName($this->filename()); } /** * Returns the extension of the file * i.e. jpg * * @return string */ public function extension() { // return the current extension return $this->extension; } /** * Reads the file content and parses it * * @param string $format * @return mixed */ public function read($format = null) { return str::parse($this->content(), $format); } /** * Setter and getter for the file content * * @param string $content * @return string */ public function content($content = null, $format = null) { if(!is_null($content)) { if(is_array($content)) { switch($format) { case 'json': $content = json_encode($content); break; case 'yaml': $content = yaml::encode($content); break; default: $content = serialize($content); break; } } else if(is_object($content)) { $content = serialize($content); } return $this->content = $content; } if(is_null($this->content)) { $this->content = file_get_contents($this->root); } return $this->content; } /** * Saves the file * * @param string $content * @return boolean */ public function save($content = null, $format = null) { $content = $this->content($content, $format); return f::write($this->root, $content); } /** * Alternative for save * * @param string $content * @return boolean */ public function write($content = null, $format = null) { return $this->save($content, $format); } /** * Change the file's modification date to now * and create it with an empty content if it is not there yet * * @return boolean */ public function touch() { return touch($this->root); } /** * Appends the content and saves the file * * @param string $content * @return boolean */ public function append($content) { $this->content = $this->content() . $content; return $this->save(); } /** * Deletes the file * * @return boolean */ public function delete() { return f::remove($this->root); } /** * Alternative for delete * * @return boolean */ public function remove() { return f::remove($this->root); } /** * Moves the file to a new location * * @param string $to * @return boolean */ public function move($to) { if(!f::move($this->root, $to)) { return false; } else { $this->root = $to; return true; } } /** * Copies the file to a new location * * @param string $to * @return boolean */ public function copy($to) { return f::copy($this->root, $to); } /** * Returns the file size as integer * * @return int */ public function size() { return f::size($this->root); } /** * Returns the human readable version of the file size * * @return string */ public function niceSize() { return f::niceSize($this->size()); } /** * Get the file's last modification time. * * @return int */ public function modified($format = null, $handler = 'date') { return f::modified($this->root, $format, $handler); } /** * Returns the mime type of a file * * @return string */ public function mime() { return f::mime($this->root); } /** * Categorize the file * * @return string */ public function type() { return f::type($this->root); } /** * Checks if a file is of a certain type * * @param string $value An extension or mime type * @return boolean */ public function is($value) { return f::is($this->root, $value); } /** * Returns the file content as base64 encoded string * * @return string */ public function base64() { return base64_encode($this->content()); } /** * Returns the file as data uri * * @return string */ public function dataUri() { return 'data:' . $this->mime() . ';base64,' . $this->base64(); } /** * Checks if the file exists * * @return boolean */ public function exists() { return file_exists($this->root); } /** * Checks if the file is writable * * @return boolean */ public function isWritable() { return is_writable($this->root); } /** * Checks if the file is readable * * @return boolean */ public function isReadable() { return is_readable($this->root); } /** * Checks if the file is executable * * @return boolean */ public function isExecutable() { return is_executable($this->root); } /** * Sends an appropriate header for the asset * * @param boolean $send * @return mixed */ public function header($send = true) { return header::type($this->mime(), false, $send); } /** * Safely requires a file if it exists * * @param array $data Optional variables, which will be made available to the file */ public function load($data = array()) { return f::load($this->root, $data); } /** * Read and send the file with the correct headers */ public function show() { f::show($this->root); } /* * Automatically sends all needed headers for the file to be downloaded * and echos the file's content * * @param string $filename Optional filename for the download */ public function download($filename = null) { f::download($this->root, $filename); } /** * Returns the exif object for this file (if image) * * @return Exif */ public function exif() { if(isset($this->cache['exif'])) return $this->cache['exif']; return $this->cache['exif'] = new Exif($this); } /** * Returns the PHP imagesize array * * @return array */ public function imagesize() { return (array)getimagesize($this->root); } /** * Returns the dimensions of the file if possible * * @return Dimensions */ public function dimensions() { if(isset($this->cache['dimensions'])) return $this->cache['dimensions']; if(in_array($this->mime(), array('image/jpeg', 'image/png', 'image/gif'))) { $size = (array)getimagesize($this->root); $width = a::get($size, 0, 0); $height = a::get($size, 1, 0); } else if($this->extension() == 'svg') { $content = $this->read(); $xml = simplexml_load_string($content); $attr = $xml->attributes(); $width = floatval($attr->width); $height = floatval($attr->height); if($width == 0 or $height == 0 and !empty($attr->viewBox)) { $box = str::split($attr->viewBox, ' '); $width = floatval(a::get($box, 2, 0)); $height = floatval(a::get($box, 3, 0)); } } else { $width = 0; $height = 0; } return $this->cache['dimensions'] = new Dimensions($width, $height); } /** * Returns the width of the asset * * @return int */ public function width() { return $this->dimensions()->width(); } /** * Returns the height of the asset * * @return int */ public function height() { return $this->dimensions()->height(); } /** * Returns the ratio of the asset * * @return int */ public function ratio() { return $this->dimensions()->ratio(); } /** * Checks if the dimensions of the asset are portrait * * @return boolean */ public function isPortrait() { return $this->dimensions()->portrait(); } /** * Checks if the dimensions of the asset are landscape * * @return boolean */ public function isLandscape() { return $this->dimensions()->landscape(); } /** * Checks if the dimensions of the asset are square * * @return boolean */ public function isSquare() { return $this->dimensions()->square(); } /** * Returns the orientation as string * landscape | portrait | square * * @return string */ public function orientation() { return $this->dimensions()->orientation(); } /** * @param array $attr * @return string */ public function html($attr = array()) { if($this->type() != 'image') return false; $img = new Brick('img'); $img->attr('src', $this->url()); $img->attr('alt', ' '); if(is_string($attr) || (is_object($attr) && method_exists($attr, '__toString'))) { $img->attr('alt', (string)$attr); } else if(is_array($attr)) { $img->attr($attr); } return $img; } /** * Scales the image if possible * * @param int $width * @param mixed $height * @param mixed $quality * @return Media */ public function resize($width, $height = null, $quality = null) { if($this->type() != 'image') return $this; $params = array('width' => $width); if($height) $params['height'] = $height; if($quality) $params['quality'] = $quality; return new Thumb($this, $params); } /** * Scales and crops the image if possible * * @param int $width * @param mixed $height * @param mixed $quality * @return Media */ public function crop($width, $height = null, $quality = null) { if($this->type() != 'image') return $this; $params = array('width' => $width, 'crop' => true); if($height) $params['height'] = $height; if($quality) $params['quality'] = $quality; return new Thumb($this, $params); } /** * Converts the media object to a * plain PHP array * * @param closure $callback * @return array */ public function toArray($callback = null) { $data = array( 'root' => $this->root(), 'url' => $this->url(), 'hash' => $this->hash(), 'dir' => $this->dir(), 'filename' => $this->filename(), 'name' => $this->name(), 'safeName' => $this->safeName(), 'extension' => $this->extension(), 'size' => $this->size(), 'niceSize' => $this->niceSize(), 'modified' => $this->modified(), 'mime' => $this->mime(), 'type' => $this->type(), 'dimensions' => $this->dimensions()->toArray() ); if(is_null($callback)) { return $data; } else { return array_map($callback, $data); } } /** * Converts the entire file array into * a json string * * @param closure $callback Filter callback * @return string */ public function toJson($callback = null) { return json_encode($this->toArray($callback)); } /** * Returns a full link to this file * Perfect for debugging in connection with echo * * @return string */ public function __toString() { return $this->root; } }