]> git.immae.eu Git - github/wallabag/wallabag.git/commitdiff
Merge pull request #4026 from wallabag/3760-ignorelist-db
authorKevin Decherf <kevin@kdecherf.com>
Sun, 26 Apr 2020 13:39:57 +0000 (15:39 +0200)
committerGitHub <noreply@github.com>
Sun, 26 Apr 2020 13:39:57 +0000 (15:39 +0200)
Move Ignore Origin rules to database

54 files changed:
app/DoctrineMigrations/Version20190826204730.php [new file with mode: 0644]
app/config/security.yml
app/config/wallabag.yml
src/Wallabag/CoreBundle/Command/InstallCommand.php
src/Wallabag/CoreBundle/Controller/ConfigController.php
src/Wallabag/CoreBundle/Controller/IgnoreOriginInstanceRuleController.php [new file with mode: 0644]
src/Wallabag/CoreBundle/DataFixtures/IgnoreOriginInstanceRuleFixtures.php [new file with mode: 0644]
src/Wallabag/CoreBundle/DataFixtures/IgnoreOriginUserRuleFixtures.php [new file with mode: 0644]
src/Wallabag/CoreBundle/DependencyInjection/Configuration.php
src/Wallabag/CoreBundle/DependencyInjection/WallabagCoreExtension.php
src/Wallabag/CoreBundle/Entity/Config.php
src/Wallabag/CoreBundle/Entity/IgnoreOriginInstanceRule.php [new file with mode: 0644]
src/Wallabag/CoreBundle/Entity/IgnoreOriginRuleInterface.php [new file with mode: 0644]
src/Wallabag/CoreBundle/Entity/IgnoreOriginUserRule.php [new file with mode: 0644]
src/Wallabag/CoreBundle/Entity/RuleInterface.php [new file with mode: 0644]
src/Wallabag/CoreBundle/Entity/TaggingRule.php
src/Wallabag/CoreBundle/Form/Type/IgnoreOriginInstanceRuleType.php [new file with mode: 0644]
src/Wallabag/CoreBundle/Form/Type/IgnoreOriginUserRuleType.php [new file with mode: 0644]
src/Wallabag/CoreBundle/Helper/ContentProxy.php
src/Wallabag/CoreBundle/Helper/RuleBasedIgnoreOriginProcessor.php [new file with mode: 0644]
src/Wallabag/CoreBundle/Operator/PHP/PatternMatches.php [new file with mode: 0644]
src/Wallabag/CoreBundle/Repository/IgnoreOriginInstanceRuleRepository.php [new file with mode: 0644]
src/Wallabag/CoreBundle/Repository/IgnoreOriginUserRuleRepository.php [new file with mode: 0644]
src/Wallabag/CoreBundle/Resources/config/services.yml
src/Wallabag/CoreBundle/Resources/translations/messages.da.yml
src/Wallabag/CoreBundle/Resources/translations/messages.de.yml
src/Wallabag/CoreBundle/Resources/translations/messages.en.yml
src/Wallabag/CoreBundle/Resources/translations/messages.es.yml
src/Wallabag/CoreBundle/Resources/translations/messages.fa.yml
src/Wallabag/CoreBundle/Resources/translations/messages.fr.yml
src/Wallabag/CoreBundle/Resources/translations/messages.it.yml
src/Wallabag/CoreBundle/Resources/translations/messages.oc.yml
src/Wallabag/CoreBundle/Resources/translations/messages.pl.yml
src/Wallabag/CoreBundle/Resources/translations/messages.pt.yml
src/Wallabag/CoreBundle/Resources/translations/messages.ro.yml
src/Wallabag/CoreBundle/Resources/translations/messages.ru.yml
src/Wallabag/CoreBundle/Resources/translations/messages.th.yml
src/Wallabag/CoreBundle/Resources/translations/messages.tr.yml
src/Wallabag/CoreBundle/Resources/views/themes/baggy/Config/index.html.twig
src/Wallabag/CoreBundle/Resources/views/themes/baggy/IgnoreOriginInstanceRule/edit.html.twig [new file with mode: 0644]
src/Wallabag/CoreBundle/Resources/views/themes/baggy/IgnoreOriginInstanceRule/index.html.twig [new file with mode: 0644]
src/Wallabag/CoreBundle/Resources/views/themes/baggy/IgnoreOriginInstanceRule/new.html.twig [new file with mode: 0644]
src/Wallabag/CoreBundle/Resources/views/themes/baggy/layout.html.twig
src/Wallabag/CoreBundle/Resources/views/themes/material/Config/index.html.twig
src/Wallabag/CoreBundle/Resources/views/themes/material/IgnoreOriginInstanceRule/edit.html.twig [new file with mode: 0644]
src/Wallabag/CoreBundle/Resources/views/themes/material/IgnoreOriginInstanceRule/index.html.twig [new file with mode: 0644]
src/Wallabag/CoreBundle/Resources/views/themes/material/IgnoreOriginInstanceRule/new.html.twig [new file with mode: 0644]
src/Wallabag/CoreBundle/Resources/views/themes/material/layout.html.twig
tests/Wallabag/CoreBundle/Command/ReloadEntryCommandTest.php
tests/Wallabag/CoreBundle/Controller/ConfigControllerTest.php
tests/Wallabag/CoreBundle/Controller/EntryControllerTest.php
tests/Wallabag/CoreBundle/Controller/IgnoreOriginInstanceRuleControllerTest.php [new file with mode: 0644]
tests/Wallabag/CoreBundle/Helper/ContentProxyTest.php
tests/Wallabag/CoreBundle/Helper/RuleBasedIgnoreOriginProcessorTest.php [new file with mode: 0644]

diff --git a/app/DoctrineMigrations/Version20190826204730.php b/app/DoctrineMigrations/Version20190826204730.php
new file mode 100644 (file)
index 0000000..ee1ba6b
--- /dev/null
@@ -0,0 +1,64 @@
+<?php
+
+declare(strict_types=1);
+
+namespace Application\Migrations;
+
+use Doctrine\DBAL\Schema\Schema;
+use Wallabag\CoreBundle\Doctrine\WallabagMigration;
+
+/**
+ * Add tables for the ignore origin rules.
+ */
+final class Version20190826204730 extends WallabagMigration
+{
+    public function up(Schema $schema): void
+    {
+        if (false === $schema->hasTable($this->getTable('ignore_origin_user_rule'))) {
+            $userTable = $schema->createTable($this->getTable('ignore_origin_user_rule', true));
+            $userTable->addColumn('id', 'integer', ['autoincrement' => true]);
+            $userTable->addColumn('config_id', 'integer');
+            $userTable->addColumn('rule', 'string', ['length' => 255]);
+            $userTable->addIndex(['config_id'], 'idx_config');
+            $userTable->setPrimaryKey(['id']);
+            $userTable->addForeignKeyConstraint($this->getTable('config'), ['config_id'], ['id'], [], 'fk_config');
+
+            if ('postgresql' === $this->connection->getDatabasePlatform()->getName()) {
+                $schema->dropSequence('ignore_origin_user_rule_id_seq');
+                $schema->createSequence('ignore_origin_user_rule_id_seq');
+            }
+        }
+
+        if (false === $schema->hasTable($this->getTable('ignore_origin_instance_rule'))) {
+            $instanceTable = $schema->createTable($this->getTable('ignore_origin_instance_rule', true));
+            $instanceTable->addColumn('id', 'integer', ['autoincrement' => true]);
+            $instanceTable->addColumn('rule', 'string', ['length' => 255]);
+            $instanceTable->setPrimaryKey(['id']);
+
+            if ('postgresql' === $this->connection->getDatabasePlatform()->getName()) {
+                $schema->dropSequence('ignore_origin_instance_rule_id_seq');
+                $schema->createSequence('ignore_origin_instance_rule_id_seq');
+            }
+        }
+    }
+
+    public function postUp(Schema $schema): void
+    {
+        foreach ($this->container->getParameter('wallabag_core.default_ignore_origin_instance_rules') as $entity) {
+            $previous_rule = $this->container
+                ->get('doctrine.orm.default_entity_manager')
+                ->getConnection()
+                ->fetchArray('SELECT * FROM ' . $this->getTable('ignore_origin_instance_rule') . " WHERE rule = '" . $entity['rule'] . "'");
+
+            if (false === $previous_rule) {
+                $this->addSql('INSERT INTO ' . $this->getTable('ignore_origin_instance_rule') . " (rule) VALUES ('" . $entity['rule'] . "');");
+            }
+        }
+    }
+
+    public function down(Schema $schema): void
+    {
+        $schema->dropTable($this->getTable('ignore_origin_user_rule'));
+        $schema->dropTable($this->getTable('ignore_origin_instance_rule'));
+    }
+}
index 760b2550320868d185be60972455147cf6257bd4..5a73440b241eebde5dbbe5a4d6d5b391d76bb5fb 100644 (file)
@@ -79,4 +79,5 @@ security:
         - { path: ^/annotations, roles: ROLE_USER }
         - { path: ^/2fa, role: IS_AUTHENTICATED_2FA_IN_PROGRESS }
         - { path: ^/users, roles: ROLE_SUPER_ADMIN }
+        - { path: ^/ignore-origin-instance-rules, roles: ROLE_SUPER_ADMIN }
         - { path: ^/, roles: ROLE_USER }
index eaa925072fd16e3af4f1833ff906daefee956cdb..4dad92001aab30ac16129aa2bb2482369c390732 100644 (file)
@@ -165,6 +165,14 @@ wallabag_core:
             value: 0
             section: entry
 
+    default_ignore_origin_instance_rules:
+        -
+            rule: host = "feedproxy.google.com"
+        -
+            rule: host = "feeds.reuters.com"
+        -
+            rule: _all ~ "https?://www\.lemonde\.fr/tiny.*"
+
 wallabag_user:
     registration_enabled: "%fosuser_registration%"
 
index 3aa332f131597a292ab830f80932afb24cc4ceab..8d08187a949562a73206b310aa2925797a629ea8 100644 (file)
@@ -12,6 +12,7 @@ use Symfony\Component\Console\Output\BufferedOutput;
 use Symfony\Component\Console\Output\OutputInterface;
 use Symfony\Component\Console\Question\Question;
 use Symfony\Component\Console\Style\SymfonyStyle;
+use Wallabag\CoreBundle\Entity\IgnoreOriginInstanceRule;
 use Wallabag\CoreBundle\Entity\InternalSetting;
 
 class InstallCommand extends ContainerAwareCommand
@@ -277,6 +278,7 @@ class InstallCommand extends ContainerAwareCommand
 
         // cleanup before insert new stuff
         $em->createQuery('DELETE FROM WallabagCoreBundle:InternalSetting')->execute();
+        $em->createQuery('DELETE FROM WallabagCoreBundle:IgnoreOriginInstanceRule')->execute();
 
         foreach ($this->getContainer()->getParameter('wallabag_core.default_internal_settings') as $setting) {
             $newSetting = new InternalSetting();
@@ -286,6 +288,12 @@ class InstallCommand extends ContainerAwareCommand
             $em->persist($newSetting);
         }
 
+        foreach ($this->getContainer()->getParameter('wallabag_core.default_ignore_origin_instance_rules') as $ignore_origin_instance_rule) {
+            $newIgnoreOriginInstanceRule = new IgnoreOriginInstanceRule();
+            $newIgnoreOriginInstanceRule->setRule($ignore_origin_instance_rule['rule']);
+            $em->persist($newIgnoreOriginInstanceRule);
+        }
+
         $em->flush();
 
         $this->io->text('<info>Config successfully setup.</info>');
index 56efe82bb88775a8f3e5fac4134a53bec85e72b8..3efc7bb3218d4bd3caf098661983fde13f17b924 100644 (file)
@@ -14,10 +14,13 @@ use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
 use Symfony\Component\Routing\Annotation\Route;
 use Symfony\Component\Validator\Constraints\Locale as LocaleConstraint;
 use Wallabag\CoreBundle\Entity\Config;
+use Wallabag\CoreBundle\Entity\IgnoreOriginUserRule;
+use Wallabag\CoreBundle\Entity\RuleInterface;
 use Wallabag\CoreBundle\Entity\TaggingRule;
 use Wallabag\CoreBundle\Form\Type\ChangePasswordType;
 use Wallabag\CoreBundle\Form\Type\ConfigType;
 use Wallabag\CoreBundle\Form\Type\FeedType;
+use Wallabag\CoreBundle\Form\Type\IgnoreOriginUserRuleType;
 use Wallabag\CoreBundle\Form\Type\TaggingRuleImportType;
 use Wallabag\CoreBundle\Form\Type\TaggingRuleType;
 use Wallabag\CoreBundle\Form\Type\UserInformationType;
@@ -173,6 +176,40 @@ class ConfigController extends Controller
             return $this->redirect($this->generateUrl('config') . '#set5');
         }
 
