Skip to content

jmather/MajaxTagParser

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

12 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

#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/

What does it do?

To make a long story extremely short, it lets you use natural equation expression to search your tags.

Example:

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

Interesting to note:

Tags with limit/exclude and groupings (expressions in parenthesis) are optimized and will only be resolved once per unique expression.

Installation

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.

Lex/Parse

$string = 'a + b';
$lexer = new Majax\TagParser\TagLexer($string)
$parser = new Majax\TagParser\TagParser($lexer);

$parsed_structure = $parser->process();

Resolving

Building Your Repository

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;
    }

}

Creating the resolver

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);

Let's show it as a cohesive example, just for good measure...

$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);

Todo

Improve tests

About

A tool to help searching tags

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages