Skip to content

Commit

Permalink
Merge pull request #25 from alchemy-fr/PS-578_dictionary-save-client-…
Browse files Browse the repository at this point in the history
…side

PS-578_dictionary-save-client-side
  • Loading branch information
jygaulier authored May 13, 2024
2 parents 0ee0df0 + be8f1fd commit f090f8a
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 71 deletions.
4 changes: 2 additions & 2 deletions bin/console
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@
* file that was distributed with this source code.
*/

use PHPExiftool\Tool\Command\ClassesBuilderCommand;
use PHPExiftool\Tool\Command\DumpCommand;
use Symfony\Component\Console\Application;
use PHPExiftool\Tool\Command\ClassesBuilder;

require __DIR__ . '/../vendor/autoload.php';

Expand All @@ -22,7 +22,7 @@ if (!class_exists('Symfony\Component\DomCrawler\Crawler')) {
}

$cli = new Application('PHPExiftool', '2.2');
$cli->addCommands(array(new ClassesBuilder()));
$cli->addCommands(array(new ClassesBuilderCommand()));
$cli->addCommands(array(new DumpCommand()));

$cli->run();
10 changes: 7 additions & 3 deletions lib/PHPExiftool/ClassUtils/tagGroupBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class tagGroupBuilder extends Builder
private ?int $writable = -1;
private array $tags = [];
private array $descriptions = [];
private array $flags = []; // count of occurences for eache flag
private array $flags = []; // count of occurences for each flag

public function addTag(array $tagComments, array $tagProperties)
{
Expand Down Expand Up @@ -134,11 +134,12 @@ public function setFlags(array $flags)
}
}

public function write(string $path): Builder
public function computeProperties(): Builder
{
$this->properties['phpType'] = $this->php_type ?: "mixed";
$this->properties['isWritable'] = ($this->writable === 1);
$this->properties['description'] = $this->descriptions;
$this->properties['tags'] = $this->tags;
if(!is_null($this->count)) { // 0 = default parent value
$this->properties['count'] = max(0, $this->count);
}
Expand All @@ -157,8 +158,11 @@ public function write(string $path): Builder
$this->properties["flags"] = $binFlags;
}

$this->properties['tags'] = $this->tags;
return $this;
}

public function write(string $path): Builder
{
parent::write($path);
return $this;
}
Expand Down
53 changes: 7 additions & 46 deletions lib/PHPExiftool/InformationDumper.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,17 +56,14 @@ class InformationDumper
private Exiftool $exiftool;
private LoggerInterface $logger;
private int $currentXmlLine;
private string $rootPath;
private string $rootNamespace;


public function __construct(Exiftool $exiftool, string $rootPath)
public function __construct(Exiftool $exiftool)
{
$this->exiftool = $exiftool;
$this->logger = new NullLogger();
$this->rootNamespace = PHPExiftool::ROOT_NAMESPACE . '\\' . PHPExiftool::SUBDIR;

$this->rootPath = $rootPath . '/' . PHPExiftool::SUBDIR;
}

public function setLogger(LoggerInterface $logger)
Expand Down Expand Up @@ -123,37 +120,18 @@ public function listDatas(string $type = self::LISTTYPE_SUPPORTED_XML, array $op
return $dom;
}

public function dumpClasses(array $options, array $lngs)
public function dumpClasses(array $options, array $lngs, callable $callback = null)
{
$dom = $this->listDatas(InformationDumper::LISTTYPE_SUPPORTED_XML, $options);

@mkdir($this->rootPath, 0754, true);

$this->logger->info(sprintf('Erasing previous files "%s/*" ', $this->rootPath));
try {
$cmd = 'rm -Rf ' . $this->rootPath . '/* 2> /dev/null';
$output = [];
@exec($cmd, $output);
}
catch (\Exception $e) {
// no-op
}

$this->logger->info('Generating classes... ');
$this->extractDump($dom, $lngs);
}

