private function _parse_sub_template($tags = TRUE, $vars = TRUE, $conditionals = FALSE, $depth = 1, $nocache_id = FALSE)
{
$this->EE->TMPL->log_item("Stash: processing inner tags");
// optional prefix to use for nocache pairs
if ($nocache_prefix = $this->EE->TMPL->fetch_param('prefix', FALSE)) {
// add to the array for optional removal at the end of template parsing
if (!in_array($nocache_prefix, self::$_nocache_prefixes)) {
self::$_nocache_prefixes[] = $nocache_prefix;
}
} else {
$nocache_prefix = 'stash';
}
// nocache tags
if (FALSE === $nocache_id) {
$this->nocache_id = $this->EE->functions->random();
}
$nocache = $nocache_prefix . $this->_nocache_suffix;
$nocache_pattern = '/' . LD . $nocache . RD . '(.*)' . LD . '\\/' . $nocache . RD . '/Usi';
// save TMPL values for later
$tagparams = $this->EE->TMPL->tagparams;
$tagdata = $this->EE->TMPL->tagdata;
// call the stash_fetch_template hook to prep nested stash embeds
if ($this->EE->extensions->active_hook('stash_fetch_template') === TRUE && !$this->_embed_nested) {
// stash embed vars
$embed_vars = (array) $this->EE->TMPL->fetch_param('embed_vars', array());
$this->EE->session->cache['stash'] = array_merge($this->EE->session->cache['stash'], $embed_vars);
// call the hook
$this->EE->extensions->call('stash_fetch_template', array('template_data' => $this->EE->TMPL->tagdata));
// don't run again for this template
$this->_embed_nested = TRUE;
}
// restore original TMPL values
$this->EE->TMPL->tagparams = $tagparams;
$this->EE->TMPL->tagdata = $tagdata;
if (self::$_nocache) {
// protect content inside {stash:nocache} tags, or {[prefix]:nocache} tags
$this->EE->TMPL->tagdata = preg_replace_callback($nocache_pattern, array($this, '_placeholders'), $this->EE->TMPL->tagdata);
} else {
// remove extraneous {stash:nocache} tags, or {[prefix]:nocache} tags
$this->EE->TMPL->tagdata = str_replace(array(LD . $nocache . RD, LD . '/' . $nocache . RD), '', $this->EE->TMPL->tagdata);
}
// parse variables
if ($vars) {
// note: each pass can expose more variables to be parsed after tag processing
$this->EE->TMPL->tagdata = $this->_parse_template_vars($this->EE->TMPL->tagdata);
if (self::$_nocache) {
// protect content inside {stash:nocache} tags that might have been exposed by parse_vars
$this->EE->TMPL->tagdata = preg_replace_callback($nocache_pattern, array($this, '_placeholders'), $this->EE->TMPL->tagdata);
} else {
// remove extraneous {stash:nocache} tags, or {[prefix]:nocache} tags
$this->EE->TMPL->tagdata = str_replace(array(LD . $nocache . RD, LD . '/' . $nocache . RD), '', $this->EE->TMPL->tagdata);
}
}
// parse conditionals?
if ($conditionals && strpos($this->EE->TMPL->tagdata, LD . 'if') !== FALSE) {
// prep {If var1 IN (var2)}../if] style conditionals
if ($this->parse_if_in) {
$this->EE->TMPL->tagdata = $this->_prep_in_conditionals($this->EE->TMPL->tagdata);
}
// parse conditionals
if (version_compare(APP_VER, '2.9', '<')) {
// pre EE 2.9, we can only parse "simple" segment and global conditionals on each pass,
// leaving "advanced" ones until after tag parsing has completed
$this->EE->TMPL->tagdata = $this->EE->TMPL->parse_simple_segment_conditionals($this->EE->TMPL->tagdata);
$this->EE->TMPL->tagdata = $this->EE->TMPL->simple_conditionals($this->EE->TMPL->tagdata, $this->EE->config->_global_vars);
} else {
// with EE 2.9 and later we can parse conditionals when the variables referenced have a value ("when ready")
// populate user variables
$user_vars = $this->_get_users_vars();
$logged_in_user_cond = array();
foreach ($user_vars as $val) {
if (isset($this->EE->session->userdata[$val]) and ($val == 'group_description' or strval($this->EE->session->userdata[$val]) != '')) {
$logged_in_user_cond['logged_in_' . $val] = $this->EE->session->userdata[$val];
}
}
// Parse conditionals for known variables *without* converting unknown variables
// used in if/else statements to false or 'n'
$this->EE->TMPL->tagdata = $this->EE->functions->prep_conditionals($this->EE->TMPL->tagdata, array_merge($this->EE->TMPL->segment_vars, $this->EE->TMPL->template_route_vars, $this->EE->TMPL->embed_vars, $logged_in_user_cond, $this->EE->config->_global_vars));
}
}
// Remove any EE comments that might have been exposed before parsing tags
if (strpos($this->EE->TMPL->tagdata, '{!--') !== FALSE) {
$this->EE->TMPL->tagdata = preg_replace("/\\{!--.*?--\\}/s", '', $this->EE->TMPL->tagdata);
}
// clone the template object
$TMPL2 = $this->EE->TMPL;
unset($this->EE->TMPL);
// parse tags, but check that there really are unparsed tags in the current shell
if ($tags && strpos($TMPL2->tagdata, LD . 'exp:') !== FALSE) {
// copy object properties from original
$this->EE->TMPL = new EE_Template();
$this->EE->TMPL->start_microtime = $TMPL2->start_microtime;
$this->EE->TMPL->template = $TMPL2->tagdata;
$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->module_data = $TMPL2->module_data;
// copy globals
$this->EE->TMPL->segment_vars = $TMPL2->segment_vars;
$this->EE->TMPL->embed_vars = $TMPL2->embed_vars;
$this->EE->TMPL->template_route_vars = array();
if (isset($TMPL2->template_route_vars)) {
$this->EE->TMPL->template_route_vars = $TMPL2->template_route_vars;
}
$this->EE->TMPL->layout_conditionals = array();
if (isset($TMPL2->layout_conditionals)) {
$this->EE->TMPL->layout_conditionals = $TMPL2->layout_conditionals;
}
// parse tags
$this->EE->TMPL->parse_tags();
$this->EE->TMPL->process_tags();
$this->EE->TMPL->loop_count = 0;
$TMPL2->tagdata = $this->EE->TMPL->template;
$TMPL2->log = array_merge($TMPL2->log, $this->EE->TMPL->log);
} else {
$depth = 1;
}
$this->EE->TMPL = $TMPL2;
unset($TMPL2);
// recursively parse?
if ($depth > 1) {
$depth--;
// the merry-go-round... parse the next shell of tags
$this->_parse_sub_template($tags, $vars, $conditionals, $depth, $this->nocache_id);
} else {
// recursive parsing complete
// parse advanced conditionals?
if ($conditionals && strpos($this->EE->TMPL->tagdata, LD . 'if') !== FALSE) {
// record if PHP is enabled for this template
$parse_php = $this->EE->TMPL->parse_php;
if (!isset($this->EE->TMPL->layout_conditionals)) {
$this->EE->TMPL->layout_conditionals = array();
}
// this will parse all remaining conditionals, with unknown variables used in if/else
// statements being converted to false or 'n' so they are parsed safely
$this->EE->TMPL->tagdata = $this->EE->TMPL->advanced_conditionals($this->EE->TMPL->tagdata);
// restore original parse_php flag for this template
$this->EE->TMPL->parse_php = $parse_php;
}
// call the 'stash_post_parse' hook
if ($this->EE->extensions->active_hook('stash_post_parse') === TRUE && $this->_embed_nested === TRUE) {
$this->EE->TMPL->tagdata = $this->EE->extensions->call('stash_post_parse', $this->EE->TMPL->tagdata, FALSE, $this->site_id);
}
// restore content inside {stash:nocache} tags
// we must do this even if nocache has been disabled, since it may have been disabled after tags were escaped
foreach ($this->_ph as $index => $val) {
$this->EE->TMPL->tagdata = str_replace('[_' . __CLASS__ . '_' . ($index + 1) . '_' . $this->nocache_id . ']', $val, $this->EE->TMPL->tagdata);
}
// parse EE nocache placeholders {NOCACHE}
$this->EE->TMPL->tagdata = $this->EE->TMPL->parse_nocache($this->EE->TMPL->tagdata);
}
}