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());
}
}