+        // handle ignore origin rules
+        $ignoreOriginUserRule = new IgnoreOriginUserRule();
+        $action = $this->generateUrl('config') . '#set6';
+
+        if ($request->query->has('ignore-origin-user-rule')) {
+            $ignoreOriginUserRule = $this->getDoctrine()
+                ->getRepository('WallabagCoreBundle:IgnoreOriginUserRule')
+                ->find($request->query->get('ignore-origin-user-rule'));
+
+            if ($this->getUser()->getId() !== $ignoreOriginUserRule->getConfig()->getUser()->getId()) {
+                return $this->redirect($action);
+            }
+
+            $action = $this->generateUrl('config', [
+                'ignore-origin-user-rule' => $ignoreOriginUserRule->getId(),
+            ]) . '#set6';
+        }
+
+        $newIgnoreOriginUserRule = $this->createForm(IgnoreOriginUserRuleType::class, $ignoreOriginUserRule, ['action' => $action]);
+        $newIgnoreOriginUserRule->handleRequest($request);
+
+        if ($newIgnoreOriginUserRule->isSubmitted() && $newIgnoreOriginUserRule->isValid()) {
+            $ignoreOriginUserRule->setConfig($config);
+            $em->persist($ignoreOriginUserRule);
+            $em->flush();
+
+            $this->addFlash(
+                'notice',
+                'flashes.config.notice.ignore_origin_rules_updated'
+            );
+
+            return $this->redirect($this->generateUrl('config') . '#set6');
+        }
+
         return $this->render('WallabagCoreBundle:Config:index.html.twig', [
             'form' => [
                 'config' => $configForm->createView(),
@@ -181,6 +218,7 @@ class ConfigController extends Controller
                 'user' => $userForm->createView(),
                 'new_tagging_rule' => $newTaggingRule->createView(),
                 'import_tagging_rule' => $taggingRulesImportform->createView(),
+                'new_ignore_origin_user_rule' => $newIgnoreOriginUserRule->createView(),
             ],
             'feed' => [
                 'username' => $user->getUsername(),
@@ -447,6 +485,43 @@ class ConfigController extends Controller
         return $this->redirect($this->generateUrl('config') . '?tagging-rule=' . $rule->getId() . '#set5');
     }
 
+    /**
+     * Deletes an ignore origin rule and redirect to the config homepage.
+     *
+     * @Route("/ignore-origin-user-rule/delete/{id}", requirements={"id" = "\d+"}, name="delete_ignore_origin_rule")
+     *
+     * @return RedirectResponse
+     */
+    public function deleteIgnoreOriginRuleAction(IgnoreOriginUserRule $rule)
+    {
+        $this->validateRuleAction($rule);
+
+        $em = $this->getDoctrine()->getManager();
+        $em->remove($rule);
+        $em->flush();
+
+        $this->addFlash(
+            'notice',
+            'flashes.config.notice.ignore_origin_rules_deleted'
+        );
+
+        return $this->redirect($this->generateUrl('config') . '#set6');
+    }
+
+    /**
+     * Edit an ignore origin rule.
+     *
+     * @Route("/ignore-origin-user-rule/edit/{id}", requirements={"id" = "\d+"}, name="edit_ignore_origin_rule")
+     *
+     * @return RedirectResponse
+     */
+    public function editIgnoreOriginRuleAction(IgnoreOriginUserRule $rule)
+    {
+        $this->validateRuleAction($rule);
+
+        return $this->redirect($this->generateUrl('config') . '?ignore-origin-user-rule=' . $rule->getId() . '#set6');
+    }
+
     /**
      * Remove all annotations OR tags OR entries for the current user.
      *
@@ -659,10 +734,10 @@ class ConfigController extends Controller
     /**
      * Validate that a rule can be edited/deleted by the current user.
      */
-    private function validateRuleAction(TaggingRule $rule)
+    private function validateRuleAction(RuleInterface $rule)
     {
         if ($this->getUser()->getId() !== $rule->getConfig()->getUser()->getId()) {
-            throw $this->createAccessDeniedException('You can not access this tagging rule.');
+            throw $this->createAccessDeniedException('You can not access this rule.');
         }
     }
 
diff --git a/src/Wallabag/CoreBundle/Controller/IgnoreOriginInstanceRuleController.php b/src/Wallabag/CoreBundle/Controller/IgnoreOriginInstanceRuleController.php
new file mode 100644 (file)
index 0000000..ef1f0ed
--- /dev/null
@@ -0,0 +1,138 @@
+<?php
+
+namespace Wallabag\CoreBundle\Controller;
+
+use Symfony\Bundle\FrameworkBundle\Controller\Controller;
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\Routing\Annotation\Route;
+use Wallabag\CoreBundle\Entity\IgnoreOriginInstanceRule;
+
+/**
+ * IgnoreOriginInstanceRuleController controller.
+ *
+ * @Route("/ignore-origin-instance-rules")
+ */
+class IgnoreOriginInstanceRuleController extends Controller
+{
+    /**
+     * Lists all IgnoreOriginInstanceRule entities.
+     *
+     * @Route("/", name="ignore_origin_instance_rules_index", methods={"GET"})
+     */
+    public function indexAction()
+    {
+        $rules = $this->get('wallabag_core.ignore_origin_instance_rule_repository')->findAll();
+
+        return $this->render('WallabagCoreBundle:IgnoreOriginInstanceRule:index.html.twig', [
+            'rules' => $rules,
+        ]);
+    }
+
+    /**
+     * Creates a new ignore origin instance rule entity.
+     *
+     * @Route("/new", name="ignore_origin_instance_rules_new", methods={"GET", "POST"})
+     *
+     * @return \Symfony\Component\HttpFoundation\Response
+     */
+    public function newAction(Request $request)
+    {
+        $ignoreOriginInstanceRule = new IgnoreOriginInstanceRule();
+
+        $form = $this->createForm('Wallabag\CoreBundle\Form\Type\IgnoreOriginInstanceRuleType', $ignoreOriginInstanceRule);
+        $form->handleRequest($request);
+
+        if ($form->isSubmitted() && $form->isValid()) {
+            $em = $this->getDoctrine()->getManager();
+            $em->persist($ignoreOriginInstanceRule);
+            $em->flush();
+
+            $this->get('session')->getFlashBag()->add(
+                'notice',
+                $this->get('translator')->trans('flashes.ignore_origin_instance_rule.notice.added')
+            );
+
+            return $this->redirectToRoute('ignore_origin_instance_rules_index');
+        }
+
+        return $this->render('WallabagCoreBundle:IgnoreOriginInstanceRule:new.html.twig', [
+            'rule' => $ignoreOriginInstanceRule,
+            'form' => $form->createView(),
+        ]);
+    }
+
+    /**
+     * Displays a form to edit an existing ignore origin instance rule entity.
+     *
+     * @Route("/{id}/edit", name="ignore_origin_instance_rules_edit", methods={"GET", "POST"})
+     *
+     * @return \Symfony\Component\HttpFoundation\Response
+     */
+    public function editAction(Request $request, IgnoreOriginInstanceRule $ignoreOriginInstanceRule)
+    {
+        $deleteForm = $this->createDeleteForm($ignoreOriginInstanceRule);
+        $editForm = $this->createForm('Wallabag\CoreBundle\Form\Type\IgnoreOriginInstanceRuleType', $ignoreOriginInstanceRule);
+        $editForm->handleRequest($request);
+
+        if ($editForm->isSubmitted() && $editForm->isValid()) {
+            $em = $this->getDoctrine()->getManager();
+            $em->persist($ignoreOriginInstanceRule);
+            $em->flush();
+
+            $this->get('session')->getFlashBag()->add(
+                'notice',
+                $this->get('translator')->trans('flashes.ignore_origin_instance_rule.notice.updated')
+            );
+
+            return $this->redirectToRoute('ignore_origin_instance_rules_index');
+        }
+
+        return $this->render('WallabagCoreBundle:IgnoreOriginInstanceRule:edit.html.twig', [
+            'rule' => $ignoreOriginInstanceRule,
+            'edit_form' => $editForm->createView(),
+            'delete_form' => $deleteForm->createView(),
+        ]);
+    }
+
+    /**
+     * Deletes a site credential entity.
+     *
+     * @Route("/{id}", name="ignore_origin_instance_rules_delete", methods={"DELETE"})
+     *
+     * @return \Symfony\Component\HttpFoundation\RedirectResponse
+     */
+    public function deleteAction(Request $request, IgnoreOriginInstanceRule $ignoreOriginInstanceRule)
+    {
+        $form = $this->createDeleteForm($ignoreOriginInstanceRule);
+        $form->handleRequest($request);
+
+        if ($form->isSubmitted() && $form->isValid()) {
+            $this->get('session')->getFlashBag()->add(
+                'notice',
+                $this->get('translator')->trans('flashes.ignore_origin_instance_rule.notice.deleted')
+            );
+
+            $em = $this->getDoctrine()->getManager();
+            $em->remove($ignoreOriginInstanceRule);
+            $em->flush();
+        }
+
+        return $this->redirectToRoute('ignore_origin_instance_rules_index');
+    }
+
+    /**
+     * Creates a form to delete a ignore origin instance rule entity.
+     *
+     * @param IgnoreOriginInstanceRule $ignoreOriginInstanceRule The ignore origin instance rule entity
+     *
+     * @return \Symfony\Component\Form\Form The form
+     */
+    private function createDeleteForm(IgnoreOriginInstanceRule $ignoreOriginInstanceRule)
+    {
+        return $this->createFormBuilder()
+            ->setAction($this->generateUrl('ignore_origin_instance_rules_delete', ['id' => $ignoreOriginInstanceRule->getId()]))
+            ->setMethod('DELETE')
+            ->getForm()
+        ;
+    }
+}
diff --git a/src/Wallabag/CoreBundle/DataFixtures/IgnoreOriginInstanceRuleFixtures.php b/src/Wallabag/CoreBundle/DataFixtures/IgnoreOriginInstanceRuleFixtures.php
new file mode 100644 (file)
index 0000000..8a0a06e
--- /dev/null
@@ -0,0 +1,36 @@
+<?php
+
+namespace Wallabag\CoreBundle\DataFixtures;
+
+use Doctrine\Bundle\FixturesBundle\Fixture;
+use Doctrine\Common\Persistence\ObjectManager;
+use Symfony\Component\DependencyInjection\ContainerAwareInterface;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+use Wallabag\CoreBundle\Entity\IgnoreOriginInstanceRule;
+
+class IgnoreOriginInstanceRuleFixtures extends Fixture implements ContainerAwareInterface
+{
+    /**
+     * @var ContainerInterface
+     */
+    private $container;
+
+    public function setContainer(ContainerInterface $container = null)
+    {
+        $this->container = $container;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function load(ObjectManager $manager)
+    {
+        foreach ($this->container->getParameter('wallabag_core.default_ignore_origin_instance_rules') as $ignore_origin_instance_rule) {
+            $newIgnoreOriginInstanceRule = new IgnoreOriginInstanceRule();
+            $newIgnoreOriginInstanceRule->setRule($ignore_origin_instance_rule['rule']);
+            $manager->persist($newIgnoreOriginInstanceRule);
+        }
+
+        $manager->flush();
+    }
+}
diff --git a/src/Wallabag/CoreBundle/DataFixtures/IgnoreOriginUserRuleFixtures.php b/src/Wallabag/CoreBundle/DataFixtures/IgnoreOriginUserRuleFixtures.php
new file mode 100644 (file)
index 0000000..679eff7
--- /dev/null
@@ -0,0 +1,36 @@
+<?php
+
+namespace Wallabag\CoreBundle\DataFixtures;
+
+use Doctrine\Bundle\FixturesBundle\Fixture;
+use Doctrine\Common\DataFixtures\DependentFixtureInterface;
+use Doctrine\Common\Persistence\ObjectManager;
+use Wallabag\CoreBundle\Entity\IgnoreOriginUserRule;
+use Wallabag\UserBundle\DataFixtures\UserFixtures;
+
+class IgnoreOriginUserRuleFixtures extends Fixture implements DependentFixtureInterface
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function load(ObjectManager $manager)
+    {
+        $rule = new IgnoreOriginUserRule();
+        $rule->setRule('host = "example.fr"');
+        $rule->setConfig($this->getReference('admin-user')->getConfig());
+
+        $manager->persist($rule);
+
+        $manager->flush();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getDependencies()
+    {
+        return [
+            UserFixtures::class,
+        ];
+    }
+}
index 7ae73371c246a69e227e7e26e067f63ca9be83d2..8574725671ffdbab0285b5a6a881d8343fd2126d 100644 (file)
@@ -65,6 +65,13 @@ class Configuration implements ConfigurationInterface
                 ->end()
                 ->scalarNode('encryption_key_path')
                 ->end()
+                ->arrayNode('default_ignore_origin_instance_rules')
+                    ->prototype('array')
+                        ->children()
+                            ->scalarNode('rule')->end()
+                        ->end()
+                    ->end()
+                ->end()
             ->end()
         ;
 
index e9a1e9e05fbdbb4bbbe89fa08a1835018d58bf88..af91e58867ff113436c71e9cae0def6d844fdffe 100644 (file)
@@ -30,6 +30,7 @@ class WallabagCoreExtension extends Extension
         $container->setParameter('wallabag_core.api_limit_mass_actions', $config['api_limit_mass_actions']);
         $container->setParameter('wallabag_core.default_internal_settings', $config['default_internal_settings']);
         $container->setParameter('wallabag_core.site_credentials.encryption_key_path', $config['encryption_key_path']);
+        $container->setParameter('wallabag_core.default_ignore_origin_instance_rules', $config['default_ignore_origin_instance_rules']);
 
         $loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config'));
         $loader->load('services.yml');
index fe7942ee261bca550ff3ef2ece24634124c37599..1bed451380eafb16a9a645efe59a9161bb1f1edb 100644 (file)
@@ -119,6 +119,12 @@ class Config
      */
     private $taggingRules;
 
+    /**
+     * @ORM\OneToMany(targetEntity="Wallabag\CoreBundle\Entity\IgnoreOriginUserRule", mappedBy="config", cascade={"remove"})
+     * @ORM\OrderBy({"id" = "ASC"})
+     */
+    private $ignoreOriginRules;
+
     /*
      * @param User     $user
      */
@@ -126,6 +132,7 @@ class Config
     {
         $this->user = $user;
         $this->taggingRules = new ArrayCollection();
+        $this->ignoreOriginRules = new ArrayCollection();
     }
 
     /**
@@ -387,4 +394,22 @@ class Config
     {
         return $this->taggingRules;
     }
+
+    /**
+     * @return Config
+     */
+    public function addIgnoreOriginRule(IgnoreOriginUserRule $rule)
+    {
+        $this->ignoreOriginRules[] = $rule;
+
+        return $this;
+    }
+
+    /**
+     * @return ArrayCollection<IgnoreOriginUserRule>
+     */
+    public function getIgnoreOriginRules()
+    {
+        return $this->ignoreOriginRules;
+    }
 }
diff --git a/src/Wallabag/CoreBundle/Entity/IgnoreOriginInstanceRule.php b/src/Wallabag/CoreBundle/Entity/IgnoreOriginInstanceRule.php
new file mode 100644 (file)
index 0000000..ce3b6e7
--- /dev/null
@@ -0,0 +1,70 @@
+<?php
+
+namespace Wallabag\CoreBundle\Entity;
+
+use Doctrine\ORM\Mapping as ORM;
+use Symfony\Bridge\RulerZ\Validator\Constraints as RulerZAssert;
+use Symfony\Component\Validator\Constraints as Assert;
+
+/**
+ * Ignore Origin rule.
+ *
+ * @ORM\Entity(repositoryClass="Wallabag\CoreBundle\Repository\IgnoreOriginInstanceRuleRepository")
+ * @ORM\Table(name="`ignore_origin_instance_rule`")
+ */
+class IgnoreOriginInstanceRule implements IgnoreOriginRuleInterface, RuleInterface
+{
+    /**
+     * @var int
+     *
+     * @ORM\Column(name="id", type="integer")
+     * @ORM\Id
+     * @ORM\GeneratedValue(strategy="AUTO")
+     */
+    private $id;
+
+    /**
+     * @var string
+     *
+     * @Assert\NotBlank()
+     * @Assert\Length(max=255)
+     * @RulerZAssert\ValidRule(
+     *  allowed_variables={"host","_all"},
+     *  allowed_operators={"=","~"}
+     * )
+     * @ORM\Column(name="rule", type="string", nullable=false)
+     */
+    private $rule;
+
+    /**
+     * Get id.
+     *
+     * @return int
+     */
+    public function getId()
+    {
+        return $this->id;
+    }
+
+    /**
+     * Set rule.
+     *
+     * @return IgnoreOriginRuleInterface
+     */
+    public function setRule(string $rule)
+    {
+        $this->rule = $rule;
+
+        return $this;
+    }
+
+    /**
+     * Get rule.
+     *
+     * @return string
+     */
+    public function getRule()
+    {
+        return $this->rule;
+    }
+}
diff --git a/src/Wallabag/CoreBundle/Entity/IgnoreOriginRuleInterface.php b/src/Wallabag/CoreBundle/Entity/IgnoreOriginRuleInterface.php
new file mode 100644 (file)
index 0000000..eb865a3
--- /dev/null
@@ -0,0 +1,12 @@
+<?php
+
+namespace Wallabag\CoreBundle\Entity;
+
+interface IgnoreOriginRuleInterface
+{
+    public function getId();
+
+    public function setRule(string $rule);
+
+    public function getRule();
+}
diff --git a/src/Wallabag/CoreBundle/Entity/IgnoreOriginUserRule.php b/src/Wallabag/CoreBundle/Entity/IgnoreOriginUserRule.php
new file mode 100644 (file)
index 0000000..0b6f318
--- /dev/null
@@ -0,0 +1,97 @@
+<?php
+
+namespace Wallabag\CoreBundle\Entity;
+
+use Doctrine\ORM\Mapping as ORM;
+use Symfony\Bridge\RulerZ\Validator\Constraints as RulerZAssert;
+use Symfony\Component\Validator\Constraints as Assert;
+
+/**
+ * Ignore Origin rule.
+ *
+ * @ORM\Entity(repositoryClass="Wallabag\CoreBundle\Repository\IgnoreOriginUserRuleRepository")
+ * @ORM\Table(name="`ignore_origin_user_rule`")
+ */
+class IgnoreOriginUserRule implements IgnoreOriginRuleInterface, RuleInterface
+{
+    /**
+     * @var int
+     *
+     * @ORM\Column(name="id", type="integer")
+     * @ORM\Id
+     * @ORM\GeneratedValue(strategy="AUTO")
+     */
+    private $id;
+
+    /**
+     * @var string
+     *
+     * @Assert\NotBlank()
+     * @Assert\Length(max=255)
+     * @RulerZAssert\ValidRule(
+     *  allowed_variables={"host","_all"},
+     *  allowed_operators={"=","~"}
+     * )
+     * @ORM\Column(name="rule", type="string", nullable=false)
+     */
+    private $rule;
+
+    /**
+     * @ORM\ManyToOne(targetEntity="Wallabag\CoreBundle\Entity\Config", inversedBy="ignoreOriginRules")
+     */
+    private $config;
+
+    /**
+     * Get id.
+     *
+     * @return int
+     */
+    public function getId()
+    {
+        return $this->id;
+    }
+
+    /**
+     * Set rule.
+     *
+     * @return IgnoreOriginRuleInterface
+     */
+    public function setRule(string $rule)
+    {
+        $this->rule = $rule;
+
+        return $this;
+    }
+
+    /**
+     * Get rule.
+     *
+     * @return string
+     */
+    public function getRule()
+    {
+        return $this->rule;
+    }
+
+    /**
+     * Set config.
+     *
+     * @return IgnoreOriginUserRule
+     */
+    public function setConfig(Config $config)
+    {
+        $this->config = $config;
+
+        return $this;
+    }
+
+    /**
+     * Get config.
+     *
+     * @return Config
+     */
+    public function getConfig()
+    {
+        return $this->config;
+    }
+}
diff --git a/src/Wallabag/CoreBundle/Entity/RuleInterface.php b/src/Wallabag/CoreBundle/Entity/RuleInterface.php
new file mode 100644 (file)
index 0000000..8e9b5c4
--- /dev/null
@@ -0,0 +1,7 @@
+<?php
+
+namespace Wallabag\CoreBundle\Entity;
+
+interface RuleInterface
+{
+}
index f716608716f1dbde4cc82cf24ff5d4ef03a5bbab..7bed7a69139d5e82a5d6986349814cfeddcc1d09 100644 (file)
@@ -17,7 +17,7 @@ use Symfony\Component\Validator\Constraints as Assert;
  * @ORM\Table(name="`tagging_rule`")
  * @ORM\Entity
  */
-class TaggingRule
+class TaggingRule implements RuleInterface
 {
     /**
      * @var int
diff --git a/src/Wallabag/CoreBundle/Form/Type/IgnoreOriginInstanceRuleType.php b/src/Wallabag/CoreBundle/Form/Type/IgnoreOriginInstanceRuleType.php
new file mode 100644 (file)
index 0000000..d2e414f
--- /dev/null
@@ -0,0 +1,37 @@
+<?php
+
+namespace Wallabag\CoreBundle\Form\Type;
+
+use Symfony\Component\Form\AbstractType;
+use Symfony\Component\Form\Extension\Core\Type\SubmitType;
+use Symfony\Component\Form\Extension\Core\Type\TextType;
+use Symfony\Component\Form\FormBuilderInterface;
+use Symfony\Component\OptionsResolver\OptionsResolver;
+
+class IgnoreOriginInstanceRuleType extends AbstractType
+{
+    public function buildForm(FormBuilderInterface $builder, array $options)
+    {
+        $builder
+            ->add('rule', TextType::class, [
+                'required' => true,
+                'label' => 'config.form_rules.rule_label',
+            ])
+            ->add('save', SubmitType::class, [
+                'label' => 'config.form.save',
+            ])
+        ;
+    }
+
+    public function configureOptions(OptionsResolver $resolver)
+    {
+        $resolver->setDefaults([
+            'data_class' => 'Wallabag\CoreBundle\Entity\IgnoreOriginInstanceRule',
+        ]);
+    }
+
+    public function getBlockPrefix()
+    {
+        return 'ignore_origin_instance_rule';
+    }
+}
diff --git a/src/Wallabag/CoreBundle/Form/Type/IgnoreOriginUserRuleType.php b/src/Wallabag/CoreBundle/Form/Type/IgnoreOriginUserRuleType.php
new file mode 100644 (file)
index 0000000..b9110f1
--- /dev/null
@@ -0,0 +1,37 @@
+<?php
+
+namespace Wallabag\CoreBundle\Form\Type;
+
+use Symfony\Component\Form\AbstractType;
+use Symfony\Component\Form\Extension\Core\Type\SubmitType;
+use Symfony\Component\Form\Extension\Core\Type\TextType;
+use Symfony\Component\Form\FormBuilderInterface;
+use Symfony\Component\OptionsResolver\OptionsResolver;
+
+class IgnoreOriginUserRuleType extends AbstractType
+{
+    public function buildForm(FormBuilderInterface $builder, array $options)
+    {
+        $builder
+            ->add('rule', TextType::class, [
+                'required' => true,
+                'label' => 'config.form_rules.rule_label',
+            ])
+            ->add('save', SubmitType::class, [
+                'label' => 'config.form.save',
+            ])
+        ;
+    }
+
+    public function configureOptions(OptionsResolver $resolver)
+    {
+        $resolver->setDefaults([
+            'data_class' => 'Wallabag\CoreBundle\Entity\IgnoreOriginUserRule',
+        ]);
+    }
+
+    public function getBlockPrefix()
+    {
+        return 'ignore_origin_user_rule';
+    }
+}
index 9c6fa8db142a9a9bd3a75a981e833a450ad31010..7e93249ddd8dd8d708ea3a868065b0556a487c96 100644 (file)
@@ -19,6 +19,7 @@ class ContentProxy
 {
     protected $graby;
     protected $tagger;
+    protected $ignoreOriginProcessor;
     protected $validator;
     protected $logger;
     protected $mimeGuesser;
@@ -26,10 +27,11 @@ class ContentProxy
     protected $eventDispatcher;
     protected $storeArticleHeaders;
 
-    public function __construct(Graby $graby, RuleBasedTagger $tagger, ValidatorInterface $validator, LoggerInterface $logger, $fetchingErrorMessage, $storeArticleHeaders = false)
+    public function __construct(Graby $graby, RuleBasedTagger $tagger, RuleBasedIgnoreOriginProcessor $ignoreOriginProcessor, ValidatorInterface $validator, LoggerInterface $logger, $fetchingErrorMessage, $storeArticleHeaders = false)
     {
         $this->graby = $graby;
         $this->tagger = $tagger;
+        $this->ignoreOriginProcessor = $ignoreOriginProcessor;
         $this->validator = $validator;
         $this->logger = $logger;
         $this->mimeGuesser = new MimeTypeExtensionGuesser();
@@ -356,7 +358,7 @@ class ContentProxy
         $diff_keys = array_keys($diff);
         sort($diff_keys);
 
-        if ($this->ignoreUrl($entry->getUrl())) {
+        if ($this->ignoreOriginProcessor->process($entry)) {
             $entry->setUrl($url);
 
             return false;
@@ -395,41 +397,6 @@ class ContentProxy
         }
     }
 
-    /**
-     * Check entry url against an ignore list to replace with content url.
-     *
-     * XXX: move the ignore list in the database to let users handle it
-     *
-     * @param string $url url to test
-     *
-     * @return bool true if url matches ignore list otherwise false
-     */
-    private function ignoreUrl($url)
-    {
-        $ignored_hosts = ['feedproxy.google.com', 'feeds.reuters.com'];
-        $ignored_patterns = ['https?://www\.lemonde\.fr/tiny.*'];
-
-        $parsed_url = parse_url($url);
-
-        $filtered = array_filter($ignored_hosts, function ($var) use ($parsed_url) {
-            return $var === $parsed_url['host'];
-        });
-
-        if ([] !== $filtered) {
-            return true;
-        }
-
-        $filtered = array_filter($ignored_patterns, function ($var) use ($url) {
-            return preg_match("`$var`i", $url);
-        });
-
-        if ([] !== $filtered) {
-            return true;
-        }
-
-        return false;
-    }
-
     /**
      * Validate that the given content has at least a title, an html and a url.
      *
diff --git a/src/Wallabag/CoreBundle/Helper/RuleBasedIgnoreOriginProcessor.php b/src/Wallabag/CoreBundle/Helper/RuleBasedIgnoreOriginProcessor.php
new file mode 100644 (file)
index 0000000..333e5b0
--- /dev/null
@@ -0,0 +1,50 @@
+<?php
+
+namespace Wallabag\CoreBundle\Helper;
+
+use Psr\Log\LoggerInterface;
+use RulerZ\RulerZ;
+use Wallabag\CoreBundle\Entity\Entry;
+use Wallabag\CoreBundle\Repository\IgnoreOriginInstanceRuleRepository;
+
+class RuleBasedIgnoreOriginProcessor
+{
+    protected $rulerz;
+    protected $logger;
+    protected $ignoreOriginInstanceRuleRepository;
+
+    public function __construct(RulerZ $rulerz, LoggerInterface $logger, IgnoreOriginInstanceRuleRepository $ignoreOriginInstanceRuleRepository)
+    {
+        $this->rulerz = $rulerz;
+        $this->logger = $logger;
+        $this->ignoreOriginInstanceRuleRepository = $ignoreOriginInstanceRuleRepository;
+    }
+
+    /**
+     * @param Entry $entry Entry to process
+     *
+     * @return bool
+     */
+    public function process(Entry $entry)
+    {
+        $url = $entry->getUrl();
+        $userRules = $entry->getUser()->getConfig()->getIgnoreOriginRules()->toArray();
+        $rules = array_merge($this->ignoreOriginInstanceRuleRepository->findAll(), $userRules);
+
+        $parsed_url = parse_url($url);
+        // We add the former url as a new key _all for pattern matching
+        $parsed_url['_all'] = $url;
+
+        foreach ($rules as $rule) {
+            if ($this->rulerz->satisfies($parsed_url, $rule->getRule())) {
+                $this->logger->info('Origin url matching ignore rule.', [
+                    'rule' => $rule->getRule(),
+                ]);
+
+                return true;
+            }
+        }
+
+        return false;
+    }
+}
diff --git a/src/Wallabag/CoreBundle/Operator/PHP/PatternMatches.php b/src/Wallabag/CoreBundle/Operator/PHP/PatternMatches.php
new file mode 100644 (file)
index 0000000..532e2bb
--- /dev/null
@@ -0,0 +1,23 @@
+<?php
+
+namespace Wallabag\CoreBundle\Operator\PHP;
+
+/**
+ * Provides a "~" operator used for ignore origin rules.
+ *
+ * It asserts that a subject matches a given regexp pattern, in a
+ * case-insensitive way.
+ *
+ * This operator will be used to compile ignore origin rules in PHP, usable
+ * directly on Entry objects for instance.
+ * It's registered in RulerZ using a service (wallabag.operator.array.pattern_matches);
+ */
+class PatternMatches
+{
+    public function __invoke($subject, $pattern)
+    {
+        $count = preg_match("`$pattern`i", $subject);
+
+        return \is_int($count) && $count > 0;
+    }
+}
diff --git a/src/Wallabag/CoreBundle/Repository/IgnoreOriginInstanceRuleRepository.php b/src/Wallabag/CoreBundle/Repository/IgnoreOriginInstanceRuleRepository.php
new file mode 100644 (file)
index 0000000..708a0ed
--- /dev/null
@@ -0,0 +1,9 @@
+<?php
+
+namespace Wallabag\CoreBundle\Repository;
+
+use Doctrine\ORM\EntityRepository;
+
+class IgnoreOriginInstanceRuleRepository extends EntityRepository
+{
+}
diff --git a/src/Wallabag/CoreBundle/Repository/IgnoreOriginUserRuleRepository.php b/src/Wallabag/CoreBundle/Repository/IgnoreOriginUserRuleRepository.php
new file mode 100644 (file)
index 0000000..8aa4c26
--- /dev/null
@@ -0,0 +1,9 @@
+<?php
+
+namespace Wallabag\CoreBundle\Repository;
+
+use Doctrine\ORM\EntityRepository;
+
+class IgnoreOriginUserRuleRepository extends EntityRepository
+{
+}
index 3f3d4de7124dacf376063daf59d626c285776e29..8417ac35c959ffb506bcd44767a6820155ffcb79 100644 (file)
@@ -92,6 +92,7 @@ services:
         arguments:
             - "@wallabag_core.graby"
             - "@wallabag_core.rule_based_tagger"
+            - "@wallabag_core.rule_based_ignore_origin_processor"
             - "@validator"
             - "@logger"
             - '%wallabag_core.fetching_error_message%'
@@ -110,6 +111,13 @@ services:
             - "@wallabag_core.entry_repository"
             - "@logger"
 
+    wallabag_core.rule_based_ignore_origin_processor:
+        class: Wallabag\CoreBundle\Helper\RuleBasedIgnoreOriginProcessor
+        arguments:
+            - "@rulerz"
+            - "@logger"
+            - "@wallabag_core.ignore_origin_instance_rule_repository"
+
     # repository as a service
     wallabag_core.entry_repository:
         class: Wallabag\CoreBundle\Repository\EntryRepository
@@ -131,6 +139,12 @@ services:
         calls:
             - [ setCrypto, [ "@wallabag_core.helper.crypto_proxy" ] ]
 
+    wallabag_core.ignore_origin_instance_rule_repository:
+        class: Wallabag\CoreBundle\Repository\IgnoreOriginInstanceRuleRepository
+        factory: [ "@doctrine.orm.default_entity_manager", getRepository ]
+        arguments:
+            - WallabagCoreBundle:IgnoreOriginInstanceRule
+
     wallabag_core.helper.entries_export:
         class: Wallabag\CoreBundle\Helper\EntriesExport
         arguments:
@@ -158,6 +172,11 @@ services:
         tags:
             - { name: rulerz.operator, target: doctrine, operator: notmatches, inline: true }
 
+    wallabag.operator.array.pattern_matches:
+        class: Wallabag\CoreBundle\Operator\PHP\PatternMatches
+        tags:
+            - { name: rulerz.operator, target: native, operator: "~" }
+
     wallabag_core.helper.redirect:
         class: Wallabag\CoreBundle\Helper\Redirect
         arguments:
index 4d5259797d2fad335a0d85b6c33f6e983e18ba4b..54df2e649dd083ecd90a5211ee9f5a3195fa5f03 100644 (file)
@@ -33,6 +33,7 @@ menu:
         back_to_unread: 'Tilbage til de ulæste artikler'
         # users_management: 'Users management'
         # site_credentials: 'Site credentials'
+        # ignore_origin_instance_rules: 'Global ignore origin rules'
         # quickstart: "Quickstart"
     top:
         add_new_entry: 'Tilføj ny artikel'
@@ -59,6 +60,7 @@ config:
         user_info: 'Brugeroplysninger'
         password: 'Adgangskode'
         # rules: 'Tagging rules'
+        # ignore_origin: 'Ignore origin rules'
         new_user: 'Tilføj bruger'
         # reset: 'Reset area'
     form:
@@ -177,6 +179,24 @@ config:
         #         and: 'One rule AND another'
         #         matches: 'Tests that a <i>subject</i> matches a <i>search</i> (case-insensitive).<br />Example: <code>title matches "football"</code>'
         #         notmatches: 'Tests that a <i>subject</i> doesn''t match match a <i>search</i> (case-insensitive).<br />Example: <code>title notmatches "football"</code>'
+    form_ignore_origin_rules:
+        # faq:
+        #     title: 'FAQ'
+        #     ignore_origin_rules_definition_title: 'What does « ignore origin rules » mean?'
+        #     ignore_origin_rules_definition_description: 'They are used by wallabag to automatically ignore an origin address after a redirect.<br />If a redirect occurs while fetching a new entry, all the ignore origin rules (<i>user defined and instance defined</i>) will be used to ignore the origin address.'
+        #     how_to_use_them_title: 'How do I use them?'
+        #     how_to_use_them_description: 'Let us assume you want to ignore the origin of an entry coming from « <i>rss.example.com</i> » (<i>knowing that after a redirect, the actual address is example.com</i>).<br />In that case, you should put « host = "rss.example.com" » in the <i>Rule</i> field.'
+        #     variables_available_title: 'Which variables and operators can I use to write rules?'
+        #     variables_available_description: 'The following variables and operators can be used to create ignore origin rules:'
+        #     meaning: 'Meaning'
+        #     variable_description:
+        #         label: 'Variable'
+        #         host: 'Host of the address'
+        #         _all: 'Full address, mainly for pattern matching'
+        #     operator_description:
+        #         label: 'Operator'
+        #         equal_to: 'Equal to…'
+        #         matches: 'Tests that a <i>subject</i> matches a <i>search</i> (case-insensitive).<br />Example: <code>_all ~ "https?://rss.example.com/foobar/.*"</code>'
     otp:
         # page_title: Two-factor authentication
         # app:
@@ -617,6 +637,8 @@ flashes:
             # otp_disabled: Two-factor authentication disabled
             # tagging_rules_imported: Tagging rules imported
             # tagging_rules_not_imported: Error while importing tagging rules
+            # ignore_origin_rules_deleted: 'Ignore origin rule deleted'
+            # ignore_origin_rules_updated: 'Ignore origin rule updated'
     entry:
         notice:
             # entry_already_saved: 'Entry already saved on %date%'
@@ -658,3 +680,8 @@ flashes:
             # added: 'Site credential for "%host%" added'
             # updated: 'Site credential for "%host%" updated'
             # deleted: 'Site credential for "%host%" deleted'
+    ignore_origin_instance_rule:
+        notice:
+            # added: 'Global ignore origin rule added'
+            # updated: 'Global ignore origin rule updated'
+            # deleted: 'Global ignore origin rule deleted'
index cd70c99ffcc60f8b2604c4d5358d75c7d3852b7d..549704d0d805f73af96d8a8960cdae387e1f19c0 100644 (file)
@@ -33,6 +33,7 @@ menu:
         back_to_unread: 'Zurück zu ungelesenen Artikeln'
         users_management: 'Benutzerverwaltung'
         site_credentials: 'Zugangsdaten'
+        # ignore_origin_instance_rules: 'Global ignore origin rules'
         quickstart: "Schnelleinstieg"
     top:
         add_new_entry: 'Neuen Artikel hinzufügen'
@@ -59,6 +60,7 @@ config:
         user_info: 'Benutzerinformation'
         password: 'Kennwort'
         rules: 'Tagging-Regeln'
+        # ignore_origin: 'Ignore origin rules'
         new_user: 'Benutzer hinzufügen'
         reset: 'Zurücksetzen'
     form:
@@ -177,6 +179,24 @@ config:
                 and: 'Eine Regel UND eine andere'
                 matches: 'Testet, ob eine <i>Variable</i> auf eine <i>Suche</i> zutrifft (Groß- und Kleinschreibung wird nicht berücksichtigt).<br />Beispiel: <code>title matches "Fußball"</code>'
                 notmatches: 'Testet, ob ein <i>Titel</i> nicht auf eine <i>Suche</i> zutrifft (Groß- und Kleinschreibung wird nicht berücksichtigt).<br />Beispiel: <code>title notmatches "Fußball"</code>'
+    form_ignore_origin_rules:
+        # faq:
+        #     title: 'FAQ'
+        #     ignore_origin_rules_definition_title: 'What does « ignore origin rules » mean?'
+        #     ignore_origin_rules_definition_description: 'They are used by wallabag to automatically ignore an origin address after a redirect.<br />If a redirect occurs while fetching a new entry, all the ignore origin rules (<i>user defined and instance defined</i>) will be used to ignore the origin address.'
+        #     how_to_use_them_title: 'How do I use them?'
+        #     how_to_use_them_description: 'Let us assume you want to ignore the origin of an entry coming from « <i>rss.example.com</i> » (<i>knowing that after a redirect, the actual address is example.com</i>).<br />In that case, you should put « host = "rss.example.com" » in the <i>Rule</i> field.'
+        #     variables_available_title: 'Which variables and operators can I use to write rules?'
+        #     variables_available_description: 'The following variables and operators can be used to create ignore origin rules:'
+        #     meaning: 'Meaning'
+        #     variable_description:
+        #         label: 'Variable'
+        #         host: 'Host of the address'
+        #         _all: 'Full address, mainly for pattern matching'
+        #     operator_description:
+        #         label: 'Operator'
+        #         equal_to: 'Equal to…'
+        #         matches: 'Tests that a <i>subject</i> matches a <i>search</i> (case-insensitive).<br />Example: <code>_all ~ "https?://rss.example.com/foobar/.*"</code>'
     otp:
         # page_title: Two-factor authentication
         # app:
@@ -617,6 +637,8 @@ flashes:
             # otp_disabled: Two-factor authentication disabled
             # tagging_rules_imported: Tagging rules imported
             # tagging_rules_not_imported: Error while importing tagging rules
+            # ignore_origin_rules_deleted: 'Ignore origin rule deleted'
+            # ignore_origin_rules_updated: 'Ignore origin rule updated'
     entry:
         notice:
             entry_already_saved: 'Eintrag bereits am %date% gespeichert'
@@ -658,3 +680,8 @@ flashes:
             added: 'Zugangsdaten für "%host%" hinzugefügt'
             updated: 'Zugangsdaten für "%host%" aktualisiert'
             deleted: 'Zugangsdaten für "%host%" gelöscht'
+    ignore_origin_instance_rule:
+        notice:
+            # added: 'Global ignore origin rule added'
+            # updated: 'Global ignore origin rule updated'
+            # deleted: 'Global ignore origin rule deleted'
index 1bc32423aeb572e01cc3c8954444ba8aa2053a64..a68a7d7de42a2e2ac32e800b456d16066b5c1682 100644 (file)
@@ -33,6 +33,7 @@ menu:
         back_to_unread: 'Back to unread articles'
         users_management: 'Users management'
         site_credentials: 'Site credentials'
+        ignore_origin_instance_rules: 'Global ignore origin rules'
         quickstart: "Quickstart"
     top:
         add_new_entry: 'Add a new entry'
@@ -59,6 +60,7 @@ config:
         user_info: 'User information'
         password: 'Password'
         rules: 'Tagging rules'
+        ignore_origin: 'Ignore origin rules'
         new_user: 'Add a user'
         reset: 'Reset area'
     form:
@@ -177,6 +179,24 @@ config:
                 and: 'One rule AND another'
                 matches: 'Tests that a <i>subject</i> matches a <i>search</i> (case-insensitive).<br />Example: <code>title matches "football"</code>'
                 notmatches: 'Tests that a <i>subject</i> doesn''t match match a <i>search</i> (case-insensitive).<br />Example: <code>title notmatches "football"</code>'
+    form_ignore_origin_rules:
+        faq:
+            title: 'FAQ'
+            ignore_origin_rules_definition_title: 'What does « ignore origin rules » mean?'
+            ignore_origin_rules_definition_description: 'They are used by wallabag to automatically ignore an origin address after a redirect.<br />If a redirect occurs while fetching a new entry, all the ignore origin rules (<i>user defined and instance defined</i>) will be used to ignore the origin address.'
+            how_to_use_them_title: 'How do I use them?'
+            how_to_use_them_description: 'Let us assume you want to ignore the origin of an entry coming from « <i>rss.example.com</i> » (<i>knowing that after a redirect, the actual address is example.com</i>).<br />In that case, you should put « host = "rss.example.com" » in the <i>Rule</i> field.'
+            variables_available_title: 'Which variables and operators can I use to write rules?'
+            variables_available_description: 'The following variables and operators can be used to create ignore origin rules:'
+            meaning: 'Meaning'
+            variable_description:
+                label: 'Variable'
+                host: 'Host of the address'
+                _all: 'Full address, mainly for pattern matching'
+            operator_description:
+                label: 'Operator'
+                equal_to: 'Equal to…'
+                matches: 'Tests that a <i>subject</i> matches a <i>search</i> (case-insensitive).<br />Example: <code>_all ~ "https?://rss.example.com/foobar/.*"</code>'
     otp:
         page_title: Two-factor authentication
         app:
@@ -594,6 +614,24 @@ site_credential:
         delete_confirm: Are you sure?
         back_to_list: Back to list
 
+ignore_origin_instance_rule:
+    page_title: Global ignore origin rules
+    new_ignore_origin_instance_rule: Create a global ignore origin rule
+    edit_ignore_origin_instance_rule: Edit an existing ignore origin rule
+    description: "Here you can manage the global ignore origin rules used to ignore some patterns of origin url."
+    list:
+        actions: Actions
+        edit_action: Edit
+        yes: Yes
+        no: No
+        create_new_one: Create a new global ignore origin rule
+    form:
+        rule_label: Rule
+        save: Save
+        delete: Delete
+        delete_confirm: Are you sure?
+        back_to_list: Back to list
+
 error:
     page_title: An error occurred
 
@@ -617,6 +655,8 @@ flashes:
             otp_disabled: Two-factor authentication disabled
             tagging_rules_imported: Tagging rules imported
             tagging_rules_not_imported: Error while importing tagging rules
+            ignore_origin_rules_deleted: 'Ignore origin rule deleted'
+            ignore_origin_rules_updated: 'Ignore origin rule updated'
     entry:
         notice:
             entry_already_saved: 'Entry already saved on %date%'
@@ -658,3 +698,8 @@ flashes:
             added: 'Site credential for "%host%" added'
             updated: 'Site credential for "%host%" updated'
             deleted: 'Site credential for "%host%" deleted'
+    ignore_origin_instance_rule:
+        notice:
+            added: 'Global ignore origin rule added'
+            updated: 'Global ignore origin rule updated'
+            deleted: 'Global ignore origin rule deleted'
index bced72e95ac86666c279929a1fa938786e559c52..c3e3ba81663500861ece89eb5f2ed7cf8a561ee9 100644 (file)
@@ -33,6 +33,7 @@ menu:
         back_to_unread: 'Volver a los artículos sin leer'
         users_management: 'Configuración de usuarios'
         site_credentials: 'Credenciales del sitio'
+        # ignore_origin_instance_rules: 'Global ignore origin rules'
         quickstart: "Inicio rápido"
     top:
         add_new_entry: 'Añadir un nuevo artículo'
@@ -59,6 +60,7 @@ config:
         user_info: 'Información de usuario'
         password: 'Contraseña'
         rules: 'Reglas de etiquetado automáticas'
+        # ignore_origin: 'Ignore origin rules'
         new_user: 'Añadir un usuario'
         reset: 'Reiniciar mi cuenta'
     form:
@@ -177,6 +179,24 @@ config:
                 and: 'Una regla Y la otra'
                 matches: 'Prueba si un <i>sujeto</i> corresponde a una <i>búsqueda</i> (insensible a mayúsculas).<br />Ejemplo : <code>title matches "fútbol"</code>'
                 notmatches: 'Prueba si <i>subject</i> no corresponde a una <i>búsqueda</i> (insensible a mayúsculas).<br />Example: <code>title notmatches "fútbol"</code>'
+    form_ignore_origin_rules:
+        # faq:
+        #     title: 'FAQ'
+        #     ignore_origin_rules_definition_title: 'What does « ignore origin rules » mean?'
+        #     ignore_origin_rules_definition_description: 'They are used by wallabag to automatically ignore an origin address after a redirect.<br />If a redirect occurs while fetching a new entry, all the ignore origin rules (<i>user defined and instance defined</i>) will be used to ignore the origin address.'
+        #     how_to_use_them_title: 'How do I use them?'
+        #     how_to_use_them_description: 'Let us assume you want to ignore the origin of an entry coming from « <i>rss.example.com</i> » (<i>knowing that after a redirect, the actual address is example.com</i>).<br />In that case, you should put « host = "rss.example.com" » in the <i>Rule</i> field.'
+        #     variables_available_title: 'Which variables and operators can I use to write rules?'
+        #     variables_available_description: 'The following variables and operators can be used to create ignore origin rules:'
+        #     meaning: 'Meaning'
+        #     variable_description:
+        #         label: 'Variable'
+        #         host: 'Host of the address'
+        #         _all: 'Full address, mainly for pattern matching'
+        #     operator_description:
+        #         label: 'Operator'
+        #         equal_to: 'Equal to…'
+        #         matches: 'Tests that a <i>subject</i> matches a <i>search</i> (case-insensitive).<br />Example: <code>_all ~ "https?://rss.example.com/foobar/.*"</code>'
     otp:
         page_title: Autenticación de dos pasos
         app:
@@ -617,6 +637,8 @@ flashes:
             # otp_disabled: Two-factor authentication disabled
             tagging_rules_imported: Reglas de etiquetado importadas
             tagging_rules_not_imported: Un error se ha producico en la importación de las reglas de etiquetado
+            # ignore_origin_rules_deleted: 'Ignore origin rule deleted'
+            # ignore_origin_rules_updated: 'Ignore origin rule updated'
     entry:
         notice:
             entry_already_saved: 'Artículo ya guardado el %fecha%'
@@ -658,3 +680,8 @@ flashes:
              added: 'Credenciales del sitio añadidas para "%host%"'
              updated: 'Credenciales del sitio actualizadas para "%host%"'
              deleted: 'Credenciales del sitio eliminadas para "%host%"'
+    ignore_origin_instance_rule:
+        notice:
+            # added: 'Global ignore origin rule added'
+            # updated: 'Global ignore origin rule updated'
+            # deleted: 'Global ignore origin rule deleted'
index 0704204aa10e2d99bfe57092a8ee7226abc92216..4a52a2081677a452221e4427e0b5dba88d5149ea 100644 (file)
@@ -33,6 +33,7 @@ menu:
         back_to_unread: 'بازگشت به خوانده‌نشده‌ها'
         # users_management: 'Users management'
         # site_credentials: 'Site credentials'
+        # ignore_origin_instance_rules: 'Global ignore origin rules'
         quickstart: "Quickstart"
     top:
         add_new_entry: 'افزودن مقالهٔ تازه'
@@ -59,6 +60,7 @@ config:
         user_info: 'اطلاعات کاربر'
         password: 'رمز'
         rules: 'برچسب‌گذاری خودکار'
+        # ignore_origin: 'Ignore origin rules'
         new_user: 'افزودن کاربر'
         # reset: 'Reset area'
     form:
@@ -177,6 +179,24 @@ config:
         #         and: 'One rule AND another'
         #         matches: 'Tests that a <i>subject</i> matches a <i>search</i> (case-insensitive).<br />Example: <code>title matches "football"</code>'
         #         notmatches: 'Tests that a <i>subject</i> doesn''t match match a <i>search</i> (case-insensitive).<br />Example: <code>title notmatches "football"</code>'
+    form_ignore_origin_rules:
+        # faq:
+        #     title: 'FAQ'
+        #     ignore_origin_rules_definition_title: 'What does « ignore origin rules » mean?'
+        #     ignore_origin_rules_definition_description: 'They are used by wallabag to automatically ignore an origin address after a redirect.<br />If a redirect occurs while fetching a new entry, all the ignore origin rules (<i>user defined and instance defined</i>) will be used to ignore the origin address.'
+        #     how_to_use_them_title: 'How do I use them?'
+        #     how_to_use_them_description: 'Let us assume you want to ignore the origin of an entry coming from « <i>rss.example.com</i> » (<i>knowing that after a redirect, the actual address is example.com</i>).<br />In that case, you should put « host = "rss.example.com" » in the <i>Rule</i> field.'
+        #     variables_available_title: 'Which variables and operators can I use to write rules?'
+        #     variables_available_description: 'The following variables and operators can be used to create ignore origin rules:'
+        #     meaning: 'Meaning'
+        #     variable_description:
+        #         label: 'Variable'
+        #         host: 'Host of the address'
+        #         _all: 'Full address, mainly for pattern matching'
+        #     operator_description:
+        #         label: 'Operator'
+        #         equal_to: 'Equal to…'
+        #         matches: 'Tests that a <i>subject</i> matches a <i>search</i> (case-insensitive).<br />Example: <code>_all ~ "https?://rss.example.com/foobar/.*"</code>'
     otp:
         # page_title: Two-factor authentication
         # app:
@@ -617,6 +637,8 @@ flashes:
             # otp_disabled: Two-factor authentication disabled
             # tagging_rules_imported: Tagging rules imported
             # tagging_rules_not_imported: Error while importing tagging rules
+            # ignore_origin_rules_deleted: 'Ignore origin rule deleted'
+            # ignore_origin_rules_updated: 'Ignore origin rule updated'
     entry:
         notice:
             entry_already_saved: 'این مقاله در تاریخ %date% ذخیره شده بود'
@@ -658,3 +680,8 @@ flashes:
             # added: 'Site credential for "%host%" added'
             # updated: 'Site credential for "%host%" updated'
             # deleted: 'Site credential for "%host%" deleted'
+    ignore_origin_instance_rule:
+        notice:
+            # added: 'Global ignore origin rule added'
+            # updated: 'Global ignore origin rule updated'
+            # deleted: 'Global ignore origin rule deleted'
index 5d5878eba15f52b299825f2159472bba2274c11a..2cfab8cf4c6c6198eeb2fe7fc39c80bc3ac2ed84 100644 (file)
@@ -33,6 +33,7 @@ menu:
         back_to_unread: "Retour aux articles non lus"
         users_management: "Gestion des utilisateurs"
         site_credentials: 'Accès aux sites'
+        ignore_origin_instance_rules: "Règles globales d'omission d'origine"
         quickstart: "Pour bien débuter"
     top:
         add_new_entry: "Sauvegarder un nouvel article"
@@ -59,6 +60,7 @@ config:
         user_info: "Mon compte"
         password: "Mot de passe"
         rules: "Règles de tag automatiques"
+        ignore_origin: "Règles d'omission d'origine"
         new_user: "Créer un compte"
         reset: "Réinitialisation"
     form:
@@ -177,6 +179,24 @@ config:
                 and: "Une règle ET l’autre"
                 matches: "Teste si un <i>sujet</i> correspond à une <i>recherche</i> (non sensible à la casse).<br />Exemple : <code>title matches \"football\"</code>"
                 notmatches: "Teste si un <i>sujet</i> ne correspond pas à une <i>recherche</i> (non sensible à la casse).<br />Exemple : <code>title notmatches \"football\"</code>"
+    form_ignore_origin_rules:
+        faq:
+            title: "FAQ"
+            ignore_origin_rules_definition_title: "Que signifient les règles d'omission d'origine ?"
+            ignore_origin_rules_definition_description: "Ce sont des règles utilisées par wallabag pour omettre automatiquement l'adresse d'origine après une redirection.<br />Si une redirection intervient pendant la récupération d'un nouvel article, toutes les règles d'omission (<i>règles utilisateur et instance</i>) seront utilisées afin d'ignorer ou non l'adresse d'origine."
+            how_to_use_them_title: "Comment les utiliser ?"
+            how_to_use_them_description: "Imaginons que vous vouliez omettre l'origine d'un article provenant de « <i>rss.example.com</i> » (<i>sachant qu'après la redirection, l'adresse réelle est example.com</i>).<br />Dans ce cas, vous devriez mettre « host = \"rss.example.com\" » dans le champ <i>Règle</i>."
+            variables_available_title: "Quelles variables et opérateurs puis-je utiliser pour écrire des règles ?"
+            variables_available_description: "Les variables et opérateurs suivants peuvent être utilisés pour écrire des règles d'omission d'origine :"
+            meaning: "Signification"
+            variable_description:
+                label: "Variable"
+                host: "Hôte"
+                _all: "Adresse complète, utile pour les expressions régulières"
+            operator_description:
+                label: "Opérateur"
+                equal_to: "Égal à…"
+                matches: "Teste si un <i>sujet</i> correspond à une <i>recherche</i> (non sensible à la casse).<br />Exemple : <code>_all ~ \"https?://rss.example.com/foobar/.*\"</code>"
     otp:
         page_title: Authentification double-facteur
         app:
@@ -618,6 +638,8 @@ flashes:
             otp_disabled: "Authentification à double-facteur désactivée"
             tagging_rules_imported: Règles bien importées
             tagging_rules_not_imported: Impossible d'importer les règles
+            ignore_origin_rules_deleted: "Règle d'omission d'origine supprimée"
+            ignore_origin_rules_updated: "Règle d'omission d'origine mise à jour"
     entry:
         notice:
             entry_already_saved: "Article déjà sauvegardé le %date%"
index 23e72f20a7574aad4569c9a4ee5bcb664862e618..af1c1fe74e083f3745bba476e4d10fb8c808a194 100644 (file)
@@ -33,6 +33,7 @@ menu:
         back_to_unread: 'Torna ai contenuti non letti'
         users_management: 'Gestione utenti'
         site_credentials: 'Credenziali sito'
+        # ignore_origin_instance_rules: 'Global ignore origin rules'
         quickstart: "Introduzione"
     top:
         add_new_entry: 'Aggiungi un nuovo contenuto'
@@ -59,6 +60,7 @@ config:
         user_info: 'Informazioni utente'
         password: 'Password'
         rules: 'Regole di etichettatura'
+        # ignore_origin: 'Ignore origin rules'
         new_user: 'Aggiungi utente'
         reset: 'Area di reset'
     form:
@@ -177,6 +179,24 @@ config:
                 and: "Una regola E un'altra"
                 matches: 'Verifica che un <i>oggetto</i> risulti in una <i>ricerca</i> (case-insensitive).<br />Esempio: <code>titolo contiene "football"</code>'
                 # notmatches: 'Tests that a <i>subject</i> doesn''t match match a <i>search</i> (case-insensitive).<br />Example: <code>title notmatches "football"</code>'
+    form_ignore_origin_rules:
+        # faq:
+        #     title: 'FAQ'
+        #     ignore_origin_rules_definition_title: 'What does « ignore origin rules » mean?'
+        #     ignore_origin_rules_definition_description: 'They are used by wallabag to automatically ignore an origin address after a redirect.<br />If a redirect occurs while fetching a new entry, all the ignore origin rules (<i>user defined and instance defined</i>) will be used to ignore the origin address.'
+        #     how_to_use_them_title: 'How do I use them?'
+        #     how_to_use_them_description: 'Let us assume you want to ignore the origin of an entry coming from « <i>rss.example.com</i> » (<i>knowing that after a redirect, the actual address is example.com</i>).<br />In that case, you should put « host = "rss.example.com" » in the <i>Rule</i> field.'
+        #     variables_available_title: 'Which variables and operators can I use to write rules?'
+        #     variables_available_description: 'The following variables and operators can be used to create ignore origin rules:'
+        #     meaning: 'Meaning'
+        #     variable_description:
+        #         label: 'Variable'
+        #         host: 'Host of the address'
+        #         _all: 'Full address, mainly for pattern matching'
+        #     operator_description:
+        #         label: 'Operator'
+        #         equal_to: 'Equal to…'
+        #         matches: 'Tests that a <i>subject</i> matches a <i>search</i> (case-insensitive).<br />Example: <code>_all ~ "https?://rss.example.com/foobar/.*"</code>'
     otp:
         # page_title: Two-factor authentication
         # app:
@@ -617,6 +637,8 @@ flashes:
             # otp_disabled: Two-factor authentication disabled
             # tagging_rules_imported: Tagging rules imported
             # tagging_rules_not_imported: Error while importing tagging rules
+            # ignore_origin_rules_deleted: 'Ignore origin rule deleted'
+            # ignore_origin_rules_updated: 'Ignore origin rule updated'
     entry:
         notice:
             entry_already_saved: 'Contenuto già salvato in data %date%'
@@ -658,3 +680,8 @@ flashes:
             # added: 'Site credential for "%host%" added'
             # updated: 'Site credential for "%host%" updated'
             # deleted: 'Site credential for "%host%" deleted'
+    ignore_origin_instance_rule:
+        notice:
+            # added: 'Global ignore origin rule added'
+            # updated: 'Global ignore origin rule updated'
+            # deleted: 'Global ignore origin rule deleted'
index 6ddff6ea75ee414d0786269d8d709f335de4253d..59dd9b221e397a97c993d335ea921f7e863af885 100644 (file)
@@ -33,6 +33,7 @@ menu:
         back_to_unread: 'Tornar als articles pas legits'
         users_management: 'Gestion dels utilizaires'
         site_credentials: 'Identificants del site'
+        # ignore_origin_instance_rules: 'Global ignore origin rules'
         quickstart: "Per ben començar"
     top:
         add_new_entry: 'Enregistrar un novèl article'
@@ -59,6 +60,7 @@ config:
         user_info: 'Mon compte'
         password: 'Senhal'
         rules: "Règlas d'etiquetas automaticas"
+        # ignore_origin: 'Ignore origin rules'
         new_user: 'Crear un compte'
         reset: 'Zòna de reïnicializacion'
     form:
@@ -177,6 +179,24 @@ config:
                 and: "Una règla E l'autra"
                 matches: 'Teste se un <i>subjècte</i> correspond a una <i>recèrca</i> (non sensibla a la cassa).<br />Exemple : <code>title matches \"football\"</code>'
                 notmatches: 'Teste se <i>subjècte</i> correspond pas a una <i>recèrca</i> (sensibla a la cassa).<br />Example : <code>title notmatches "football"</code>'
+    form_ignore_origin_rules:
+        # faq:
+        #     title: 'FAQ'
+        #     ignore_origin_rules_definition_title: 'What does « ignore origin rules » mean?'
+        #     ignore_origin_rules_definition_description: 'They are used by wallabag to automatically ignore an origin address after a redirect.<br />If a redirect occurs while fetching a new entry, all the ignore origin rules (<i>user defined and instance defined</i>) will be used to ignore the origin address.'
+        #     how_to_use_them_title: 'How do I use them?'
+        #     how_to_use_them_description: 'Let us assume you want to ignore the origin of an entry coming from « <i>rss.example.com</i> » (<i>knowing that after a redirect, the actual address is example.com</i>).<br />In that case, you should put « host = "rss.example.com" » in the <i>Rule</i> field.'
+        #     variables_available_title: 'Which variables and operators can I use to write rules?'
+        #     variables_available_description: 'The following variables and operators can be used to create ignore origin rules:'
+        #     meaning: 'Meaning'
+        #     variable_description:
+        #         label: 'Variable'
+        #         host: 'Host of the address'
+        #         _all: 'Full address, mainly for pattern matching'
+        #     operator_description:
+        #         label: 'Operator'
+        #         equal_to: 'Equal to…'
+        #         matches: 'Tests that a <i>subject</i> matches a <i>search</i> (case-insensitive).<br />Example: <code>_all ~ "https?://rss.example.com/foobar/.*"</code>'
     otp:
         page_title: Autentificacion en dos temps
         app:
@@ -617,6 +637,8 @@ flashes:
             # otp_disabled: Two-factor authentication disabled
             tagging_rules_imported: Règlas d’etiquetatge importadas
             tagging_rules_not_imported: Error en important las règlas d’etiquetatge
+            # ignore_origin_rules_deleted: 'Ignore origin rule deleted'
+            # ignore_origin_rules_updated: 'Ignore origin rule updated'
     entry:
         notice:
             entry_already_saved: 'Article ja salvagardat lo %date%'
@@ -658,3 +680,8 @@ flashes:
             added: 'Identificant per "%host%" ajustat'
             updated: 'Identificant per "%host%" mes a jorn'
             deleted: 'Identificant per "%host%" suprimit'
+    ignore_origin_instance_rule:
+        notice:
+            # added: 'Global ignore origin rule added'
+            # updated: 'Global ignore origin rule updated'
+            # deleted: 'Global ignore origin rule deleted'
index 770477c96dcd142dbeaab1c1e58bc4a15943544e..c09ef47abfe14f97fa00e96adbb2df25677609db 100644 (file)
@@ -33,6 +33,7 @@ menu:
         back_to_unread: 'Powrót do nieprzeczytanych artykułów'
         users_management: 'Zarządzanie użytkownikami'
         site_credentials: 'Poświadczenia strony'
+        # ignore_origin_instance_rules: 'Global ignore origin rules'
         quickstart: "Szybki start"
     top:
         add_new_entry: 'Dodaj nowy wpis'
@@ -59,6 +60,7 @@ config:
         user_info: 'Informacje o użytkowniku'
         password: 'Hasło'
         rules: 'Zasady tagowania'
+        # ignore_origin: 'Ignore origin rules'
         new_user: 'Dodaj użytkownika'
         reset: 'Reset'
     form:
@@ -177,6 +179,24 @@ config:
                 and: 'Jedna reguła I inna'
                 matches: 'Sprawdź czy <i>temat</i> pasuje <i>szukaj</i> (duże lub małe litery).<br />Przykład: <code>tytuł zawiera "piłka nożna"</code>'
                 notmatches: 'Sprawdź czy <i>temat</i> nie zawiera <i>szukaj</i> (duże lub małe litery).<br />Przykład: <code>tytuł nie zawiera "piłka nożna"</code>'
+    form_ignore_origin_rules:
+        # faq:
+        #     title: 'FAQ'
+        #     ignore_origin_rules_definition_title: 'What does « ignore origin rules » mean?'
+        #     ignore_origin_rules_definition_description: 'They are used by wallabag to automatically ignore an origin address after a redirect.<br />If a redirect occurs while fetching a new entry, all the ignore origin rules (<i>user defined and instance defined</i>) will be used to ignore the origin address.'
+        #     how_to_use_them_title: 'How do I use them?'
+        #     how_to_use_them_description: 'Let us assume you want to ignore the origin of an entry coming from « <i>rss.example.com</i> » (<i>knowing that after a redirect, the actual address is example.com</i>).<br />In that case, you should put « host = "rss.example.com" » in the <i>Rule</i> field.'
+        #     variables_available_title: 'Which variables and operators can I use to write rules?'
+        #     variables_available_description: 'The following variables and operators can be used to create ignore origin rules:'
+        #     meaning: 'Meaning'
+        #     variable_description:
+        #         label: 'Variable'
+        #         host: 'Host of the address'
+        #         _all: 'Full address, mainly for pattern matching'
+        #     operator_description:
+        #         label: 'Operator'
+        #         equal_to: 'Equal to…'
+        #         matches: 'Tests that a <i>subject</i> matches a <i>search</i> (case-insensitive).<br />Example: <code>_all ~ "https?://rss.example.com/foobar/.*"</code>'
     otp:
         # page_title: Two-factor authentication
         # app:
@@ -617,6 +637,8 @@ flashes:
             # otp_disabled: Two-factor authentication disabled
             # tagging_rules_imported: Tagging rules imported
             # tagging_rules_not_imported: Error while importing tagging rules
+            # ignore_origin_rules_deleted: 'Ignore origin rule deleted'
+            # ignore_origin_rules_updated: 'Ignore origin rule updated'
     entry:
         notice:
             entry_already_saved: 'Wpis już został dodany %date%'
@@ -658,3 +680,8 @@ flashes:
             added: 'Poświadczenie dla "%host%" dodane'
             updated: 'Poświadczenie dla "%host%" zaktualizowane'
             deleted: 'Poświadczenie dla "%host%" usuniętę'
+    ignore_origin_instance_rule:
+        notice:
+            # added: 'Global ignore origin rule added'
+            # updated: 'Global ignore origin rule updated'
+            # deleted: 'Global ignore origin rule deleted'
index d993cb059a9b87093519a5fec262c491d13ffbd0..293a4e443abb1ac6f50444496f2ce38f738ed461 100644 (file)
@@ -33,6 +33,7 @@ menu:
         back_to_unread: 'Voltar para os artigos não lidos'
         users_management: 'Gestão de Usuários'
         site_credentials: 'Credenciais do site'
+        # ignore_origin_instance_rules: 'Global ignore origin rules'
         quickstart: "Começo Rápido"
     top:
         add_new_entry: 'Adicionar um novo artigo'
@@ -59,6 +60,7 @@ config:
         user_info: 'Informação do Usuário'
         password: 'Senha'
         rules: 'Regras de tags'
+        # ignore_origin: 'Ignore origin rules'
         new_user: 'Adicionar um usuário'
         reset: 'Reiniciar minha conta'
     form:
@@ -177,6 +179,24 @@ config:
                 and: 'Uma regra E outra'
                 matches: 'Testa que um <i>assunto</i> corresponde a uma <i>pesquisa</i> (maiúscula ou minúscula).<br />Exemplo: <code>title matches "futebol"</code>'
                 notmatches: 'Testa que um <i>assunto</i> não corresponde a uma <i>search</i> (maiúscula ou minúscula).<br />Exemplo: <code>title notmatches "futebol"</code>'
+    form_ignore_origin_rules:
+        # faq:
+        #     title: 'FAQ'
+        #     ignore_origin_rules_definition_title: 'What does « ignore origin rules » mean?'
+        #     ignore_origin_rules_definition_description: 'They are used by wallabag to automatically ignore an origin address after a redirect.<br />If a redirect occurs while fetching a new entry, all the ignore origin rules (<i>user defined and instance defined</i>) will be used to ignore the origin address.'
+        #     how_to_use_them_title: 'How do I use them?'
+        #     how_to_use_them_description: 'Let us assume you want to ignore the origin of an entry coming from « <i>rss.example.com</i> » (<i>knowing that after a redirect, the actual address is example.com</i>).<br />In that case, you should put « host = "rss.example.com" » in the <i>Rule</i> field.'
+        #     variables_available_title: 'Which variables and operators can I use to write rules?'
+        #     variables_available_description: 'The following variables and operators can be used to create ignore origin rules:'
+        #     meaning: 'Meaning'
+        #     variable_description:
+        #         label: 'Variable'
+        #         host: 'Host of the address'
+        #         _all: 'Full address, mainly for pattern matching'
+        #     operator_description:
+        #         label: 'Operator'
+        #         equal_to: 'Equal to…'
+        #         matches: 'Tests that a <i>subject</i> matches a <i>search</i> (case-insensitive).<br />Example: <code>_all ~ "https?://rss.example.com/foobar/.*"</code>'
     otp:
         page_title: Autenticação de dois fatores
         app:
@@ -657,3 +677,8 @@ flashes:
             added: 'Credencial do site para "%host%" foi adicionada'
             updated: 'Credencial do site pa "%host%" atualizada'
             deleted: 'Credencial do site pa "%host%" removida'
+    ignore_origin_instance_rule:
+        notice:
+            # added: 'Global ignore origin rule added'
+            # updated: 'Global ignore origin rule updated'
+            # deleted: 'Global ignore origin rule deleted'
index bc8b72e0b15523a32d8ce51cad4368c48b0f35c9..3c605709336e322760bee3ced689e8556fc272a2 100644 (file)
@@ -33,6 +33,7 @@ menu:
         back_to_unread: 'Înapoi la articolele necitite'
         # users_management: 'Users management'
         # site_credentials: 'Site credentials'
+        # ignore_origin_instance_rules: 'Global ignore origin rules'
         # quickstart: "Quickstart"
     top:
         add_new_entry: 'Introdu un nou articol'
@@ -59,6 +60,7 @@ config:
         user_info: 'Informații despre utilizator'
         password: 'Parolă'
         # rules: 'Tagging rules'
+        # ignore_origin: 'Ignore origin rules'
         new_user: 'Crează un utilizator'
         # reset: 'Reset area'
     form:
@@ -177,6 +179,24 @@ config:
         #         and: 'One rule AND another'
         #         matches: 'Tests that a <i>subject</i> matches a <i>search</i> (case-insensitive).<br />Example: <code>title matches "football"</code>'
         #         notmatches: 'Tests that a <i>subject</i> doesn''t match match a <i>search</i> (case-insensitive).<br />Example: <code>title notmatches "football"</code>'
+    form_ignore_origin_rules:
+        # faq:
+        #     title: 'FAQ'
+        #     ignore_origin_rules_definition_title: 'What does « ignore origin rules » mean?'
+        #     ignore_origin_rules_definition_description: 'They are used by wallabag to automatically ignore an origin address after a redirect.<br />If a redirect occurs while fetching a new entry, all the ignore origin rules (<i>user defined and instance defined</i>) will be used to ignore the origin address.'
+        #     how_to_use_them_title: 'How do I use them?'
+        #     how_to_use_them_description: 'Let us assume you want to ignore the origin of an entry coming from « <i>rss.example.com</i> » (<i>knowing that after a redirect, the actual address is example.com</i>).<br />In that case, you should put « host = "rss.example.com" » in the <i>Rule</i> field.'
+        #     variables_available_title: 'Which variables and operators can I use to write rules?'
+        #     variables_available_description: 'The following variables and operators can be used to create ignore origin rules:'
+        #     meaning: 'Meaning'
+        #     variable_description:
+        #         label: 'Variable'
+        #         host: 'Host of the address'
+        #         _all: 'Full address, mainly for pattern matching'
+        #     operator_description:
+        #         label: 'Operator'
+        #         equal_to: 'Equal to…'
+        #         matches: 'Tests that a <i>subject</i> matches a <i>search</i> (case-insensitive).<br />Example: <code>_all ~ "https?://rss.example.com/foobar/.*"</code>'
     otp:
         # page_title: Two-factor authentication
         # app:
@@ -616,6 +636,8 @@ flashes:
             # otp_disabled: Two-factor authentication disabled
             # tagging_rules_imported: Tagging rules imported
             # tagging_rules_not_imported: Error while importing tagging rules
+            # ignore_origin_rules_deleted: 'Ignore origin rule deleted'
+            # ignore_origin_rules_updated: 'Ignore origin rule updated'
     entry:
         notice:
             # entry_already_saved: 'Entry already saved on %date%'
@@ -657,3 +679,8 @@ flashes:
             # added: 'Site credential for "%host%" added'
             # updated: 'Site credential for "%host%" updated'
             # deleted: 'Site credential for "%host%" deleted'
+    ignore_origin_instance_rule:
+        notice:
+            # added: 'Global ignore origin rule added'
+            # updated: 'Global ignore origin rule updated'
+            # deleted: 'Global ignore origin rule deleted'
index 2f7f55e535f319da6b88999cda83f90bc4b1cf2f..eead4ec68b6a74dd8c77a4cbb2f92b11bc10587c 100644 (file)
@@ -33,6 +33,7 @@ menu:
         back_to_unread: 'Назад к непрочитанным записям'
         users_management: 'Управление пользователями'
         site_credentials: 'Site credentials'
+        # ignore_origin_instance_rules: 'Global ignore origin rules'
         quickstart: "Быстрый старт"
     top:
         add_new_entry: 'Добавить новую запись'
@@ -59,6 +60,7 @@ config:
         user_info: 'Информация о пользователе'
         password: 'Пароль'
         rules: 'Правила настройки простановки тегов'
+        # ignore_origin: 'Ignore origin rules'
         new_user: 'Добавить пользователя'
         reset: 'Сброс данных'
     form:
@@ -177,6 +179,24 @@ config:
                 and: 'Одно правило И другое'
                 matches: 'Тесты, в которых <i> тема </i> соответствует <i> поиску </i> (без учета регистра). Пример: <code> title matches "футбол" </code>'
                 # notmatches: 'Tests that a <i>subject</i> doesn''t match match a <i>search</i> (case-insensitive).<br />Example: <code>title notmatches "football"</code>'
+    form_ignore_origin_rules:
+        # faq:
+        #     title: 'FAQ'
+        #     ignore_origin_rules_definition_title: 'What does « ignore origin rules » mean?'
+        #     ignore_origin_rules_definition_description: 'They are used by wallabag to automatically ignore an origin address after a redirect.<br />If a redirect occurs while fetching a new entry, all the ignore origin rules (<i>user defined and instance defined</i>) will be used to ignore the origin address.'
+        #     how_to_use_them_title: 'How do I use them?'
+        #     how_to_use_them_description: 'Let us assume you want to ignore the origin of an entry coming from « <i>rss.example.com</i> » (<i>knowing that after a redirect, the actual address is example.com</i>).<br />In that case, you should put « host = "rss.example.com" » in the <i>Rule</i> field.'
+        #     variables_available_title: 'Which variables and operators can I use to write rules?'
+        #     variables_available_description: 'The following variables and operators can be used to create ignore origin rules:'
+        #     meaning: 'Meaning'
+        #     variable_description:
+        #         label: 'Variable'
+        #         host: 'Host of the address'
+        #         _all: 'Full address, mainly for pattern matching'
+        #     operator_description:
+        #         label: 'Operator'
+        #         equal_to: 'Equal to…'
+        #         matches: 'Tests that a <i>subject</i> matches a <i>search</i> (case-insensitive).<br />Example: <code>_all ~ "https?://rss.example.com/foobar/.*"</code>'
     otp:
         # page_title: Two-factor authentication
         # app:
@@ -616,6 +636,8 @@ flashes:
             # otp_disabled: Two-factor authentication disabled
             # tagging_rules_imported: Tagging rules imported
             # tagging_rules_not_imported: Error while importing tagging rules
+            # ignore_origin_rules_deleted: 'Ignore origin rule deleted'
+            # ignore_origin_rules_updated: 'Ignore origin rule updated'
     entry:
         notice:
             entry_already_saved: 'Запись была сохранена ранее %date%'
@@ -657,3 +679,8 @@ flashes:
             # added: 'Site credential for "%host%" added'
             # updated: 'Site credential for "%host%" updated'
             # deleted: 'Site credential for "%host%" deleted'
+    ignore_origin_instance_rule:
+        notice:
+            # added: 'Global ignore origin rule added'
+            # updated: 'Global ignore origin rule updated'
+            # deleted: 'Global ignore origin rule deleted'
index 48e1c34ad13aafe67f494cc2e604ea32ff2c73e2..8d2b05f3fe2db3500bff4049d373c821d692cf5b 100644 (file)
@@ -33,6 +33,7 @@ menu:
         back_to_unread: 'กลับไปยังรายการที่ไม่ได้อ่าน'
         users_management: 'การจัดการผู้ใช้'
         site_credentials: 'การรับรองไซต์'
+        # ignore_origin_instance_rules: 'Global ignore origin rules'
         quickstart: "เริ่มแบบด่วน"
     top:
         add_new_entry: 'เพิ่มรายการใหม่'
@@ -59,6 +60,7 @@ config:
         user_info: 'ข้อมูลผู้ใช้'
         password: 'รหัสผ่าน'
         rules: 'การแท็กข้อบังคับ'
+        # ignore_origin: 'Ignore origin rules'
         new_user: 'เพิ่มผู้ใช้'
         reset: 'รีเซ็ตพื้นที่ '
     form:
@@ -177,6 +179,24 @@ config:
                 and: 'หนึ่งข้อบังคับและอื่นๆ'
                 matches: 'ทดสอบว่า <i>เรื่อง</i> นี้ตรงกับ <i>การต้นหา</i> (กรณีไม่ทราบ).<br />ตัวอย่าง: <code>หัวข้อที่ตรงกับ "football"</code>'
                 notmatches: 'ทดสอบว่า <i>เรื่อง</i> นี้ไม่ตรงกับ <i>การต้นหา</i> (กรณีไม่ทราบ).<br />ตัวอย่าง: <code>หัวข้อทีไม่ตรงกับ "football"</code>'
+    form_ignore_origin_rules:
+        # faq:
+        #     title: 'FAQ'
+        #     ignore_origin_rules_definition_title: 'What does « ignore origin rules » mean?'
+        #     ignore_origin_rules_definition_description: 'They are used by wallabag to automatically ignore an origin address after a redirect.<br />If a redirect occurs while fetching a new entry, all the ignore origin rules (<i>user defined and instance defined</i>) will be used to ignore the origin address.'
+        #     how_to_use_them_title: 'How do I use them?'
+        #     how_to_use_them_description: 'Let us assume you want to ignore the origin of an entry coming from « <i>rss.example.com</i> » (<i>knowing that after a redirect, the actual address is example.com</i>).<br />In that case, you should put « host = "rss.example.com" » in the <i>Rule</i> field.'
+        #     variables_available_title: 'Which variables and operators can I use to write rules?'
+        #     variables_available_description: 'The following variables and operators can be used to create ignore origin rules:'
+        #     meaning: 'Meaning'
+        #     variable_description:
+        #         label: 'Variable'
+        #         host: 'Host of the address'
+        #         _all: 'Full address, mainly for pattern matching'
+        #     operator_description:
+        #         label: 'Operator'
+        #         equal_to: 'Equal to…'
+        #         matches: 'Tests that a <i>subject</i> matches a <i>search</i> (case-insensitive).<br />Example: <code>_all ~ "https?://rss.example.com/foobar/.*"</code>'
     otp:
         # page_title: Two-factor authentication
         # app:
@@ -616,6 +636,8 @@ flashes:
             # otp_disabled: Two-factor authentication disabled
             # tagging_rules_imported: Tagging rules imported
             # tagging_rules_not_imported: Error while importing tagging rules
+            # ignore_origin_rules_deleted: 'Ignore origin rule deleted'
+            # ignore_origin_rules_updated: 'Ignore origin rule updated'
     entry:
         notice:
             entry_already_saved: 'รายการพร้อมบันทึกที่ %date%'
@@ -657,3 +679,8 @@ flashes:
             added: 'ไซต์ข้อมูลประจำตัวสำหรับ "%host%" ที่ทำการเพิ่ม'
             updated: 'ไซต์ข้อมูลประจำตัวสำหรับ "%host%" ที่ทำการอัปเดต'
             deleted: 'ไซต์ข้อมูลประจำตัวสำหรับ "%host%" ที่ทำการลบ'
+    ignore_origin_instance_rule:
+        notice:
+            # added: 'Global ignore origin rule added'
+            # updated: 'Global ignore origin rule updated'
+            # deleted: 'Global ignore origin rule deleted'
index 19029c0b1cabcd262db74f090dac40bf947fbcb3..dfbc301086575b7ede0c9ff75a107fea9d2bf0be 100644 (file)
@@ -33,6 +33,7 @@ menu:
         back_to_unread: 'Okunmayan makalelere geri dön'
         # users_management: 'Users management'
         # site_credentials: 'Site credentials'
+        # ignore_origin_instance_rules: 'Global ignore origin rules'
         quickstart: "Hızlı başlangıç"
     top:
         add_new_entry: 'Yeni bir makale ekle'
@@ -59,6 +60,7 @@ config:
         user_info: 'Kullanıcı bilgileri'
         password: 'Şifre'
         rules: 'Etiketleme kuralları'
+        # ignore_origin: 'Ignore origin rules'
         new_user: 'Bir kullanıcı ekle'
         # reset: 'Reset area'
     form:
@@ -177,6 +179,24 @@ config:
                 and: 'Bir kural ve diğeri'
                 # matches: 'Tests that a <i>subject</i> matches a <i>search</i> (case-insensitive).<br />Example: <code>title matches "football"</code>'
                 # notmatches: 'Tests that a <i>subject</i> doesn''t match match a <i>search</i> (case-insensitive).<br />Example: <code>title notmatches "football"</code>'
+    form_ignore_origin_rules:
+        # faq:
+        #     title: 'FAQ'
+        #     ignore_origin_rules_definition_title: 'What does « ignore origin rules » mean?'
+        #     ignore_origin_rules_definition_description: 'They are used by wallabag to automatically ignore an origin address after a redirect.<br />If a redirect occurs while fetching a new entry, all the ignore origin rules (<i>user defined and instance defined</i>) will be used to ignore the origin address.'
+        #     how_to_use_them_title: 'How do I use them?'
+        #     how_to_use_them_description: 'Let us assume you want to ignore the origin of an entry coming from « <i>rss.example.com</i> » (<i>knowing that after a redirect, the actual address is example.com</i>).<br />In that case, you should put « host = "rss.example.com" » in the <i>Rule</i> field.'
+        #     variables_available_title: 'Which variables and operators can I use to write rules?'
+        #     variables_available_description: 'The following variables and operators can be used to create ignore origin rules:'
+        #     meaning: 'Meaning'
+        #     variable_description:
+        #         label: 'Variable'
+        #         host: 'Host of the address'
+        #         _all: 'Full address, mainly for pattern matching'
+        #     operator_description:
+        #         label: 'Operator'
+        #         equal_to: 'Equal to…'
+        #         matches: 'Tests that a <i>subject</i> matches a <i>search</i> (case-insensitive).<br />Example: <code>_all ~ "https?://rss.example.com/foobar/.*"</code>'
     otp:
         # page_title: Two-factor authentication
         # app:
@@ -616,6 +636,8 @@ flashes:
             # otp_disabled: Two-factor authentication disabled
             # tagging_rules_imported: Tagging rules imported
             # tagging_rules_not_imported: Error while importing tagging rules
+            # ignore_origin_rules_deleted: 'Ignore origin rule deleted'
+            # ignore_origin_rules_updated: 'Ignore origin rule updated'
     entry:
         notice:
             entry_already_saved: 'Entry already saved on %date%'
@@ -657,3 +679,8 @@ flashes:
             # added: 'Site credential for "%host%" added'
             # updated: 'Site credential for "%host%" updated'
             # deleted: 'Site credential for "%host%" deleted'
+    ignore_origin_instance_rule:
+        notice:
+            # added: 'Global ignore origin rule added'
+            # updated: 'Global ignore origin rule updated'
+            # deleted: 'Global ignore origin rule deleted'
index eb395eac475af6b492414ede4c78c7d4cd42c622..b6edce39efe5e9d792dd6d791c834aa1f2318a73 100644 (file)
         </div>
     </div>
 
+    <h2>{{ 'config.tab_menu.ignore_origin'|trans }}</h2>
+
+    <ul>
+        {% for ignore_origin_rule in app.user.config.ignoreOriginRules %}
+            <li>
+                {{ 'config.form_rules.if_label'|trans }}
+                « {{ ignore_origin_rule.rule }} »
+                <a href="{{ path('edit_ignore_origin_rule', {id: ignore_origin_rule.id}) }}" title="{{ 'config.form_rules.edit_rule_label'|trans }}" class="tool mode_edit">✎</a>
+                <a href="{{ path('delete_ignore_origin_rule', {id: ignore_origin_rule.id}) }}" title="{{ 'config.form_rules.delete_rule_label'|trans }}" class="tool delete icon-trash icon"></a>
+            </li>
+        {% endfor %}
+    </ul>
+
+    {{ form_start(form.new_ignore_origin_user_rule) }}
+        {{ form_errors(form.new_ignore_origin_user_rule) }}
+
+        <fieldset class="w500p inline">
+            <div class="row">
+                {{ form_label(form.new_ignore_origin_user_rule.rule) }}
+                {{ form_errors(form.new_ignore_origin_user_rule.rule) }}
+                {{ form_widget(form.new_ignore_origin_user_rule.rule) }}
+            </div>
+        </fieldset>
+
+        {{ form_rest(form.new_ignore_origin_user_rule) }}
+    </form>
+
+    <div class="row">
+        <div class="input-field col s12">
+            <h4>{{ 'config.form_ignore_origin_rules.faq.title'|trans }}</h4>
+
+            <h5>{{ 'config.form_ignore_origin_rules.faq.ignore_origin_rules_definition_title'|trans }}</h5>
+            <p class="help">{{ 'config.form_ignore_origin_rules.faq.ignore_origin_rules_definition_description'|trans|raw }}</p>
+
+            <h5>{{ 'config.form_ignore_origin_rules.faq.how_to_use_them_title'|trans }}</h5>
+            <p class="help">{{ 'config.form_ignore_origin_rules.faq.how_to_use_them_description'|trans|raw }}</p>
+
+            <h5>{{ 'config.form_ignore_origin_rules.faq.variables_available_title'|trans }}</h5>
+            <p class="help">
+                {{ 'config.form_ignore_origin_rules.faq.variables_available_description'|trans }}
+            </p>
+
+            <table class="bordered">
+                <thead>
+                    <tr>
+                        <th>{{ 'config.form_ignore_origin_rules.faq.variable_description.label'|trans }}</th>
+                        <th>{{ 'config.form_ignore_origin_rules.faq.meaning'|trans }}</th>
+                        <th>{{ 'config.form_ignore_origin_rules.faq.operator_description.label'|trans }}</th>
+                        <th>{{ 'config.form_ignore_origin_rules.faq.meaning'|trans }}</th>
+                    </tr>
+                </thead>
+
+                <tbody>
+                    <tr>
+                        <td>host</td>
+                        <td>{{ 'config.form_ignore_origin_rules.faq.variable_description.host'|trans }}</td>
+                        <td>=</td>
+                        <td>{{ 'config.form_ignore_origin_rules.faq.operator_description.equal_to'|trans }}</td>
+                    </tr>
+                    <tr>
+                        <td>_all</td>
+                        <td>{{ 'config.form_ignore_origin_rules.faq.variable_description._all'|trans }}</td>
+                        <td>~</td>
+                        <td>{{ 'config.form_ignore_origin_rules.faq.operator_description.matches'|trans|raw }}</td>
+                    </tr>
+                </tbody>
+            </table>
+        </div>
+    </div>
+
     <h2>{{ 'config.reset.title'|trans }}</h2>
     <fieldset class="w500p inline">
         <p>{{ 'config.reset.description'|trans }}</p>
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/IgnoreOriginInstanceRule/edit.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/baggy/IgnoreOriginInstanceRule/edit.html.twig
new file mode 100644 (file)
index 0000000..30c2a52
--- /dev/null
@@ -0,0 +1,87 @@
+{% extends "WallabagCoreBundle::layout.html.twig" %}
+
+{% block title %}{{ 'ignore_origin_instance_rule.page_title'|trans }}{% endblock %}
+
+{% block content %}
+
+    <div class="row">
+        <div class="col s12">
+            <div class="card-panel">
+                <div class="row">
+                    <div class="input-field col s12">
+                        <h4>{{ 'ignore_origin_instance_rule.edit_ignore_origin_instance_rule'|trans }}</h4>
+
+                        <div id="set6" class="col s12">
+                            {{ form_start(edit_form) }}
+                                {{ form_errors(edit_form) }}
+
+                                <div class="row">
+                                    <div class="input-field col s12">
+                                        {{ form_label(edit_form.rule) }}
+                                        {{ form_errors(edit_form.rule) }}
+                                        {{ form_widget(edit_form.rule) }}
+                                    </div>
+                                </div>
+
+                                <br/>
+
+                                {{ form_widget(edit_form.save, {'attr': {'class': 'btn waves-effect waves-light'}}) }}
+                                {{ form_widget(edit_form._token) }}
+                            </form>
+                            <p>
+                                {{ form_start(delete_form) }}
+                                    <button onclick="return confirm('{{ 'ignore_origin_instance_rule.form.delete_confirm'|trans|escape('js') }}')" type="submit" class="btn waves-effect waves-light red">{{ 'ignore_origin_instance_rule.form.delete'|trans }}</button>
+                                {{ form_end(delete_form) }}
+                            </p>
+                            <p><a class="waves-effect waves-light btn blue-grey" href="{{ path('ignore_origin_instance_rules_index') }}">{{ 'ignore_origin_instance_rule.form.back_to_list'|trans }}</a></p>
+                        </div>
+                    </div>
+                </div>
+
+                <div class="row">
+                    <div class="input-field col s12">
+                        <h4>{{ 'config.form_ignore_origin_rules.faq.title'|trans }}</h4>
+
+                        <h5>{{ 'config.form_ignore_origin_rules.faq.ignore_origin_rules_definition_title'|trans }}</h5>
+                        <p class="help">{{ 'config.form_ignore_origin_rules.faq.ignore_origin_rules_definition_description'|trans|raw }}</p>
+
+                        <h5>{{ 'config.form_ignore_origin_rules.faq.how_to_use_them_title'|trans }}</h5>
+                        <p class="help">{{ 'config.form_ignore_origin_rules.faq.how_to_use_them_description'|trans|raw }}</p>
+
+                        <h5>{{ 'config.form_ignore_origin_rules.faq.variables_available_title'|trans }}</h5>
+                        <p class="help">
+                            {{ 'config.form_ignore_origin_rules.faq.variables_available_description'|trans }}
+                        </p>
+
+                        <table class="bordered">
+                            <thead>
+                                <tr>
+                                    <th>{{ 'config.form_ignore_origin_rules.faq.variable_description.label'|trans }}</th>
+                                    <th>{{ 'config.form_ignore_origin_rules.faq.meaning'|trans }}</th>
+                                    <th>{{ 'config.form_ignore_origin_rules.faq.operator_description.label'|trans }}</th>
+                                    <th>{{ 'config.form_ignore_origin_rules.faq.meaning'|trans }}</th>
+                                </tr>
+                            </thead>
+
+                            <tbody>
+                                <tr>
+                                    <td>host</td>
+                                    <td>{{ 'config.form_ignore_origin_rules.faq.variable_description.host'|trans }}</td>
+                                    <td>=</td>
+                                    <td>{{ 'config.form_ignore_origin_rules.faq.operator_description.equal_to'|trans }}</td>
+                                </tr>
+                                <tr>
+                                    <td>_all</td>
+                                    <td>{{ 'config.form_ignore_origin_rules.faq.variable_description._all'|trans }}</td>
+                                    <td>~</td>
+                                    <td>{{ 'config.form_ignore_origin_rules.faq.operator_description.matches'|trans|raw }}</td>
+                                </tr>
+                            </tbody>
+                        </table>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+
+{% endblock %}
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/IgnoreOriginInstanceRule/index.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/baggy/IgnoreOriginInstanceRule/index.html.twig
new file mode 100644 (file)
index 0000000..2de7cf0
--- /dev/null
@@ -0,0 +1,42 @@
+{% extends "WallabagCoreBundle::layout.html.twig" %}
+
+{% block title %}{{ 'ignore_origin_instance_rule.page_title'|trans }}{% endblock %}
+
+{% block content %}
+
+    <div class="row">
+        <div class="col s12">
+            <div class="card-panel">
+                <div class="row">
+                    <div class="input-field col s12">
+                        <p class="help">{{ 'ignore_origin_instance_rule.description'|trans|raw }}</p>
+
+                        <table class="bordered">
+                            <thead>
+                                <tr>
+                                    <th>{{ 'ignore_origin_instance_rule.form.rule_label'|trans }}</th>
+                                    <th>{{ 'ignore_origin_instance_rule.list.actions'|trans }}</th>
+                                </tr>
+                            </thead>
+                            <tbody>
+                            {% for rule in rules %}
+                                <tr>
+                                    <td>{{ rule.rule }}</td>
+                                    <td>
+                                        <a href="{{ path('ignore_origin_instance_rules_edit', { 'id': rule.id }) }}">{{ 'ignore_origin_instance_rule.list.edit_action'|trans }}</a>
+                                    </td>
+                                </tr>
+                            {% endfor %}
+                            </tbody>
+                        </table>
+                        <br />
+                        <p>
+                            <a href="{{ path('ignore_origin_instance_rules_new') }}" class="waves-effect waves-light btn">{{ 'ignore_origin_instance_rule.list.create_new_one'|trans }}</a>
+                        </p>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+
+{% endblock %}
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/IgnoreOriginInstanceRule/new.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/baggy/IgnoreOriginInstanceRule/new.html.twig
new file mode 100644 (file)
index 0000000..cb052ff
--- /dev/null
@@ -0,0 +1,80 @@
+{% extends "WallabagCoreBundle::layout.html.twig" %}
+
+{% block title %}{{ 'ignore_origin_instance_rule.page_title'|trans }}{% endblock %}
+
+{% block content %}
+
+    <div class="row">
+        <div class="col s12">
+            <div class="card-panel">
+                <div class="row">
+                    <div class="input-field col s12">
+                        <h4>{{ 'ignore_origin_instance_rule.new_ignore_origin_instance_rule'|trans }}</h4>
+
+                        <div id="set6" class="col s12">
+                            {{ form_start(form) }}
+                                {{ form_errors(form) }}
+
+                                <div class="row">
+                                    <div class="input-field col s12">
+                                        {{ form_label(form.rule) }}
+                                        {{ form_errors(form.rule) }}
+                                        {{ form_widget(form.rule) }}
+                                    </div>
+                                </div>
+
+                                {{ form_widget(form.save, {'attr': {'class': 'btn waves-effect waves-light'}}) }}
+                                {{ form_rest(form) }}
+                            </form>
+                            <p><a class="waves-effect waves-light btn blue-grey" href="{{ path('ignore_origin_instance_rules_index') }}">{{ 'ignore_origin_instance_rule.form.back_to_list'|trans }}</a></p>
+                        </div>
+                    </div>
+                </div>
+
+                <div class="row">
+                    <div class="input-field col s12">
+                        <h4>{{ 'config.form_ignore_origin_rules.faq.title'|trans }}</h4>
+
+                        <h5>{{ 'config.form_ignore_origin_rules.faq.ignore_origin_rules_definition_title'|trans }}</h5>
+                        <p class="help">{{ 'config.form_ignore_origin_rules.faq.ignore_origin_rules_definition_description'|trans|raw }}</p>
+
+                        <h5>{{ 'config.form_ignore_origin_rules.faq.how_to_use_them_title'|trans }}</h5>
+                        <p class="help">{{ 'config.form_ignore_origin_rules.faq.how_to_use_them_description'|trans|raw }}</p>
+
+                        <h5>{{ 'config.form_ignore_origin_rules.faq.variables_available_title'|trans }}</h5>
+                        <p class="help">
+                            {{ 'config.form_ignore_origin_rules.faq.variables_available_description'|trans }}
+                        </p>
+
+                        <table class="bordered">
+                            <thead>
+                                <tr>
+                                    <th>{{ 'config.form_ignore_origin_rules.faq.variable_description.label'|trans }}</th>
+                                    <th>{{ 'config.form_ignore_origin_rules.faq.meaning'|trans }}</th>
+                                    <th>{{ 'config.form_ignore_origin_rules.faq.operator_description.label'|trans }}</th>
+                                    <th>{{ 'config.form_ignore_origin_rules.faq.meaning'|trans }}</th>
+                                </tr>
+                            </thead>
+
+                            <tbody>
+                                <tr>
+                                    <td>host</td>
+                                    <td>{{ 'config.form_ignore_origin_rules.faq.variable_description.host'|trans }}</td>
+                                    <td>=</td>
+                                    <td>{{ 'config.form_ignore_origin_rules.faq.operator_description.equal_to'|trans }}</td>
+                                </tr>
+                                <tr>
+                                    <td>_all</td>
+                                    <td>{{ 'config.form_ignore_origin_rules.faq.variable_description._all'|trans }}</td>
+                                    <td>~</td>
+                                    <td>{{ 'config.form_ignore_origin_rules.faq.operator_description.matches'|trans|raw }}</td>
+                                </tr>
+                            </tbody>
+                        </table>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+
+{% endblock %}
index 6b1e2bd794679d2162b06d906562cdf601fa289d..e1446ff7c5ded75dea28b51ed199c7e74263384f 100644 (file)
@@ -45,6 +45,7 @@
         {% if is_granted('ROLE_SUPER_ADMIN') %}
             <li class="menu users"><a href="{{ path('user_index') }}">{{ 'menu.left.users_management'|trans }}</a></li>
             <li class="menu internal"><a href="{{ path('craue_config_settings_modify') }}">{{ 'menu.left.internal_settings'|trans }}</a></li>
+            <li class="menu ignore"><a href="{{ path('ignore_origin_instance_rules_index') }}">{{ 'menu.left.ignore_origin_instance_rules'|trans }}</a></li>
         {% endif %}
         <li class="menu import"><a href="{{ path('import') }}">{{ 'menu.left.import'|trans }}</a></li>
         <li class="menu howto"><a href="{{ path('howto') }}">{{ 'menu.left.howto'|trans }}</a></li>
index c2e92ad106ef6a3f597e0d6f3a3eb68ad5696d6a..22b38a1b651671056eb381b8e541b861e935eb65 100644 (file)
@@ -16,7 +16,8 @@
                             <li class="tab col s12 m6 l3"><a href="#set3">{{ 'config.tab_menu.user_info'|trans }}</a></li>
                             <li class="tab col s12 m6 l3"><a href="#set4">{{ 'config.tab_menu.password'|trans }}</a></li>
                             <li class="tab col s12 m6 l3"><a href="#set5">{{ 'config.tab_menu.rules'|trans }}</a></li>
-                            <li class="tab col s12 m6 l3"><a href="#set6">{{ 'config.tab_menu.reset'|trans }}</a></li>
+                            <li class="tab col s12 m6 l3"><a href="#set6">{{ 'config.tab_menu.ignore_origin'|trans }}</a></li>
+                            <li class="tab col s12 m6 l3"><a href="#set7">{{ 'config.tab_menu.reset'|trans }}</a></li>
                         </ul>
                     </div>
 
                                         « {{ tagging_rule.rule }} »
                                         {{ 'config.form_rules.then_tag_as_label'|trans }}
                                         « {{ tagging_rule.tags|join(', ') }} »
-                                        <a href="{{ path('edit_tagging_rule', {id: tagging_rule.id}) }}" title="{{ 'config.form_rules.edit_rule_label'|trans }}">
-                                            <i class="tool grey-text mode_edit material-icons">mode_edit</i>
+                                        <a href="{{ path('edit_tagging_rule', {id: tagging_rule.id}) }}" title="{{ 'config.form_rules.edit_rule_label'|trans }}" class="mode_edit">
+                                            <i class="tool grey-text material-icons">mode_edit</i>
                                         </a>
-                                        <a href="{{ path('delete_tagging_rule', {id: tagging_rule.id}) }}" title="{{ 'config.form_rules.delete_rule_label'|trans }}">
-                                            <i class="tool grey-text delete material-icons">delete</i>
+                                        <a href="{{ path('delete_tagging_rule', {id: tagging_rule.id}) }}" title="{{ 'config.form_rules.delete_rule_label'|trans }}" class="delete">
+                                            <i class="tool grey-text material-icons">delete</i>
                                         </a>
                                     </li>
                                     {% endfor %}
                     </div>
 
                     <div id="set6" class="col s12">
+                        {% if app.user.config.ignoreOriginRules is not empty %}
+                        <div class="row">
+                            <div class="input-field col s12">
+                                <ul>
+                                    {% for ignore_origin_rule in app.user.config.ignoreOriginRules %}
+                                    <li>
+                                        {{ 'config.form_rules.if_label'|trans }}
+                                        « {{ ignore_origin_rule.rule }} »
+                                        <a href="{{ path('edit_ignore_origin_rule', {id: ignore_origin_rule.id}) }}" title="{{ 'config.form_rules.edit_rule_label'|trans }}" class="mode_edit">
+                                            <i class="tool grey-text material-icons">mode_edit</i>
+                                        </a>
+                                        <a href="{{ path('delete_ignore_origin_rule', {id: ignore_origin_rule.id}) }}" title="{{ 'config.form_rules.delete_rule_label'|trans }}" class="delete">
+                                            <i class="tool grey-text material-icons">delete</i>
+                                        </a>
+                                    </li>
+                                    {% endfor %}
+                                </ul>
+                            </div>
+                        </div>
+                        {% endif %}
+
+                        {{ form_start(form.new_ignore_origin_user_rule) }}
+                            {{ form_errors(form.new_ignore_origin_user_rule) }}
+
+                            <div class="row">
+                                <div class="input-field col s12">
+                                    {{ form_label(form.new_ignore_origin_user_rule.rule) }}
+                                    {{ form_errors(form.new_ignore_origin_user_rule.rule) }}
+                                    {{ form_widget(form.new_ignore_origin_user_rule.rule) }}
+                                </div>
+                            </div>
+
+                            {{ form_widget(form.new_ignore_origin_user_rule.save, {'attr': {'class': 'btn waves-effect waves-light'}}) }}
+                            {{ form_rest(form.new_ignore_origin_user_rule) }}
+                        </form>
+
+
+
+                        <div class="row">
+                            <div class="input-field col s12">
+                                <h4>{{ 'config.form_ignore_origin_rules.faq.title'|trans }}</h4>
+
+                                <h5>{{ 'config.form_ignore_origin_rules.faq.ignore_origin_rules_definition_title'|trans }}</h5>
+                                <p class="help">{{ 'config.form_ignore_origin_rules.faq.ignore_origin_rules_definition_description'|trans|raw }}</p>
+
+                                <h5>{{ 'config.form_ignore_origin_rules.faq.how_to_use_them_title'|trans }}</h5>
+                                <p class="help">{{ 'config.form_ignore_origin_rules.faq.how_to_use_them_description'|trans|raw }}</p>
+
+                                <h5>{{ 'config.form_ignore_origin_rules.faq.variables_available_title'|trans }}</h5>
+                                <p class="help">
+                                    {{ 'config.form_ignore_origin_rules.faq.variables_available_description'|trans }}
+                                </p>
+
+                                <table class="bordered">
+                                    <thead>
+                                        <tr>
+                                            <th>{{ 'config.form_ignore_origin_rules.faq.variable_description.label'|trans }}</th>
+                                            <th>{{ 'config.form_ignore_origin_rules.faq.meaning'|trans }}</th>
+                                            <th>{{ 'config.form_ignore_origin_rules.faq.operator_description.label'|trans }}</th>
+                                            <th>{{ 'config.form_ignore_origin_rules.faq.meaning'|trans }}</th>
+                                        </tr>
+                                    </thead>
+
+                                    <tbody>
+                                        <tr>
+                                            <td>host</td>
+                                            <td>{{ 'config.form_ignore_origin_rules.faq.variable_description.host'|trans }}</td>
+                                            <td>=</td>
+                                            <td>{{ 'config.form_ignore_origin_rules.faq.operator_description.equal_to'|trans }}</td>
+                                        </tr>
+                                        <tr>
+                                            <td>_all</td>
+                                            <td>{{ 'config.form_ignore_origin_rules.faq.variable_description._all'|trans }}</td>
+                                            <td>~</td>
+                                            <td>{{ 'config.form_ignore_origin_rules.faq.operator_description.matches'|trans|raw }}</td>
+                                        </tr>
+                                    </tbody>
+                                </table>
+                            </div>
+                        </div>
+                    </div>
+                    
+                    <div id="set7" class="col s12">
                         <div class="row">
                             <h5>{{ 'config.reset.title'|trans }}</h5>
                             <p>{{ 'config.reset.description'|trans }}</p>
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/material/IgnoreOriginInstanceRule/edit.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/material/IgnoreOriginInstanceRule/edit.html.twig
new file mode 100644 (file)
index 0000000..30c2a52
--- /dev/null
@@ -0,0 +1,87 @@
+{% extends "WallabagCoreBundle::layout.html.twig" %}
+
+{% block title %}{{ 'ignore_origin_instance_rule.page_title'|trans }}{% endblock %}
+
+{% block content %}
+
+    <div class="row">
+        <div class="col s12">
+            <div class="card-panel">
+                <div class="row">
+                    <div class="input-field col s12">
+                        <h4>{{ 'ignore_origin_instance_rule.edit_ignore_origin_instance_rule'|trans }}</h4>
+
+                        <div id="set6" class="col s12">
+                            {{ form_start(edit_form) }}
+                                {{ form_errors(edit_form) }}
+
+                                <div class="row">
+                                    <div class="input-field col s12">
+                                        {{ form_label(edit_form.rule) }}
+                                        {{ form_errors(edit_form.rule) }}
+                                        {{ form_widget(edit_form.rule) }}
+                                    </div>
+                                </div>
+
+                                <br/>
+
+                                {{ form_widget(edit_form.save, {'attr': {'class': 'btn waves-effect waves-light'}}) }}
+                                {{ form_widget(edit_form._token) }}
+                            </form>
+                            <p>
+                                {{ form_start(delete_form) }}
+                                    <button onclick="return confirm('{{ 'ignore_origin_instance_rule.form.delete_confirm'|trans|escape('js') }}')" type="submit" class="btn waves-effect waves-light red">{{ 'ignore_origin_instance_rule.form.delete'|trans }}</button>
+                                {{ form_end(delete_form) }}
+                            </p>
+                            <p><a class="waves-effect waves-light btn blue-grey" href="{{ path('ignore_origin_instance_rules_index') }}">{{ 'ignore_origin_instance_rule.form.back_to_list'|trans }}</a></p>
+                        </div>
+                    </div>
+                </div>
+
+                <div class="row">
+                    <div class="input-field col s12">
+                        <h4>{{ 'config.form_ignore_origin_rules.faq.title'|trans }}</h4>
+
+                        <h5>{{ 'config.form_ignore_origin_rules.faq.ignore_origin_rules_definition_title'|trans }}</h5>
+                        <p class="help">{{ 'config.form_ignore_origin_rules.faq.ignore_origin_rules_definition_description'|trans|raw }}</p>
+
+                        <h5>{{ 'config.form_ignore_origin_rules.faq.how_to_use_them_title'|trans }}</h5>
+                        <p class="help">{{ 'config.form_ignore_origin_rules.faq.how_to_use_them_description'|trans|raw }}</p>
+
+                        <h5>{{ 'config.form_ignore_origin_rules.faq.variables_available_title'|trans }}</h5>
+                        <p class="help">
+                            {{ 'config.form_ignore_origin_rules.faq.variables_available_description'|trans }}
+                        </p>
+
+                        <table class="bordered">
+                            <thead>
+                                <tr>
+                                    <th>{{ 'config.form_ignore_origin_rules.faq.variable_description.label'|trans }}</th>
+                                    <th>{{ 'config.form_ignore_origin_rules.faq.meaning'|trans }}</th>
+                                    <th>{{ 'config.form_ignore_origin_rules.faq.operator_description.label'|trans }}</th>
+                                    <th>{{ 'config.form_ignore_origin_rules.faq.meaning'|trans }}</th>
+                                </tr>
+                            </thead>
+
+                            <tbody>
+                                <tr>
+                                    <td>host</td>
+                                    <td>{{ 'config.form_ignore_origin_rules.faq.variable_description.host'|trans }}</td>
+                                    <td>=</td>
+                                    <td>{{ 'config.form_ignore_origin_rules.faq.operator_description.equal_to'|trans }}</td>
+                                </tr>
+                                <tr>
+                                    <td>_all</td>
+                                    <td>{{ 'config.form_ignore_origin_rules.faq.variable_description._all'|trans }}</td>
+                                    <td>~</td>
+                                    <td>{{ 'config.form_ignore_origin_rules.faq.operator_description.matches'|trans|raw }}</td>
+                                </tr>
+                            </tbody>
+                        </table>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+
+{% endblock %}
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/material/IgnoreOriginInstanceRule/index.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/material/IgnoreOriginInstanceRule/index.html.twig
new file mode 100644 (file)
index 0000000..2de7cf0
--- /dev/null
@@ -0,0 +1,42 @@
+{% extends "WallabagCoreBundle::layout.html.twig" %}
+
+{% block title %}{{ 'ignore_origin_instance_rule.page_title'|trans }}{% endblock %}
+
+{% block content %}
+
+    <div class="row">
+        <div class="col s12">
+            <div class="card-panel">
+                <div class="row">
+                    <div class="input-field col s12">
+                        <p class="help">{{ 'ignore_origin_instance_rule.description'|trans|raw }}</p>
+
+                        <table class="bordered">
+                            <thead>
+                                <tr>
+                                    <th>{{ 'ignore_origin_instance_rule.form.rule_label'|trans }}</th>
+                                    <th>{{ 'ignore_origin_instance_rule.list.actions'|trans }}</th>
+                                </tr>
+                            </thead>
+                            <tbody>
+                            {% for rule in rules %}
+                                <tr>
+                                    <td>{{ rule.rule }}</td>
+                                    <td>
+                                        <a href="{{ path('ignore_origin_instance_rules_edit', { 'id': rule.id }) }}">{{ 'ignore_origin_instance_rule.list.edit_action'|trans }}</a>
+                                    </td>
+                                </tr>
+                            {% endfor %}
+                            </tbody>
+                        </table>
+                        <br />
+                        <p>
+                            <a href="{{ path('ignore_origin_instance_rules_new') }}" class="waves-effect waves-light btn">{{ 'ignore_origin_instance_rule.list.create_new_one'|trans }}</a>
+                        </p>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+
+{% endblock %}
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/material/IgnoreOriginInstanceRule/new.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/material/IgnoreOriginInstanceRule/new.html.twig
new file mode 100644 (file)
index 0000000..cb052ff
--- /dev/null
@@ -0,0 +1,80 @@
+{% extends "WallabagCoreBundle::layout.html.twig" %}
+
+{% block title %}{{ 'ignore_origin_instance_rule.page_title'|trans }}{% endblock %}
+
+{% block content %}
+
+    <div class="row">
+        <div class="col s12">
+            <div class="card-panel">
+                <div class="row">
+                    <div class="input-field col s12">
+                        <h4>{{ 'ignore_origin_instance_rule.new_ignore_origin_instance_rule'|trans }}</h4>
+
+                        <div id="set6" class="col s12">
+                            {{ form_start(form) }}
+                                {{ form_errors(form) }}
+
+                                <div class="row">
+                                    <div class="input-field col s12">
+                                        {{ form_label(form.rule) }}
+                                        {{ form_errors(form.rule) }}
+                                        {{ form_widget(form.rule) }}
+                                    </div>
+                                </div>
+
+                                {{ form_widget(form.save, {'attr': {'class': 'btn waves-effect waves-light'}}) }}
+                                {{ form_rest(form) }}
+                            </form>
+                            <p><a class="waves-effect waves-light btn blue-grey" href="{{ path('ignore_origin_instance_rules_index') }}">{{ 'ignore_origin_instance_rule.form.back_to_list'|trans }}</a></p>
+                        </div>
+                    </div>
+                </div>
+
+                <div class="row">
+                    <div class="input-field col s12">
+                        <h4>{{ 'config.form_ignore_origin_rules.faq.title'|trans }}</h4>
+
+                        <h5>{{ 'config.form_ignore_origin_rules.faq.ignore_origin_rules_definition_title'|trans }}</h5>
+                        <p class="help">{{ 'config.form_ignore_origin_rules.faq.ignore_origin_rules_definition_description'|trans|raw }}</p>
+
+                        <h5>{{ 'config.form_ignore_origin_rules.faq.how_to_use_them_title'|trans }}</h5>
+                        <p class="help">{{ 'config.form_ignore_origin_rules.faq.how_to_use_them_description'|trans|raw }}</p>
+
+                        <h5>{{ 'config.form_ignore_origin_rules.faq.variables_available_title'|trans }}</h5>
+                        <p class="help">
+                            {{ 'config.form_ignore_origin_rules.faq.variables_available_description'|trans }}
+                        </p>
+
+                        <table class="bordered">
+                            <thead>
+                                <tr>
+                                    <th>{{ 'config.form_ignore_origin_rules.faq.variable_description.label'|trans }}</th>
+                                    <th>{{ 'config.form_ignore_origin_rules.faq.meaning'|trans }}</th>
+                                    <th>{{ 'config.form_ignore_origin_rules.faq.operator_description.label'|trans }}</th>
+                                    <th>{{ 'config.form_ignore_origin_rules.faq.meaning'|trans }}</th>
+                                </tr>
+                            </thead>
+
+                            <tbody>
+                                <tr>
+                                    <td>host</td>
+                                    <td>{{ 'config.form_ignore_origin_rules.faq.variable_description.host'|trans }}</td>
+                                    <td>=</td>
+                                    <td>{{ 'config.form_ignore_origin_rules.faq.operator_description.equal_to'|trans }}</td>
+                                </tr>
+                                <tr>
+                                    <td>_all</td>
+                                    <td>{{ 'config.form_ignore_origin_rules.faq.variable_description._all'|trans }}</td>
+                                    <td>~</td>
+                                    <td>{{ 'config.form_ignore_origin_rules.faq.operator_description.matches'|trans|raw }}</td>
+                                </tr>
+                            </tbody>
+                        </table>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+
+{% endblock %}
index c51d07fc2a64f8e121f34a0b05f743eb9b5f54a3..d9b6d190a188e4a3c0b790788fe36ab25ba9ea50 100644 (file)
                     <a class="waves-effect" href="{{ path('user_index') }}">{{ 'menu.left.users_management'|trans }}</a>
                 </li>
 
-                <li class="bold border-bottom {% if currentRoute == 'craue_config_settings_modify' %}active{% endif %}">
+                <li class="bold {% if currentRoute == 'craue_config_settings_modify' %}active{% endif %}">
                     <a class="waves-effect" href="{{ path('craue_config_settings_modify') }}">{{ 'menu.left.internal_settings'|trans }}</a>
                 </li>
+
+                <li class="bold border-bottom {% if currentRoute == 'ignore_origin_instance_rules_index' %}active{% endif %}">
+                    <a class="waves-effect" href="{{ path('ignore_origin_instance_rules_index') }}">{{ 'menu.left.ignore_origin_instance_rules'|trans }}</a>
+                </li>
             {% endif %}
             <li class="bold {% if currentRoute == 'import' %}active{% endif %}">
                 <a class="waves-effect" href="{{ path('import') }}">{{ 'menu.left.import'|trans }}</a>
index c4bd6dacecbc50d1317e00b30c6939332d01df28..a0e2939cf27528951c955da2a51022af08ce4df9 100644 (file)
@@ -45,6 +45,9 @@ class ReloadEntryCommandTest extends WallabagCoreTestCase
         $this->getEntityManager()->flush();
     }
 
+    /**
+     * @group NetworkCalls
+     */
     public function testRunReloadEntryCommand()
     {
         $application = new Application($this->getClient()->getKernel());
@@ -70,6 +73,9 @@ class ReloadEntryCommandTest extends WallabagCoreTestCase
         $this->assertContains('Done', $tester->getDisplay());
     }
 
+    /**
+     * @group NetworkCalls
+     */
     public function testRunReloadEntryWithUsernameCommand()
     {
         $application = new Application($this->getClient()->getKernel());
index b3b3a19a74a8c43c427d3896c51ec9d7d791717c..92d222679f538daa6f210a8e3c31632c73e9667d 100644 (file)
@@ -435,7 +435,6 @@ class ConfigControllerTest extends WallabagCoreTestCase
     public function testTaggingRuleCreation()
     {
         $this->logInAs('admin');
-        $this->useTheme('baggy');
         $client = $this->getClient();
 
         $crawler = $client->request('GET', '/config');
@@ -457,7 +456,7 @@ class ConfigControllerTest extends WallabagCoreTestCase
 
         $this->assertContains('flashes.config.notice.tagging_rules_updated', $crawler->filter('body')->extract(['_text'])[0]);
 
-        $editLink = $crawler->filter('.mode_edit')->last()->link();
+        $editLink = $crawler->filter('div[id=set5] a.mode_edit')->last()->link();
 
         $crawler = $client->click($editLink);
         $this->assertSame(302, $client->getResponse()->getStatusCode());
@@ -482,7 +481,7 @@ class ConfigControllerTest extends WallabagCoreTestCase
 
         $this->assertContains('readingTime <= 30', $crawler->filter('body')->extract(['_text'])[0]);
 
-        $deleteLink = $crawler->filter('.delete')->last()->link();
+        $deleteLink = $crawler->filter('div[id=set5] a.delete')->last()->link();
 
         $crawler = $client->click($deleteLink);
         $this->assertSame(302, $client->getResponse()->getStatusCode());
@@ -574,11 +573,11 @@ class ConfigControllerTest extends WallabagCoreTestCase
             ->getRepository('WallabagCoreBundle:TaggingRule')
             ->findAll()[0];
 
-        $crawler = $client->request('GET', '/tagging-rule/edit/' . $rule->getId());
+        $crawler = $client->request('GET', '/tagging-rule/delete/' . $rule->getId());
 
         $this->assertSame(403, $client->getResponse()->getStatusCode());
         $this->assertGreaterThan(1, $body = $crawler->filter('body')->extract(['_text']));
-        $this->assertContains('You can not access this tagging rule', $body[0]);
+        $this->assertContains('You can not access this rule', $body[0]);
     }
 
     public function testEditingTaggingRuleFromAnOtherUser()
@@ -594,7 +593,144 @@ class ConfigControllerTest extends WallabagCoreTestCase
 
         $this->assertSame(403, $client->getResponse()->getStatusCode());
         $this->assertGreaterThan(1, $body = $crawler->filter('body')->extract(['_text']));
-        $this->assertContains('You can not access this tagging rule', $body[0]);
+        $this->assertContains('You can not access this rule', $body[0]);
+    }
+
+    public function testIgnoreOriginRuleCreation()
+    {
+        $this->logInAs('admin');
+        $client = $this->getClient();
+
+        $crawler = $client->request('GET', '/config');
+
+        $this->assertSame(200, $client->getResponse()->getStatusCode());
+
+        $form = $crawler->filter('button[id=ignore_origin_user_rule_save]')->form();
+
+        $data = [
+            'ignore_origin_user_rule[rule]' => 'host = "example.com"',
+        ];
+
+        $client->submit($form, $data);
+
+        $this->assertSame(302, $client->getResponse()->getStatusCode());
+
+        $crawler = $client->followRedirect();
+
+        $this->assertContains('flashes.config.notice.ignore_origin_rules_updated', $crawler->filter('body')->extract(['_text'])[0]);
+
+        $editLink = $crawler->filter('div[id=set6] a.mode_edit')->last()->link();
+
+        $crawler = $client->click($editLink);
+        $this->assertSame(302, $client->getResponse()->getStatusCode());
+        $this->assertContains('?ignore-origin-user-rule=', $client->getResponse()->headers->get('location'));
+
+        $crawler = $client->followRedirect();
+
+        $form = $crawler->filter('button[id=ignore_origin_user_rule_save]')->form();
+
+        $data = [
+            'ignore_origin_user_rule[rule]' => 'host = "example.org"',
+        ];
+
+        $client->submit($form, $data);
+
+        $this->assertSame(302, $client->getResponse()->getStatusCode());
+
+        $crawler = $client->followRedirect();
+
+        $this->assertContains('flashes.config.notice.ignore_origin_rules_updated', $crawler->filter('body')->extract(['_text'])[0]);
+
+        $this->assertContains('host = "example.org"', $crawler->filter('body')->extract(['_text'])[0]);
+
+        $deleteLink = $crawler->filter('div[id=set6] a.delete')->last()->link();
+
+        $crawler = $client->click($deleteLink);
+        $this->assertSame(302, $client->getResponse()->getStatusCode());
+
+        $crawler = $client->followRedirect();
+        $this->assertContains('flashes.config.notice.ignore_origin_rules_deleted', $crawler->filter('body')->extract(['_text'])[0]);
+    }
+
+    public function dataForIgnoreOriginRuleCreationFail()
+    {
+        return [
+            [
+                [
+                    'ignore_origin_user_rule[rule]' => 'foo = "bar"',
+                ],
+                [
+                    'The variable',
+                    'does not exist.',
+                ],
+            ],
+            [
+                [
+                    'ignore_origin_user_rule[rule]' => '_all != "none"',
+                ],
+                [
+                    'The operator',
+                    'does not exist.',
+                ],
+            ],
+        ];
+    }
+
+    /**
+     * @dataProvider dataForIgnoreOriginRuleCreationFail
+     */
+    public function testIgnoreOriginRuleCreationFail($data, $messages)
+    {
+        $this->logInAs('admin');
+        $client = $this->getClient();
+
+        $crawler = $client->request('GET', '/config');
+
+        $this->assertSame(200, $client->getResponse()->getStatusCode());
+
+        $form = $crawler->filter('button[id=ignore_origin_user_rule_save]')->form();
+
+        $crawler = $client->submit($form, $data);
+
+        $this->assertSame(200, $client->getResponse()->getStatusCode());
+
+        $this->assertGreaterThan(1, $body = $crawler->filter('body')->extract(['_text']));
+
+        foreach ($messages as $message) {
+            $this->assertContains($message, $body[0]);
+        }
+    }
+
+    public function testDeletingIgnoreOriginRuleFromAnOtherUser()
+    {
+        $this->logInAs('bob');
+        $client = $this->getClient();
+
+        $rule = $client->getContainer()->get('doctrine.orm.entity_manager')
+            ->getRepository('WallabagCoreBundle:IgnoreOriginUserRule')
+            ->findAll()[0];
+
+        $crawler = $client->request('GET', '/ignore-origin-user-rule/edit/' . $rule->getId());
+
+        $this->assertSame(403, $client->getResponse()->getStatusCode());
+        $this->assertGreaterThan(1, $body = $crawler->filter('body')->extract(['_text']));
+        $this->assertContains('You can not access this rule', $body[0]);
+    }
+
+    public function testEditingIgnoreOriginRuleFromAnOtherUser()
+    {
+        $this->logInAs('bob');
+        $client = $this->getClient();
+
+        $rule = $client->getContainer()->get('doctrine.orm.entity_manager')
+            ->getRepository('WallabagCoreBundle:IgnoreOriginUserRule')
+            ->findAll()[0];
+
+        $crawler = $client->request('GET', '/ignore-origin-user-rule/edit/' . $rule->getId());
+
+        $this->assertSame(403, $client->getResponse()->getStatusCode());
+        $this->assertGreaterThan(1, $body = $crawler->filter('body')->extract(['_text']));
+        $this->assertContains('You can not access this rule', $body[0]);
     }
 
     public function testDemoMode()
@@ -676,6 +812,9 @@ class ConfigControllerTest extends WallabagCoreTestCase
         $em->flush();
     }
 
