1<?php 2 3namespace dokuwiki\File; 4 5use Exception; 6use JpegMeta; 7use splitbrain\slika\ImageInfo; 8 9class MediaFile 10{ 11 protected $id; 12 protected $rev; 13 protected $path; 14 15 protected $mime; 16 protected $ext; 17 protected $downloadable; 18 19 protected $width; 20 protected $height; 21 protected $meta; 22 23 /** 24 * MediaFile constructor. 25 * @param string $id 26 * @param string|int $rev optional revision 27 */ 28 public function __construct($id, $rev = '') 29 { 30 $this->id = $id; //FIXME should it be cleaned? 31 $this->path = mediaFN($id, $rev); 32 $this->rev = $rev; 33 34 [$this->ext, $this->mime, $this->downloadable] = mimetype($this->path, false); 35 } 36 37 /** @return string */ 38 public function getId() 39 { 40 return $this->id; 41 } 42 43 /** @return string|int Empty string for current version */ 44 public function getRev() 45 { 46 return $this->rev; 47 } 48 49 /** @return string */ 50 public function getPath() 51 { 52 return $this->path; 53 } 54 55 /** 56 * The ID without namespace, used for display purposes 57 * 58 * @return string 59 */ 60 public function getDisplayName() 61 { 62 return noNS($this->id); 63 } 64 65 /** @return string */ 66 public function getMime() 67 { 68 if (!$this->mime) return 'application/octet-stream'; 69 return $this->mime; 70 } 71 72 /** @return string */ 73 public function getExtension() 74 { 75 return (string)$this->ext; 76 } 77 78 /** 79 * Similar to the extesion but does some clean up 80 * 81 * @return string 82 */ 83 public function getIcoClass() 84 { 85 $ext = $this->getExtension(); 86 if ($ext === '') $ext = 'file'; 87 return preg_replace('/[^_\-a-z0-9]+/i', '_', $ext); 88 } 89 90 /** 91 * Should this file be downloaded instead being displayed inline? 92 * 93 * @return bool 94 */ 95 public function isDownloadable() 96 { 97 return $this->downloadable; 98 } 99 100 /** @return int */ 101 public function getFileSize() 102 { 103 return filesize($this->path); 104 } 105 106 /** @return int */ 107 public function getLastModified() 108 { 109 return filemtime($this->path); 110 } 111 112 /** @return bool */ 113 public function isWritable() 114 { 115 return is_writable($this->path); 116 } 117 118 /** @return bool */ 119 public function isImage() 120 { 121 return (str_starts_with($this->mime, 'image/')); 122 } 123 124 /** 125 * initializes width and height for images when requested 126 */ 127 protected function initSizes() 128 { 129 $this->width = 0; 130 $this->height = 0; 131 if (!$this->isImage()) return; 132 $info = getimagesize($this->path); 133 if ($info === false) return; 134 [$this->width, $this->height] = $info; 135 } 136 137 /** 138 * Returns the width if this is a supported image, 0 otherwise 139 * 140 * @return int 141 */ 142 public function getWidth() 143 { 144 if ($this->width === null) $this->initSizes(); 145 return $this->width; 146 } 147 148 /** 149 * Returns the height if this is a supported image, 0 otherwise 150 * 151 * @return int 152 */ 153 public function getHeight() 154 { 155 if ($this->height === null) $this->initSizes(); 156 return $this->height; 157 } 158 159 /** 160 * Returns the final display dimensions a fetch.php URL with the given 161 * parameters would produce, including EXIF auto-rotation 162 * 163 * @param int $w requested width (0 = no constraint) 164 * @param int $h requested height (0 = no constraint) 165 * @param bool $crop true for center-crop, false for bounding-box fit 166 * @return array [width, height]; [0, 0] for non-images/unreadable files 167 */ 168 public function getDisplayDimensions($w = 0, $h = 0, $crop = false) 169 { 170 try { 171 $info = (new ImageInfo($this->path))->autorotate(); 172 } catch (Exception) { 173 return [0, 0]; 174 } 175 if ($w === 0 && $h === 0) return $info->getDimensions(); 176 if ($crop) return $info->crop($w, $h)->getDimensions(); 177 return $info->resize($w, $h)->getDimensions(); 178 } 179 180 /** 181 * Returns the permissions the current user has on the file 182 * 183 * @todo doing this for each file within a namespace is a waste, we need to cache this somehow 184 * @return int 185 */ 186 public function userPermission() 187 { 188 return auth_quickaclcheck(getNS($this->id) . ':*'); 189 } 190 191 /** @return JpegMeta */ 192 public function getMeta() 193 { 194 if ($this->meta === null) $this->meta = new JpegMeta($this->path); 195 return $this->meta; 196 } 197} 198