--- /dev/null
+<?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'));
+ }
+}
- { 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 }
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%"
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
// 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();
$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>');
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;
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(),
'user' => $userForm->createView(),
'new_tagging_rule' => $newTaggingRule->createView(),
'import_tagging_rule' => $taggingRulesImportform->createView(),
+ 'new_ignore_origin_user_rule' => $newIgnoreOriginUserRule->createView(),
],
'feed' => [
'username' => $user->getUsername(),
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.
*
/**
* 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.');
}
}
--- /dev/null
+<?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()
+ ;
+ }
+}
--- /dev/null
+<?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();
+ }
+}
--- /dev/null
+<?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,
+ ];
+ }
+}
->end()
->scalarNode('encryption_key_path')
->end()
+ ->arrayNode('default_ignore_origin_instance_rules')
+ ->prototype('array')
+ ->children()
+ ->scalarNode('rule')->end()
+ ->end()
+ ->end()
+ ->end()
->end()
;
$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');
*/
private $taggingRules;
+ /**
+ * @ORM\OneToMany(targetEntity="Wallabag\CoreBundle\Entity\IgnoreOriginUserRule", mappedBy="config", cascade={"remove"})
+ * @ORM\OrderBy({"id" = "ASC"})
+ */
+ private $ignoreOriginRules;
+
/*
* @param User $user
*/
{
$this->user = $user;
$this->taggingRules = new ArrayCollection();
+ $this->ignoreOriginRules = new ArrayCollection();
}
/**
{
return $this->taggingRules;
}
+
+ /**
+ * @return Config
+ */
+ public function addIgnoreOriginRule(IgnoreOriginUserRule $rule)
+ {
+ $this->ignoreOriginRules[] = $rule;
+
+ return $this;
+ }
+
+ /**
+ * @return ArrayCollection<IgnoreOriginUserRule>
+ */
+ public function getIgnoreOriginRules()
+ {
+ return $this->ignoreOriginRules;
+ }
}
--- /dev/null
+<?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;
+ }
+}
--- /dev/null
+<?php
+
+namespace Wallabag\CoreBundle\Entity;
+
+interface IgnoreOriginRuleInterface
+{
+ public function getId();
+
+ public function setRule(string $rule);
+
+ public function getRule();
+}
--- /dev/null
+<?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;
+ }
+}
--- /dev/null
+<?php
+
+namespace Wallabag\CoreBundle\Entity;
+
+interface RuleInterface
+{
+}
* @ORM\Table(name="`tagging_rule`")
* @ORM\Entity
*/
-class TaggingRule
+class TaggingRule implements RuleInterface
{
/**
* @var int
--- /dev/null
+<?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';
+ }
+}
--- /dev/null
+<?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';
+ }
+}
{
protected $graby;
protected $tagger;
+ protected $ignoreOriginProcessor;
protected $validator;
protected $logger;
protected $mimeGuesser;
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();
$diff_keys = array_keys($diff);
sort($diff_keys);
- if ($this->ignoreUrl($entry->getUrl())) {
+ if ($this->ignoreOriginProcessor->process($entry)) {
$entry->setUrl($url);
return false;
}
}
- /**
- * 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.
*
--- /dev/null
+<?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;
+ }
+}
--- /dev/null
+<?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;
+ }
+}
--- /dev/null
+<?php
+
+namespace Wallabag\CoreBundle\Repository;
+
+use Doctrine\ORM\EntityRepository;
+
+class IgnoreOriginInstanceRuleRepository extends EntityRepository
+{
+}
--- /dev/null
+<?php
+
+namespace Wallabag\CoreBundle\Repository;
+
+use Doctrine\ORM\EntityRepository;
+
+class IgnoreOriginUserRuleRepository extends EntityRepository
+{
+}
arguments:
- "@wallabag_core.graby"
- "@wallabag_core.rule_based_tagger"
+ - "@wallabag_core.rule_based_ignore_origin_processor"
- "@validator"
- "@logger"
- '%wallabag_core.fetching_error_message%'
- "@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
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:
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:
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'
user_info: 'Brugeroplysninger'
password: 'Adgangskode'
# rules: 'Tagging rules'
+ # ignore_origin: 'Ignore origin rules'
new_user: 'Tilføj bruger'
# reset: 'Reset area'
form:
# 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:
# 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%'
# 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'
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'
user_info: 'Benutzerinformation'
password: 'Kennwort'
rules: 'Tagging-Regeln'
+ # ignore_origin: 'Ignore origin rules'
new_user: 'Benutzer hinzufügen'
reset: 'Zurücksetzen'
form:
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:
# 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'
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'
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'
user_info: 'User information'
password: 'Password'
rules: 'Tagging rules'
+ ignore_origin: 'Ignore origin rules'
new_user: 'Add a user'
reset: 'Reset area'
form:
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:
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
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%'
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'
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'
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:
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:
# 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%'
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'
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: 'افزودن مقالهٔ تازه'
user_info: 'اطلاعات کاربر'
password: 'رمز'
rules: 'برچسبگذاری خودکار'
+ # ignore_origin: 'Ignore origin rules'
new_user: 'افزودن کاربر'
# reset: 'Reset area'
form:
# 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:
# 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% ذخیره شده بود'
# 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'
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"
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:
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:
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%"
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'
user_info: 'Informazioni utente'
password: 'Password'
rules: 'Regole di etichettatura'
+ # ignore_origin: 'Ignore origin rules'
new_user: 'Aggiungi utente'
reset: 'Area di reset'
form:
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:
# 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%'
# 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'
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'
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:
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:
# 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%'
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'
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'
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:
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:
# 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%'
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'
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'
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:
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:
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'
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'
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:
# 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:
# 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%'
# 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'
back_to_unread: 'Назад к непрочитанным записям'
users_management: 'Управление пользователями'
site_credentials: 'Site credentials'
+ # ignore_origin_instance_rules: 'Global ignore origin rules'
quickstart: "Быстрый старт"
top:
add_new_entry: 'Добавить новую запись'
user_info: 'Информация о пользователе'
password: 'Пароль'
rules: 'Правила настройки простановки тегов'
+ # ignore_origin: 'Ignore origin rules'
new_user: 'Добавить пользователя'
reset: 'Сброс данных'
form:
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:
# 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%'
# 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'
back_to_unread: 'กลับไปยังรายการที่ไม่ได้อ่าน'
users_management: 'การจัดการผู้ใช้'
site_credentials: 'การรับรองไซต์'
+ # ignore_origin_instance_rules: 'Global ignore origin rules'
quickstart: "เริ่มแบบด่วน"
top:
add_new_entry: 'เพิ่มรายการใหม่'
user_info: 'ข้อมูลผู้ใช้'
password: 'รหัสผ่าน'
rules: 'การแท็กข้อบังคับ'
+ # ignore_origin: 'Ignore origin rules'
new_user: 'เพิ่มผู้ใช้'
reset: 'รีเซ็ตพื้นที่ '
form:
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:
# 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%'
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'
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'
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:
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:
# 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%'
# 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'
</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>
--- /dev/null
+{% 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 %}
--- /dev/null
+{% 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 %}
--- /dev/null
+{% 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 %}
{% 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>
<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>
--- /dev/null
+{% 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 %}
--- /dev/null
+{% 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 %}
--- /dev/null
+{% 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 %}
<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>
$this->getEntityManager()->flush();
}
+ /**
+ * @group NetworkCalls
+ */
public function testRunReloadEntryCommand()
{
$application = new Application($this->getClient()->getKernel());
$this->assertContains('Done', $tester->getDisplay());
}
+ /**
+ * @group NetworkCalls
+ */
public function testRunReloadEntryWithUsernameCommand()
{
$application = new Application($this->getClient()->getKernel());
public function testTaggingRuleCreation()
{
$this->logInAs('admin');
- $this->useTheme('baggy');
$client = $this->getClient();
$crawler = $client->request('GET', '/config');
$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());
$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());
->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()
$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()
$em->flush();
}
+ /**
+ * @group NetworkCalls
+ */
public function testDeleteAccount()
{
$client = $this->getClient();
$this->assertContains('login', $client->getResponse()->headers->get('location'));
}
+ /**
+ * @group NetworkCalls
+ */
public function testQuickstart()
{
$this->logInAs('empty');
$this->assertCount(1, $crawler->filter('form[name=entry]'));
}
+ /**
+ * @group NetworkCalls
+ */
public function testPostNewViaBookmarklet()
{
$this->logInAs('admin');
}
/**
- * This test will require an internet connection.
+ * @group NetworkCalls
*/
public function testPostNewOk()
{
$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';
$this->assertContains('/view/', $client->getResponse()->getTargetUrl());
}
+ /**
+ * @group NetworkCalls
+ */
public function testPostNewOkUrlExistWithAccent()
{
$this->logInAs('admin');
}
/**
- * This test will require an internet connection.
+ * @group NetworkCalls
*/
public function testPostNewOkUrlExistWithRedirection()
{
}
/**
- * This test will require an internet connection.
+ * @group NetworkCalls
*/
public function testPostNewThatWillBeTagged()
{
}
/**
- * This test will require an internet connection.
+ * @group NetworkCalls
*/
public function testReload()
{
$this->assertSame(404, $client->getResponse()->getStatusCode());
}
+ /**
+ * @group NetworkCalls
+ */
public function testNewEntryWithDownloadImagesEnabled()
{
$this->downloadImagesEnabled = true;
/**
* @dataProvider dataForLanguage
+ * @group NetworkCalls
*/
public function testLanguageValidation($url, $expectedLanguage)
{
}
/**
- * This test will require an internet connection.
+ * @group NetworkCalls
*/
public function testRestrictedArticle()
{
--- /dev/null
+<?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]);
+ }
+ }
+}
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;
$tagger->expects($this->once())
->method('tag');
+ $ruleBasedIgnoreOriginProcessor = $this->getRuleBasedIgnoreOriginProcessorMock();
+
$graby = $this->getMockBuilder('Graby\Graby')
->setMethods(['fetchContent'])
->disableOriginalConstructor()
'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');
$tagger->expects($this->once())
->method('tag');
+ $ruleBasedIgnoreOriginProcessor = $this->getRuleBasedIgnoreOriginProcessorMock();
+
$graby = $this->getMockBuilder('Graby\Graby')
->setMethods(['fetchContent'])
->disableOriginalConstructor()
'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');
$tagger->expects($this->once())
->method('tag');
+ $ruleBasedIgnoreOriginProcessor = $this->getRuleBasedIgnoreOriginProcessorMock();
+
$graby = $this->getMockBuilder('Graby\Graby')
->setMethods(['fetchContent'])
->disableOriginalConstructor()
'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');
$tagger->expects($this->once())
->method('tag');
+ $ruleBasedIgnoreOriginProcessor = $this->getRuleBasedIgnoreOriginProcessorMock();
+ $ruleBasedIgnoreOriginProcessor->expects($this->once())
+ ->method('process');
+
$graby = $this->getMockBuilder('Graby\Graby')
->setMethods(['fetchContent'])
->disableOriginalConstructor()
],
]);
- $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');
$tagger->expects($this->once())
->method('tag');
+ $ruleBasedIgnoreOriginProcessor = $this->getRuleBasedIgnoreOriginProcessorMock();
+ $ruleBasedIgnoreOriginProcessor->expects($this->once())
+ ->method('process');
+
$graby = $this->getMockBuilder('Graby\Graby')
->setMethods(['fetchContent'])
->disableOriginalConstructor()
],
]);
- $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');
$tagger->expects($this->once())
->method('tag');
+ $ruleBasedIgnoreOriginProcessor = $this->getRuleBasedIgnoreOriginProcessorMock();
+ $ruleBasedIgnoreOriginProcessor->expects($this->once())
+ ->method('process');
+
$graby = $this->getMockBuilder('Graby\Graby')
->setMethods(['fetchContent'])
->disableOriginalConstructor()
'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');
$tagger->expects($this->once())
->method('tag');
+ $ruleBasedIgnoreOriginProcessor = $this->getRuleBasedIgnoreOriginProcessorMock();
+ $ruleBasedIgnoreOriginProcessor->expects($this->once())
+ ->method('process');
+
$graby = $this->getMockBuilder('Graby\Graby')
->setMethods(['fetchContent'])
->disableOriginalConstructor()
'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');
$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')
],
]);
- $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');
$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')
'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');
$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,
$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,
$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,
->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,
$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,
$tagger->expects($this->once())
->method('tag');
+ $ruleBasedIgnoreOriginProcessor = $this->getRuleBasedIgnoreOriginProcessorMock();
+
$graby = $this->getMockBuilder('Graby\Graby')
->setMethods(['fetchContent'])
->disableOriginalConstructor()
],
]);
- $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');
$tagger->expects($this->once())
->method('tag');
+ $ruleBasedIgnoreOriginProcessor = $this->getRuleBasedIgnoreOriginProcessorMock();
+
$graby = $this->getMockBuilder('Graby\Graby')
->setMethods(['fetchContent'])
->disableOriginalConstructor()
'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');
$tagger->expects($this->once())
->method('tag');
+ $ruleBasedIgnoreOriginProcessor = $this->getRuleBasedIgnoreOriginProcessorMock();
+
$graby = $this->getMockBuilder('Graby\Graby')
->setMethods(['fetchContent'])
->disableOriginalConstructor()
'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');
$tagger->expects($this->once())
->method('tag');
+ $ruleBasedIgnoreOriginProcessor = $this->getRuleBasedIgnoreOriginProcessorMock();
+
$graby = $this->getMockBuilder('Graby\Graby')
->setMethods(['fetchContent'])
->disableOriginalConstructor()
'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');
$tagger->expects($this->once())
->method('tag');
+ $ruleBasedIgnoreOriginProcessor = $this->getRuleBasedIgnoreOriginProcessorMock();
+
$graby = $this->getMockBuilder('Graby\Graby')
->setMethods(['fetchContent'])
->disableOriginalConstructor()
'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');
$tagger->expects($this->once())
->method('tag');
+ $ruleBasedIgnoreOriginProcessor = $this->getRuleBasedIgnoreOriginProcessorMock();
+
$graby = $this->getMockBuilder('Graby\Graby')
->setMethods(['fetchContent'])
->disableOriginalConstructor()
'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');
$tagger->expects($this->once())
->method('tag');
+ $ruleBasedIgnoreOriginProcessor = $this->getRuleBasedIgnoreOriginProcessorMock();
+
$graby = $this->getMockBuilder('Graby\Graby')
->setMethods(['fetchContent'])
->disableOriginalConstructor()
'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');
* $expected_entry_url
* $expected_origin_url
* $expected_domain
+ * $processor_result
*/
public function dataForChangedUrl()
{
'http://1.1.1.1',
'http://0.0.0.0',
'1.1.1.1',
+ false,
],
'origin already set' => [
'http://0.0.0.0',
'http://1.1.1.1',
'http://hello',
'1.1.1.1',
+ false,
],
'trailing slash' => [
'https://example.com/hello-world',
'https://example.com/hello-world/',
null,
'example.com',
+ false,
],
'query string in fetched content' => [
'https://example.org/hello',
'https://example.org/hello?world=1',
'https://example.org/hello',
'example.org',
+ false,
],
'fragment in fetched content' => [
'https://example.org/hello',
'https://example.org/hello',
null,
'example.org',
+ false,
],
'fragment and query string in fetched content' => [
'https://example.org/hello',
'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',
'https://example.org/world?foo',
'https://example.org/hello',
'example.org',
+ false,
],
'feedproxy ignore list test' => [
'http://feedproxy.google.com/~r/Wallabag/~3/helloworld',
'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',
'https://example.org/hello-wallabag',
'https://example.org/this-is-source',
'example.org',
+ true,
],
'lemonde ignore pattern test' => [
'http://www.lemonde.fr/tiny/url',
'http://example.com/hello-world',
null,
'example.com',
+ true,
],
];
}
/**
* @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(
->getMock();
}
+ private function getRuleBasedIgnoreOriginProcessorMock()
+ {
+ return $this->getMockBuilder(RuleBasedIgnoreOriginProcessor::class)
+ ->setMethods(['process'])
+ ->disableOriginalConstructor()
+ ->getMock();
+ }
+
private function getLogger()
{
return new NullLogger();
--- /dev/null
+<?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');
+ }
+}