--- /dev/null
+<?php
+/**
+ * @category Horde
+ * @package Horde_Log
+ * @subpackage Filters
+ * @author James Pepin <james@jamespepin.com>
+ * @license http://opensource.org/licenses/bsd-license.php BSD
+ */
+
+/**
+ * Filters log events using defined constraints on one or more fields of the
+ * $event array
+ *
+ * @category Horde
+ * @package Horde_Log
+ * @subpackage Filters
+ * @author James Pepin <james@jamespepin.com>
+ * @license http://opensource.org/licenses/bsd-license.php BSD
+ *
+ * @todo Implement constraint objects for the different types of filtering ie
+ * regex,required,type..etc.. so we can add different constaints ad infinitum.
+ */
+class Horde_Log_Filter_Constraint implements Horde_Log_Filter_Interface
+{
+ private $_constraints = array();
+
+ /**
+ * Add a constraint to the filter
+ *
+ * @param string $field The field to apply the constraint to
+ * @param Horde_Constraint $constraint The constraint to apply
+ */
+ public function addConstraint($field, Horde_Constraint $constraint)
+ {
+ if ($this->_constraints[$field] instanceof Horde_Constraint) {
+ $this->_constraints[$field] = new Horde_Constraint_And($this->_constraints[$field], $constraint);
+ } else {
+ $this->_constraints[$field] = $constraint;
+ }
+ }
+
+ /**
+ * Add a regular expression to filter by
+ *
+ * Takes a field name and a regex, if the regex does not match then the
+ * event is filtered.
+ *
+ * @param string $field The name of the field that should be part of the event
+ * @param string $regex The regular expression to filter by
+ */
+ public function addRegex($field, $regex)
+ {
+ $constraint = new Horde_Constraint_PregMatch($regex);
+ $this->addConstraint($field, $constraint);
+ }
+
+ /**
+ * Add a required field to the filter
+ *
+ * If the field does not exist on the event, then it is filtered.
+ *
+ * @param string $field The name of the field that should be part of the event
+ */
+ public function addRequiredField($field)
+ {
+ $notNull = new Horde_Constraint_Not(new Horde_Constraint_Null());
+ $this->addConstraint($field, $notNull);
+ }
+
+ /**
+ * Adds all arguments passed as required fields
+ */
+ public function addRequiredFields()
+ {
+ $fields = func_get_args();
+ foreach ($fields as $f) {
+ $this->addRequiredField($f);
+ }
+ }
+
+ /**
+ * Returns TRUE to accept the message, FALSE to block it.
+ *
+ * @param array $event Log event
+ * @return boolean accepted?
+ */
+ public function accept($event)
+ {
+ foreach ($this->_constraints as $field => $constraint) {
+ if (!$constraint->evaluate($event[$field])) {
+ return false;
+ }
+ }
+ return true;
+ }
+}
<email>mike@maintainable.com</email>
<active>yes</active>
</lead>
- <date>2009-02-09</date>
- <time>23:26:00</time>
+ <date>2009-09-25</date>
+ <time>23:00:00</time>
<version>
- <release>0.2.0</release>
+ <release>0.3.0</release>
<api>0.2.0</api>
</version>
<stability>
<api>beta</api>
</stability>
<license uri="http://opensource.org/licenses/bsd-license.php">BSD</license>
- <notes>* Added Horde_Log_Filter_Suppress.
+ <notes>* Added Horde_Log_Filter_Constraint, for flexible filtering per-field by the Horde_Constraint package
</notes>
<contents>
<dir name="/">
<dir name="Horde">
<dir name="Log">
<dir name="Filter">
+ <file name="Constraint.php" role="php" />
<file name="Interface.php" role="php" />
<file name="Level.php" role="php" />
<file name="Message.php" role="php" />
<min>5.2</min>
</php>
<pearinstaller>
- <min>1.5.0</min>
+ <min>1.7.0</min>
</pearinstaller>
+ <package>
+ <name>Constraint</name>
+ <channel>pear.horde.org</channel>
+ </package>
</required>
</dependencies>
<phprelease>
<filelist>
<install name="lib/Horde/Log/Exception.php" as="Horde/Log/Exception.php" />
+ <install name="lib/Horde/Log/Filter/Constraint.php" as="Horde/Log/Filter/Constraint.php" />
<install name="lib/Horde/Log/Filter/Interface.php" as="Horde/Log/Filter/Interface.php" />
<install name="lib/Horde/Log/Filter/Level.php" as="Horde/Log/Filter/Level.php" />
<install name="lib/Horde/Log/Filter/Message.php" as="Horde/Log/Filter/Message.php" />
--- /dev/null
+<?php
+/**
+ * Horde Log package
+ *
+ * @category Horde
+ * @package Horde_Log
+ * @subpackage UnitTests
+ * @author James Pepin <james@jamespepin.com>
+ * @license http://opensource.org/licenses/bsd-license.php BSD
+ */
+
+/**
+ * @category Horde
+ * @package Horde_Log
+ * @subpackage UnitTests
+ * @author James Pepin <james@jamespepin.com>
+ * @license http://opensource.org/licenses/bsd-license.php BSD
+ */
+class Horde_Log_Filter_ConstraintTest extends Horde_Test_Case
+{
+ public function testFilterDoesNotAcceptWhenRequiredFieldIsMissing()
+ {
+ $event = array(
+ 'someotherfield' => 'other value',
+ );
+ $filterator = new Horde_Log_Filter_Constraint();
+ $filterator->addRequiredField('required_field');
+
+ $this->assertFalse($filterator->accept($event));
+ }
+
+ public function testFilterAcceptsWhenRequiredFieldisPresent()
+ {
+ $event = array(
+ 'required_field' => 'somevalue',
+ 'someotherfield' => 'other value',
+ );
+ $filterator = new Horde_Log_Filter_Constraint();
+ $filterator->addRequiredField('required_field');
+
+ $this->assertTrue($filterator->accept($event));
+ }
+
+ public function testFilterAcceptsWhenRegexMatchesField()
+ {
+ $event = array(
+ 'regex_field' => 'somevalue',
+ 'someotherfield' => 'other value',
+ );
+ $filterator = new Horde_Log_Filter_Constraint();
+ $filterator->addRegex('regex_field', '/somevalue/');
+
+ $this->assertTrue($filterator->accept($event));
+ }
+
+ public function testFilterAcceptsWhenRegex_DOESNOT_MatcheField()
+ {
+ $event = array(
+ 'regex_field' => 'somevalue',
+ 'someotherfield' => 'other value',
+ );
+ $filterator = new Horde_Log_Filter_Constraint();
+ $filterator->addRegex('regex_field', '/someothervalue/');
+
+ $this->assertFalse($filterator->accept($event));
+ }
+
+ private function getConstraintMock($returnVal)
+ {
+ $const = $this->getMock('Horde_Constraint', array('evaluate'));
+ $const->expects($this->once())
+ ->method('evaluate')
+ ->will($this->returnValue($returnVal));
+ return $const;
+ }
+
+ public function testFilterCallsEvalOnAllConstraintsWhenTheyAreAllTrue()
+ {
+ $filterator = new Horde_Log_Filter_Constraint();
+ $filterator->addConstraint('fieldname', $this->getConstraintMock(true));
+ $filterator->addConstraint('fieldname', $this->getConstraintMock(true));
+
+ $filterator->accept(array('fieldname' => 'foo'));
+ }
+
+ public function testFilterStopsWhenItFindsAFalseCondition()
+ {
+ $filterator = new Horde_Log_Filter_Constraint();
+ $filterator->addConstraint('fieldname', $this->getConstraintMock(true));
+ $filterator->addConstraint('fieldname', $this->getConstraintMock(true));
+ $filterator->addConstraint('fieldname', new Horde_Constraint_AlwaysFalse());
+
+ $const = $this->getMock('Horde_Constraint', array('evaluate'));
+ $const->expects($this->never())
+ ->method('evaluate');
+ $filterator->addConstraint('fieldname', $const);
+ $filterator->accept(array('fieldname' => 'foo'));
+
+ }
+
+ public function testFilterAcceptCallsConstraintOnNullWhenFieldDoesnotExist()
+ {
+ $filterator = new Horde_Log_Filter_Constraint();
+ $const = $this->getMock('Horde_Constraint', array('evaluate'));
+ $const->expects($this->once())
+ ->method('evaluate')
+ ->with(null);
+ $filterator->addConstraint('fieldname', $const);
+ $filterator->accept(array('someotherfield' => 'foo'));
+ }
+}