#Majax TagParser
This project aims to help make tags much more useful for search and filtering.
Based on the initial lexer/parser concept from:
http://www.codediesel.com/php/building-a-simple-parser-and-lexer-in-php/
To make a long story extremely short, it lets you use natural equation expression to search your tags.
a + b // addition: return all from tags A and B
a - b // subtraction: return all from tag A not in B
a|b // limit: returns only tags from A also in B
a^b // exclude: returns all from tag A not in B, chainable with limit
a^b|c // returns all from A not in B which are also in C
(a + b) - (c + d) // supports parenthesis for your sanity
Tags with limit/exclude and groupings (expressions in parenthesis) are optimized and will only be resolved once per unique expression.
Import into your project and either include in your autoloader or use the autoload.php file to autoload it.
Then there are two steps to fully resolve a given string.
$string = 'a + b';
$lexer = new Majax\TagParser\TagLexer($string)
$parser = new Majax\TagParser\TagParser($lexer);
$parsed_structure = $parser->process();
To resolve, you will need to pass a repository to the Resolver. The signature needed to be implemented is:
/**
* @abstract
* @param $tag String
* @return string[]
*/
public function getIdsForTag($tag);
In Symfony 1.4.x, a repository could look like:
/**
* PluginTagTable
*
* This class has been auto-generated by the Doctrine ORM Framework
*/
class PluginTagTable extends Doctrine_Table implements \Majax\TagParser\TagRepositoryInterface
{
/**
* @param $tag String
* @return string[]
*/
public function getIdsForTag($tag)
{
$sql = 'SELECT tt.thing_id FROM tags t, thing_tags tt WHERE rt.tag_id = t.id AND t.name = ?';
$results = $this->getConnection()->execute($sql, array($tag));
$res = $results->fetchAll(Doctrine::FETCH_ASSOC);
$results = array();
foreach($res as $row)
{
$results[] = $row['thing_id'];
}
return $results;
}
}
Now you just have to pass this into the resolver like so (we will use Symfony 1.4.x as an example again):
$resolver = new \Majax\TagParser\Resolver(Doctrine::getTable('Tag'));
$thing_ids = $resolver->process($parsed_structure);
$string = 'a + b';
$parser = new Majax\TagParser\TagParser();
$repository = Doctrine::getTable('Tag'); // platform/framework/implementation specific
$lexer = new Majax\TagParser\TagLexer($string); // alternately can call ->setInput() instead of constructor
$parsed_structure = $parser->process($lexer);
$resolver = new \Majax\TagParser\Resolver($repository);
$thing_ids = $resolver->process($parsed_structure);
Improve tests