/system/expressionengine/libraries/Template.php
PHP | 3955 lines | 3760 code | 81 blank | 114 comment | 53 complexity | 11391eadc288d12a85eb932d03c7f3c2 MD5 | raw file
Large files files are truncated, but you can click here to view the full file
- <?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
- /**
- * ExpressionEngine - by EllisLab
- *
- * @package ExpressionEngine
- * @author EllisLab Dev Team
- * @copyright Copyright (c) 2003 - 2012, EllisLab, Inc.
- * @license http://ellislab.com/expressionengine/user-guide/license.html
- * @link http://ellislab.com
- * @since Version 2.0
- * @filesource
- */
-
- // ------------------------------------------------------------------------
- /**
- * ExpressionEngine Template Parser Class
- *
- * @package ExpressionEngine
- * @subpackage Core
- * @category Core
- * @author EllisLab Dev Team
- * @link http://ellislab.com
- */
- class EE_Template {
-
- var $loop_count = 0; // Main loop counter.
- var $depth = 0; // Sub-template loop depth
- var $in_point = ''; // String position of matched opening tag
- var $template = ''; // The requested template (page)
- var $final_template = ''; // The finalized template
- var $fl_tmpl = ''; // 'Floating' copy of the template. Used as a temporary "work area".
- var $cache_hash = ''; // md5 checksum of the template name. Used as title of cache file.
- var $cache_status = ''; // Status of page cache (NO_CACHE, CURRENT, EXPIRED)
- var $tag_cache_status = ''; // Status of tag cache (NO_CACHE, CURRENT, EXPIRED)
- var $cache_timestamp = '';
- var $template_type = ''; // Type of template (webpage, rss)
- var $embed_type = ''; // Type of template for embedded template
- var $template_hits = 0;
- var $php_parse_location = 'output'; // Where in the chain the PHP gets parsed
- var $template_edit_date = ''; // Template edit date
- var $templates_sofar = ''; // Templates processed so far, subtemplate tracker
- var $encode_email = TRUE; // Whether to use the email encoder. This is set automatically
- var $hit_lock_override = FALSE; // Set to TRUE if you want hits tracked on sub-templates
- var $hit_lock = FALSE; // Lets us lock the hit counter if sub-templates are contained in a template
- var $parse_php = FALSE; // Whether to parse PHP or not
- var $protect_javascript = TRUE; // Protect javascript in conditionals
-
- var $tag_data = array(); // Data contained in tags
- var $modules = array(); // List of installed modules
- var $module_data = array(); // Data for modules from exp_channels
- var $plugins = array(); // List of installed plug-ins
-
- var $var_single = array(); // "Single" variables
- var $var_cond = array(); // "Conditional" variables
- var $var_pair = array(); // "Paired" variables
- var $global_vars = array(); // This array can be set via the path.php file
- var $embed_vars = array(); // This array can be set via the {embed} tag
- var $segment_vars = array(); // Array of segment variables
-
- var $tagparts = array(); // The parts of the tag: {exp:comment:form}
- var $tagdata = ''; // The chunk between tag pairs. This is what modules will utilize
- var $tagproper = ''; // The full opening tag
- var $no_results = ''; // The contents of the {if no_results}{/if} conditionals
- var $no_results_block = ''; // The {if no_results}{/if} chunk
- var $search_fields = array(); // Special array of tag parameters that begin with 'search:'
- var $date_vars = array(); // Date variables found in the tagdata (FALSE if date variables do not exist in tagdata)
- var $unfound_vars = array(); // These are variables that have not been found in the tagdata and can be ignored
- var $conditional_vars = array(); // Used by the template variable parser to prep conditionals
- var $TYPE = FALSE; // FALSE if Typography has not been instantiated, Typography Class object otherwise
-
- var $related_data = array(); // A multi-dimensional array containing any related tags
- var $related_id = ''; // Used temporarily for the related ID number
- var $related_markers = array(); // Used temporarily
-
- var $site_ids = array(); // Site IDs for the Sites Request for a Tag
- var $sites = array(); // Array of sites with site_id as key and site_name as value, used to determine site_ids for tag, above.
- var $site_prefs_cache = array(); // Array of cached site prefs, to allow fetching of another site's template files
-
- var $reverse_related_data = array(); // A multi-dimensional array containing any reverse related tags
-
- var $t_cache_path = 'tag_cache/'; // Location of the tag cache file
- var $p_cache_path = 'page_cache/'; // Location of the page cache file
- var $disable_caching = FALSE;
-
- var $debugging = FALSE; // Template parser debugging on?
- var $cease_processing = FALSE; // Used with no_results() method.
- var $log = array(); // Log of Template processing
- var $start_microtime = 0; // For Logging (= microtime())
- var $strict_urls = FALSE; // Whether to make URLs operate strictly or not. This is set via a template global pref
-
- var $realm = 'Restricted Content'; // Localize?
- var $marker = '0o93H7pQ09L8X1t49cHY01Z5j4TT91fGfr'; // Temporary marker used as a place-holder for template data
- var $form_id = ''; // Form Id
- var $form_class = ''; // Form Class
- // --------------------------------------------------------------------
-
- /**
- * Constructor
- *
- * @return void
- */
- public function __construct()
- {
- // Make a local reference to the ExpressionEngine super object
- $this->EE =& get_instance();
-
- if ($this->EE->config->item('multiple_sites_enabled') != 'y')
- {
- $this->sites[$this->EE->config->item('site_id')] = $this->EE->config->item('site_short_name');
- }
-
- if ($this->EE->config->item('template_debugging') === 'y' && $this->EE->session->userdata['group_id'] == 1)
- {
- $this->debugging = TRUE;
-
- $this->start_microtime = microtime(TRUE);
- }
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Run Template Engine
- *
- * Upon a Page or a Preview, it Runs the Processing of a Template
- * based on URI request or method arguments
- *
- * @param string
- * @param string
- * @return void
- */
- public function run_template_engine($template_group = '', $template = '')
- {
- $this->log_item(" - Begin Template Processing - ");
-
- // Set the name of the cache folder for both tag and page caching
-
- if ($this->EE->uri->uri_string != '')
- {
- $this->t_cache_path .= md5($this->EE->functions->fetch_site_index().$this->EE->uri->uri_string).'/';
- $this->p_cache_path .= md5($this->EE->functions->fetch_site_index().$this->EE->uri->uri_string).'/';
- }
- else
- {
- $this->t_cache_path .= md5($this->EE->config->item('site_url').'index'.$this->EE->uri->query_string).'/';
- $this->p_cache_path .= md5($this->EE->config->item('site_url').'index'.$this->EE->uri->query_string).'/';
- }
-
- // We limit the total number of cache files in order to
- // keep some sanity with large sites or ones that get
- // hit by over-ambitious crawlers.
- if ($this->disable_caching == FALSE)
- {
- if ($dh = @opendir(APPPATH.'cache/page_cache'))
- {
- $i = 0;
- while (FALSE !== (readdir($dh)))
- {
- $i++;
- }
-
- $max = ( ! $this->EE->config->item('max_caches') OR ! is_numeric($this->EE->config->item('max_caches')) OR $this->EE->config->item('max_caches') > 1000) ? 1000 : $this->EE->config->item('max_caches');
-
- if ($i > $max)
- {
- $this->EE->functions->clear_caching('page');
- }
- }
- }
-
- $this->log_item("URI: ".$this->EE->uri->uri_string);
- $this->log_item("Path.php Template: {$template_group}/{$template}");
-
- $this->fetch_and_parse($template_group, $template, FALSE);
-
- $this->log_item(" - End Template Processing - ");
- $this->log_item("Parse Global Variables");
- if ($this->template_type == 'static')
- {
- $this->final_template = $this->restore_xml_declaration($this->final_template);
- }
- else
- {
- $this->final_template = $this->parse_globals($this->final_template);
- }
-
- $this->log_item("Template Parsing Finished");
-
- $this->EE->output->out_type = $this->template_type;
- $this->EE->output->set_output($this->final_template);
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Fetch and Process Template
- *
- * Determines what template to process, fetches the template and its preferences, and then processes all of it
- *
- * @param string
- * @param string
- * @param bool
- * @param int
- * @return void
- */
- public function fetch_and_parse($template_group = '', $template = '', $sub = FALSE, $site_id = '')
- {
- // add this template to our subtemplate tracker
- $this->templates_sofar = $this->templates_sofar.'|'.$site_id.':'.$template_group.'/'.$template.'|';
-
- // Fetch the requested template
- // The template can either come from the DB or a cache file
- // Do not use a reference!
-
- $this->cache_status = 'NO_CACHE';
-
- $this->log_item("Retrieving Template");
-
- $this->template = ($template_group != '' AND $template != '') ?
- $this->fetch_template($template_group, $template, FALSE, $site_id) :
- $this->parse_template_uri();
-
- $this->log_item("Template Type: ".$this->template_type);
-
- $this->parse($this->template, $sub, $site_id);
-
- // -------------------------------------------
- // 'template_post_parse' hook.
- // - Modify template after tag parsing
- //
- if ($this->EE->extensions->active_hook('template_post_parse') === TRUE)
- {
- $this->final_template = $this->EE->extensions->call(
- 'template_post_parse',
- $this->final_template,
- $sub,
- $site_id
- );
- }
- //
- // -------------------------------------------
- }
- // --------------------------------------------------------------------
-
- /**
- * Parse a string as a template
- *
- * @param string
- * @param string
- * @return void
- */
- public function parse(&$str, $sub = FALSE, $site_id = '')
- {
- if ($str != '')
- {
- $this->template =& $str;
- }
- // Static Content, No Parsing
- if ($this->template_type == 'static' OR $this->embed_type == 'static')
- {
- if ($sub == FALSE)
- {
- $this->final_template = $this->template;
- }
-
- return;
- }
-
- /* -------------------------------------
- /* "Smart" Static Parsing
- /*
- /* Performed on embedded webpage templates only that do not have
- /* ExpressionEngine tags or PHP in them.
- /*
- /* Hidden Configuration Variable
- /* - smart_static_parsing => Bypass parsing of templates that could be
- /* of the type 'static' but aren't? (y/n)
- /* -------------------------------------*/
- if ($this->EE->config->item('smart_static_parsing') !== 'n' && $this->embed_type == 'webpage' && ! stristr($this->template, LD) && ! stristr($this->template, '<?'))
- {
- $this->log_item("Smart Static Parsing Triggered");
- if ($sub == FALSE)
- {
- $this->final_template = $this->template;
- }
-
- return;
- }
-
- // Parse 'Site' variables
- $this->log_item("Parsing Site Variables");
-
- // load site variables into the global_vars array
- foreach (array('site_id', 'site_label', 'site_short_name') as $site_var)
- {
- $this->EE->config->_global_vars[$site_var] = stripslashes($this->EE->config->item($site_var));
- }
-
- // Parse {last_segment} variable
- $seg_array = $this->EE->uri->segment_array();
- $this->EE->config->_global_vars['last_segment'] = end($seg_array);
- // Parse manual variables and Snippets
- // These are variables that can be set in the path.php file
-
- if (count($this->EE->config->_global_vars) > 0)
- {
- $this->log_item("Snippets (Keys): ".implode('|', array_keys($this->EE->config->_global_vars)));
- $this->log_item("Snippets (Values): ".trim(implode('|', $this->EE->config->_global_vars)));
-
- foreach ($this->EE->config->_global_vars as $key => $val)
- {
- $this->template = str_replace(LD.$key.RD, $val, $this->template);
- }
-
- // in case any of these variables have EE comments of their own
- $this->template = $this->remove_ee_comments($this->template);
- }
-
- // Parse URI segments
- // This code lets admins fetch URI segments which become
- // available as: {segment_1} {segment_2}
-
- for ($i = 1; $i < 10; $i++)
- {
- $this->template = str_replace(LD.'segment_'.$i.RD, $this->EE->uri->segment($i), $this->template);
- $this->segment_vars['segment_'.$i] = $this->EE->uri->segment($i);
- }
-
- // Parse {embed} tag variables
- if ($sub === TRUE && count($this->embed_vars) > 0)
- {
- $this->log_item("Embed Variables (Keys): ".implode('|', array_keys($this->embed_vars)));
- $this->log_item("Embed Variables (Values): ".trim(implode('|', $this->embed_vars)));
-
- foreach ($this->embed_vars as $key => $val)
- {
- // add 'embed:' to the key for replacement and so these variables work in conditionals
- $this->embed_vars['embed:'.$key] = $val;
- unset($this->embed_vars[$key]);
- $this->template = str_replace(LD.'embed:'.$key.RD, $val, $this->template);
- }
- }
-
- // cleanup of leftover/undeclared embed variables
- // don't worry with undeclared embed: vars in conditionals as the conditionals processor will handle that adequately
- if (strpos($this->template, LD.'embed:') !== FALSE)
- {
- $this->template = preg_replace('/'.LD.'embed:([^!]+?)'.RD.'/', '', $this->template);
- }
-
- // Parse date format string "constants"
- $date_constants = array('DATE_ATOM' => '%Y-%m-%dT%H:%i:%s%Q',
- 'DATE_COOKIE' => '%l, %d-%M-%y %H:%i:%s UTC',
- 'DATE_ISO8601' => '%Y-%m-%dT%H:%i:%s%Q',
- 'DATE_RFC822' => '%D, %d %M %y %H:%i:%s %O',
- 'DATE_RFC850' => '%l, %d-%M-%y %H:%m:%i UTC',
- 'DATE_RFC1036' => '%D, %d %M %y %H:%i:%s %O',
- 'DATE_RFC1123' => '%D, %d %M %Y %H:%i:%s %O',
- 'DATE_RFC2822' => '%D, %d %M %Y %H:%i:%s %O',
- 'DATE_RSS' => '%D, %d %M %Y %H:%i:%s %O',
- 'DATE_W3C' => '%Y-%m-%dT%H:%i:%s%Q'
- );
- foreach ($date_constants as $key => $val)
- {
- $this->template = str_replace(LD.$key.RD, $val, $this->template);
- }
-
- $this->log_item("Parse Date Format String Constants");
-
- // Template's Last Edit time {template_edit_date format="%Y %m %d %H:%i:%s"}
- if (strpos($this->template, LD.'template_edit_date') !== FALSE && preg_match_all("/".LD."template_edit_date\s+format=([\"\'])([^\\1]*?)\\1".RD."/", $this->template, $matches))
- {
- for ($j = 0; $j < count($matches[0]); $j++)
- {
- $this->template = str_replace($matches[0][$j], $this->EE->localize->decode_date($matches[2][$j], $this->template_edit_date), $this->template);
- }
- }
- // Current time {current_time format="%Y %m %d %H:%i:%s"}
- if (strpos($this->template, LD.'current_time') !== FALSE && preg_match_all("/".LD."current_time\s+format=([\"\'])([^\\1]*?)\\1".RD."/", $this->template, $matches))
- {
- for ($j = 0; $j < count($matches[0]); $j++)
- {
- $this->template = str_replace($matches[0][$j], $this->EE->localize->decode_date($matches[2][$j], $this->EE->localize->now), $this->template);
- }
- }
-
- $this->template = str_replace(LD.'current_time'.RD, $this->EE->localize->now, $this->template);
-
- $this->log_item("Parse Current Time Variables");
-
- // Is the main template cached?
- // If a cache file exists for the primary template
- // there is no reason to go further.
- // However we do need to fetch any subtemplates
-
- if ($this->cache_status == 'CURRENT' AND $sub == FALSE)
- {
- $this->log_item("Cached Template Used");
-
- $this->template = $this->parse_nocache($this->template);
-
- // Smite Our Enemies: Advanced Conditionals
- if (stristr($this->template, LD.'if'))
- {
- $this->template = $this->advanced_conditionals($this->template);
- }
-
- $this->log_item("Conditionals Parsed, Processing Sub Templates");
-
- $this->final_template = $this->template;
- $this->process_sub_templates($this->template);
- return;
- }
-
- // Remove whitespace from variables.
- // This helps prevent errors, particularly if PHP is used in a template
- $this->template = preg_replace("/".LD."\s*(\S+)\s*".RD."/U", LD."\\1".RD, $this->template);
-
- // Parse Input Stage PHP
- if ($this->parse_php == TRUE && $this->php_parse_location == 'input' && $this->cache_status != 'CURRENT')
- {
- $this->log_item("Parsing PHP on Input");
- $this->template = $this->parse_template_php($this->template);
- }
-
- // Smite Our Enemies: Conditionals
- $this->log_item("Parsing Segment, Embed, and Global Vars Conditionals");
-
- $this->template = $this->parse_simple_segment_conditionals($this->template);
- $this->template = $this->simple_conditionals($this->template, $this->embed_vars);
- $this->template = $this->simple_conditionals($this->template, $this->EE->config->_global_vars);
- // Assign Variables
- if (strpos($this->template, 'preload_replace') !== FALSE)
- {
- if (preg_match_all("/".LD."preload_replace:(.+?)=([\"\'])([^\\2]*?)\\2".RD."/i", $this->template, $matches))
- {
- $this->log_item("Processing Preload Text Replacements: ".trim(implode('|', $matches[1])));
-
- for ($j = 0; $j < count($matches[0]); $j++)
- {
- $this->template = str_replace($matches[0][$j], "", $this->template);
- $this->template = str_replace(LD.$matches[1][$j].RD, $matches[3][$j], $this->template);
- }
- }
- }
-
- // Parse Plugin and Module Tags
- $this->tags();
-
- if ($this->cease_processing === TRUE)
- {
- return;
- }
-
- // Parse Output Stage PHP
- if ($this->parse_php == TRUE AND $this->php_parse_location == 'output' AND $this->cache_status != 'CURRENT')
- {
- $this->log_item("Parsing PHP on Output");
- $this->template = $this->parse_template_php($this->template);
- }
-
- // Write the cache file if needed
- if ($this->cache_status == 'EXPIRED')
- {
- $this->template = $this->EE->functions->insert_action_ids($this->template);
- $this->write_cache_file($this->cache_hash, $this->template, 'template');
- }
-
- // Parse Our Uncacheable Forms
- $this->template = $this->parse_nocache($this->template);
-
- // Smite Our Enemies: Advanced Conditionals
- if (strpos($this->template, LD.'if') !== FALSE)
- {
- $this->log_item("Processing Advanced Conditionals");
- $this->template = $this->advanced_conditionals($this->template);
- }
-
- // Build finalized template
-
- // We only do this on the first pass.
- // The sub-template routine will insert embedded
- // templates into the master template
-
- if ($sub == FALSE)
- {
- $this->final_template = $this->template;
- $this->process_sub_templates($this->template);
- }
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Processes Any Embedded Templates in String
- *
- * If any {embed=} tags are found, it processes those templates and does a replacement.
- *
- * @param string
- * @return void
- */
- public function process_sub_templates($template)
- {
- // Match all {embed=bla/bla} tags
- $matches = array();
-
- if ( ! preg_match_all("/(".LD."embed\s*=)(.*?)".RD."/s", $template, $matches))
- {
- return;
- }
-
- // Loop until we have parsed all sub-templates
-
- // For each embedded tag we encounter we'll run the template parsing
- // function - AND - through the beauty of recursive functions we
- // will also call THIS function as well, allowing us to parse
- // infinitely nested sub-templates in one giant loop o' love
-
- $this->log_item(" - Processing Sub Templates (Depth: ".($this->depth+1).") - ");
-
- $i = 0;
- $this->depth++;
-
- $this->log_item("List of Embeds: ".str_replace(array('"', "'"), '', trim(implode(',', $matches[2]))));
-
- // re-match the full tag of each if necessary before we start processing
- // necessary evil in case template globals are used inside the embed tag,
- // doing this within the processing loop will result in leaving unparsed
- // embed tags e.g. {embed="foo/bar" var="{global_var}/{custom_field}"}
- $temp = $template;
- foreach ($matches[2] as $key => $val)
- {
- if (strpos($val, LD) !== FALSE)
- {
- $matches[0][$key] = $this->EE->functions->full_tag($matches[0][$key], $temp);
- $matches[2][$key] = substr(str_replace($matches[1][$key], '', $matches[0][$key]), 0, -1);
- $temp = str_replace($matches[0][$key], '', $temp);
- }
- }
-
- // Load the string helper
- $this->EE->load->helper('string');
- foreach($matches[2] as $key => $val)
- {
- $parts = preg_split("/\s+/", $val, 2);
- $this->embed_vars = (isset($parts[1])) ? $this->EE->functions->assign_parameters($parts[1]) : array();
-
- if ($this->embed_vars === FALSE)
- {
- $this->embed_vars = array();
- }
-
- $val = trim_slashes(strip_quotes($parts[0]));
- if (strpos($val, '/') === FALSE)
- {
- continue;
- }
-
- $ex = explode("/", trim($val));
-
- if (count($ex) != 2)
- {
- continue;
- }
-
- // Determine Site
- $site_id = $this->EE->config->item('site_id');
-
- if (stristr($ex[0], ':'))
- {
- $name = substr($ex[0], 0, strpos($ex[0], ':'));
-
- if ($this->EE->config->item('multiple_sites_enabled') == 'y' && ! IS_CORE)
- {
- if (count($this->sites) == 0)
- {
- // This should really be cached somewhere
- $this->EE->db->select('site_id, site_name');
- $sites_query = $this->EE->db->get('sites');
-
- foreach($sites_query->result_array() as $row)
- {
- $this->sites[$row['site_id']] = $row['site_name'];
- }
- }
-
- $site_id = array_search($name, $this->sites);
-
- if (empty($site_id))
- {
- $site_id = $this->EE->config->item('site_id');
- }
- }
-
- $ex[0] = str_replace($name.':', '', $ex[0]);
- }
-
- // Loop Prevention
- /* -------------------------------------------
- /* Hidden Configuration Variable
- /* - template_loop_prevention => 'n'
- Whether or not loop prevention is enabled - y/n
- /* -------------------------------------------*/
-
- if (substr_count($this->templates_sofar, '|'.$site_id.':'.$ex['0'].'/'.$ex['1'].'|') > 1 && $this->EE->config->item('template_loop_prevention') != 'n')
- {
- $this->final_template = ($this->EE->config->item('debug') >= 1) ? str_replace('%s', $ex['0'].'/'.$ex['1'], $this->EE->lang->line('template_loop')) : "";
- return;
- }
-
- // Process Subtemplate
- $this->log_item("Processing Sub Template: ".$ex[0]."/".$ex[1]);
-
- $this->fetch_and_parse($ex[0], $ex[1], TRUE, $site_id);
-
- $this->final_template = str_replace($matches[0][$key], $this->template, $this->final_template);
-
- $this->embed_type = '';
-
- // Here we go again! Wheeeeeee.....
- $this->process_sub_templates($this->template);
- // pull the subtemplate tracker back a level to the parent template
- $this->templates_sofar = substr($this->templates_sofar, 0, - strlen('|'.$site_id.':'.$ex[0].'/'.$ex[1].'|'));
- }
-
- $this->depth--;
-
- if ($this->depth == 0)
- {
- $this->templates_sofar = '';
- }
- }
- // --------------------------------------------------------------------
-
- /**
- * Finds Tags, Parses Them
- *
- * Goes Through the Template, Finds the Beginning and End of Tags, and Stores Tag Data in a Class Array
- *
- * @return void
- */
- public function parse_tags()
- {
- while (TRUE)
- {
- // Make a "floating" copy of the template which we'll progressively slice into pieces with each loop
-
- $this->fl_tmpl = $this->template;
-
- // Identify the string position of the first occurence of a matched tag
-
- $this->in_point = strpos($this->fl_tmpl, LD.'exp:');
-
- // If the above variable returns FALSE we are done looking for tags
- // This single conditional keeps the template engine from spiraling
- // out of control in an infinite loop.
-
- if (FALSE === $this->in_point)
- {
- break;
- }
- else
- {
- // Process the tag data
- // These REGEXs parse out the various components contained in any given tag.
-
- // Grab the opening portion of the tag: {exp:some:tag param="value" param="value"}
- if ( ! preg_match("/".LD.'exp:'.".*?".RD."/s", $this->fl_tmpl, $matches))
- {
- $this->template = preg_replace("/".LD.'exp:'.".*?$/", '', $this->template);
- break;
- }
-
- // Checking for variables/tags embedded within tags
- // {exp:channel:entries channel="{master_channel_name}"}
- if (stristr(substr($matches[0], 1), LD) !== FALSE)
- {
- $matches[0] = $this->EE->functions->full_tag($matches[0]);
- }
- $this->log_item("Tag: ".$matches[0]);
-
- $raw_tag = str_replace(array("\r\n", "\r", "\n", "\t"), " ", $matches[0]);
-
- $tag_length = strlen($raw_tag);
-
- $data_start = $this->in_point + $tag_length;
- $tag = trim(substr($raw_tag, 1, -1));
- $args = trim((preg_match("/\s+.*/", $tag, $matches))) ? $matches[0] : '';
- $tag = trim(str_replace($args, '', $tag));
-
- $cur_tag_close = LD.'/'.$tag.RD;
-
- // Deprecate "weblog" tags, but allow them to work until 2.1, then remove this.
- if (strpos($tag, ':weblog:') !== FALSE OR strpos($tag, ' weblog=') !== FALSE)
- {
- $tag = str_replace(array(':weblog:', ' weblog='), array(':channel:', ' channel='), $tag);
- $this->log_item("WARNING: Deprecated 'weblog' tag used, please change to 'channel'");
- }
-
- // -----------------------------------------
- // Grab the class name and method names contained in the tag
-
- $class = explode(':', substr($tag, strlen('exp') + 1));
-
- // Tags can either have one segment or two:
- // {exp:first_segment}
- // {exp:first_segment:second_segment}
- //
- // These two segments represent either a "class:constructor"
- // or a "class:method". We need to determine which one it is.
-
- // if (count($class) == 1)
- // {
- // $class[1] = $class[0];
- // }
-
- foreach($class as $key => $value)
- {
- $class[$key] = trim($value);
- }
-
- // -----------------------------------------
- // Assign parameters based on the arguments from the tag
- $args = $this->EE->functions->assign_parameters($args);
- // standardized mechanism for "search" type parameters get some extra lovin'
- $search_fields = array();
-
- if ($args !== FALSE)
- {
- foreach ($args as $key => $val)
- {
- if (strncmp($key, 'search:', 7) == 0)
- {
- $search_fields[substr($key, 7)] = $val;
- }
- }
- }
-
- // Trim the floating template, removing the tag we just parsed.
-
- $this->fl_tmpl = substr($this->fl_tmpl, $this->in_point + $tag_length);
-
- $out_point = strpos($this->fl_tmpl, $cur_tag_close);
-
- // Do we have a tag pair?
-
- if (FALSE !== $out_point)
- {
- // Assign the data contained between the opening/closing tag pair
-
- $this->log_item("Closing Tag Found");
-
- $block = substr($this->template, $data_start, $out_point);
-
- // Fetch the "no_results" data
-
- $no_results = '';
- $no_results_block = '';
-
- if (strpos($block, 'if no_results') !== FALSE && preg_match("/".LD."if no_results".RD."(.*?)".LD.'\/'."if".RD."/s", $block, $match))
- {
- // Match the entirety of the conditional, dude. Bad Rick!
-
- if (stristr($match[1], LD.'if'))
- {
- $match[0] = $this->EE->functions->full_tag($match[0], $block, LD.'if', LD.'\/'."if".RD);
- }
-
- $no_results = substr($match[0], strlen(LD."if no_results".RD), -strlen(LD.'/'."if".RD));
- $no_results_block = $match[0];
- }
-
- // Define the entire "chunk" - from the left edge of the opening tag
- // to the right edge of closing tag.
- $out_point = $out_point + $tag_length + strlen($cur_tag_close);
-
- $chunk = substr($this->template, $this->in_point, $out_point);
- }
- else
- {
- // Single tag...
-
- $this->log_item("No Closing Tag");
-
- $block = ''; // Single tags don't contain data blocks
-
- $no_results = '';
- $no_results_block = '';
-
- // Define the entire opening tag as a "chunk"
-
- $chunk = substr($this->template, $this->in_point, $tag_length);
- }
-
- // Strip the "chunk" from the template, replacing it with a unique marker.
-
- if (stristr($raw_tag, 'random'))
- {
- $this->template = preg_replace("|".preg_quote($chunk)."|s", 'M'.$this->loop_count.$this->marker, $this->template, 1);
- }
- else
- {
- $this->template = str_replace($chunk, 'M'.$this->loop_count.$this->marker, $this->template);
- }
-
- $cfile = md5($chunk); // This becomes the name of the cache file
- // Build a multi-dimensional array containing all of the tag data we've assembled
- $this->tag_data[$this->loop_count]['tag'] = $raw_tag;
- $this->tag_data[$this->loop_count]['class'] = $class[0];
- $this->tag_data[$this->loop_count]['method'] = (isset($class[1])) ? $class[1] : FALSE;
- $this->tag_data[$this->loop_count]['tagparts'] = $class;
- $this->tag_data[$this->loop_count]['params'] = $args;
- $this->tag_data[$this->loop_count]['chunk'] = $chunk; // Matched data block - including opening/closing tags
- $this->tag_data[$this->loop_count]['block'] = $block; // Matched data block - no tags
- $this->tag_data[$this->loop_count]['cache'] = $args;
- $this->tag_data[$this->loop_count]['cfile'] = $cfile;
- $this->tag_data[$this->loop_count]['no_results'] = $no_results;
- $this->tag_data[$this->loop_count]['no_results_block'] = $no_results_block;
- $this->tag_data[$this->loop_count]['search_fields'] = $search_fields;
- } // END IF
- // Increment counter
- $this->loop_count++;
- } // END WHILE
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Looks Through Template Looking for Tags
- *
- * Goes Through the Template, Finds the Beginning and End of Tags, and Stores Tag Data in a Class Array
- *
- * @return void
- */
- public function tags()
- {
- // Fetch installed modules and plugins if needed
- if (count($this->modules) == 0)
- {
- $this->fetch_addons();
- }
- // Parse the template.
- $this->log_item(" - Beginning Tag Processing - ");
- while (is_int(strpos($this->template, LD.'exp:')))
- {
- // Initialize values between loops
- $this->tag_data = array();
- $this->var_single = array();
- $this->var_cond = array();
- $this->var_pair = array();
- $this->loop_count = 0;
-
- $this->log_item("Parsing Tags in Template");
- // Run the template parser
- $this->parse_tags();
- $this->log_item("Processing Tags");
-
- // Run the class/method handler
- $this->process_tags();
-
- if ($this->cease_processing === TRUE)
- {
- return;
- }
- }
-
- $this->log_item(" - End Tag Processing - ");
- }
- // --------------------------------------------------------------------
-
- /**
- * Process Tags
- *
- * Takes the Class Array Full of Tag Data and Processes the Tags One by One. Class class, feeds
- * data to class, takes results, and puts it back into the Template.
- *
- * @return void
- */
- public function process_tags()
- {
- $plugins = array();
- $modules = array();
-
- // Fill an array with the names of all the classes that we previously extracted from the tags
-
- for ($i = 0, $ctd = count($this->tag_data); $i < $ctd; $i++)
- {
- // Check the tag cache file
- $cache_contents = $this->fetch_cache_file($this->tag_data[$i]['cfile'], 'tag', $this->tag_data[$i]['cache']);
-
- // Set cache status for final processing
- $this->tag_data[$i]['cache'] = $this->tag_cache_status;
- if ($this->tag_cache_status == 'CURRENT')
- {
- // If so, replace the marker in the tag with the cache data
-
- $this->log_item("Tag Cached and Cache is Current");
-
- $this->template = str_replace('M'.$i.$this->marker, $cache_contents, $this->template);
- }
- else
- {
- // Is a module or plug-in being requested?
-
- if ( ! in_array($this->tag_data[$i]['class'] , $this->modules))
- {
- if ( ! in_array($this->tag_data[$i]['class'] , $this->plugins))
- {
-
- $this->log_item("Invalid Tag");
- if ($this->EE->config->item('debug') >= 1)
- {
- if (isset($this->tag_data[$i]['tagparts'][1]) &&
- $this->tag_data[$i]['tagparts'][0] == $this->tag_data[$i]['tagparts'][1] &&
- ! isset($this->tag_data[$i]['tagparts'][2]))
- {
- unset($this->tag_data[$i]['tagparts'][1]);
- }
-
- $error = $this->EE->lang->line('error_tag_syntax');
- $error .= '<br /><br />';
- $error .= htmlspecialchars(LD);
- $error .= 'exp:'.implode(':', $this->tag_data[$i]['tagparts']);
- $error .= htmlspecialchars(RD);
- $error .= '<br /><br />';
- $error .= $this->EE->lang->line('error_fix_syntax');
-
- $this->EE->output->fatal_error($error);
- }
- else
- return FALSE;
- }
- else
- {
- $plugins[] = $this->tag_data[$i]['class'];
- $this->log_item("Plugin Tag: ".ucfirst($this->tag_data[$i]['class']).'/'.$this->tag_data[$i]['method']);
- }
- }
- else
- {
- $modules[] = $this->tag_data[$i]['class'];
- $this->log_item("Module Tag: ".ucfirst($this->tag_data[$i]['class']).'/'.$this->tag_data[$i]['method']);
- }
- }
- }
- // Remove duplicate class names and re-order the array
-
- $plugins = array_values(array_unique($plugins));
- $modules = array_values(array_unique($modules));
-
- // Dynamically require the file that contains each class
-
- $this->log_item("Including Files for Plugins and Modules");
-
- foreach ($plugins as $plugin)
- {
- // make sure it's not already included just in case
- if ( ! class_exists($plugin))
- {
- if (in_array($plugin ,$this->EE->core->native_plugins))
- {
- require_once PATH_PI."pi.{$plugin}.php";
- }
- else
- {
- require_once PATH_THIRD."{$plugin}/pi.{$plugin}.php";
- }
- }
- }
-
- foreach ($modules as $module)
- {
- // make sure it's not already included just in case
- if ( ! class_exists($module))
- {
- if (in_array($module, $this->EE->core->native_modules))
- {
- require_once PATH_MOD."{$module}/mod.{$module}.php";
- }
- else
- {
- require_once PATH_THIRD."{$module}/mod.{$module}.php";
- }
- }
- }
-
- $this->log_item("Files for Plugins and Modules All Included");
-
- // Only Retrieve Data if Not Done Before and Modules Being Called
- if (count($this->module_data) == 0 && count(array_intersect($this->modules, $modules)) > 0)
- {
- $this->EE->db->select('module_version, module_name');
- $query = $this->EE->db->get('modules');
- foreach($query->result_array() as $row)
- {
- $this->module_data[$row['module_name']] = array('version' => $row['module_version']);
- }
- }
-
- // Final data processing
- // Loop through the master array containing our extracted template data
-
- $this->log_item("Beginning Final Tag Data Processing");
-
- reset($this->tag_data);
- for ($i = 0; $i < count($this->tag_data); $i++)
- {
- if ($this->tag_data[$i]['cache'] != 'CURRENT')
- {
- $this->log_item("Calling Class/Method: ".ucfirst($this->tag_data[$i]['class'])."/".$this->tag_data[$i]['method']);
-
- /* ---------------------------------
- /* Plugin as Parameter
- /*
- /* - Example: channel="{exp:some_plugin}"
- /* - A bit of a hidden feature. Has been tested but not quite
- /* ready to say it is ready for prime time as I might want to
- /* move it to earlier in processing so that if there are
- /* multiple plugins being used as parameters it is only called
- /* once instead of for every single parameter. - Paul
- /* ---------------------------------*/
-
- if (substr_count($this->tag_data[$i]['tag'], LD.'exp') > 1 && isset($this->tag_data[$i]['params']['parse']) && $this->tag_data[$i]['params']['parse'] == 'inward')
- {
- foreach($this->tag_data[$i]['params'] as $name => $param)
- {
- if (stristr($this->tag_data[$i]['params'][$name], LD.'exp'))
- {
- $this->log_item("Plugin in Parameter, Processing Plugin First");
-
- $TMPL2 = clone $this;
- while (is_int(strpos($TMPL2->tag_data[$i]['params'][$name], LD.'exp:')))
- {
- unset($this->EE->TMPL);
- $this->EE->TMPL = new EE_Template();
- $this->EE->TMPL->start_microtime = $this->start_microtime;
- $this->EE->TMPL->template = $TMPL2->tag_data[$i]['params'][$name];
- $this->EE->TMPL->tag_data = array();
- $this->EE->TMPL->var_single = array();
- $this->EE->TMPL->var_cond = array();
- $this->EE->TMPL->var_pair = array();
- $this->EE->TMPL->plugins = $TMPL2->plugins;
- $this->EE->TMPL->modules = $TMPL2->modules;
- $this->EE->TMPL->parse_tags();
- $this->EE->TMPL->process_tags();
- $this->EE->TMPL->loop_count = 0;
- $TMPL2->tag_data[$i]['params'][$name] = $this->EE->TMPL->template;
- $TMPL2->log = array_merge($TMPL2->log, $this->EE->TMPL->log);
- }
-
- foreach (get_object_vars($TMPL2) as $key => $value)
- {
- $this->$key = $value;
- }
-
- unset($TMPL2);
-
- $this->EE->TMPL = $this;
- }
- }
- }
-
- // Nested Plugins...
- if (in_array($this->tag_data[$i]['class'] , $this->plugins) && strpos($this->tag_data[$i]['block'], LD.'exp:') !== FALSE)
- {
- if ( ! isset($this->tag_data[$i]['params']['parse']) OR $this->tag_data[$i]['params']['parse'] != 'inward')
- {
- $this->log_item("Nested Plugins in Tag, Parsing Outward First");
-
- $TMPL2 = clone $this;
-
- while (is_int(strpos($TMPL2->tag_data[$i]['block'], LD.'exp:')))
- {
- unset($this->EE->TMPL);
- $this->EE->TMPL = new EE_Template();
- $this->EE->TMPL->start_microtime = $this->start_microtime;
- $this->EE->TMPL->template = $TMPL2->tag_data[$i]['block'];
- $this->EE->TMPL->tag_data = array();
- $this->EE->TMPL->var_single = array();
- $this->EE->TMPL->var_cond = array();
- $this->EE->TMPL->var_pair = array();
- $this->EE->TMPL->plugins = $TMPL2->plugins;
- $this->EE->TMPL->modules = $TMPL2->modules;
- $this->EE->TMPL->parse_tags();
- $this->EE->TMPL->process_tags();
- $this->EE->TMPL->loop_count = 0;
- $TMPL2->tag_data[$i]['block'] = $this->EE->TMPL->template;
- $TMPL2->log = array_merge($TMPL2->log, $this->EE->TMPL->log);
- }
- foreach (get_object_vars($TMPL2) as $key => $value)
- {
- $this->$key = $value;
- }
-
- unset($TMPL2);
-
- $this->EE->TMPL = $this;
- }
- }
- // Assign the data chunk, parameters
-
- // We moved the no_results_block here because of nested tags. The first
- // parsed tag has priority for that conditional.
- $this->tagdata = str_replace($this->tag_data[$i]['no_results_block'], '', $this->tag_data[$i]['block']);
- $this->tagparams = $this->tag_data[$i]['params'];
- $this->tagchunk = $this->tag_data[$i]['chunk'];
- $this->tagproper = $this->tag_data[$i]['tag'];
- $this->tagparts = $this->tag_data[$i]['tagparts'];
- $this->no_results = $this->tag_data[$i]['no_results'];
- $this->search_fields = $this->tag_data[$i]['search_fields'];
- // Assign Sites for Tag
- $this->_fetch_site_ids();
-
- // Fetch Form Class/Id Attributes
- $this->tag_data[$i] = $this->_assign_form_params($this->tag_data[$i]);
- // Relationship Data Pulled Out
-
- // If the channel:entries tag or search:search_results is being called
- // we need to extract any relationship data that might be present.
- // Note: This needs to happen before extracting the variables
- // in the tag so it doesn't get confused as to which entry the
- // variables belong to.
-
- if (($this->tag_data[$i]['class'] == 'channel' AND $this->tag_data[$i]['method'] == 'entries')
- OR ($this->tag_data[$i]['class'] == 'search' AND $this->tag_data[$i]['method'] == 'search_results'))
- {
- $this->tagdata = $this->assign_relationship_data($this->tagdata);
- }
- // LEGACY CODE
- // Fetch the variables for this particular tag
- // Hopefully, with Jones' new parsing code we should be able to stop using the
- // assign_variables and assign_conditional_variables() methods entirely. -Paul
-
- $vars = $this->EE->functions->assign_variables($this->tag_data[$i]['block']);
-
- if (count($this->related_markers) > 0)
- {
- foreach ($this->related_markers as $mkr)
- {
- if ( ! isset($vars['var_single'][$mkr]))
- {
- $vars['var_single'][$mkr] = $mkr;
- }
- }
- }
- $this->var_single = $vars['var_single'];
- $this->var_pair = $vars['var_pair'];
- if ($this->related_id != '')
- {
- $this->var_single[$this->related_id] = $this->related_id;
- $this->related_id = '';
- }
-
- // Assign the class name and method name
- $class_name = ucfirst($this->tag_data[$i]['class']);
- $meth_name = $this->tag_data[$i]['method'];
-
- // If it's a third party class or a first party module,
- // add the root folder to the loader paths so we can use
- // libraries, models, and helpers
-
- $package_path = '';
-
- if ( ! in_array($this->tag_data[$i]['class'], $this->EE->core->native_plugins))
- {
- $package_path = in_array($this->tag_data[$i]['class'], $this->EE->core->native_modules) ? PATH_MOD : PATH_THIRD;
- $package_path .= strtolower($this->tag_data[$i]['class'].'/');
-
- $this->EE->load->add_package_path($package_path, FALSE);
- }
-
- // Dynamically instantiate the class.
- // If module, only if it is installed...
- if (in_array($this->tag_data[$i]['class'], $this->modules) && ! isset($this->module_data[$class_name]))
- {
- $this->log_item("Problem Processing Module: Module Not Installed");
- }
- else
- {
- $this->log_item(" -> Class Called: ".$class_name);
-
- $EE = new $class_name();
- }
-
- // This gives proper PHP5 __construct() support in
- // plugins and modules with only a single __construct()
- // and allows them to be named __construct() instead of a
- // PHP4-style contructor.
- if ($meth_name === FALSE && isset($EE))
- {
- if (method_exists($EE, $class_name))
- {
- $meth_name = $class_name;
- }
- elseif (method_exists($EE, '__construct'))
- {
- $meth_name = '__construct';
- }
- }
-
- // Does method exist? Is This A Module and Is It Installed?
- if ((in_array($this->tag_data[$i]['class'], $this->modules) &&
- ! isset($this->module_data[$class_name])) OR
- ! is_callable(array($EE, $meth_name)))
- {
-
- $this->log_item("Tag Not Processed: Method Inexistent or Module Not Installed");
- if ($this->EE->config->item('debug') >= 1)
- {
- if (isset($this->tag_data[$i]['tagparts'][1]) && $this->tag_data[$i]['tagparts'][0] == $this->tag_data[$i]['tagparts'][1] &&
- ! isset($this->tag_data[$i]['tagparts'][2]))
- {
- unset($this->tag_data[$i]['tagparts'][1]);
- }
-
- $error = $this->EE->lang->line('error_tag_module_processing');
- $error .= '<br /><br />';
- $error .= htmlspecialchars(LD);
- $error .= 'exp:'.implode(':', $this->tag_data[$i]['tagparts']);
- $error .= htmlspecialchars(RD);
- $error .= '<br /><br />';
- $error .= str_replace('%x', $this->tag_data[$i]['class'], str_replace('%y', $meth_name, $this->EE->lang->line('error_fix_module_processing')));
-
- $this->EE->output->fatal_error($error);
- }
- else
- {
- return;
- }
- }
-
- /*
-
- OK, lets grab the data returned from the class.
-
- First, however, lets determine if the tag has one or two segments.
- If it only has one, we don't want to call the constructor again since
- it was already called during instantiation.
-
- Note: If it only has one segment, only the object constructor will be called.
- Since constructors can't return a value just by initialializing the object
- the output of the class must be assigned to a variable called $this->return_data
-
- */
-
- $this->log_item(" -> Method Called: ".$meth_name);
-
- if ((strtolower($class_name) == strtolower($meth_name)) OR ($meth_name == '__construct'))
- {
- $return_data = (isset($EE->return_data)) ? $EE->return_data : '';
- }
- else
- {
- $return_data = $EE->$meth_name();
- }
- // if it's a third party add-on or module, remove the temporarily added path for local libraries, models, etc.
- // if a "no results" template is returned, $this->tag_data will be reset inside of the scope
- // of the tag being processed. So let's use the locally scoped variable for the class name
-
- if ($package_path)
- {
- $this->EE->load->remove_package_path($package_path);
- }
- // 404 Page Triggered, Cease All Processing of Tags From Now On
- if ($this->cease_processing === TRUE)
- {
- return;
- }
-
- $this->log_item(" -> Data Returned");
-
- // Write cache file if needed
-
- if ($this->tag_data[$i]['cache'] == 'EXPIRED')
- {
- $this->write_cache_file($this->tag_data[$i]['cfile'], $return_data);
- }
- // Replace the temporary markers we added earlier with the fully parsed data
-
- $this->template = str_replace('M'.$i.$this->marker, $return_data, $this->template);
-
- // Initialize data in case there are susequent loops
-
- $this->var_single = array();
- $this->var_cond = array();
- $this->var_pair = array();
-
- unset($return_data);
- unset($class_name);
- unset($meth_name);
- unset($EE);
- }
- }
- }
- // --------------------------------------------------------------------
-
- /**
- * Process Tags
- *
- * Channel entries can have related entries embedded within them.
- * We'll extract the related tag data, stash it away in an array, and
- * replace it with a marker string so that the template parser
- * doesn't see it. In the channel class we'll check to see if the
- * $this->EE->TMPL->related_data array contains anything. If so, we'll celebrate
- * wildly.
- *
- * @param string
- * @return string
- */
- public function assign_relationship_data($chunk)
- {
- $this->related_markers = array();
-
- if (preg_match_all("/".LD."related_entries\s+id\s*=\s*[\"\'](.+?)[\"\']".RD."(.+?)".LD.'\/'."related_entries".RD."/is", $chunk, $matches))
- {
- $this->log_item("Assigning Related Entry Data");
-
- $no_rel_content = '';
-
- for ($j = 0; $j < count($matches[0]); $j++)
- {
- $rand = $this->EE->functions->random('alnum', 8);
- $marker = LD.'REL['.$matches[1][$j].']'.$rand.'REL'.RD;
-
- if (preg_match("/".LD."if no_related_entries".RD."(.*?)".LD.'\/'."if".RD."/s", $matches[2][$j], $no_rel_match))
- {
- // Match the entirety of the conditional
-
- if (stristr($no_rel_match[1], LD.'if'))
- {
- $match[0] = $this->EE->functions->full_tag($no_rel_match[0], $matches[2][$j], LD.'if', LD.'\/'."if".RD);
- }
-
- $no_rel_content = substr($no_rel_match[0], strlen(LD."if no_related_entries".RD), -strlen(LD.'/'."if".RD));
- }
-
- $this->related_markers[] = $matches[1][$j];
- $vars = $this->EE->functions->assign_variables($matches[2][$j]);
- $this->related_id = $matches[1][$j];
- $this->related_data[$rand] = array(
- 'marker' => $rand,
- 'field_name' => $matches[1][$j],
- 'tagdata' => $matches[2][$j],
- 'var_single' => $vars['var_single'],
- 'var_pair' => $vars['var_pair'],
- 'var_cond' => $this->EE->functions->assign_conditional_variables($matches[2][$j], '\/', LD, RD),
- 'no_rel_content' => $no_rel_content
- );
-
- $chunk = str_replace($matches[0][$j], $marker, $chunk);
- }
- }
- if (preg_match_all("/".LD."reverse_related_entries\s*(.*?)".RD."(.+?)".LD.'\/'."reverse_related_entries".RD."/is", $chunk, $matches))
- {
- $this->log_item("Assigning Reverse Related Entry Data");
-
- for ($j = 0; $j < count($matches[0]); $j++)
- {
- $rand = $this->EE->functions->random('alnum', 8);
- $marker = LD.'REV_REL['.$rand.']REV_REL'.RD;
- $vars = $this->EE->functions->assign_variables($matches[2][$j]);
-
- $no_rev_content = '';
- if (preg_match("/".LD."if no_reverse_related_entries".RD."(.*?)".LD.'\/'."if".RD."/s", $matches[2][$j], $no_rev_match))
- {
- // Match the entirety of the conditional
-
- if (stristr($no_rev_match[1], LD.'if'))
- {
- $match[0] = $this->EE->functions->full_tag($no_rev_match[0], $matches[2][$j], LD.'if', LD.'\/'."if".RD);
- }
-
- $no_rev_content = substr($no_rev_match[0], strlen(LD."if no_reverse_related_entries".RD), -strlen(LD.'/'."if".RD));
- }
-
- $this->reverse_related_data[$rand] = array(
- 'marker' => $rand,
- 'tagdata' => $matches[2][$j],
- 'var_single' => $vars['var_single'],
- 'var_pair' => $vars['var_pair'],
- 'var_cond' => $this->EE->functions->assign_conditional_variables($matches[2][$j], '\/', LD, RD),
- 'params' => $this->EE->functions->assign_parameters($matches[1][$j]),
- 'no_rev_content' => $no_rev_content
- );
-
- $chunk = str_replace($matches[0][$j], $marker, $chunk);
- }
- }
-
- return $chunk;
- }
- // --------------------------------------------------------------------
-
- /**
- * Fetch Parameter for Tag
- *
- * Used by Modules to fetch a paramter for the tag currently be processed. We also have code
- * in here to convert legacy values like 'y' and 'on' to their more respectable full values.
- * Further, if one assigns the second argument, it will be returned as the value if a
- * parameter of the $which name does not exist for this tag. Handy for default values!
- *
- * @access string
- * @access bool
- * @return string
- */
- public function fetch_param($which, $default = FALSE)
- {
- if ( ! isset($this->tagparams[$which]))
- {
- return $default;
- }
- else
- {
- // Making yes/no tag parameters consistent. No "y/n" or "on/off".
- switch($this->tagparams[$which])
- {
- case 'y' :
- case 'on' :
- return 'yes';
- break;
- case 'n' :
- case 'off' :
- return 'no';
- break;
- default :
- return $this->tagparams[$which];
- break;
- …
Large files files are truncated, but you can click here to view the full file