+    /**
+     * @group NetworkCalls
+     */
     public function testDeleteAccount()
     {
         $client = $this->getClient();
index 5b80683078d9a101aff1b6b0ee098e60ad952526..0aa562d80787e772ee1910391ca9b68fc6a26245 100644 (file)
@@ -40,6 +40,9 @@ class EntryControllerTest extends WallabagCoreTestCase
         $this->assertContains('login', $client->getResponse()->headers->get('location'));
     }
 
+    /**
+     * @group NetworkCalls
+     */
     public function testQuickstart()
     {
         $this->logInAs('empty');
@@ -87,6 +90,9 @@ class EntryControllerTest extends WallabagCoreTestCase
         $this->assertCount(1, $crawler->filter('form[name=entry]'));
     }
 
+    /**
+     * @group NetworkCalls
+     */
     public function testPostNewViaBookmarklet()
     {
         $this->logInAs('admin');
@@ -131,7 +137,7 @@ class EntryControllerTest extends WallabagCoreTestCase
     }
 
     /**
-     * This test will require an internet connection.
+     * @group NetworkCalls
      */
     public function testPostNewOk()
     {
@@ -169,6 +175,9 @@ class EntryControllerTest extends WallabagCoreTestCase
         $client->getContainer()->get('craue_config')->set('store_article_headers', 0);
     }
 