protected function extractDump(DOMDocument $dump, array $lngs)
{
$nGroups = 0;
$nTags = 0;

/** @var tagGroupBuilder[] $tagGroupBuilders */
$tagGroupBuilders = [];
$group_ids = []; // to check group_id belongs to only one class

$crawler = new Crawler();
$crawler->addDocument($dump);
$crawler->addDocument($dom);

$tag_count = count($crawler->filter('table>tag'));
$this->logger->info(sprintf('tag count : %d', $tag_count));
Expand Down Expand Up @@ -262,7 +240,6 @@ protected function extractDump(DOMDocument $dump, array $lngs)
}

$this->logger->info(sprintf("building \"%s\"", $fq_classname));
$nGroups++;

$tagGroupBuilder = new tagGroupBuilder(
$this->rootNamespace,
Expand Down Expand Up @@ -385,28 +362,12 @@ protected function extractDump(DOMDocument $dump, array $lngs)
}
}

$this->logger->info(sprintf("Writing %d classes... ", $nGroups));

foreach ($tagGroupBuilders as $fq_classname => $builder) {
$builder->write($this->rootPath);
$builder->computeProperties();
if($callback) {
$callback($fq_classname, $builder);
}
}

$this->logger->info(sprintf("%d classes covers %d tags.", $nGroups, $nTags));

$this->logger->info(sprintf("Writing helper Table"));
ksort($group_ids, SORT_NATURAL + SORT_FLAG_CASE);
$file = $this->rootPath . '/Helper.php';
file_put_contents($file,
"<?php\n"
. "namespace " . $this->rootNamespace . ";\n\n"
. "use PHPExiftool\\Driver\\HelperInterface;\n\n"
. "class Helper implements HelperInterface\n"
. "{\n"
. " static function getIndex(): array {\n"
. " return " . var_export($group_ids, true) . ";\n"
. " }\n"
. "}\n"
);
}

protected function getPhpType(string $type): ?string
Expand Down
71 changes: 56 additions & 15 deletions lib/PHPExiftool/PHPExiftool.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,51 +2,92 @@

namespace PHPExiftool;

use PHPExiftool\ClassUtils\tagGroupBuilder;
use PHPExiftool\Driver\TagGroupFactory;
use Psr\Log\LoggerInterface;
use Psr\Log\NullLogger;
use PHPExiftool\Exception\DirectoryNotFoundException;

