123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142 |
- <?php
- /**
- * This file is part of the PHPExiftool package.
- *
- * (c) Alchemy <support@alchemy.fr>
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
- namespace PHPExiftool;
- use PHPExiftool\Exception\RuntimeException;
- use Symfony\Component\Process\Process;
- class ExiftoolServer extends Exiftool
- {
- private $pipefile;
- private $server;
- private $offset = 0;
- public function __construct()
- {
- $this->setUp();
- }
- public function __destruct()
- {
- $this->cleanup();
- }
- public function reset()
- {
- $this->cleanup();
- $this->setUp();
- }
- public function start()
- {
- $this->server->start();
- }
- public function stop()
- {
- if ($this->isRunning()) {
- file_put_contents($this->pipefile, "-stay_open False\n", FILE_APPEND);
- }
- $this->server->stop();
- }
- public function isRunning()
- {
- return null !== $this->server && $this->server->isRunning();
- }
- public function executeCommand($commands, $timeout = 4)
- {
- $optwithargs = array('-i', '-charset', '-if', '-w', '-common_args');
- if (true !== $this->isRunning()) {
- throw new RuntimeException('Server is not running');
- }
- $prev = null;
- // // first split execute (sub queries)
- //
- // if (false !== $pos = strpos($commands, '-common_args')) {
- // $common_args = substr($commands, $pos + 12);
- //
- // $recomposed = array();
- //
- // foreach (explode(' -execute ', substr($commands, 0, $pos)) as $subcommand) {
- // $recomposed[] = $subcommand . ' ' . $common_args;
- // }
- // $commands = implode(' -execute ', $recomposed);
- // }
- foreach (explode(' ', $commands) as $command) {
- if ($command == '-q') {
- continue;
- }
- if (substr($command, 0, 1) === "'" && substr($command, -1) === "'") {
- $command = substr($command, 1, -1);
- }
- if (substr($command, 0, 1) === '"' && substr($command, -1) === '"') {
- $command = substr($command, 1, -1);
- }
- $end = "\n";
- file_put_contents($this->pipefile, $command . $end, FILE_APPEND);
- }
- file_put_contents($this->pipefile, "\n-execute\n", FILE_APPEND);
- // here we send sigcont
- //$this->server->signal(SIGCONT);
- $start = microtime(true);
- while ((strlen($this->server->getOutput()) <= $this->offset || substr(substr($this->server->getOutput(), $this->offset), -8) !== "{ready}\n") && (microtime(true) - $start) < $timeout) {
- usleep(25000);
- }
- // var_dump(microtime(true) - $start);
- // server output should be cached here because streams are polled
- // everytime I request the output
- $outputIsValid = substr($this->server->getOutput(), -8) === "{ready}\n";
- $output = $outputIsValid ? substr($this->server->getOutput(), $this->offset, -8) : '';
- $this->offset = strlen($this->server->getOutput());
- if (trim($output) === '' && $outputIsValid === false && $this->server->getErrorOutput()) {
- throw new RuntimeException('Command failed');
- }
- return $output;
- }
- private function setUp()
- {
- $this->pipefile = tempnam(sys_get_temp_dir(), 'exiftool-pipe');
- $this->server = new Process(self::getBinary() . ' -stay_open True -@ ' . $this->pipefile);
- }
- private function cleanup()
- {
- $this->stop();
- if (file_exists($this->pipefile) && is_writable($this->pipefile)) {
- unlink($this->pipefile);
- $this->pipefile = null;
- }
- $this->server = null;
- }
- }
|