+    /**
+     * @group NetworkCalls
+     */
     public function testPostWithMultipleAuthors()
     {
         $url = 'https://www.liberation.fr/planete/2017/04/05/donald-trump-et-xi-jinping-tentative-de-flirt-en-floride_1560768';
@@ -229,6 +238,9 @@ class EntryControllerTest extends WallabagCoreTestCase
         $this->assertContains('/view/', $client->getResponse()->getTargetUrl());
     }
 
+    /**
+     * @group NetworkCalls
+     */
     public function testPostNewOkUrlExistWithAccent()
     {
         $this->logInAs('admin');
@@ -265,7 +277,7 @@ class EntryControllerTest extends WallabagCoreTestCase
     }
 
     /**
-     * This test will require an internet connection.
+     * @group NetworkCalls
      */
     public function testPostNewOkUrlExistWithRedirection()
     {
@@ -303,7 +315,7 @@ class EntryControllerTest extends WallabagCoreTestCase
     }
 
     /**
-     * This test will require an internet connection.
+     * @group NetworkCalls
      */
     public function testPostNewThatWillBeTagged()
     {
@@ -430,7 +442,7 @@ class EntryControllerTest extends WallabagCoreTestCase
     }
 
     /**
-     * This test will require an internet connection.
+     * @group NetworkCalls
      */
     public function testReload()
     {
@@ -1056,6 +1068,9 @@ class EntryControllerTest extends WallabagCoreTestCase
         $this->assertSame(404, $client->getResponse()->getStatusCode());
     }
 
