diff --git a/src/Configuration/ConfigurationDefaults.php b/src/Configuration/ConfigurationDefaults.php index a5828d7..9a5b626 100644 --- a/src/Configuration/ConfigurationDefaults.php +++ b/src/Configuration/ConfigurationDefaults.php @@ -116,13 +116,19 @@ public function __construct(&$settings) { '#engine' => 'Convert\\ImageMagick', ), ), - 'pdf->jpg' => array( + 'pdf->(jpg|png)' => array( 'imagemagick:default' => array( '#engine' => 'Convert\\ImageMagick', "colorspace" => "sRGB", "flatten" => 1, ), ), + 'pdf->(zip/png)' => array( + 'imagemagick:default' => array( + '#engine' => 'Convert\\ImageMagick', + "colorspace" => "sRGB", + ), + ), 'ps->pdf' => array( 'ghostscript:default' => array( '#engine' => 'Convert\\GhostScript', diff --git a/src/Engine/Convert/ImageMagick.php b/src/Engine/Convert/ImageMagick.php index 56f0a81..664ec84 100644 --- a/src/Engine/Convert/ImageMagick.php +++ b/src/Engine/Convert/ImageMagick.php @@ -12,6 +12,7 @@ use FileConverter\Engine\EngineBase; use FileConverter\Util\Shell; +use FileConverter\Engine\Helper\Archive; class ImageMagick extends EngineBase { protected $cmd_options = array( array( @@ -46,8 +47,49 @@ class ImageMagick extends EngineBase { ), ); + public function convertFile($source, $destination) { + if (preg_match('@zip/(?.*)$@s', $this->conversion[1], $arr)) { + // Create a temp directory and convert the images. + $ext = $arr['ext']; + $imageArchive = new Archive($this); + $imagePath = $imageArchive->getTempDirectory(); + $this->shell(array( + $this->cmd, + Shell::argOptions($this->cmd_options, $this->configuration, 1), + $source, + "$imagePath/page.$ext", + )); + + // Create the temp directory + $archive = new Archive($this); + $tmp = $archive->getTempDirectory(); + // Rename the multiple image files in a standardized way + if (is_file("$imagePath/page.$ext")) { + $path = "$tmp/img/page1.$ext"; + $this->isTempWritable($path); + rename("$imagePath/page.$ext", $path); + } + else { + $i = 0; + while (is_file("$imagePath/page-$i.$ext")) { + $path = "$tmp/img/page" . ($i + 1) . ".$ext"; + $this->isTempWritable($path); + rename("$imagePath/page-$i.$ext", $path); + ++$i; + } + } + // Zip the files + $archive->save($destination); + return; + } + + return parent::convertFile($source, $destination); + } + public function getConvertFileShell($source, &$destination) { - $multipage = array('pdf'); + $multipage = array( + 'pdf', + ); if (in_array($this->conversion[0], $multipage)) { if (!in_array($this->conversion[1], $multipage)) { $source .= '[0]'; diff --git a/src/Engine/EngineBase.php b/src/Engine/EngineBase.php index d4f0187..ae13746 100644 --- a/src/Engine/EngineBase.php +++ b/src/Engine/EngineBase.php @@ -26,7 +26,7 @@ abstract class EngineBase { protected $converter = NULL; protected $conversion = array( 'null', - 'null' + 'null', ); protected $settings = array(); protected $configuration = array(); @@ -142,6 +142,23 @@ public function getConfiguration() { return $this->configuration; } + /** + * Get the conversion type + * @param string $target source|destination + * @param number $depth 0=full|1=top|2=2-levels + * @return string + */ + public function getConversion($target = 'source', $depth = 0) { + $type = $this->conversion[$target === 'source' ? 0 : 1]; + if ($depth < 1 || $depth > 1 + substr_count($type, '/')) { + return $type; + } + $tmp = explode('/', $type, $depth + 1); + array_pop($tmp); + $type = join('/', $tmp); + return $type; + } + public function getHelp($type = 'installation') { $os = $this->settings['operating_system']; $os_version = $this->settings['operating_system_version']; @@ -182,6 +199,26 @@ public function getVersionInfo() { abstract public function isAvailable(); + protected function isTempWritable($path) { + $dir = $this->settings['temp_dir']; + $path = preg_replace('@/[^/]*$@s', '', $path); + if (strpos($path, $dir) !== 0) { + return FALSE; + } + if (is_dir($path)) { + return TRUE; + } + $tmp = explode('/', $path); + $path = ''; + while (!empty($tmp)) { + $path .= '/' . array_shift($tmp); + if (!is_dir($path)) { + mkdir($path); + } + } + return (bool) is_dir($path); + } + public function shell($command) { $cmd = ""; $stderr = NULL; diff --git a/src/Engine/Helper/Archive.php b/src/Engine/Helper/Archive.php new file mode 100644 index 0000000..a567976 --- /dev/null +++ b/src/Engine/Helper/Archive.php @@ -0,0 +1,71 @@ +engine =& $engine; + } + + public function __destruct() { + if (isset($this->tempDirectory)) { + $this->engine->shell(array( + 'rm', + Shell::arg('rf', Shell::SHELL_ARG_BOOL_SGL, TRUE), + Shell::arg($this->tempDirectory, Shell::SHELL_ARG_BASIC), + )); + } + } + + public function getTempDirectory() { + if (!isset($this->tempDirectory)) { + $this->tempDirectory = $this->engine->getTempFile('dir'); + @unlink($this->tempDirectory); + mkdir($this->tempDirectory); + } + return $this->tempDirectory; + } + + public function save($destination) { + switch ($ext = $this->engine->getConversion('destination', 1)) { + case 'zip': + $temp = $this->engine->getTempFile('zip'); + @unlink($temp); + $cmd = array( + 'cd', + Shell::arg($this->getTempDirectory(), Shell::SHELL_ARG_BASIC), + Shell::arg('; ', Shell::SHELL_SAFE), + $this->engine->shellWhich('zip'), + Shell::arg('r', Shell::SHELL_ARG_BOOL_SGL, TRUE), + Shell::arg($temp, Shell::SHELL_ARG_BASIC), + Shell::arg('.', Shell::SHELL_SAFE), + ); + echo $this->engine->shell($cmd); + rename($temp, $destination); + break; + + default: + throw new \InvalidArgumentException("Invalid archive format spec: $ext"); + } + } + +}