Skip to content

Commit

Permalink
Updated the parser for better performance.
Browse files Browse the repository at this point in the history
  • Loading branch information
Pascal Kriete authored and Pascal Kriete committed Nov 9, 2008
1 parent 9bfb317 commit f59b458
Showing 1 changed file with 77 additions and 90 deletions.
167 changes: 77 additions & 90 deletions application/libraries/SP_Parser.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@
class SP_Parser extends CI_Parser {

var $CI;
var $globals = array();
var $id;

var $dynamic_parsed = FALSE;
var $dynamic = array('category', 'forum', 'thread', 'post', 'member');

/**
* Constructor
Expand All @@ -13,6 +16,11 @@ class SP_Parser extends CI_Parser {
function SP_Parser()
{
$this->CI =& get_instance();

// $this->delim is just too much typing
// ditch them, but still use them
define(T_OPEN, $this->l_delim);
define(T_CLOSE, $this->r_delim);
}

// --------------------------------------------------------------------
Expand All @@ -35,19 +43,18 @@ function parse($text, $nest_vars = array())

// Conditionals that use the globals
$text = $this->_conditionals($text);

// The dynamic content needs an id
$id = end($this->CI->uri->segment_array());
$id = is_numeric($id) ? $id : FALSE;

// Parse the db content - lots of work get's done here
$text = $this->_db_content($text, $id);
$this->id = is_numeric($id) ? $id : FALSE;

// Start parsing the pairs
$text = $this->_find_pairs($text);

// Last conditional run
$text = $this->_conditionals($text);

// Nested optionals?
return $text;
}

Expand Down Expand Up @@ -102,8 +109,7 @@ function _simple_tags($text, $nest_vars)
$text = $this->_parse_single($key, (string)$val, $text);
}

// Add them to the global array so other parsers can use them
$this->_set_global($simple_tags);
// Free up memory
unset($simple_tags);

return $text;
Expand All @@ -112,77 +118,92 @@ function _simple_tags($text, $nest_vars)
// --------------------------------------------------------------------

/**
* Parse the dynamic [read:automagic from url] tags
* Find pairs and parse them accordingly
*
* @access public
*/
function _db_content($text, $id = FALSE)
function _find_pairs($text)
{
$db_content = array(
$pairs = array(
'category',
'forum',
'forums',
'thread',
'threads',
'post',
'member'
);

$tag_name = '('.implode('|', $pairs).')';
$optional = '(?: (.+?))?';
$parameter = '(?:[:](\d+))?';

// Only want to look for dynamic stuff once
$dynamic_parsed = FALSE;
// One regex to rule them all
$regex = "#" . T_OPEN . $tag_name . $parameter . $optional . T_CLOSE . "(.+?)" . T_OPEN . '/\\1' . T_CLOSE. "#is";

foreach($db_content as $node_type)
return preg_replace_callback($regex, array($this, '_handle_pairs'), $text);
}

// --------------------------------------------------------------------

/**
* Handle the inner parsing for each pair
*
* @access public
*/
function _handle_pairs($matches)
{
// For readability
$text = $matches[0];
$tag = $matches[1];
$param = $matches[2];
$optional = $matches[3];
$inner = $matches[4];

// The function that will do the heavy lifting
$pf = '_parse_'.$tag;

if (! method_exists($this, $pf))
{
// Regular expression patterns
$optional = '(?: (.+?))?';
$dynamic = "#{" . $node_type . $optional . "}(.+?){" . '/'.$node_type . "}#is";
$static = "#{" . $node_type . ':(\d+)' . $optional . "}(.+?){" . '/'.$node_type . "}#is";

// Parsing function for this node type
$pf = '_parse_'.$node_type;

// If there is no id or we've found a dynamic one - skip it
if (is_numeric($id) && ! $dynamic_parsed)
// Unknown tag - do nothing
return $text;
}

// If it's in the dynamic list, it needs an id of some sort.
// The first time we use the function parameter (url id)
// after that it must have a :id to be parsed
if (in_array($tag, $this->dynamic))
{
// No parameter, check dynamic
if ( ! $param)
{
// Dynamic content
if ( preg_match_all($dynamic, $text, $matches))

// Dynamic gone or we have no id? Skip
if ($this->dynamic_parsed || ! $this->id)
{
// First and last dynamic one
$dynamic_parsed = TRUE;

foreach($matches[0] as $key => $full_match)
{
$optional = $matches[1][$key];
$inner = $matches[2][$key];

$optional = $this->_split_optional($optional);

$replace = $this->$pf($inner, $optional, $id);
$text = str_replace($full_match, $replace, $text);
}
return $text;
}
}

// Static content
if ( preg_match_all($static, $text, $matches))
{
foreach($matches[0] as $key => $full_match)
else
{
$id = $matches[1][$key];
$optional = $matches[2][$key];
$inner = $matches[3][$key];

$optional = $this->_split_optional($optional);

$replace = $this->$pf($inner, $optional, $id);
$text = str_replace($full_match, $replace, $text);
// This will be a the dynamic one
$this->dynamic_parsed = TRUE;
$id = $this->id;
}
}
else
{
$id = $param;
}
}

return $text;
// Make an optionals array
$optional = $this->_split_optional($optional);

return $this->$pf($inner, $optional, $id);
}

// --------------------------------------------------------------------

/**
* Parse the category tags
*
Expand Down Expand Up @@ -298,7 +319,6 @@ function _parse_node($current, $text, $node_type, $prefix = '')

$text = $this->_parse_single($tmp_key, (string)$tmp_val, $text);
}

return $text;
}

Expand Down Expand Up @@ -398,39 +418,6 @@ function _parse_php($text)

// --------------------------------------------------------------------

/**
* Add parsed tags to the globals array
*
* @access private
*/
function _set_global($key, $val = FALSE)
{
if (is_array($key))
{
$this->globals = array_merge($this->globals, $key);
return;
}
$this->globals[$key] = $value;
}

// --------------------------------------------------------------------

/**
* Returns the value of the parsed tag
*
* @access private
*/
function _get_global($key)
{
if (isset($this->globals[$key]))
{
return $this->globals[$key];
}
return FALSE;
}

// --------------------------------------------------------------------

/**
* Checks for an optional part and splits it into a nice array
*
Expand Down

0 comments on commit f59b458

Please sign in to comment.