+    /**
+     * @group NetworkCalls
+     */
     public function testNewEntryWithDownloadImagesEnabled()
     {
         $this->downloadImagesEnabled = true;
@@ -1383,6 +1398,7 @@ class EntryControllerTest extends WallabagCoreTestCase
 
     /**
      * @dataProvider dataForLanguage
+     * @group NetworkCalls
      */
     public function testLanguageValidation($url, $expectedLanguage)
     {
@@ -1414,7 +1430,7 @@ class EntryControllerTest extends WallabagCoreTestCase
     }
 
     /**
-     * This test will require an internet connection.
+     * @group NetworkCalls
      */
     public function testRestrictedArticle()
     {
diff --git a/tests/Wallabag/CoreBundle/Controller/IgnoreOriginInstanceRuleControllerTest.php b/tests/Wallabag/CoreBundle/Controller/IgnoreOriginInstanceRuleControllerTest.php
new file mode 100644 (file)
index 0000000..9783cd2
--- /dev/null
@@ -0,0 +1,148 @@
+<?php
+
+namespace Tests\Wallabag\CoreBundle\Controller;
+
+use Tests\Wallabag\CoreBundle\WallabagCoreTestCase;
+
+class IgnoreOriginInstanceRuleControllerTest extends WallabagCoreTestCase
+{
+    public function testListIgnoreOriginInstanceRule()
+    {
+        $this->logInAs('admin');
+        $client = $this->getClient();
+
+        $crawler = $client->request('GET', '/ignore-origin-instance-rules/');
+
+        $this->assertSame(200, $client->getResponse()->getStatusCode());
+
+        $body = $crawler->filter('body')->extract(['_text'])[0];
+
+        $this->assertContains('ignore_origin_instance_rule.description', $body);
+        $this->assertContains('ignore_origin_instance_rule.list.create_new_one', $body);
+    }
+
+    public function testIgnoreOriginInstanceRuleCreationEditionDeletion()
+    {
+        $this->logInAs('admin');
+        $client = $this->getClient();
+
+        // Creation
+        $crawler = $client->request('GET', '/ignore-origin-instance-rules/new');
+
+        $this->assertSame(200, $client->getResponse()->getStatusCode());
+
+        $body = $crawler->filter('body')->extract(['_text'])[0];
+
+        $this->assertContains('ignore_origin_instance_rule.new_ignore_origin_instance_rule', $body);
+        $this->assertContains('ignore_origin_instance_rule.form.back_to_list', $body);
+
+        $form = $crawler->filter('button[id=ignore_origin_instance_rule_save]')->form();
+
+        $data = [
+            'ignore_origin_instance_rule[rule]' => 'host = "foo.example.com"',
+        ];
+
+        $client->submit($form, $data);
+
+        $this->assertSame(302, $client->getResponse()->getStatusCode());
+
+        $crawler = $client->followRedirect();
+
+        $this->assertContains('flashes.ignore_origin_instance_rule.notice.added', $crawler->filter('body')->extract(['_text'])[0]);
+
+        // Edition
+        $editLink = $crawler->filter('div[id=content] table a')->last()->link();
+
+        $crawler = $client->click($editLink);
+
+        $this->assertSame(200, $client->getResponse()->getStatusCode());
+
+        $this->assertContains('foo.example.com', $crawler->filter('form[name=ignore_origin_instance_rule] input[type=text]')->extract(['value'])[0]);
+
+        $body = $crawler->filter('body')->extract(['_text'])[0];
+
+        $this->assertContains('ignore_origin_instance_rule.edit_ignore_origin_instance_rule', $body);
+        $this->assertContains('ignore_origin_instance_rule.form.back_to_list', $body);
+
+        $form = $crawler->filter('button[id=ignore_origin_instance_rule_save]')->form();
+
+        $data = [
+            'ignore_origin_instance_rule[rule]' => 'host = "bar.example.com"',
+        ];
+
+        $client->submit($form, $data);
+
+        $this->assertSame(302, $client->getResponse()->getStatusCode());
+
+        $crawler = $client->followRedirect();
+
+        $this->assertContains('flashes.ignore_origin_instance_rule.notice.updated', $crawler->filter('body')->extract(['_text'])[0]);
+
+        $editLink = $crawler->filter('div[id=content] table a')->last()->link();
+
+        $crawler = $client->click($editLink);
+
+        $this->assertSame(200, $client->getResponse()->getStatusCode());
+
+        $this->assertContains('bar.example.com', $crawler->filter('form[name=ignore_origin_instance_rule] input[type=text]')->extract(['value'])[0]);
+
+        $deleteForm = $crawler->filter('body')->selectButton('ignore_origin_instance_rule.form.delete')->form();
+
+        $client->submit($deleteForm, []);
+
+        $this->assertSame(302, $client->getResponse()->getStatusCode());
+
+        $crawler = $client->followRedirect();
+
+        $this->assertContains('flashes.ignore_origin_instance_rule.notice.deleted', $crawler->filter('body')->extract(['_text'])[0]);
+    }
+
+    public function dataForIgnoreOriginInstanceRuleCreationFail()
+    {
+        return [
+            [
+                [
+                    'ignore_origin_instance_rule[rule]' => 'foo = "bar"',
+                ],
+                [
+                    'The variable',
+                    'does not exist.',
+                ],
+            ],
+            [
+                [
+                    'ignore_origin_instance_rule[rule]' => '_all != "none"',
+                ],
+                [
+                    'The operator',
+                    'does not exist.',
+                ],
+            ],
+        ];
+    }
+
+    /**
+     * @dataProvider dataForIgnoreOriginInstanceRuleCreationFail
+     */
+    public function testIgnoreOriginInstanceRuleCreationFail($data, $messages)
+    {
+        $this->logInAs('admin');
+        $client = $this->getClient();
+
+        $crawler = $client->request('GET', '/ignore-origin-instance-rules/new');
+
+        $this->assertSame(200, $client->getResponse()->getStatusCode());
+
+        $form = $crawler->filter('button[id=ignore_origin_instance_rule_save]')->form();
+
+        $crawler = $client->submit($form, $data);
+
+        $this->assertSame(200, $client->getResponse()->getStatusCode());
+
+        $this->assertGreaterThan(1, $body = $crawler->filter('body')->extract(['_text']));
+
+        foreach ($messages as $message) {
+            $this->assertContains($message, $body[0]);
+        }
+    }
+}
index 9ce72c79c1277ec08ded6eb7f3d8b4265cc4fdf7..a65ac17cf81d8bbe781cc9366514051a3dac8991 100644 (file)
@@ -12,6 +12,7 @@ use Symfony\Component\Validator\ConstraintViolationList;
 use Symfony\Component\Validator\Validator\RecursiveValidator;
 use Wallabag\CoreBundle\Entity\Entry;
 use Wallabag\CoreBundle\Helper\ContentProxy;
+use Wallabag\CoreBundle\Helper\RuleBasedIgnoreOriginProcessor;
 use Wallabag\CoreBundle\Helper\RuleBasedTagger;
 use Wallabag\UserBundle\Entity\User;
 
@@ -25,6 +26,8 @@ class ContentProxyTest extends TestCase
         $tagger->expects($this->once())
             ->method('tag');
 
+        $ruleBasedIgnoreOriginProcessor = $this->getRuleBasedIgnoreOriginProcessorMock();
+
         $graby = $this->getMockBuilder('Graby\Graby')
             ->setMethods(['fetchContent'])
             ->disableOriginalConstructor()
@@ -42,7 +45,7 @@ class ContentProxyTest extends TestCase
                 'language' => '',
             ]);
 
