10603f506SAndreas Gohr<?php 20603f506SAndreas Gohr 30603f506SAndreas Gohrnamespace dokuwiki\File; 40603f506SAndreas Gohr 5*dd9e8e5eSAndreas Gohruse Exception; 679a2d784SGerrit Uitslaguse JpegMeta; 7*dd9e8e5eSAndreas Gohruse splitbrain\slika\ImageInfo; 80603f506SAndreas Gohr 90603f506SAndreas Gohrclass MediaFile 100603f506SAndreas Gohr{ 110603f506SAndreas Gohr protected $id; 12fe9d054bSAndreas Gohr protected $rev; 130603f506SAndreas Gohr protected $path; 140603f506SAndreas Gohr 150603f506SAndreas Gohr protected $mime; 160603f506SAndreas Gohr protected $ext; 170603f506SAndreas Gohr protected $downloadable; 180603f506SAndreas Gohr 190603f506SAndreas Gohr protected $width; 200603f506SAndreas Gohr protected $height; 210603f506SAndreas Gohr protected $meta; 220603f506SAndreas Gohr 230603f506SAndreas Gohr /** 240603f506SAndreas Gohr * MediaFile constructor. 250603f506SAndreas Gohr * @param string $id 260603f506SAndreas Gohr * @param string|int $rev optional revision 270603f506SAndreas Gohr */ 280603f506SAndreas Gohr public function __construct($id, $rev = '') 290603f506SAndreas Gohr { 300603f506SAndreas Gohr $this->id = $id; //FIXME should it be cleaned? 310603f506SAndreas Gohr $this->path = mediaFN($id, $rev); 32fe9d054bSAndreas Gohr $this->rev = $rev; 330603f506SAndreas Gohr 34445164b2SAndreas Gohr [$this->ext, $this->mime, $this->downloadable] = mimetype($this->path, false); 350603f506SAndreas Gohr } 360603f506SAndreas Gohr 370603f506SAndreas Gohr /** @return string */ 380603f506SAndreas Gohr public function getId() 390603f506SAndreas Gohr { 400603f506SAndreas Gohr return $this->id; 410603f506SAndreas Gohr } 420603f506SAndreas Gohr 43fe9d054bSAndreas Gohr /** @return string|int Empty string for current version */ 44fe9d054bSAndreas Gohr public function getRev() 45fe9d054bSAndreas Gohr { 46fe9d054bSAndreas Gohr return $this->rev; 47fe9d054bSAndreas Gohr } 48fe9d054bSAndreas Gohr 490603f506SAndreas Gohr /** @return string */ 500603f506SAndreas Gohr public function getPath() 510603f506SAndreas Gohr { 520603f506SAndreas Gohr return $this->path; 530603f506SAndreas Gohr } 540603f506SAndreas Gohr 550603f506SAndreas Gohr /** 560603f506SAndreas Gohr * The ID without namespace, used for display purposes 570603f506SAndreas Gohr * 580603f506SAndreas Gohr * @return string 590603f506SAndreas Gohr */ 600603f506SAndreas Gohr public function getDisplayName() 610603f506SAndreas Gohr { 620603f506SAndreas Gohr return noNS($this->id); 630603f506SAndreas Gohr } 640603f506SAndreas Gohr 650603f506SAndreas Gohr /** @return string */ 660603f506SAndreas Gohr public function getMime() 670603f506SAndreas Gohr { 680603f506SAndreas Gohr if (!$this->mime) return 'application/octet-stream'; 690603f506SAndreas Gohr return $this->mime; 700603f506SAndreas Gohr } 710603f506SAndreas Gohr 720603f506SAndreas Gohr /** @return string */ 730603f506SAndreas Gohr public function getExtension() 740603f506SAndreas Gohr { 750603f506SAndreas Gohr return (string)$this->ext; 760603f506SAndreas Gohr } 770603f506SAndreas Gohr 780603f506SAndreas Gohr /** 790603f506SAndreas Gohr * Similar to the extesion but does some clean up 800603f506SAndreas Gohr * 810603f506SAndreas Gohr * @return string 820603f506SAndreas Gohr */ 830603f506SAndreas Gohr public function getIcoClass() 840603f506SAndreas Gohr { 850603f506SAndreas Gohr $ext = $this->getExtension(); 860603f506SAndreas Gohr if ($ext === '') $ext = 'file'; 870603f506SAndreas Gohr return preg_replace('/[^_\-a-z0-9]+/i', '_', $ext); 880603f506SAndreas Gohr } 890603f506SAndreas Gohr 900603f506SAndreas Gohr /** 910603f506SAndreas Gohr * Should this file be downloaded instead being displayed inline? 920603f506SAndreas Gohr * 930603f506SAndreas Gohr * @return bool 940603f506SAndreas Gohr */ 950603f506SAndreas Gohr public function isDownloadable() 960603f506SAndreas Gohr { 970603f506SAndreas Gohr return $this->downloadable; 980603f506SAndreas Gohr } 990603f506SAndreas Gohr 1000603f506SAndreas Gohr /** @return int */ 1010603f506SAndreas Gohr public function getFileSize() 1020603f506SAndreas Gohr { 1030603f506SAndreas Gohr return filesize($this->path); 1040603f506SAndreas Gohr } 1050603f506SAndreas Gohr 1060603f506SAndreas Gohr /** @return int */ 1070603f506SAndreas Gohr public function getLastModified() 1080603f506SAndreas Gohr { 1090603f506SAndreas Gohr return filemtime($this->path); 1100603f506SAndreas Gohr } 1110603f506SAndreas Gohr 1120603f506SAndreas Gohr /** @return bool */ 1130603f506SAndreas Gohr public function isWritable() 1140603f506SAndreas Gohr { 1150603f506SAndreas Gohr return is_writable($this->path); 1160603f506SAndreas Gohr } 1170603f506SAndreas Gohr 1180603f506SAndreas Gohr /** @return bool */ 1190603f506SAndreas Gohr public function isImage() 1200603f506SAndreas Gohr { 1216c16a3a9Sfiwswe return (str_starts_with($this->mime, 'image/')); 1220603f506SAndreas Gohr } 1230603f506SAndreas Gohr 1240603f506SAndreas Gohr /** 1250603f506SAndreas Gohr * initializes width and height for images when requested 1260603f506SAndreas Gohr */ 1270603f506SAndreas Gohr protected function initSizes() 1280603f506SAndreas Gohr { 1290603f506SAndreas Gohr $this->width = 0; 1300603f506SAndreas Gohr $this->height = 0; 1310603f506SAndreas Gohr if (!$this->isImage()) return; 1320603f506SAndreas Gohr $info = getimagesize($this->path); 1330603f506SAndreas Gohr if ($info === false) return; 134445164b2SAndreas Gohr [$this->width, $this->height] = $info; 1350603f506SAndreas Gohr } 1360603f506SAndreas Gohr 1370603f506SAndreas Gohr /** 1380603f506SAndreas Gohr * Returns the width if this is a supported image, 0 otherwise 1390603f506SAndreas Gohr * 1400603f506SAndreas Gohr * @return int 1410603f506SAndreas Gohr */ 1420603f506SAndreas Gohr public function getWidth() 1430603f506SAndreas Gohr { 1440603f506SAndreas Gohr if ($this->width === null) $this->initSizes(); 1450603f506SAndreas Gohr return $this->width; 1460603f506SAndreas Gohr } 1470603f506SAndreas Gohr 1480603f506SAndreas Gohr /** 1490603f506SAndreas Gohr * Returns the height if this is a supported image, 0 otherwise 1500603f506SAndreas Gohr * 1510603f506SAndreas Gohr * @return int 1520603f506SAndreas Gohr */ 1530603f506SAndreas Gohr public function getHeight() 1540603f506SAndreas Gohr { 1550603f506SAndreas Gohr if ($this->height === null) $this->initSizes(); 1560603f506SAndreas Gohr return $this->height; 1570603f506SAndreas Gohr } 1580603f506SAndreas Gohr 1590603f506SAndreas Gohr /** 160*dd9e8e5eSAndreas Gohr * Returns the final display dimensions a fetch.php URL with the given 161*dd9e8e5eSAndreas Gohr * parameters would produce, including EXIF auto-rotation 162*dd9e8e5eSAndreas Gohr * 163*dd9e8e5eSAndreas Gohr * @param int $w requested width (0 = no constraint) 164*dd9e8e5eSAndreas Gohr * @param int $h requested height (0 = no constraint) 165*dd9e8e5eSAndreas Gohr * @param bool $crop true for center-crop, false for bounding-box fit 166*dd9e8e5eSAndreas Gohr * @return array [width, height]; [0, 0] for non-images/unreadable files 167*dd9e8e5eSAndreas Gohr */ 168*dd9e8e5eSAndreas Gohr public function getDisplayDimensions($w = 0, $h = 0, $crop = false) 169*dd9e8e5eSAndreas Gohr { 170*dd9e8e5eSAndreas Gohr try { 171*dd9e8e5eSAndreas Gohr $info = (new ImageInfo($this->path))->autorotate(); 172*dd9e8e5eSAndreas Gohr } catch (Exception $e) { 173*dd9e8e5eSAndreas Gohr return [0, 0]; 174*dd9e8e5eSAndreas Gohr } 175*dd9e8e5eSAndreas Gohr if ($w === 0 && $h === 0) return $info->getDimensions(); 176*dd9e8e5eSAndreas Gohr if ($crop) return $info->crop($w, $h)->getDimensions(); 177*dd9e8e5eSAndreas Gohr return $info->resize($w, $h)->getDimensions(); 178*dd9e8e5eSAndreas Gohr } 179*dd9e8e5eSAndreas Gohr 180*dd9e8e5eSAndreas Gohr /** 1810603f506SAndreas Gohr * Returns the permissions the current user has on the file 1820603f506SAndreas Gohr * 1830603f506SAndreas Gohr * @todo doing this for each file within a namespace is a waste, we need to cache this somehow 1840603f506SAndreas Gohr * @return int 1850603f506SAndreas Gohr */ 1860603f506SAndreas Gohr public function userPermission() 1870603f506SAndreas Gohr { 1880603f506SAndreas Gohr return auth_quickaclcheck(getNS($this->id) . ':*'); 1890603f506SAndreas Gohr } 1900603f506SAndreas Gohr 19179a2d784SGerrit Uitslag /** @return JpegMeta */ 1920603f506SAndreas Gohr public function getMeta() 1930603f506SAndreas Gohr { 19479a2d784SGerrit Uitslag if ($this->meta === null) $this->meta = new JpegMeta($this->path); 1950603f506SAndreas Gohr return $this->meta; 1960603f506SAndreas Gohr } 1970603f506SAndreas Gohr} 198