/
www
/
wwwroot
/
alo88.autos
/
wp-content
/
plugins
/
wp-content-crawler
/
app
/
Objects
/
File
/
Upload File
HOME
<?php /** * Created by PhpStorm. * User: turgutsaricam * Date: 11/12/2018 * Time: 17:34 * * @since 1.8.0 */ namespace WPCCrawler\Objects\File; use Exception; use Illuminate\Filesystem\Filesystem; use WPCCrawler\Factory; use WPCCrawler\Objects\Enums\FileTemplateShortCodeName; use WPCCrawler\Objects\Enums\ShortCodeName; use WPCCrawler\Objects\Informing\Informer; class MediaFile { /** @var string Raw source URL after "find-replace in image URLs" options applied to it. */ private $sourceUrl; /** @var string|null Raw source URL retrieved from the target site */ private $originalSourceUrl; /** @var string|null */ private $localUrl; /** @var string|null */ private $localPath; /** @var bool True if this file is a gallery image. */ private $isGalleryImage = false; /** @var string|null */ private $mediaTitle; /** @var string|null */ private $mediaDescription; /** @var string|null */ private $mediaCaption; /** @var string|null */ private $mediaAlt; /** @var string */ private $originalFileName; /** @var int|null Media ID of this file, retrieved by inserting the media into the database. */ private $mediaId; /** @var string[] Stores the paths of the copies of the file */ private $copyFilePaths = []; /** * @param string $sourceUrl See {@link $sourceUrl} * @param string|null $localPath See {@link $localPath} */ public function __construct(string $sourceUrl, ?string $localPath) { $this->sourceUrl = $sourceUrl; $this->setLocalPath($localPath); $this->originalFileName = $this->getFileSystem()->name($this->localPath ?: $sourceUrl); } /** * @return string */ public function getSourceUrl(): string { return $this->sourceUrl; } /** * @param string $sourceUrl * @return MediaFile */ public function setSourceUrl(string $sourceUrl): self { $this->sourceUrl = $sourceUrl; return $this; } /** * @return string */ public function getOriginalSourceUrl(): string { return $this->originalSourceUrl ?: $this->getSourceUrl(); } /** * @param string|null $originalSourceUrl * @return MediaFile */ public function setOriginalSourceUrl(?string $originalSourceUrl): self { $this->originalSourceUrl = $originalSourceUrl; return $this; } /** * @return string */ public function getLocalUrl(): string { // If there is no local URL, create it. if ($this->localUrl === null) { $url = FileService::getInstance()->getUrlForPathUnderUploadsDir($this->getLocalPath()); if ($url !== null) { $this->localUrl = $url; } } return $this->localUrl ?: ''; } /** * @param string|null $localUrl * @return MediaFile */ public function setLocalUrl(?string $localUrl): self { $this->localUrl = $localUrl; return $this; } /** * @return string */ public function getOriginalFileName(): string { return $this->originalFileName; } /** * @return string|null */ public function getLocalPath(): ?string { return $this->localPath; } /** * @param string|null $localPath * @return MediaFile */ public function setLocalPath(?string $localPath): self { if ($localPath !== null) { try { $this->localPath = Factory::fileSystem()->exists($localPath) // Get rid of the ".." and "." parts inside the local path without resolving the symlinks ? FileService::getInstance()->getAbsolutePath($localPath) : null; } catch (Exception $e) { $this->localPath = null; } } else { $this->localPath = null; } // If this is a test, store the file path as test file path so that it will be deleted later. MediaService::getInstance()->addTestFilePath($this->localPath); // Make the local URL null, since the path of the file has just changed. $this->localUrl = null; return $this; } /** * @return bool */ public function isGalleryImage(): bool { return $this->isGalleryImage; } /** * @param bool $isGalleryImage * @return MediaFile */ public function setIsGalleryImage(bool $isGalleryImage): self { $this->isGalleryImage = $isGalleryImage; return $this; } /** * @return string */ public function getMediaTitle(): string { if ($this->mediaTitle !== null) { return $this->mediaTitle; } $baseName = $this->getBaseName(); if ($baseName === null) { return ''; } $result = preg_replace('/\.[^.]+$/', '', $baseName); return is_string($result) ? $result : ''; } /** * @param null|string $mediaTitle * @return MediaFile */ public function setMediaTitle(?string $mediaTitle): self { $this->mediaTitle = $mediaTitle; return $this; } /** * @return string */ public function getMediaDescription(): string { return $this->mediaDescription !== null ? $this->mediaDescription : ''; } /** * @param null|string $mediaDescription * @return MediaFile */ public function setMediaDescription(?string $mediaDescription): self { $this->mediaDescription = $mediaDescription; return $this; } /** * @return string */ public function getMediaCaption(): string { return $this->mediaCaption !== null ? $this->mediaCaption : ''; } /** * @param null|string $mediaCaption * @return MediaFile */ public function setMediaCaption(?string $mediaCaption): self { $this->mediaCaption = $mediaCaption; return $this; } /** * @return string */ public function getMediaAlt(): string { return $this->mediaAlt !== null ? $this->mediaAlt : ''; } /** * @param null|string $mediaAlt * @return MediaFile */ public function setMediaAlt(?string $mediaAlt): self { $this->mediaAlt = $mediaAlt; return $this; } /** * @return int|null */ public function getMediaId(): ?int { return $this->mediaId; } /** * @param int|null $mediaId */ public function setMediaId(?int $mediaId): void { $this->mediaId = $mediaId; } /* * OPERATIONS */ /** * @return bool True if the media file exists. * @since 1.8.0 */ public function exists(): bool { $path = $this->getLocalPath(); return $path === null ? false : $this->getFileSystem()->exists($path); } /** * @return bool True if the media file path is a file. * @since 1.8.0 */ public function isFile(): bool { $path = $this->getLocalPath(); return $path === null ? false : strlen($this->getFileSystem()->extension($path)) > 0; } /** * @return string|null Directory of the media file * @since 1.8.0 */ public function getDirectory(): ?string { $path = $this->getLocalPath(); return $path === null ? null : $this->getFileSystem()->dirname($path); } /** * @return string|null Name of the media file * @since 1.8.0 */ public function getName(): ?string { $path = $this->getLocalPath(); return $path === null ? null : $this->getFileSystem()->name($path); } /** * @return string|null Base name of the file, i.e. file name with extension. * @since 1.8.0 */ public function getBaseName(): ?string { $path = $this->getLocalPath(); return $path === null ? null : $this->getFileSystem()->basename($path); } /** * @return string|null Extension of the media file * @since 1.8.0 */ public function getExtension(): ?string { $path = $this->getLocalPath(); return $path === null ? null : $this->getFileSystem()->extension($path); } /** * @return string Mime type or empty string if mime type does not exist. * @since 1.8.0 */ public function getMimeType(): string { $path = $this->getLocalPath(); if ($path === null) return ''; $mimeType = $this->getFileSystem()->mimeType($path); return $mimeType ?: ''; } /** * @return string|null MD5 hash of the file, if the file exists. * @since 1.8.0 */ public function getMD5Hash(): ?string { $path = $this->getLocalPath(); return $path === null ? null : $this->getFileSystem()->hash($path); } /** * @return string|null A unique SHA1 string created by using {@link uniqid()} and the base name of the file, if * there is a file. * @since 1.8.0 */ public function getRandomUniqueHash(): ?string { $baseName = $this->getBaseName(); return $baseName === null ? null : sha1($baseName . uniqid('wpcc')); } /** * @return int File size in kilobytes. * @since 1.8.0 */ public function getFileSizeByte(): int { return $this->getFileSize(); } /** * @return int File size in kilobytes. * @since 1.8.0 */ public function getFileSizeKb(): int { return (int) ($this->getFileSize() / 1000); } /** * @return int File size in megabytes. * @since 1.8.0 */ public function getFileSizeMb(): int { return (int) ($this->getFileSize() / 1000000); } /** * Rename the file. * * @param string|null $newName New name of the file. Without extension. * @return bool True if the renaming was successful. * @since 1.8.0 */ public function rename(?string $newName): bool { $newName = FileService::getInstance()->validateFileName($newName); // If there is no name after validation, assign a default name. if (!$newName) $newName = 'no-name'; // If the new name is the same as the old name, stop by indicating success. if ($newName === $this->getName()) return true; $directory = $this->getDirectory(); if (!$directory) return false; // Rename the file $newPath = $this->getUniqueFilePath($newName, $directory); if ($newPath === null) return false; $success = $this->move($newPath); if (!$success) return false; // If the file name does not exist, we cannot rename the copies. The copies probably do not exist in that case, // too. At this point in execution, we already moved the file. So, the file name probably exists. However, to // be on the safe side, we check its existence. If the file name does not exist, return true, because we already // moved the file. Also note that, we get the file name here again, because the names has been changed above. // We need the changed name. So, we retrieve the name by calling getName() method again. $fileName = $this->getName(); if ($fileName === null) return true; // If there are copies, rename them as well. $copyFilePaths = $this->copyFilePaths; // First, clear the copy file paths since we are gonna rename them. $this->clearCopyFilePaths(); // Rename the copy files foreach($copyFilePaths as $copyFilePath) { // Get the directory of the copy file $directoryPath = $this->getFileSystem()->dirname($copyFilePath); // Get a unique name for the copy file in the same directory $newCopyFilePath = $this->getUniqueFilePath($fileName, $directoryPath); // Try to rename the file if ($newCopyFilePath && @$this->getFileSystem()->move($copyFilePath, $newCopyFilePath)) { // If renamed, store it. $this->addCopyFilePath($newCopyFilePath); // If testing, remove the old copy file path from test file paths. MediaService::getInstance()->removeTestFilePath($copyFilePath); } else { // Otherwise, inform the user. Informer::addError(sprintf(_wpcc('File %1$s could not be moved to %2$s'), $copyFilePath, $newCopyFilePath ?: '"null"')) ->addAsLog(); } } return true; } /** * @param string $newPath New path of the file * @return bool True if the operation has been successful. * @since 1.8.0 */ public function move($newPath): bool { $newPath = FileService::getInstance()->forceDirectorySeparator($newPath); if (!$newPath) return false; $localPath = $this->getLocalPath(); if (!$localPath) return false; $result = @$this->getFileSystem()->move($localPath, $newPath); // If the file was moved, set the new path. if ($result) { // If this is a test, remove the previous local path. MediaService::getInstance()->removeTestFilePath($localPath); $this->setLocalPath($newPath); } else { // Otherwise, inform the user. Informer::addError(sprintf(_wpcc('File %1$s could not be moved to %2$s'), $localPath, $newPath)) ->addAsLog(); } return $result; } /** * @param string $newDirectoryPath New directory path * @return bool True if the file has been successfully moved. Otherwise, false. * @since 1.8.0 */ public function moveToDirectory($newDirectoryPath): bool { $newDirectoryPath = FileService::getInstance()->forceDirectorySeparator($newDirectoryPath); $baseName = $this->getBaseName(); if (!$newDirectoryPath || $baseName === null) return false; // Make sure the directories exist. If not, create them. Stop if they do not exist. if (!$this->makeDirectory($newDirectoryPath)) return false; // We now have the target directory created. Let's move the file to that directory. return $this->move($newDirectoryPath . DIRECTORY_SEPARATOR . $baseName); } /** * @param string $directoryPath Target directory path * @return false|string False if the operation was not successful. Otherwise, copied file's path. * @since 1.8.0 */ public function copyToDirectory($directoryPath) { $directoryPath = FileService::getInstance()->forceDirectorySeparator($directoryPath); if (!$directoryPath) return false; // Make sure the directories exist. If not, create them. Stop if they do not exist. if (!$this->makeDirectory($directoryPath)) return false; $fileName = $this->getName(); if ($fileName === null) return false; // Get the new name $copyPath = $this->getUniqueFilePath($fileName, $directoryPath); if ($copyPath === null) return false; // Copy the file $localPath = $this->getLocalPath(); if ($localPath === null) return false; $success = $this->getFileSystem()->copy($localPath, $copyPath); // If the file is copied, store the copy file's path. if ($success) $this->addCopyFilePath($copyPath); return $success === false ? false : $copyPath; } /** * Delete the local file. * * @return bool True if the file has been successfully deleted. Otherwise, false. * @since 1.8.0 */ public function delete(): bool { $localPath = $this->getLocalPath(); if (!$localPath) return true; $result = $this->getFileSystem()->delete($localPath); if (!$result) { // Inform the user if the file could not be deleted Informer::addError(sprintf(_wpcc('File %1$s could not be deleted.'), $localPath)) ->addAsLog(); } return $result; } /** * Delete copies of the local file. * * @return bool True if all of the copy file have been deleted. Otherwise, false. * @since 1.8.0 */ public function deleteCopyFiles(): bool { if (!$this->copyFilePaths) return true; $success = true; // Delete a copy file foreach($this->copyFilePaths as $copyPath) { if (!$this->getFileSystem()->delete($copyPath)) { $success = false; // Inform the user if the file could not be deleted Informer::addError(sprintf(_wpcc('File %1$s could not be deleted.'), $copyPath)) ->addAsLog(); } else { // If file is deleted and this is a test, remove the path from test file paths. MediaService::getInstance()->removeTestFilePath($copyPath); } } return $success; } /** * Get URLs of the files that are copies of the file. * * @return string[] An array of copy file URLs * @since 1.8.0 */ public function getCopyFileUrls(): array { if (!$this->copyFilePaths) return []; $urls = []; foreach($this->copyFilePaths as $filePath) { $url = FileService::getInstance()->getUrlForPathUnderUploadsDir($filePath); if (!$url) continue; $urls[] = $url; } return $urls; } /* * */ /** * @return Filesystem * @since 1.8.0 */ public function getFileSystem(): Filesystem { return FileService::getInstance()->getFileSystem(); } /** * @return array A map storing short code names of media files templates and corresponding values * @since 1.8.0 */ public function getShortCodeMap(): array { return [ ShortCodeName::WCC_ITEM => function() { return $this->getSourceUrl(); }, FileTemplateShortCodeName::ORIGINAL_FILE_NAME => function() { return $this->getOriginalFileName(); }, FileTemplateShortCodeName::ORIGINAL_TITLE => function() { return $this->getMediaTitle(); }, FileTemplateShortCodeName::ORIGINAL_ALT => function() { return $this->getMediaAlt(); }, FileTemplateShortCodeName::PREPARED_FILE_NAME => function() { return $this->getName() ?: ''; }, FileTemplateShortCodeName::FILE_EXT => function() { return $this->getExtension() ?: ''; }, FileTemplateShortCodeName::MIME_TYPE => function() { return $this->getMimeType(); }, FileTemplateShortCodeName::FILE_SIZE_BYTE => function() { return $this->getFileSizeByte(); }, FileTemplateShortCodeName::FILE_SIZE_KB => function() { return $this->getFileSizeKb(); }, FileTemplateShortCodeName::FILE_SIZE_MB => function() { return $this->getFileSizeMb(); }, FileTemplateShortCodeName::BASE_NAME => function() { return $this->getBaseName() ?: ''; }, FileTemplateShortCodeName::MD5_HASH => function() { return $this->getMD5Hash() ?: ''; }, FileTemplateShortCodeName::RANDOM_HASH => function() { return $this->getRandomUniqueHash() ?: ''; }, FileTemplateShortCodeName::LOCAL_URL => function() { return $this->getLocalUrl(); }, ]; } /* * */ /** * Clear copy file paths. * * @since 1.8.0 */ private function clearCopyFilePaths(): void { // Clear the copy file paths $this->copyFilePaths = []; } /** * Add a copy file path. * * @param string $copyFilePath * @since 1.8.0 */ private function addCopyFilePath(string $copyFilePath): void { $this->copyFilePaths[] = $copyFilePath; // If this is a test, store the file path as a test file path. MediaService::getInstance()->addTestFilePath($copyFilePath); } /** * @return int Size of the file in bytes * @since 1.8.0 */ private function getFileSize(): int { $localPath = $this->getLocalPath(); $size = $localPath ? $this->getFileSystem()->size($localPath) : 0; return $size ?: 0; } /** * Get unique file path under a directory. * * @param string $fileName File name without extension * @param string $directory Directory path. The file name will be unique to this directory. * @return string|null Absolute file path that is unique to the given directory, if there is a file. Otherwise, null. * @since 1.8.0 */ private function getUniqueFilePath(string $fileName, string $directory): ?string { $ext = $this->getExtension(); if ($ext === null) { return null; } return FileService::getInstance()->getUniqueFilePath( $fileName . '.' . $ext, $directory, $this->getLocalPath() ); } /** * @param string $directoryPath Directory or file path. * @return bool True if the directories of the file or the given path exist. * @since 1.8.0 */ private function makeDirectory(string $directoryPath): bool { // Get the directory path of the given path. $directoryPath = rtrim(FileService::getInstance()->forceDirectorySeparator($directoryPath), DIRECTORY_SEPARATOR); $directoryPath = strlen($this->getFileSystem()->extension($directoryPath)) ? $this->getFileSystem()->dirname($directoryPath) : $directoryPath; // If the directories do not exist, create them. if (!$this->getFileSystem()->isDirectory($directoryPath)) { $result = $this->getFileSystem()->makeDirectory($directoryPath, 0755, true); // Stop if the directories could not be created. if (!$result) { Informer::addError( sprintf(_wpcc('%1$s directory could not be created'), $directoryPath) )->addAsLog(); return false; } } return true; } }