-        $proxy = new ContentProxy($graby, $tagger, $this->getValidator(), $this->getLogger(), $this->fetchingErrorMessage);
+        $proxy = new ContentProxy($graby, $tagger, $ruleBasedIgnoreOriginProcessor, $this->getValidator(), $this->getLogger(), $this->fetchingErrorMessage);
         $entry = new Entry(new User());
         $proxy->updateEntry($entry, 'http://user@:80');
 
@@ -62,6 +65,8 @@ class ContentProxyTest extends TestCase
         $tagger->expects($this->once())
             ->method('tag');
 
+        $ruleBasedIgnoreOriginProcessor = $this->getRuleBasedIgnoreOriginProcessorMock();
+
         $graby = $this->getMockBuilder('Graby\Graby')
             ->setMethods(['fetchContent'])
             ->disableOriginalConstructor()
@@ -79,7 +84,7 @@ class ContentProxyTest extends TestCase
                 'language' => '',
             ]);
 
-        $proxy = new ContentProxy($graby, $tagger, $this->getValidator(), $this->getLogger(), $this->fetchingErrorMessage);
+        $proxy = new ContentProxy($graby, $tagger, $ruleBasedIgnoreOriginProcessor, $this->getValidator(), $this->getLogger(), $this->fetchingErrorMessage);
         $entry = new Entry(new User());
         $proxy->updateEntry($entry, 'http://0.0.0.0');
 