class PHPExiftool
{
const v = "3.1.2";
const v = "4.1.0";
const ROOT_NAMESPACE = "PHPExiftool\\Driver";
const SUBDIR = "TagGroup";

private string $classesRootDirectory;
private ?string $classesRootDirectory = null;
private LoggerInterface $logger;
private Factory $factory;

public function __construct(string $classesRootDirectory, ?LoggerInterface $logger = null)
public function __construct(?string $classesRootDirectory = null, ?LoggerInterface $logger = null)
{
$c = substr($classesRootDirectory, 0, 1);
if($c !== '/') {
throw new DirectoryNotFoundException(sprintf("classesRootDirectory must be absolute, \"%s\" given", $classesRootDirectory));
}
if(!file_exists($classesRootDirectory) || !is_writable($classesRootDirectory)) {
throw new DirectoryNotFoundException(sprintf("classesRootDirectory \"%s\" must exists and be writable", $classesRootDirectory));
if($classesRootDirectory !== null) {
$this->setClassesRootDirectory($classesRootDirectory);
}

$this->classesRootDirectory = realpath($classesRootDirectory);
if($logger === null) {
$logger = new NullLogger();
}
$this->logger = $logger;
$this->setLogger($logger);
$this->factory = new Factory($this);
}



public function setLogger(LoggerInterface $logger)
{
$this->logger = $logger;
}

/**
* @param string|null $classesRootDirectory
*/
public function setClassesRootDirectory(?string $classesRootDirectory): void
{
$c = substr($classesRootDirectory, 0, 1);
if ($c !== '/') {
throw new DirectoryNotFoundException(sprintf("classesRootDirectory must be absolute, \"%s\" given", $classesRootDirectory));
}
if (!file_exists($classesRootDirectory) || !is_writable($classesRootDirectory)) {
throw new DirectoryNotFoundException(sprintf("classesRootDirectory \"%s\" must exists and be writable", $classesRootDirectory));
}

public function generateClasses(array $options, array $lngs = ['en']): void
$this->classesRootDirectory = realpath($classesRootDirectory);
}

public function generateClasses(array $options, array $lngs = ['en'], ?callable $cb = null): int
{
$dumper = new InformationDumper(new Exiftool(new NullLogger()), $this->classesRootDirectory);
$classesDirectory = $this->classesRootDirectory . '/' . self::SUBDIR;
$rootNamespace = self::ROOT_NAMESPACE . '\\' . self::SUBDIR;

$dumper = new InformationDumper(new Exiftool($this->logger));

$group_ids = [];
$dumper->dumpClasses(
$options,
$lngs,
$cb ?: function (string $fq_classname, tagGroupBuilder $tgb) use($classesDirectory, &$group_ids) {
$tgb->write($classesDirectory);
$group_ids[$tgb->getProperty('id')] = $fq_classname;
}
);

if(!$cb) {
$this->logger->info(sprintf("Writing helper Table"));
ksort($group_ids, SORT_NATURAL + SORT_FLAG_CASE);
$file = $classesDirectory . '/Helper.php';
file_put_contents($file,
"<?php\n"
. "namespace " . $rootNamespace . ";\n\n"
. "use " . self::ROOT_NAMESPACE . "\\HelperInterface;\n\n"
. "class Helper implements HelperInterface\n"
. "{\n"
. " static function getIndex(): array {\n"
. " return " . var_export($group_ids, true) . ";\n"
. " }\n"
. "}\n"
);
}

$dumper->dumpClasses($options, $lngs);
return count($group_ids);
}

public function isClassesGenerated(): bool
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
use Monolog\Handler\NullHandler;
use Monolog\Handler\StreamHandler;
use Monolog\Logger;
use PHPExiftool\ClassUtils\tagGroupBuilder;
use PHPExiftool\Exiftool;
use PHPExiftool\InformationDumper;
use PHPExiftool\PHPExiftool;
Expand All @@ -29,7 +30,7 @@
* @author Romain Neutron - [email protected]
* @license http://opensource.org/licenses/MIT MIT
*/
class ClassesBuilder extends Command
class ClassesBuilderCommand extends Command
{
protected InputInterface $input;
protected OutputInterface $output;
Expand Down Expand Up @@ -80,14 +81,27 @@ protected function execute(InputInterface $input, OutputInterface $output): int
}


$dumper = new InformationDumper(new Exiftool($logger), $input->getOption('path'));
$dumper->setLogger($logger);
$path = realpath($input->getOption('path'));
$subPath = $path . '/' . PHPExiftool::SUBDIR; // security : do NOT rm passed cli option
@mkdir($subPath, 0755, true);
$logger->info(sprintf('Erasing previous files "%s/*" ', $subPath));
try {
$cmd = 'rm -Rf ' . $subPath . '/* 2> /dev/null';
$output = [];
@exec($cmd, $output);
}
catch (\Exception $e) {
// no-op
}
$logger->info('Generating classes... ');

$dumper->dumpClasses($options, $input->getOption('lng'));
$PHPExiftool = new PHPExiftool($path, $logger);
$nClasses = $PHPExiftool->generateClasses($options, $input->getOption('lng'));

$this->output->writeln(
sprintf(
'Generated in %d seconds (%d Mb)',
'Generated %d classes in %d seconds (%d Mb)',
$nClasses,
(microtime(true) - $start),
memory_get_peak_usage() >> 20
)
Expand Down

0 comments on commit f090f8a

Please sign in to comment.