diff --git a/bin/generate-filters b/bin/generate-filters index 8215e67..cdb2755 100755 --- a/bin/generate-filters +++ b/bin/generate-filters @@ -1,14 +1,4 @@ #!/usr/bin/env php get('app.cli'); +$application->setDefaultCommand(GenerateCommand::NAME); +$application->run(); diff --git a/composer.json b/composer.json index 04bc605..f6e6514 100644 --- a/composer.json +++ b/composer.json @@ -10,20 +10,34 @@ } ], "require": { + "symfony/config": "^3.4", + "symfony/console": "^3.4", + "symfony/dependency-injection": "^3.4", + "symfony/filesystem": "^3.4", + "symfony/yaml": "^3.4", "tightenco/collect": "^5.4" }, "require-dev": { - "phpunit/phpunit": "^5.7" + "phpunit/phpunit": "^5.7", + "symfony/var-dumper": "^3.4" }, "autoload": { "psr-4": { "Opdavies\\GmailFilterBuilder\\": "src/" } }, + "autoload-dev": { + "psr-4": { + "Tests\\Opdavies\\GmailFilterBuilder\\": "tests/" + } + }, "extra": { "branch-alias": { "dev-master": "1.1-dev" } }, - "bin": ["bin/generate-filters"] + "bin": ["bin/generate-filters"], + "config": { + "sort-packages": true + } } diff --git a/config/services.yml b/config/services.yml new file mode 100644 index 0000000..75f8706 --- /dev/null +++ b/config/services.yml @@ -0,0 +1,13 @@ +services: + app.cli: + class: Symfony\Component\Console\Application + autowire: true + + app.builder: + class: Opdavies\GmailFilterBuilder\Service\Builder + + app.generate.command: + class: Opdavies\GmailFilterBuilder\Console\Command\GenerateCommand + autowire: true + tags: + - { name: ConsoleCommand } diff --git a/src/Builder.php b/src/Builder.php index 8071191..a5cd6d7 100644 --- a/src/Builder.php +++ b/src/Builder.php @@ -2,89 +2,11 @@ namespace Opdavies\GmailFilterBuilder; -class Builder +use Opdavies\GmailFilterBuilder\Service\Builder as NewBuilder; + +/** + * @deprecated + */ +class Builder extends NewBuilder { - /** - * @var array - */ - private $filters = []; - - public function __construct(array $filters) - { - $this->filters = $filters; - } - - public function __toString() - { - return $this->build(); - } - - /** - * Build XML for a set of filters. - * - * @return string - */ - private function build() - { - $prefix = "" . PHP_EOL . ""; - $suffix = ''; - - $xml = collect($this->filters)->map(function ($items) { - return $this->buildEntry($items); - })->implode(PHP_EOL); - - return collect([$prefix, $xml, $suffix])->implode(PHP_EOL); - } - - /** - * Build XML for an filter. - * - * @param Filter $filter - * - * @return string - */ - private function buildEntry(Filter $filter) - { - $entry = collect($filter->getProperties())->map(function ($value, $key) { - return $this->buildProperty($value, $key); - })->implode(PHP_EOL); - - return collect(['', $entry, ''])->implode(PHP_EOL); - } - - /** - * Build XML for a property. - * - * @param string $value - * @param string $key - * - * @return string - */ - private function buildProperty($value, $key) - { - if (collect(['from', 'to'])->contains($key)) { - $value = $this->implode($value); - } - - return vsprintf("", [ - $key, - htmlentities($this->implode($value)), - ]); - } - - /** - * Implode values with the appropriate prefix, suffix and separator. - */ - private function implode($value, $separator = '|') - { - if (is_string($value)) { - return $value; - } - - if (is_array($value) && count($value) === 1) { - return reset($value); - } - - return sprintf('(%s)', collect($value)->implode($separator)); - } } diff --git a/src/Console/Command/GenerateCommand.php b/src/Console/Command/GenerateCommand.php new file mode 100644 index 0000000..0ea5751 --- /dev/null +++ b/src/Console/Command/GenerateCommand.php @@ -0,0 +1,58 @@ +setName(self::NAME) + ->setDefinition([ + new InputOption('input-file', null, InputOption::VALUE_OPTIONAL, 'The name of the PHP file containing your filters.', 'filters.php'), + new InputOption('output-file', null, InputOption::VALUE_OPTIONAL, 'The name of the XML file to generate.', 'filters.xml') + ]) + ->setDescription('Generates XML for Gmail filters.') + ; + } + + /** + * {@inheritdoc} + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + $inputFile = $input->getOption('input-file'); + $outputFile = $input->getOption('output-file'); + + if (file_exists(__DIR__.'/../../../../'.$inputFile)) { + $filters = require(__DIR__.'/../../../../'.$inputFile); + } elseif (file_exists(__DIR__.'/../../../'.$inputFile)) { + $filters = require(__DIR__.'/../../../'.$inputFile); + } else { + throw new \Exception('No filters.php file found.'); + } + + $io = new SymfonyStyle($input, $output); + + try { + new Builder($filters, $outputFile); + + $io->success(sprintf('%s file generated.', $outputFile)); + } catch (IOException $e) { + $io->error($e->getMessage()); + } + } +} diff --git a/src/Container/CommandCompilerClass.php b/src/Container/CommandCompilerClass.php new file mode 100644 index 0000000..2bf07b6 --- /dev/null +++ b/src/Container/CommandCompilerClass.php @@ -0,0 +1,22 @@ +findDefinition('app.cli'); + $taggedServices = $container->findTaggedServiceIds('ConsoleCommand'); + + foreach ($taggedServices as $id => $tags) { + $definition->addMethodCall('add', [new Reference($id)]); + } + } +} diff --git a/src/Container/Container.php b/src/Container/Container.php new file mode 100644 index 0000000..905a9e4 --- /dev/null +++ b/src/Container/Container.php @@ -0,0 +1,24 @@ +containerBuilder = new ContainerBuilder(); + $loader = new YamlFileLoader($this->containerBuilder, new FileLocator(__DIR__.'/../../config')); + $loader->load('services.yml'); + $this->containerBuilder->addCompilerPass(new CommandCompilerClass()); + $this->containerBuilder->compile(); + } + + public function get($className) + { + return $this->containerBuilder->get($className); + } +} diff --git a/src/Filter.php b/src/Filter.php index 1b37c4b..553fa89 100644 --- a/src/Filter.php +++ b/src/Filter.php @@ -2,240 +2,11 @@ namespace Opdavies\GmailFilterBuilder; -class Filter +use Opdavies\GmailFilterBuilder\Model\Filter as NewFilter; + +/** + * @deprecated + */ +class Filter extends NewFilter { - /** - * @var array - */ - private $properties = []; - - /** - * @return static - */ - public static function create() - { - return new static(); - } - - /** - * @param string $value - * - * @return $this - */ - public function has($value) - { - $this->properties['hasTheWord'] = $value; - - return $this; - } - - /** - * @param string $value - * - * @return $this - */ - public function hasNot($value) - { - $this->properties['doesNotHaveTheWord'] = $value; - - return $this; - } - - /** - * @param string|array $values - * - * @return $this - */ - public function from($values) - { - $this->properties['from'] = collect($values)->map(function ($value) { - return trim($value); - })->all(); - - return $this; - } - - /** - * @param string|array $values - * - * @return $this - */ - public function to($values) - { - $this->properties['to'] = collect($values)->map(function ($value) { - return trim($value); - })->all(); - - return $this; - } - - /** - * @param string $subject - * - * @return $this - */ - public function subject($subject) - { - $this->properties['subject'] = $subject; - - return $this; - } - - /** - * @return $this - */ - public function hasAttachment() - { - $this->properties['hasAttachment'] = 'true'; - - return $this; - } - - /** - * @return $this - */ - public function excludeChats() - { - $this->properties['excludeChats'] = 'true'; - - return $this; - } - - /** - * @param string $label - * - * @return $this - */ - public function label($label) - { - $this->properties['label'] = $label; - - return $this; - } - - /** - * @return $this - */ - public function archive() - { - $this->properties['shouldArchive'] = 'true'; - - return $this; - } - - /** - * @param string $label - * - * @return $this - */ - public function labelAndArchive($label) - { - $this->label($label)->archive(); - - return $this; - } - - /** - * @return $this - */ - public function spam() - { - $this->properties['shouldSpam'] = 'true'; - $this->properties['shouldNeverSpam'] = 'false'; - - return $this; - } - - /** - * @return $this - */ - public function neverSpam() - { - $this->properties['shouldSpam'] = 'false'; - $this->properties['shouldNeverSpam'] = 'true'; - - return $this; - } - - /** - * @return $this - */ - public function trash() - { - $this->properties['shouldTrash'] = 'true'; - - return $this; - } - - /** - * @return $this - */ - public function read() - { - $this->properties['markAsRead'] = 'true'; - - return $this; - } - - /** - * @return $this - */ - public function star() - { - $this->properties['shouldStar'] = 'true'; - - return $this; - } - - /** - * @param string $to - * - * @return $this - */ - public function forward($to) - { - $this->properties['forwardTo'] = $to; - - return $this; - } - - /** - * @return $this - */ - public function important() - { - $this->properties['shouldAlwaysMarkAsImportant'] = 'true'; - - return $this; - } - - /** - * @return $this - */ - public function notImportant() - { - $this->properties['shouldNeverMarkAsImportant'] = 'true'; - - return $this; - } - - /** - * @param string $category - * - * @return $this - */ - public function categorise($category) - { - $this->properties['smartLabelToApply'] = $category; - - return $this; - } - - /** - * @return array - */ - public function getProperties() - { - return $this->properties; - } } diff --git a/src/Model/Filter.php b/src/Model/Filter.php new file mode 100644 index 0000000..75d036f --- /dev/null +++ b/src/Model/Filter.php @@ -0,0 +1,241 @@ +properties['hasTheWord'] = $value; + + return $this; + } + + /** + * @param string $value + * + * @return $this + */ + public function hasNot($value) + { + $this->properties['doesNotHaveTheWord'] = $value; + + return $this; + } + + /** + * @param string|array $values + * + * @return $this + */ + public function from($values) + { + $this->properties['from'] = collect($values)->map(function ($value) { + return trim($value); + })->all(); + + return $this; + } + + /** + * @param string|array $values + * + * @return $this + */ + public function to($values) + { + $this->properties['to'] = collect($values)->map(function ($value) { + return trim($value); + })->all(); + + return $this; + } + + /** + * @param string $subject + * + * @return $this + */ + public function subject($subject) + { + $this->properties['subject'] = $subject; + + return $this; + } + + /** + * @return $this + */ + public function hasAttachment() + { + $this->properties['hasAttachment'] = 'true'; + + return $this; + } + + /** + * @return $this + */ + public function excludeChats() + { + $this->properties['excludeChats'] = 'true'; + + return $this; + } + + /** + * @param string $label + * + * @return $this + */ + public function label($label) + { + $this->properties['label'] = $label; + + return $this; + } + + /** + * @return $this + */ + public function archive() + { + $this->properties['shouldArchive'] = 'true'; + + return $this; + } + + /** + * @param string $label + * + * @return $this + */ + public function labelAndArchive($label) + { + $this->label($label)->archive(); + + return $this; + } + + /** + * @return $this + */ + public function spam() + { + $this->properties['shouldSpam'] = 'true'; + $this->properties['shouldNeverSpam'] = 'false'; + + return $this; + } + + /** + * @return $this + */ + public function neverSpam() + { + $this->properties['shouldSpam'] = 'false'; + $this->properties['shouldNeverSpam'] = 'true'; + + return $this; + } + + /** + * @return $this + */ + public function trash() + { + $this->properties['shouldTrash'] = 'true'; + + return $this; + } + + /** + * @return $this + */ + public function read() + { + $this->properties['markAsRead'] = 'true'; + + return $this; + } + + /** + * @return $this + */ + public function star() + { + $this->properties['shouldStar'] = 'true'; + + return $this; + } + + /** + * @param string $to + * + * @return $this + */ + public function forward($to) + { + $this->properties['forwardTo'] = $to; + + return $this; + } + + /** + * @return $this + */ + public function important() + { + $this->properties['shouldAlwaysMarkAsImportant'] = 'true'; + + return $this; + } + + /** + * @return $this + */ + public function notImportant() + { + $this->properties['shouldNeverMarkAsImportant'] = 'true'; + + return $this; + } + + /** + * @param string $category + * + * @return $this + */ + public function categorise($category) + { + $this->properties['smartLabelToApply'] = $category; + + return $this; + } + + /** + * @return array + */ + public function getProperties() + { + return $this->properties; + } +} diff --git a/src/Service/Builder.php b/src/Service/Builder.php new file mode 100644 index 0000000..9acdbb7 --- /dev/null +++ b/src/Service/Builder.php @@ -0,0 +1,128 @@ +filesystem = new Filesystem(); + $this->filters = $filters; + $this->outputFile = $outputFile; + $this->writeFile = $writeFile; + + $this->build(); + } + + public function __toString() + { + return $this->build(); + } + + /** + * Returns the generated XML. + * + * @return string + */ + public function getXml() + { + return $this->xml; + } + + /** + * Build XML for a set of filters. + * + * @return string + */ + private function build() + { + $prefix = "" . PHP_EOL . ""; + $suffix = ''; + + $xml = collect($this->filters)->map(function ($items) { + return $this->buildEntry($items); + })->implode(PHP_EOL); + + $this->xml = collect([$prefix, $xml, $suffix])->implode(PHP_EOL); + + if ($this->writeFile) { + $this->filesystem->dumpFile($this->outputFile, $this->xml); + } + } + + /** + * Build XML for an filter. + * + * @param Filter $filter + * + * @return string + */ + private function buildEntry(Filter $filter) + { + $entry = collect($filter->getProperties())->map(function ($value, $key) { + return $this->buildProperty($value, $key); + })->implode(PHP_EOL); + + return collect(['', $entry, ''])->implode(PHP_EOL); + } + + /** + * Build XML for a property. + * + * @param string $value + * @param string $key + * + * @return string + */ + private function buildProperty($value, $key) + { + if (collect(['from', 'to'])->contains($key)) { + $value = $this->implode($value); + } + + return vsprintf("", [ + $key, + htmlentities($this->implode($value)), + ]); + } + + /** + * Implode values with the appropriate prefix, suffix and separator. + */ + private function implode($value, $separator = '|') + { + if (is_string($value)) { + return $value; + } + + if (is_array($value) && count($value) === 1) { + return reset($value); + } + + return sprintf('(%s)', collect($value)->implode($separator)); + } +} diff --git a/tests/Unit/BuilderTest.php b/tests/Unit/BuilderTest.php index 25f24d3..cf70229 100644 --- a/tests/Unit/BuilderTest.php +++ b/tests/Unit/BuilderTest.php @@ -18,7 +18,7 @@ class BuilderTest extends TestCase ->star() ->important(); - $result = new Builder([$filterA, $filterB]); + $result = new Builder([$filterA, $filterB], '', false); $expected = << @@ -36,6 +36,6 @@ class BuilderTest extends TestCase EOF; - $this->assertEquals($expected, $result->__toString()); + $this->assertEquals($expected, $result->getXml()); } }