@@ -99,6 +104,8 @@ class ContentProxyTest extends TestCase
         $tagger->expects($this->once())
             ->method('tag');
 
+        $ruleBasedIgnoreOriginProcessor = $this->getRuleBasedIgnoreOriginProcessorMock();
+
         $graby = $this->getMockBuilder('Graby\Graby')
             ->setMethods(['fetchContent'])
             ->disableOriginalConstructor()
@@ -118,7 +125,7 @@ class ContentProxyTest extends TestCase
                 'description' => 'desc',
             ]);
 
-        $proxy = new ContentProxy($graby, $tagger, $this->getValidator(), $this->getLogger(), $this->fetchingErrorMessage);
+        $proxy = new ContentProxy($graby, $tagger, $ruleBasedIgnoreOriginProcessor, $this->getValidator(), $this->getLogger(), $this->fetchingErrorMessage);
         $entry = new Entry(new User());
         $proxy->updateEntry($entry, 'http://domain.io');
 
@@ -139,6 +146,10 @@ class ContentProxyTest extends TestCase
         $tagger->expects($this->once())
             ->method('tag');
 
+        $ruleBasedIgnoreOriginProcessor = $this->getRuleBasedIgnoreOriginProcessorMock();
+        $ruleBasedIgnoreOriginProcessor->expects($this->once())
+            ->method('process');
+
         $graby = $this->getMockBuilder('Graby\Graby')
             ->setMethods(['fetchContent'])
             ->disableOriginalConstructor()
@@ -159,7 +170,7 @@ class ContentProxyTest extends TestCase
                 ],
             ]);
 
-        $proxy = new ContentProxy($graby, $tagger, $this->getValidator(), $this->getLogger(), $this->fetchingErrorMessage);
+        $proxy = new ContentProxy($graby, $tagger, $ruleBasedIgnoreOriginProcessor, $this->getValidator(), $this->getLogger(), $this->fetchingErrorMessage);
         $entry = new Entry(new User());
         $proxy->updateEntry($entry, 'http://0.0.0.0');
 
@@ -180,6 +191,10 @@ class ContentProxyTest extends TestCase
         $tagger->expects($this->once())
             ->method('tag');
 
+        $ruleBasedIgnoreOriginProcessor = $this->getRuleBasedIgnoreOriginProcessorMock();
+        $ruleBasedIgnoreOriginProcessor->expects($this->once())
+            ->method('process');
+
         $graby = $this->getMockBuilder('Graby\Graby')
             ->setMethods(['fetchContent'])
             ->disableOriginalConstructor()
@@ -200,7 +215,7 @@ class ContentProxyTest extends TestCase
                 ],
             ]);
 
-        $proxy = new ContentProxy($graby, $tagger, $this->getValidator(), $this->getLogger(), $this->fetchingErrorMessage);
+        $proxy = new ContentProxy($graby, $tagger, $ruleBasedIgnoreOriginProcessor, $this->getValidator(), $this->getLogger(), $this->fetchingErrorMessage);
         $entry = new Entry(new User());
         $proxy->updateEntry($entry, 'http://0.0.0.0');
 
@@ -221,6 +236,10 @@ class ContentProxyTest extends TestCase
         $tagger->expects($this->once())
             ->method('tag');
 
+        $ruleBasedIgnoreOriginProcessor = $this->getRuleBasedIgnoreOriginProcessorMock();
+        $ruleBasedIgnoreOriginProcessor->expects($this->once())
+            ->method('process');
+
         $graby = $this->getMockBuilder('Graby\Graby')
             ->setMethods(['fetchContent'])
             ->disableOriginalConstructor()
@@ -240,7 +259,7 @@ class ContentProxyTest extends TestCase
                 'image' => null,
             ]);
 
-        $proxy = new ContentProxy($graby, $tagger, $this->getValidator(), $this->getLogger(), $this->fetchingErrorMessage);
+        $proxy = new ContentProxy($graby, $tagger, $ruleBasedIgnoreOriginProcessor, $this->getValidator(), $this->getLogger(), $this->fetchingErrorMessage);
         $entry = new Entry(new User());
         $proxy->updateEntry($entry, 'http://0.0.0.0');
 
@@ -261,6 +280,10 @@ class ContentProxyTest extends TestCase
         $tagger->expects($this->once())
             ->method('tag');
 
+        $ruleBasedIgnoreOriginProcessor = $this->getRuleBasedIgnoreOriginProcessorMock();
+        $ruleBasedIgnoreOriginProcessor->expects($this->once())
+            ->method('process');
+
         $graby = $this->getMockBuilder('Graby\Graby')
             ->setMethods(['fetchContent'])
             ->disableOriginalConstructor()
@@ -280,7 +303,7 @@ class ContentProxyTest extends TestCase
                 'image' => 'http://3.3.3.3/cover.jpg',
             ]);
 
-        $proxy = new ContentProxy($graby, $tagger, $this->getValidator(), $this->getLogger(), $this->fetchingErrorMessage);
+        $proxy = new ContentProxy($graby, $tagger, $ruleBasedIgnoreOriginProcessor, $this->getValidator(), $this->getLogger(), $this->fetchingErrorMessage);
         $entry = new Entry(new User());
         $proxy->updateEntry($entry, 'http://0.0.0.0');
 
@@ -301,6 +324,10 @@ class ContentProxyTest extends TestCase
         $tagger->expects($this->once())
             ->method('tag');
 
+        $ruleBasedIgnoreOriginProcessor = $this->getRuleBasedIgnoreOriginProcessorMock();
+        $ruleBasedIgnoreOriginProcessor->expects($this->once())
+            ->method('process');
+
         $validator = $this->getValidator(false);
         $validator->expects($this->once())
             ->method('validate')
@@ -324,7 +351,7 @@ class ContentProxyTest extends TestCase
                 ],
             ]);
 
-        $proxy = new ContentProxy($graby, $tagger, $validator, $this->getLogger(), $this->fetchingErrorMessage);
+        $proxy = new ContentProxy($graby, $tagger, $ruleBasedIgnoreOriginProcessor, $validator, $this->getLogger(), $this->fetchingErrorMessage);
         $entry = new Entry(new User());
         $proxy->updateEntry($entry, 'http://0.0.0.0');
 
@@ -344,6 +371,10 @@ class ContentProxyTest extends TestCase
         $tagger->expects($this->once())
             ->method('tag');
 
+        $ruleBasedIgnoreOriginProcessor = $this->getRuleBasedIgnoreOriginProcessorMock();
+        $ruleBasedIgnoreOriginProcessor->expects($this->once())
+            ->method('process');
+
         $validator = $this->getValidator(false);
         $validator->expects($this->exactly(2))
             ->method('validate')
@@ -372,7 +403,7 @@ class ContentProxyTest extends TestCase
                 'image' => 'https://',
             ]);
 
