getUri()->getAbsolutePath(); // preserve only the relative path of the path $this->path = trim(str_replace($root, '', $data['path']), '\\/'); if (empty($data['name'])) { throw new \InvalidArgumentException('Missing file name.', 400); } if (!isset($data['extension'])) { // extract file extension from original file name if (preg_match("/\.([a-z0-9]{2,})$/i", $data['name'], $match)) { $data['extension'] = end($match); } else { // we have a file w/o extension $data['extension'] = ''; } } $this->extension = $data['extension']; // keep name without file extension $this->name = preg_replace("/\.{$this->extension}$/", '', $data['name']); if (empty($data['filename'])) { do { // use a random (probable) unique ID as file name $data['filename'] = VBOPerformanceIndicator::uuid() . ($this->extension ? '.' . $this->extension : ''); // repeat in case we have been so unlucky } while (JFile::exists($root . '/' . $this->path . '/' . $data['filename'])); } $this->filename = $data['filename']; // register file mime type $this->type = $data['type'] ?? null; } /** * Returns the original file name. * * @param bool $extension Whether the file extension should be included. * * @return string */ public function getName(bool $extension = true) { if ($extension) { return $this->name . ($this->extension ? '.' . $this->extension : ''); } return $this->name; } /** * Returns the real file name. * * @return string */ public function getFilename() { return $this->filename; } /** * Returns the file extension. * * @return string */ public function getExtension() { return $this->extension; } /** * Returns the file MIME type. * * @return string */ public function getMimeType() { if (!$this->type) { // fetch MIME type at runtime $this->type = $this->exists() ? mime_content_type($this->getPath()) : ''; } return $this->type; } /** * Returns the full path of the attachment. * * @return string */ public function getPath() { return JPath::clean( VBOFactory::getPlatform()->getUri()->getAbsolutePath() . '/' . $this->path . '/' . $this->getFilename() ); } /** * Returns the file URI. * * @return string */ public function getUrl() { return JUri::root() . preg_replace("/\\\\+/", '/', $this->path) . '/' . $this->getFilename(); } /** * Returns the file size. * * @return int */ public function getSize() { if (!$this->exists()) { return 0; } return filesize($this->getPath()); } /** * Checks whether the attachment actually exists. * * @return bool */ public function exists() { return JFile::exists($this->getPath()); } /** * Returns the blob of the file in base 64 format. * * @return string * * @since 1.8.8 */ public function getBase64() { if (!$this->exists()) { throw new RuntimeException('Missing [' . $this->getName() . '] attachment.', 404); } $blob = ''; // open file in read mode $fp = fopen($this->getPath(), 'r'); // read blob chunk by chunk while (!feof($fp)) { $blob .= fgets($fp, 8192); } fclose($fp); // return base64 encoded version return 'data:' . $this->getMimeType() . ';base64,' . base64_encode($blob); } /** * @inheritDoc * * @see JsonSerializable */ #[ReturnTypeWillChange] public function jsonSerialize() { $size = $this->getSize(); return [ 'name' => $this->getName(true), 'filename' => $this->getFilename(), 'extension' => $this->getExtension(), 'type' => $this->getMimeType(), 'url' => $this->getUrl(), 'path' => $this->path, 'size' => [ 'value' => $size, 'text' => JHtml::fetch('number.bytes', $size, 'auto', 0), ], ]; } }