* @link http://getkirby.com * @copyright Bastian Allgeier * @license http://getkirby.com/license */ abstract class FileAbstract extends Media { use Kirby\Traits\Image; static public $methods = array(); public $kirby; public $site; public $page; public $files; /** * Constructor * * @param Files The parent files collection * @param string The filename */ public function __construct(Files $files, $filename) { $this->kirby = $files->kirby; $this->site = $files->site; $this->page = $files->page; $this->files = $files; $this->root = $this->files->page()->root() . DS . $filename; parent::__construct($this->root); } /** * Returns the kirby object * * @return Kirby */ public function kirby() { return $this->kirby; } /** * Returns the parent site object * * @return Site */ public function site() { return $this->site; } /** * Returns the parent page object * * @return Page */ public function page() { return $this->page; } /** * Returns the parent files collection * * @return Files */ public function files() { return $this->files; } /** * Returns the full root for the content file * * @return string */ public function textfile() { return $this->page->textfile($this->filename()); } public function siblings() { return $this->files->not($this->filename); } public function next() { $siblings = $this->files; $index = $siblings->indexOf($this); if($index === false) return false; return $this->files->nth($index+1); } public function hasNext() { return $this->next(); } public function prev() { $siblings = $this->files; $index = $siblings->indexOf($this); if($index === false) return false; return $this->files->nth($index-1); } public function hasPrev() { return $this->prev(); } /** * Returns the absolute URL for the file * * @return string */ public function url($raw = false) { if($raw || empty($this->modifications)) { return $this->page->contentUrl() . '/' . rawurlencode($this->filename); } else { return $this->kirby->component('thumb')->url($this); } } /** * Returns the relative URI for the image * * @return string */ public function uri() { return $this->page->uri() . '/' . rawurlencode($this->filename); } /** * Returns the full directory path starting from the content folder * * @return string */ public function diruri() { return $this->page->diruri() . '/' . rawurlencode($this->filename); } /** * Get the meta information * * @return Content */ public function meta() { if(isset($this->cache['meta'])) { return $this->cache['meta']; } else { $inventory = $this->page->inventory(); $file = isset($inventory['meta'][$this->filename]) ? $this->page->root() . DS . $inventory['meta'][$this->filename] : null; return $this->cache['meta'] = new Content($this->page, $file); } } /** * Custom modified method for files * * @param string $format * @return string */ public function modified($format = null, $handler = null) { return parent::modified($format, $handler ? $handler : $this->kirby->options['date.handler']); } /** * Magic getter for all meta fields * * @return Field */ public function __call($key, $arguments = null) { if(isset(static::$methods[$key])) { if(!$arguments) $arguments = array(); array_unshift($arguments, clone $this); return call(static::$methods[$key], $arguments); } else { return $this->meta()->get($key, $arguments); } } /** * Generates a new filename for a given name * and makes sure to handle badly given extensions correctly * * @param string $name * @return string */ public function createNewFilename($name, $safeName = true) { $name = basename($safeName ? f::safeName($name) : $name); $ext = f::extension($name); // remove possible extensions if(in_array($ext, f::extensions())) { $name = f::name($name); } return trim($name . '.' . $this->extension(), '.'); } /** * Renames the file and also its meta info txt * * @param string $filename * @param boolean $safeName */ public function rename($name, $safeName = true) { $filename = $this->createNewFilename($name, $safeName); $root = $this->dir() . DS . $filename; if(empty($name)) { throw new Exception('The filename is missing'); } if($root == $this->root()) return $filename; if(file_exists($root)) { throw new Exception('A file with that name already exists'); } if(!f::move($this->root(), $root)) { throw new Exception('The file could not be renamed'); } $meta = $this->textfile(); if(file_exists($meta)) { f::move($meta, $this->page->textfile($filename)); } // reset the page cache $this->page->reset(); // reset the basics $this->root = $root; $this->filename = $filename; $this->name = $name; $this->cache = array(); cache::flush(); return $filename; } public function update($data = array()) { $data = array_merge((array)$this->meta()->toArray(), $data); foreach($data as $k => $v) { if(is_null($v)) unset($data[$k]); } if(!data::write($this->textfile(), $data, 'kd')) { throw new Exception('The file data could not be saved'); } // reset the page cache $this->page->reset(); // reset the file cache $this->cache = array(); cache::flush(); return true; } public function delete() { // delete the meta file f::remove($this->textfile()); if(!f::remove($this->root())) { throw new Exception('The file could not be deleted'); } cache::flush(); return true; } /** * Get formatted date fields * * @param string $format * @param string $field * @return mixed */ public function date($format = null, $field = 'date') { if($timestamp = strtotime($this->meta()->$field())) { if(is_null($format)) { return $timestamp; } else { return $this->kirby->options['date.handler']($format, $timestamp); } } else { return false; } } /** * Converts the entire file object into * a plain PHP array * * @param closure $callback Filter callback * @return array */ public function toArray($callback = null) { $data = parent::toArray(); // add the meta content $data['meta'] = $this->meta()->toArray(); if(is_null($callback)) { return $data; } else { return array_map($callback, $data); } } }