-        $proxy = new ContentProxy($graby, $tagger, $validator, $this->getLogger(), $this->fetchingErrorMessage);
+        $proxy = new ContentProxy($graby, $tagger, $ruleBasedIgnoreOriginProcessor, $validator, $this->getLogger(), $this->fetchingErrorMessage);
         $entry = new Entry(new User());
         $proxy->updateEntry($entry, 'http://0.0.0.0');
 
@@ -393,7 +424,11 @@ class ContentProxyTest extends TestCase
         $tagger->expects($this->once())
             ->method('tag');
 
-        $proxy = new ContentProxy((new Graby()), $tagger, $this->getValidator(), $this->getLogger(), $this->fetchingErrorMessage, true);
+        $ruleBasedIgnoreOriginProcessor = $this->getRuleBasedIgnoreOriginProcessorMock();
+        $ruleBasedIgnoreOriginProcessor->expects($this->once())
+            ->method('process');
+
+        $proxy = new ContentProxy((new Graby()), $tagger, $ruleBasedIgnoreOriginProcessor, $this->getValidator(), $this->getLogger(), $this->fetchingErrorMessage, true);
         $entry = new Entry(new User());
         $proxy->updateEntry(
             $entry,
@@ -433,10 +468,12 @@ class ContentProxyTest extends TestCase
         $tagger->expects($this->once())
             ->method('tag');
 
+        $ruleBasedIgnoreOriginProcessor = $this->getRuleBasedIgnoreOriginProcessorMock();
+
         $logHandler = new TestHandler();
         $logger = new Logger('test', [$logHandler]);
 
-        $proxy = new ContentProxy((new Graby()), $tagger, $this->getValidator(), $logger, $this->fetchingErrorMessage);
+        $proxy = new ContentProxy((new Graby()), $tagger, $ruleBasedIgnoreOriginProcessor, $this->getValidator(), $logger, $this->fetchingErrorMessage);
         $entry = new Entry(new User());
         $proxy->updateEntry(
             $entry,
@@ -469,11 +506,13 @@ class ContentProxyTest extends TestCase
         $tagger->expects($this->once())
             ->method('tag');
 
+        $ruleBasedIgnoreOriginProcessor = $this->getRuleBasedIgnoreOriginProcessorMock();
+
         $logger = new Logger('foo');
         $handler = new TestHandler();
         $logger->pushHandler($handler);
 
-        $proxy = new ContentProxy((new Graby()), $tagger, $this->getValidator(), $logger, $this->fetchingErrorMessage);
+        $proxy = new ContentProxy((new Graby()), $tagger, $ruleBasedIgnoreOriginProcessor, $this->getValidator(), $logger, $this->fetchingErrorMessage);
         $entry = new Entry(new User());
         $proxy->updateEntry(
             $entry,
@@ -512,7 +551,9 @@ class ContentProxyTest extends TestCase
             ->method('tag')
             ->will($this->throwException(new \Exception()));
 
-        $proxy = new ContentProxy((new Graby()), $tagger, $this->getValidator(), $this->getLogger(), $this->fetchingErrorMessage);
+        $ruleBasedIgnoreOriginProcessor = $this->getRuleBasedIgnoreOriginProcessorMock();
+
+        $proxy = new ContentProxy((new Graby()), $tagger, $ruleBasedIgnoreOriginProcessor, $this->getValidator(), $this->getLogger(), $this->fetchingErrorMessage);
         $entry = new Entry(new User());
         $proxy->updateEntry(
             $entry,
@@ -554,7 +595,9 @@ class ContentProxyTest extends TestCase
         $tagger->expects($this->once())
             ->method('tag');
 
-        $proxy = new ContentProxy((new Graby()), $tagger, $this->getValidator(), $this->getLogger(), $this->fetchingErrorMessage);
+        $ruleBasedIgnoreOriginProcessor = $this->getRuleBasedIgnoreOriginProcessorMock();
+
+        $proxy = new ContentProxy((new Graby()), $tagger, $ruleBasedIgnoreOriginProcessor, $this->getValidator(), $this->getLogger(), $this->fetchingErrorMessage);
         $entry = new Entry(new User());
         $proxy->updateEntry(
             $entry,
@@ -590,6 +633,8 @@ class ContentProxyTest extends TestCase
         $tagger->expects($this->once())
             ->method('tag');
 
+        $ruleBasedIgnoreOriginProcessor = $this->getRuleBasedIgnoreOriginProcessorMock();
+
         $graby = $this->getMockBuilder('Graby\Graby')
             ->setMethods(['fetchContent'])
             ->disableOriginalConstructor()
@@ -607,7 +652,7 @@ class ContentProxyTest extends TestCase
                 ],
             ]);
 
-        $proxy = new ContentProxy($graby, $tagger, $this->getValidator(), $this->getLogger(), $this->fetchingErrorMessage);
+        $proxy = new ContentProxy($graby, $tagger, $ruleBasedIgnoreOriginProcessor, $this->getValidator(), $this->getLogger(), $this->fetchingErrorMessage);
         $entry = new Entry(new User());
         $proxy->updateEntry($entry, 'http://0.0.0.0');
 
@@ -631,6 +676,8 @@ class ContentProxyTest extends TestCase
         $tagger->expects($this->once())
             ->method('tag');
 
+        $ruleBasedIgnoreOriginProcessor = $this->getRuleBasedIgnoreOriginProcessorMock();
+
         $graby = $this->getMockBuilder('Graby\Graby')
             ->setMethods(['fetchContent'])
             ->disableOriginalConstructor()
@@ -648,7 +695,7 @@ class ContentProxyTest extends TestCase
                 'language' => '',
             ]);
 
-        $proxy = new ContentProxy($graby, $tagger, $this->getValidator(), $this->getLogger(), $this->fetchingErrorMessage);
+        $proxy = new ContentProxy($graby, $tagger, $ruleBasedIgnoreOriginProcessor, $this->getValidator(), $this->getLogger(), $this->fetchingErrorMessage);
         $entry = new Entry(new User());
         $proxy->updateEntry($entry, 'http://0.0.0.0');
 
@@ -668,6 +715,8 @@ class ContentProxyTest extends TestCase
         $tagger->expects($this->once())
             ->method('tag');
 
+        $ruleBasedIgnoreOriginProcessor = $this->getRuleBasedIgnoreOriginProcessorMock();
+
         $graby = $this->getMockBuilder('Graby\Graby')
             ->setMethods(['fetchContent'])
             ->disableOriginalConstructor()
@@ -685,7 +734,7 @@ class ContentProxyTest extends TestCase
                 'language' => '',
             ]);
 
-        $proxy = new ContentProxy($graby, $tagger, $this->getValidator(), $this->getLogger(), $this->fetchingErrorMessage);
+        $proxy = new ContentProxy($graby, $tagger, $ruleBasedIgnoreOriginProcessor, $this->getValidator(), $this->getLogger(), $this->fetchingErrorMessage);
         $entry = new Entry(new User());
         $proxy->updateEntry($entry, 'http://0.0.0.0');
 
@@ -704,6 +753,8 @@ class ContentProxyTest extends TestCase
         $tagger->expects($this->once())
             ->method('tag');
 
+        $ruleBasedIgnoreOriginProcessor = $this->getRuleBasedIgnoreOriginProcessorMock();
+
         $graby = $this->getMockBuilder('Graby\Graby')
             ->setMethods(['fetchContent'])
             ->disableOriginalConstructor()
@@ -721,7 +772,7 @@ class ContentProxyTest extends TestCase
                 'language' => '',
             ]);
 
-        $proxy = new ContentProxy($graby, $tagger, $this->getValidator(), $this->getLogger(), $this->fetchingErrorMessage);
+        $proxy = new ContentProxy($graby, $tagger, $ruleBasedIgnoreOriginProcessor, $this->getValidator(), $this->getLogger(), $this->fetchingErrorMessage);
         $entry = new Entry(new User());
         $proxy->updateEntry($entry, 'http://0.0.0.0');
 
@@ -740,6 +791,8 @@ class ContentProxyTest extends TestCase
         $tagger->expects($this->once())
             ->method('tag');
 
+        $ruleBasedIgnoreOriginProcessor = $this->getRuleBasedIgnoreOriginProcessorMock();
+
         $graby = $this->getMockBuilder('Graby\Graby')
             ->setMethods(['fetchContent'])
             ->disableOriginalConstructor()
@@ -757,7 +810,7 @@ class ContentProxyTest extends TestCase
                 'language' => '',
             ]);
 
-        $proxy = new ContentProxy($graby, $tagger, $this->getValidator(), $this->getLogger(), $this->fetchingErrorMessage);
+        $proxy = new ContentProxy($graby, $tagger, $ruleBasedIgnoreOriginProcessor, $this->getValidator(), $this->getLogger(), $this->fetchingErrorMessage);
         $entry = new Entry(new User());
         $proxy->updateEntry($entry, 'http://0.0.0.0');
 
@@ -776,6 +829,8 @@ class ContentProxyTest extends TestCase
         $tagger->expects($this->once())
             ->method('tag');
 
+        $ruleBasedIgnoreOriginProcessor = $this->getRuleBasedIgnoreOriginProcessorMock();
+
         $graby = $this->getMockBuilder('Graby\Graby')
             ->setMethods(['fetchContent'])
             ->disableOriginalConstructor()
@@ -793,7 +848,7 @@ class ContentProxyTest extends TestCase
                 'language' => '',
             ]);
 
-        $proxy = new ContentProxy($graby, $tagger, $this->getValidator(), $this->getLogger(), $this->fetchingErrorMessage);
+        $proxy = new ContentProxy($graby, $tagger, $ruleBasedIgnoreOriginProcessor, $this->getValidator(), $this->getLogger(), $this->fetchingErrorMessage);
         $entry = new Entry(new User());
         $proxy->updateEntry($entry, 'http://0.0.0.0');
 
@@ -813,6 +868,8 @@ class ContentProxyTest extends TestCase
         $tagger->expects($this->once())
             ->method('tag');
 
+        $ruleBasedIgnoreOriginProcessor = $this->getRuleBasedIgnoreOriginProcessorMock();
+
         $graby = $this->getMockBuilder('Graby\Graby')
             ->setMethods(['fetchContent'])
             ->disableOriginalConstructor()
@@ -830,7 +887,7 @@ class ContentProxyTest extends TestCase
                 'language' => '',
             ]);
 
-        $proxy = new ContentProxy($graby, $tagger, $this->getValidator(), $this->getLogger(), $this->fetchingErrorMessage);
+        $proxy = new ContentProxy($graby, $tagger, $ruleBasedIgnoreOriginProcessor, $this->getValidator(), $this->getLogger(), $this->fetchingErrorMessage);
         $entry = new Entry(new User());
         $proxy->updateEntry($entry, 'http://0.0.0.0');
 
@@ -850,6 +907,7 @@ class ContentProxyTest extends TestCase
      * $expected_entry_url
      * $expected_origin_url
      * $expected_domain
+     * $processor_result
      */
     public function dataForChangedUrl()
     {
@@ -861,6 +919,7 @@ class ContentProxyTest extends TestCase
                 'http://1.1.1.1',
                 'http://0.0.0.0',
                 '1.1.1.1',
+                false,
             ],
             'origin already set' => [
                 'http://0.0.0.0',
@@ -869,6 +928,7 @@ class ContentProxyTest extends TestCase
                 'http://1.1.1.1',
                 'http://hello',
                 '1.1.1.1',
+                false,
             ],
             'trailing slash' => [
                 'https://example.com/hello-world',
@@ -877,6 +937,7 @@ class ContentProxyTest extends TestCase
                 'https://example.com/hello-world/',
                 null,
                 'example.com',
+                false,
             ],
             'query string in fetched content' => [
                 'https://example.org/hello',
@@ -885,6 +946,7 @@ class ContentProxyTest extends TestCase
                 'https://example.org/hello?world=1',
                 'https://example.org/hello',
                 'example.org',
+                false,
             ],
             'fragment in fetched content' => [
                 'https://example.org/hello',
@@ -893,6 +955,7 @@ class ContentProxyTest extends TestCase
                 'https://example.org/hello',
                 null,
                 'example.org',
+                false,
             ],
             'fragment and query string in fetched content' => [
                 'https://example.org/hello',
@@ -901,6 +964,7 @@ class ContentProxyTest extends TestCase
                 'https://example.org/hello?foo#world',
                 'https://example.org/hello',
                 'example.org',
+                false,
             ],
             'different path and query string in fetch content' => [
                 'https://example.org/hello',
@@ -909,6 +973,7 @@ class ContentProxyTest extends TestCase
                 'https://example.org/world?foo',
                 'https://example.org/hello',
                 'example.org',
+                false,
             ],
             'feedproxy ignore list test' => [
                 'http://feedproxy.google.com/~r/Wallabag/~3/helloworld',
@@ -917,6 +982,7 @@ class ContentProxyTest extends TestCase
                 'https://example.org/hello-wallabag',
                 null,
                 'example.org',
+                true,
             ],
             'feedproxy ignore list test with origin url already set' => [
                 'http://feedproxy.google.com/~r/Wallabag/~3/helloworld',
@@ -925,6 +991,7 @@ class ContentProxyTest extends TestCase
                 'https://example.org/hello-wallabag',
                 'https://example.org/this-is-source',
                 'example.org',
+                true,
             ],
             'lemonde ignore pattern test' => [
                 'http://www.lemonde.fr/tiny/url',
@@ -933,6 +1000,7 @@ class ContentProxyTest extends TestCase
                 'http://example.com/hello-world',
                 null,
                 'example.com',
+                true,
             ],
         ];
     }
@@ -940,13 +1008,18 @@ class ContentProxyTest extends TestCase
     /**
      * @dataProvider dataForChangedUrl
      */
-    public function testWithChangedUrl($entry_url, $origin_url, $content_url, $expected_entry_url, $expected_origin_url, $expected_domain)
+    public function testWithChangedUrl($entry_url, $origin_url, $content_url, $expected_entry_url, $expected_origin_url, $expected_domain, $processor_result)
     {
         $tagger = $this->getTaggerMock();
         $tagger->expects($this->once())
             ->method('tag');
 
-        $proxy = new ContentProxy((new Graby()), $tagger, $this->getValidator(), $this->getLogger(), $this->fetchingErrorMessage, true);
+        $ruleBasedIgnoreOriginProcessor = $this->getRuleBasedIgnoreOriginProcessorMock();
+        $ruleBasedIgnoreOriginProcessor->expects($this->once())
+            ->method('process')
+            ->willReturn($processor_result);
+
+        $proxy = new ContentProxy((new Graby()), $tagger, $ruleBasedIgnoreOriginProcessor, $this->getValidator(), $this->getLogger(), $this->fetchingErrorMessage, true);
         $entry = new Entry(new User());
         $entry->setOriginUrl($origin_url);
         $proxy->updateEntry(
@@ -1015,6 +1088,14 @@ class ContentProxyTest extends TestCase
             ->getMock();
     }
 
+    private function getRuleBasedIgnoreOriginProcessorMock()
+    {
+        return $this->getMockBuilder(RuleBasedIgnoreOriginProcessor::class)
+            ->setMethods(['process'])
+            ->disableOriginalConstructor()
+            ->getMock();
+    }
+
     private function getLogger()
     {
         return new NullLogger();
diff --git a/tests/Wallabag/CoreBundle/Helper/RuleBasedIgnoreOriginProcessorTest.php b/tests/Wallabag/CoreBundle/Helper/RuleBasedIgnoreOriginProcessorTest.php
new file mode 100644 (file)
index 0000000..9e39bc8
--- /dev/null
@@ -0,0 +1,212 @@
+<?php
+
+namespace Tests\Wallabag\CoreBundle\Helper;
+
+use Monolog\Handler\TestHandler;
+use Monolog\Logger;
+use PHPUnit\Framework\TestCase;
+use Wallabag\CoreBundle\Entity\Config;
+use Wallabag\CoreBundle\Entity\Entry;
+use Wallabag\CoreBundle\Entity\IgnoreOriginInstanceRule;
+use Wallabag\CoreBundle\Entity\IgnoreOriginUserRule;
+use Wallabag\CoreBundle\Helper\RuleBasedIgnoreOriginProcessor;
+use Wallabag\UserBundle\Entity\User;
+
+class RuleBasedIgnoreOriginProcessorTest extends TestCase
+{
+    private $rulerz;
+    private $processor;
+    private $ignoreOriginInstanceRuleRepository;
+    private $logger;
+    private $handler;
+
+    public function setUp()
+    {
+        $this->rulerz = $this->getRulerZMock();
+        $this->logger = $this->getLogger();
+        $this->ignoreOriginInstanceRuleRepository = $this->getIgnoreOriginInstanceRuleRepositoryMock();
+        $this->handler = new TestHandler();
+        $this->logger->pushHandler($this->handler);
+
+        $this->processor = new RuleBasedIgnoreOriginProcessor($this->rulerz, $this->logger, $this->ignoreOriginInstanceRuleRepository);
+    }
+
+    public function testProcessWithNoRule()
+    {
+        $user = $this->getUser();
+        $entry = new Entry($user);
+        $entry->setUrl('http://example.com/hello-world');
+
+        $this->ignoreOriginInstanceRuleRepository
+            ->expects($this->once())
+            ->method('findAll')
+            ->willReturn([]);
+
+        $this->rulerz
+            ->expects($this->never())
+            ->method('satisfies');
+
+        $result = $this->processor->process($entry);
+
+        $this->assertFalse($result);
+    }
+
+    public function testProcessWithNoMatchingRule()
+    {
+        $userRule = $this->getIgnoreOriginUserRule('rule as string');
+        $user = $this->getUser([$userRule]);
+        $entry = new Entry($user);
+        $entry->setUrl('http://example.com/hello-world');
+
+        $this->ignoreOriginInstanceRuleRepository
+            ->expects($this->once())
+            ->method('findAll')
+            ->willReturn([]);
+
+        $this->rulerz
+            ->expects($this->once())
+            ->method('satisfies')
+            ->willReturn(false);
+
+        $result = $this->processor->process($entry);
+
+        $this->assertFalse($result);
+    }
+
+    public function testProcessWithAMatchingRule()
+    {
+        $userRule = $this->getIgnoreOriginUserRule('rule as string');
+        $user = $this->getUser([$userRule]);
+        $entry = new Entry($user);
+        $entry->setUrl('http://example.com/hello-world');
+
+        $this->ignoreOriginInstanceRuleRepository
+            ->expects($this->once())
+            ->method('findAll')
+            ->willReturn([]);
+
+        $this->rulerz
+            ->expects($this->once())
+            ->method('satisfies')
+            ->willReturn(true);
+
+        $result = $this->processor->process($entry);
+
+        $this->assertTrue($result);
+    }
+
+    public function testProcessWithAMixOfMatchingRules()
+    {
+        $userRule = $this->getIgnoreOriginUserRule('rule as string');
+        $anotherUserRule = $this->getIgnoreOriginUserRule('another rule as string');
+        $user = $this->getUser([$userRule, $anotherUserRule]);
+        $entry = new Entry($user);
+        $entry->setUrl('http://example.com/hello-world');
+
+        $this->ignoreOriginInstanceRuleRepository
+            ->expects($this->once())
+            ->method('findAll')
+            ->willReturn([]);
+
+        $this->rulerz
+            ->method('satisfies')
+            ->will($this->onConsecutiveCalls(false, true));
+
+        $result = $this->processor->process($entry);
+
+        $this->assertTrue($result);
+    }
+
+    public function testProcessWithInstanceRules()
+    {
+        $user = $this->getUser();
+        $entry = new Entry($user);
+        $entry->setUrl('http://example.com/hello-world');
+
+        $instanceRule = $this->getIgnoreOriginInstanceRule('rule as string');
+        $this->ignoreOriginInstanceRuleRepository
+            ->expects($this->once())
+            ->method('findAll')
+            ->willReturn([$instanceRule]);
+
+        $this->rulerz
+            ->expects($this->once())
+            ->method('satisfies')
+            ->willReturn(true);
+
+        $result = $this->processor->process($entry);
+
+        $this->assertTrue($result);
+    }
+
+    public function testProcessWithMixedRules()
+    {
+        $userRule = $this->getIgnoreOriginUserRule('rule as string');
+        $user = $this->getUser([$userRule]);
+        $entry = new Entry($user);
+        $entry->setUrl('http://example.com/hello-world');
+
+        $instanceRule = $this->getIgnoreOriginInstanceRule('rule as string');
+        $this->ignoreOriginInstanceRuleRepository
+            ->expects($this->once())
+            ->method('findAll')
+            ->willReturn([$instanceRule]);
+
+        $this->rulerz
+            ->method('satisfies')
+            ->will($this->onConsecutiveCalls(false, true));
+
+        $result = $this->processor->process($entry);
+
+        $this->assertTrue($result);
+    }
+
+    private function getUser(array $ignoreOriginRules = [])
+    {
+        $user = new User();
+        $config = new Config($user);
+
+        $user->setConfig($config);
+
+        foreach ($ignoreOriginRules as $rule) {
+            $config->addIgnoreOriginRule($rule);
+        }
+
+        return $user;
+    }
+
+    private function getIgnoreOriginUserRule($rule)
+    {
+        $ignoreOriginUserRule = new IgnoreOriginUserRule();
+        $ignoreOriginUserRule->setRule($rule);
+
+        return $ignoreOriginUserRule;
+    }
+
+    private function getIgnoreOriginInstanceRule($rule)
+    {
+        $ignoreOriginInstanceRule = new IgnoreOriginInstanceRule();
+        $ignoreOriginInstanceRule->setRule($rule);
+
+        return $ignoreOriginInstanceRule;
+    }
+
+    private function getRulerZMock()
+    {
+        return $this->getMockBuilder('RulerZ\RulerZ')
+            ->disableOriginalConstructor()
+            ->getMock();
+    }
+
+    private function getIgnoreOriginInstanceRuleRepositoryMock()
+    {
+        return $this->getMockBuilder('Wallabag\CoreBundle\Repository\IgnoreOriginInstanceRuleRepository')
+            ->disableOriginalConstructor()
+            ->getMock();
+    }
+
+    private function getLogger()
+    {
+        return new Logger('foo');
+    }
+}