639 lines
13 KiB
PHP
639 lines
13 KiB
PHP
<?php
|
|
|
|
/**
|
|
* Media
|
|
*
|
|
* @package Kirby Toolkit
|
|
* @author Bastian Allgeier <bastian@getkirby.com>
|
|
* @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;
|
|
}
|
|
|
|
}
|