mirror of
https://github.com/wallabag/wallabag.git
synced 2024-10-31 22:28:54 +00:00
Add new Helper to process Ignore Origin rules and RulerZ operator
This commits adds a new helper like RuleBasedTagger for processing ignore origin rules. It also adds a new custom RulerZ operator for the '~' pattern matching rule. Renames 'pattern' with '_all' in IgnoreOriginRule entity. Signed-off-by: Kevin Decherf <kevin@kdecherf.com>
This commit is contained in:
parent
24230a5130
commit
f39c5a2a70
6 changed files with 300 additions and 4 deletions
|
@ -11,7 +11,6 @@ use Symfony\Component\Validator\Constraints as Assert;
|
|||
*
|
||||
* @ORM\Entity(repositoryClass="Wallabag\CoreBundle\Repository\IgnoreOriginInstanceRuleRepository")
|
||||
* @ORM\Table(name="`ignore_origin_instance_rule`")
|
||||
* @ORM\Entity
|
||||
*/
|
||||
class IgnoreOriginInstanceRule implements IgnoreOriginRuleInterface, RuleInterface
|
||||
{
|
||||
|
@ -30,7 +29,7 @@ class IgnoreOriginInstanceRule implements IgnoreOriginRuleInterface, RuleInterfa
|
|||
* @Assert\NotBlank()
|
||||
* @Assert\Length(max=255)
|
||||
* @RulerZAssert\ValidRule(
|
||||
* allowed_variables={"host","pattern"},
|
||||
* allowed_variables={"host","_all"},
|
||||
* allowed_operators={"=","~"}
|
||||
* )
|
||||
* @ORM\Column(name="rule", type="string", nullable=false)
|
||||
|
|
|
@ -11,7 +11,6 @@ use Symfony\Component\Validator\Constraints as Assert;
|
|||
*
|
||||
* @ORM\Entity(repositoryClass="Wallabag\CoreBundle\Repository\IgnoreOriginUserRuleRepository")
|
||||
* @ORM\Table(name="`ignore_origin_user_rule`")
|
||||
* @ORM\Entity
|
||||
*/
|
||||
class IgnoreOriginUserRule implements IgnoreOriginRuleInterface, RuleInterface
|
||||
{
|
||||
|
@ -30,7 +29,7 @@ class IgnoreOriginUserRule implements IgnoreOriginRuleInterface, RuleInterface
|
|||
* @Assert\NotBlank()
|
||||
* @Assert\Length(max=255)
|
||||
* @RulerZAssert\ValidRule(
|
||||
* allowed_variables={"host","pattern"},
|
||||
* allowed_variables={"host","_all"},
|
||||
* allowed_operators={"=","~"}
|
||||
* )
|
||||
* @ORM\Column(name="rule", type="string", nullable=false)
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
<?php
|
||||
|
||||
namespace Wallabag\CoreBundle\Helper;
|
||||
|
||||
use Psr\Log\LoggerInterface;
|
||||
use RulerZ\RulerZ;
|
||||
use Wallabag\CoreBundle\Entity\Entry;
|
||||
use Wallabag\CoreBundle\Repository\IgnoreOriginInstanceRuleRepository;
|
||||
|
||||
class RuleBasedIgnoreOriginProcessor
|
||||
{
|
||||
protected $rulerz;
|
||||
protected $logger;
|
||||
protected $ignoreOriginInstanceRuleRepository;
|
||||
|
||||
public function __construct(RulerZ $rulerz, LoggerInterface $logger, IgnoreOriginInstanceRuleRepository $ignoreOriginInstanceRuleRepository)
|
||||
{
|
||||
$this->rulerz = $rulerz;
|
||||
$this->logger = $logger;
|
||||
$this->ignoreOriginInstanceRuleRepository = $ignoreOriginInstanceRuleRepository;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Entry $entry Entry to process
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function process(Entry $entry)
|
||||
{
|
||||
$url = $entry->getUrl();
|
||||
$userRules = $entry->getUser()->getConfig()->getIgnoreOriginRules()->toArray();
|
||||
$rules = array_merge($this->ignoreOriginInstanceRuleRepository->findAll(), $userRules);
|
||||
|
||||
$parsed_url = parse_url($url);
|
||||
// We add the former url as a new key _all for pattern matching
|
||||
$parsed_url['_all'] = $url;
|
||||
|
||||
foreach ($rules as $rule) {
|
||||
if ($this->rulerz->satisfies($parsed_url, $rule->getRule())) {
|
||||
$this->logger->info('Origin url matching ignore rule.', [
|
||||
'rule' => $rule->getRule(),
|
||||
]);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
23
src/Wallabag/CoreBundle/Operator/PHP/PatternMatches.php
Normal file
23
src/Wallabag/CoreBundle/Operator/PHP/PatternMatches.php
Normal file
|
@ -0,0 +1,23 @@
|
|||
<?php
|
||||
|
||||
namespace Wallabag\CoreBundle\Operator\PHP;
|
||||
|
||||
/**
|
||||
* Provides a "~" operator used for ignore origin rules.
|
||||
*
|
||||
* It asserts that a subject matches a given regexp pattern, in a
|
||||
* case-insensitive way.
|
||||
*
|
||||
* This operator will be used to compile ignore origin rules in PHP, usable
|
||||
* directly on Entry objects for instance.
|
||||
* It's registered in RulerZ using a service (wallabag.operator.array.pattern_matches);
|
||||
*/
|
||||
class PatternMatches
|
||||
{
|
||||
public function __invoke($subject, $pattern)
|
||||
{
|
||||
$count = preg_match("`$pattern`i", $subject);
|
||||
|
||||
return \is_int($count) && $count > 0;
|
||||
}
|
||||
}
|
|
@ -92,6 +92,7 @@ services:
|
|||
arguments:
|
||||
- "@wallabag_core.graby"
|
||||
- "@wallabag_core.rule_based_tagger"
|
||||
- "@wallabag_core.rule_based_ignore_origin_processor"
|
||||
- "@validator"
|
||||
- "@logger"
|
||||
- '%wallabag_core.fetching_error_message%'
|
||||
|
@ -110,6 +111,13 @@ services:
|
|||
- "@wallabag_core.entry_repository"
|
||||
- "@logger"
|
||||
|
||||
wallabag_core.rule_based_ignore_origin_processor:
|
||||
class: Wallabag\CoreBundle\Helper\RuleBasedIgnoreOriginProcessor
|
||||
arguments:
|
||||
- "@rulerz"
|
||||
- "@logger"
|
||||
- "@wallabag_core.ignore_origin_instance_rule_repository"
|
||||
|
||||
# repository as a service
|
||||
wallabag_core.entry_repository:
|
||||
class: Wallabag\CoreBundle\Repository\EntryRepository
|
||||
|
@ -164,6 +172,11 @@ services:
|
|||
tags:
|
||||
- { name: rulerz.operator, target: doctrine, operator: notmatches, inline: true }
|
||||
|
||||
wallabag.operator.array.pattern_matches:
|
||||
class: Wallabag\CoreBundle\Operator\PHP\PatternMatches
|
||||
tags:
|
||||
- { name: rulerz.operator, target: native, operator: "~" }
|
||||
|
||||
wallabag_core.helper.redirect:
|
||||
class: Wallabag\CoreBundle\Helper\Redirect
|
||||
arguments:
|
||||
|
|
|
@ -0,0 +1,212 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\Wallabag\CoreBundle\Helper;
|
||||
|
||||
use Monolog\Handler\TestHandler;
|
||||
use Monolog\Logger;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Wallabag\CoreBundle\Entity\Config;
|
||||
use Wallabag\CoreBundle\Entity\Entry;
|
||||
use Wallabag\CoreBundle\Entity\IgnoreOriginInstanceRule;
|
||||
use Wallabag\CoreBundle\Entity\IgnoreOriginUserRule;
|
||||
use Wallabag\CoreBundle\Helper\RuleBasedIgnoreOriginProcessor;
|
||||
use Wallabag\UserBundle\Entity\User;
|
||||
|
||||
class RuleBasedIgnoreOriginProcessorTest extends TestCase
|
||||
{
|
||||
private $rulerz;
|
||||
private $processor;
|
||||
private $ignoreOriginInstanceRuleRepository;
|
||||
private $logger;
|
||||
private $handler;
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
$this->rulerz = $this->getRulerZMock();
|
||||
$this->logger = $this->getLogger();
|
||||
$this->ignoreOriginInstanceRuleRepository = $this->getIgnoreOriginInstanceRuleRepositoryMock();
|
||||
$this->handler = new TestHandler();
|
||||
$this->logger->pushHandler($this->handler);
|
||||
|
||||
$this->processor = new RuleBasedIgnoreOriginProcessor($this->rulerz, $this->logger, $this->ignoreOriginInstanceRuleRepository);
|
||||
}
|
||||
|
||||
public function testProcessWithNoRule()
|
||||
{
|
||||
$user = $this->getUser();
|
||||
$entry = new Entry($user);
|
||||
$entry->setUrl('http://example.com/hello-world');
|
||||
|
||||
$this->ignoreOriginInstanceRuleRepository
|
||||
->expects($this->once())
|
||||
->method('findAll')
|
||||
->willReturn([]);
|
||||
|
||||
$this->rulerz
|
||||
->expects($this->never())
|
||||
->method('satisfies');
|
||||
|
||||
$result = $this->processor->process($entry);
|
||||
|
||||
$this->assertFalse($result);
|
||||
}
|
||||
|
||||
public function testProcessWithNoMatchingRule()
|
||||
{
|
||||
$userRule = $this->getIgnoreOriginUserRule('rule as string');
|
||||
$user = $this->getUser([$userRule]);
|
||||
$entry = new Entry($user);
|
||||
$entry->setUrl('http://example.com/hello-world');
|
||||
|
||||
$this->ignoreOriginInstanceRuleRepository
|
||||
->expects($this->once())
|
||||
->method('findAll')
|
||||
->willReturn([]);
|
||||
|
||||
$this->rulerz
|
||||
->expects($this->once())
|
||||
->method('satisfies')
|
||||
->willReturn(false);
|
||||
|
||||
$result = $this->processor->process($entry);
|
||||
|
||||
$this->assertFalse($result);
|
||||
}
|
||||
|
||||
public function testProcessWithAMatchingRule()
|
||||
{
|
||||
$userRule = $this->getIgnoreOriginUserRule('rule as string');
|
||||
$user = $this->getUser([$userRule]);
|
||||
$entry = new Entry($user);
|
||||
$entry->setUrl('http://example.com/hello-world');
|
||||
|
||||
$this->ignoreOriginInstanceRuleRepository
|
||||
->expects($this->once())
|
||||
->method('findAll')
|
||||
->willReturn([]);
|
||||
|
||||
$this->rulerz
|
||||
->expects($this->once())
|
||||
->method('satisfies')
|
||||
->willReturn(true);
|
||||
|
||||
$result = $this->processor->process($entry);
|
||||
|
||||
$this->assertTrue($result);
|
||||
}
|
||||
|
||||
public function testProcessWithAMixOfMatchingRules()
|
||||
{
|
||||
$userRule = $this->getIgnoreOriginUserRule('rule as string');
|
||||
$anotherUserRule = $this->getIgnoreOriginUserRule('another rule as string');
|
||||
$user = $this->getUser([$userRule, $anotherUserRule]);
|
||||
$entry = new Entry($user);
|
||||
$entry->setUrl('http://example.com/hello-world');
|
||||
|
||||
$this->ignoreOriginInstanceRuleRepository
|
||||
->expects($this->once())
|
||||
->method('findAll')
|
||||
->willReturn([]);
|
||||
|
||||
$this->rulerz
|
||||
->method('satisfies')
|
||||
->will($this->onConsecutiveCalls(false, true));
|
||||
|
||||
$result = $this->processor->process($entry);
|
||||
|
||||
$this->assertTrue($result);
|
||||
}
|
||||
|
||||
public function testProcessWithInstanceRules()
|
||||
{
|
||||
$user = $this->getUser();
|
||||
$entry = new Entry($user);
|
||||
$entry->setUrl('http://example.com/hello-world');
|
||||
|
||||
$instanceRule = $this->getIgnoreOriginInstanceRule('rule as string');
|
||||
$this->ignoreOriginInstanceRuleRepository
|
||||
->expects($this->once())
|
||||
->method('findAll')
|
||||
->willReturn([$instanceRule]);
|
||||
|
||||
$this->rulerz
|
||||
->expects($this->once())
|
||||
->method('satisfies')
|
||||
->willReturn(true);
|
||||
|
||||
$result = $this->processor->process($entry);
|
||||
|
||||
$this->assertTrue($result);
|
||||
}
|
||||
|
||||
public function testProcessWithMixedRules()
|
||||
{
|
||||
$userRule = $this->getIgnoreOriginUserRule('rule as string');
|
||||
$user = $this->getUser([$userRule]);
|
||||
$entry = new Entry($user);
|
||||
$entry->setUrl('http://example.com/hello-world');
|
||||
|
||||
$instanceRule = $this->getIgnoreOriginInstanceRule('rule as string');
|
||||
$this->ignoreOriginInstanceRuleRepository
|
||||
->expects($this->once())
|
||||
->method('findAll')
|
||||
->willReturn([$instanceRule]);
|
||||
|
||||
$this->rulerz
|
||||
->method('satisfies')
|
||||
->will($this->onConsecutiveCalls(false, true));
|
||||
|
||||
$result = $this->processor->process($entry);
|
||||
|
||||
$this->assertTrue($result);
|
||||
}
|
||||
|
||||
private function getUser(array $ignoreOriginRules = [])
|
||||
{
|
||||
$user = new User();
|
||||
$config = new Config($user);
|
||||
|
||||
$user->setConfig($config);
|
||||
|
||||
foreach ($ignoreOriginRules as $rule) {
|
||||
$config->addIgnoreOriginRule($rule);
|
||||
}
|
||||
|
||||
return $user;
|
||||
}
|
||||
|
||||
private function getIgnoreOriginUserRule($rule)
|
||||
{
|
||||
$ignoreOriginUserRule = new IgnoreOriginUserRule();
|
||||
$ignoreOriginUserRule->setRule($rule);
|
||||
|
||||
return $ignoreOriginUserRule;
|
||||
}
|
||||
|
||||
private function getIgnoreOriginInstanceRule($rule)
|
||||
{
|
||||
$ignoreOriginInstanceRule = new IgnoreOriginInstanceRule();
|
||||
$ignoreOriginInstanceRule->setRule($rule);
|
||||
|
||||
return $ignoreOriginInstanceRule;
|
||||
}
|
||||
|
||||
private function getRulerZMock()
|
||||
{
|
||||
return $this->getMockBuilder('RulerZ\RulerZ')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
}
|
||||
|
||||
private function getIgnoreOriginInstanceRuleRepositoryMock()
|
||||
{
|
||||
return $this->getMockBuilder('Wallabag\CoreBundle\Repository\IgnoreOriginInstanceRuleRepository')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
}
|
||||
|
||||
private function getLogger()
|
||||
{
|
||||
return new Logger('foo');
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue