/** * @param $path */ public static function optimize($path) { $format = getimagesize($path); if (is_array($format) && array_key_exists("mime", $format)) { $format = strtolower(str_replace("image/", "", $format["mime"])); if ($format == "png") { $optimizer = self::getPngOptimizerCli(); if ($optimizer) { /*if($optimizer["type"] == "pngquant") { Console::exec($optimizer["path"] . " --ext xxxoptimized.png " . $path, null, 60); $newFile = preg_replace("/\.png$/", "", $path); $newFile .= "xxxoptimized.png"; if(file_exists($newFile)) { unlink($path); rename($newFile, $path); } } else */ if ($optimizer["type"] == "pngcrush") { $newFile = $path . ".xxxoptimized"; Console::exec($optimizer["path"] . " " . $path . " " . $newFile, null, 60); if (file_exists($newFile)) { unlink($path); rename($newFile, $path); } } } } else { if ($format == "jpeg") { $optimizer = self::getJpegOptimizerCli(); if ($optimizer) { if ($optimizer["type"] == "imgmin") { $newFile = $path . ".xxxoptimized"; Console::exec($optimizer["path"] . " " . $path . " " . $newFile, null, 60); if (file_exists($newFile)) { unlink($path); rename($newFile, $path); } } else { if ($optimizer["type"] == "jpegoptim") { $additionalParams = ""; if (filesize($path) > 10000) { $additionalParams = " --all-progressive"; } Console::exec($optimizer["path"] . $additionalParams . " -o --strip-all --max=85 " . $path, null, 60); } } } } } } }
/** * @param $width * @param $height * @return $this|Imagick */ public function resize($width, $height) { if (!$this->isOriginal || !$this->isSvg()) { return parent::resize($width, $height); } $width = (int) $width; $height = (int) $height; $tmpFile = PIMCORE_SYSTEM_TEMP_DIRECTORY . "/" . uniqid() . "_pimcore_image_svg_resize_tmp_file.png"; $this->tmpFiles[] = $tmpFile; Console::exec(self::getBinary() . " -w " . $width . " -h " . $height . " -D -f " . $this->imagePath . " -e " . $tmpFile); $this->initImagick($tmpFile); return $this; }
/** * @param $url * @param $outputFile * @param int $screenWidth * @param string $format * @return bool */ public static function convert($url, $outputFile, $screenWidth = 1200, $format = "png") { // add parameter pimcore_preview to prevent inclusion of google analytics code, cache, etc. $url .= (strpos($url, "?") ? "&" : "?") . "pimcore_preview=true"; $arguments = " --width " . $screenWidth . " --format " . $format . " \"" . $url . "\" " . $outputFile; // use xvfb if possible if ($xvfb = self::getXvfbBinary()) { $command = $xvfb . " --auto-servernum --server-args=\"-screen 0, 1280x1024x24\" " . self::getWkhtmltoimageBinary() . " --use-xserver" . $arguments; } else { $command = self::getWkhtmltoimageBinary() . $arguments; } Console::exec($command, PIMCORE_LOG_DIRECTORY . "/wkhtmltoimage.log", 60); if (file_exists($outputFile) && filesize($outputFile) > 1000) { return true; } return false; }
/** * @return int * @throws \Exception */ public function getDuration() { $tmpFile = PIMCORE_SYSTEM_TEMP_DIRECTORY . "/video-info-" . uniqid() . ".out"; $cmd = self::getFfmpegCli() . " -i " . realpath($this->file); Console::exec($cmd, $tmpFile, null, 60); $contents = file_get_contents($tmpFile); unlink($tmpFile); return $this->extractDuration($contents); }
/** * @param null $page * @param null $path * @return bool|string */ public function getText($page = null, $path = null) { try { $path = $path ? $path : $this->path; $pageRange = ""; try { // first try to use poppler's pdftotext, because this produces more accurate results than the txtwrite device from ghostscript if ($page) { $pageRange = "-f " . $page . " -l " . $page . " "; } $text = Console::exec(self::getPdftotextCli() . " " . $pageRange . $path . " -", null, 120); } catch (\Exception $e) { // pure ghostscript way if ($page) { $pageRange = "-dFirstPage=" . $page . " -dLastPage=" . $page . " "; } $textFile = PIMCORE_SYSTEM_TEMP_DIRECTORY . "/pdf-text-extract-" . uniqid() . ".txt"; Console::exec(self::getGhostscriptCli() . " -dBATCH -dNOPAUSE -sDEVICE=txtwrite " . $pageRange . "-dTextFormat=2 -sOutputFile=" . $textFile . " " . $path, null, 120); if (is_file($textFile)) { $text = file_get_contents($textFile); // this is a little bit strange the default option -dTextFormat=3 from ghostscript should return utf-8 but it doesn't // so we use option 2 which returns UCS-2LE and convert it here back to UTF-8 which works fine $text = mb_convert_encoding($text, 'UTF-8', 'UCS-2LE'); unlink($textFile); } } return $text; } catch (\Exception $e) { \Logger::error($e); return false; } }
/** * @param null $page * @param null $path * @return bool|string * @throws \Exception */ public function getText($page = null, $path = null) { $path = $path ? $this->preparePath($path) : $this->path; if ($page || parent::isFileTypeSupported($path)) { // for per page extraction we have to convert the document to PDF and extract the text via ghostscript return parent::getText($page, $this->getPdf($path)); } elseif (File::getFileExtension($path)) { // if we want to get the text of the whole document, we can use libreoffices text export feature $cmd = self::getLibreOfficeCli() . " --headless --nologo --nofirststartwizard --norestore --convert-to txt:Text --outdir " . escapeshellarg(PIMCORE_TEMPORARY_DIRECTORY) . " " . escapeshellarg($path); $out = Console::exec($cmd, null, 240); Logger::debug("LibreOffice Output was: " . $out); $tmpName = PIMCORE_TEMPORARY_DIRECTORY . "/" . preg_replace("/\\." . File::getFileExtension($path) . "\$/", ".txt", basename($path)); if (file_exists($tmpName)) { $text = file_get_contents($tmpName); $text = \Pimcore\Tool\Text::convertToUTF8($text); unlink($tmpName); return $text; } else { $message = "Couldn't convert document to PDF: " . $path . " with the command: '" . $cmd . "' - now trying to get the text out of the PDF ..."; Logger::error($message); return parent::getText(null, $this->getPdf($path)); } } return ""; // default empty string }
public function wordExportDownloadAction() { $id = $this->getParam("id"); $exportFile = PIMCORE_SYSTEM_TEMP_DIRECTORY . "/" . $id . ".html"; // add closing body/html //$f = fopen($exportFile, "a+"); //fwrite($f, "</body></html>"); //fclose($f); // should be done via Pimcore_Document(_Adapter_LibreOffice) in the future if (\Pimcore\Document::isFileTypeSupported("docx")) { $lockKey = "soffice"; Model\Tool\Lock::acquire($lockKey); // avoid parallel conversions of the same document $out = Tool\Console::exec(\Pimcore\Document\Adapter\LibreOffice::getLibreOfficeCli() . ' --headless --convert-to docx:"Office Open XML Text" --outdir ' . PIMCORE_TEMPORARY_DIRECTORY . " " . $exportFile); \Logger::debug("LibreOffice Output was: " . $out); $tmpName = PIMCORE_TEMPORARY_DIRECTORY . "/" . preg_replace("/\\." . File::getFileExtension($exportFile) . "\$/", ".docx", basename($exportFile)); Model\Tool\Lock::release($lockKey); // end what should be done in Pimcore_Document header("Content-Type: application/vnd.openxmlformats-officedocument.wordprocessingml.document"); header('Content-Disposition: attachment; filename="' . basename($tmpName) . '"'); } else { // no conversion, output html file $tmpName = $exportFile; header("Content-Type: text/html"); header('Content-Disposition: attachment; filename="' . basename($tmpName) . '"'); } while (@ob_end_flush()) { } flush(); readfile($tmpName); @unlink($exportFile); @unlink($tmpName); exit; }
public function downloadImageThumbnailAction() { $image = Asset\Image::getById($this->getParam("id")); $config = null; if ($this->getParam("config")) { $config = \Zend_Json::decode($this->getParam("config")); } elseif ($this->getParam("type")) { $predefined = ["web" => ["resize_mode" => "scaleByWidth", "width" => 3500, "dpi" => 72, "format" => "JPEG", "quality" => 85], "print" => ["resize_mode" => "scaleByWidth", "width" => 6000, "dpi" => 300, "format" => "JPEG", "quality" => 95], "office" => ["resize_mode" => "scaleByWidth", "width" => 1190, "dpi" => 144, "format" => "JPEG", "quality" => 90]]; $config = $predefined[$this->getParam("type")]; } if ($config) { $thumbnailConfig = new Asset\Image\Thumbnail\Config(); $thumbnailConfig->setName("pimcore-download-" . $image->getId() . "-" . md5($this->getParam("config"))); if ($config["resize_mode"] == "scaleByWidth") { $thumbnailConfig->addItem("scaleByWidth", ["width" => $config["width"]]); } elseif ($config["resize_mode"] == "scaleByHeight") { $thumbnailConfig->addItem("scaleByHeight", ["height" => $config["height"]]); } else { $thumbnailConfig->addItem("resize", ["width" => $config["width"], "height" => $config["height"]]); } $thumbnailConfig->setQuality($config["quality"]); $thumbnailConfig->setFormat($config["format"]); if ($thumbnailConfig->getFormat() == "JPEG") { $thumbnailConfig->setPreserveMetaData(true); $thumbnailConfig->setPreserveColor(true); } $thumbnail = $image->getThumbnail($thumbnailConfig); $thumbnailFile = $thumbnail->getFileSystemPath(); $exiftool = \Pimcore\Tool\Console::getExecutable("exiftool"); if ($thumbnailConfig->getFormat() == "JPEG" && $exiftool && isset($config["dpi"]) && $config["dpi"]) { \Pimcore\Tool\Console::exec($exiftool . " -overwrite_original -xresolution=" . $config["dpi"] . " -yresolution=" . $config["dpi"] . " -resolutionunit=inches " . escapeshellarg($thumbnailFile)); } $downloadFilename = str_replace("." . File::getFileExtension($image->getFilename()), "." . $thumbnail->getFileExtension(), $image->getFilename()); $downloadFilename = strtolower($downloadFilename); header('Content-Disposition: attachment; filename="' . $downloadFilename . '"'); header("Content-Type: " . $thumbnail->getMimeType(), true); // we have to clear the stat cache here, otherwise filesize() would return the wrong value // the reason is that exiftool modifies the file's size, but PHP doesn't know anything about that clearstatcache(); header("Content-Length: " . filesize($thumbnailFile), true); $this->sendThumbnailCacheHeaders(); while (@ob_end_flush()) { } flush(); readfile($thumbnailFile); @unlink($thumbnailFile); exit; } }
public static function optimizeJpegoptim($path) { $bin = \Pimcore\Tool\Console::getExecutable("jpegoptim"); if ($bin) { $newFile = self::getTempFile("jpg"); $additionalParams = ""; if (filesize($path) > 10000) { $additionalParams = " --all-progressive"; } $content = Console::exec($bin . $additionalParams . " -o --strip-all --max=85 --stdout " . $path, null, 60); if ($content) { File::put($newFile, $content); } return $newFile; } return null; }
protected function execute(InputInterface $input, OutputInterface $output) { $currentRevision = null; if ($input->getOption("source-build")) { $currentRevision = $input->getOption("source-build"); } $availableUpdates = Update::getAvailableUpdates($currentRevision); if ($input->getOption("list")) { if (count($availableUpdates["releases"])) { $rows = []; foreach ($availableUpdates["releases"] as $release) { $rows[] = [$release["version"], date("Y-m-d", $release["date"]), $release["id"]]; } $table = new Table($output); $table->setHeaders(array('Version', 'Date', 'Build'))->setRows($rows); $table->render(); } if (count($availableUpdates["revisions"])) { $this->output->writeln("The latest available build is: <comment>" . $availableUpdates["revisions"][0]["id"] . "</comment> (" . date("Y-m-d", $availableUpdates["revisions"][0]["date"]) . ")"); } if (!count($availableUpdates["releases"]) && !count($availableUpdates["revisions"])) { $this->output->writeln("<info>No updates available</info>"); } } if ($input->getOption("update")) { $returnMessages = []; $build = null; $updateInfo = trim($input->getOption("update")); if (is_numeric($updateInfo)) { $build = $updateInfo; } else { // get build nr. by version number foreach ($availableUpdates["releases"] as $release) { if ($release["version"] == $updateInfo) { $build = $release["id"]; break; } } } if (!$build) { $this->writeError("Update with build / version " . $updateInfo . " not found."); exit; } $helper = $this->getHelper('question'); $question = new ConfirmationQuestion("You are going to update to build {$build}! Continue with this action? (y/n)", false); if (!$helper->ask($input, $output, $question)) { return; } $this->output->writeln("Starting the update process ..."); if ($input->getOption("dry-run")) { $this->output->writeln("<info>---------- DRY-RUN ----------</info>"); } $jobs = Update::getJobs($build, $currentRevision); $steps = count($jobs["parallel"]) + count($jobs["procedural"]); $progress = new ProgressBar($output, $steps); $progress->start(); foreach ($jobs["parallel"] as $job) { if ($job["type"] == "download") { Update::downloadData($job["revision"], $job["url"]); } $progress->advance(); } $maintenanceModeId = 'cache-warming-dummy-session-id'; Admin::activateMaintenanceMode($maintenanceModeId); $stoppedByError = false; foreach ($jobs["procedural"] as $job) { if ($input->getOption("dry-run")) { $job["dry-run"] = true; } $phpCli = Console::getPhpCli(); $cmd = $phpCli . " " . realpath(PIMCORE_PATH . DIRECTORY_SEPARATOR . "cli" . DIRECTORY_SEPARATOR . "console.php") . " internal:update-processor " . escapeshellarg(json_encode($job)); $return = Console::exec($cmd); $return = trim($return); $returnData = @json_decode($return, true); if (is_array($returnData)) { if (trim($returnData["message"])) { $returnMessages[] = [$job["revision"], strip_tags($returnData["message"])]; } if (!$returnData["success"]) { $stoppedByError = true; break; } } else { $stoppedByError = true; break; } $progress->advance(); } $progress->finish(); Admin::deactivateMaintenanceMode(); $this->output->writeln("\n"); if ($stoppedByError) { $this->output->writeln("<error>Update stopped by error! Please check your logs</error>"); $this->output->writeln("Last return value was: " . $return); } else { $this->output->writeln("<info>Update done!</info>"); if (count($returnMessages)) { $table = new Table($output); $table->setHeaders(array('Build', 'Message'))->setRows($returnMessages); $table->render(); } } } }
/** * @param $script * @param $arguments * @param $outputFile * @param $timeout * @return string */ public static function runPhpScript($script, $arguments = "", $outputFile = null, $timeout = null) { $cmd = self::buildPhpScriptCmd($script, $arguments); $return = Console::exec($cmd, $outputFile, $timeout); return $return; }