public function set_list()
{
/* Sample use
---------------------------------------------------------
{exp:stash:set_list name="blog_entries"}
{stash:item_title}{title}{/stash:item_title}
{stash:item_img_url}{img_url}{/stash:item_img_url}
{stash:item_copy}{copy}{/stash:item_copy}
{/exp:stash:set_list}
--------------------------------------------------------- */
// name and context
$name = $this->EE->TMPL->fetch_param('name', FALSE);
$context = $this->EE->TMPL->fetch_param('context', NULL);
$scope = strtolower($this->EE->TMPL->fetch_param('scope', $this->default_scope));
// local|user|site
// are we trying to *overwrite* an existing list (replace it but not change the existing list if the new list is empty)?
$overwrite = $this->EE->TMPL->fetch_param('overwrite', FALSE);
if ($overwrite) {
$this->replace = TRUE;
}
if (!!$name) {
if ($context !== NULL && count(explode(':', $name) == 1)) {
$name = $context . ':' . $name;
}
}
// replace '@' placeholders with the current context
$stash_key = $this->_parse_context($name);
// no results prefix
$prefix = $this->EE->TMPL->fetch_param('prefix', NULL);
// check for prefixed no_results block
if (!is_null($prefix)) {
$this->_prep_no_results($prefix);
}
// Unprefix common variables in wrapped tags
if ($unprefix = $this->EE->TMPL->fetch_param('unprefix')) {
$this->EE->TMPL->tagdata = $this->_un_prefix($unprefix, $this->EE->TMPL->tagdata);
}
// do we want to replace an existing list variable?
$set = TRUE;
if (!$this->replace && !$this->_update) {
// try to get existing value
$existing_value = FALSE;
if (array_key_exists($name, $this->_stash)) {
$existing_value = $this->_stash[$name];
} elseif ($scope !== 'local') {
// narrow the scope to user?
$session_id = $scope === 'user' ? $this->_session_id : '_global';
$existing_value = $this->EE->stash_model->get_key($stash_key, $this->bundle_id, $session_id, $this->site_id);
}
if ($existing_value !== FALSE) {
// yes, it's already been stashed, make sure it's in the stash memory cache
$this->EE->TMPL->tagdata = $this->_stash[$name] = $existing_value;
// don't overwrite existing value
$set = FALSE;
}
unset($existing_value);
}
if ($set) {
// do any parsing and string transforms before making the list
$this->EE->TMPL->tagdata = $this->_parse_output($this->EE->TMPL->tagdata);
$this->parse_complete = TRUE;
// make sure we don't run parsing again, if we're saving the list
// get stash variable pairs (note: picks up outer pairs, nested pairs and singles are ignored)
preg_match_all('#' . LD . '(stash:[a-z0-9\\-_]+)' . RD . '.*?' . LD . '/\\g{1}' . RD . '#ims', $this->EE->TMPL->tagdata, $matches);
if (isset($matches[1])) {
$this->EE->TMPL->var_pair = array_flip(array_unique($matches[1]));
}
// get the first key and see if it repeats
$keys = array_keys($this->EE->TMPL->var_pair);
if (!empty($keys)) {
$first_key = $keys[0];
preg_match_all('/' . LD . $first_key . RD . '/', $this->EE->TMPL->tagdata, $matches);
if (count($matches[0]) > 1) {
// yes we have repeating keys, so let's split the tagdata up into rows
$this->EE->TMPL->tagdata = str_replace(LD . $first_key . RD, $this->_list_delimiter . LD . $first_key . RD, $this->EE->TMPL->tagdata);
// get an array of rows, remove first element which will be empty
$rows = explode($this->_list_delimiter, $this->EE->TMPL->tagdata);
array_shift($rows);
// serialize each row and append
// bracket the serilaized string with delimiters
$tagdata = '';
foreach ($rows as $row) {
$this->EE->TMPL->tagdata = $row;
$this->_serialize_stash_tag_pairs();
if (!empty($this->EE->TMPL->tagdata)) {
$tagdata .= $this->_list_delimiter . $this->EE->TMPL->tagdata;
}
}
$this->EE->TMPL->tagdata = trim($tagdata, $this->_list_delimiter);
} else {
// get the stash var pairs values
$this->_serialize_stash_tag_pairs();
}
if ($this->not_empty($this->EE->TMPL->tagdata)) {
// set the list, but do we need to disable match/against?
if (FALSE !== $this->EE->TMPL->fetch_param('against', FALSE)) {
// already matched/against a specified column in the list, so disable match/against
unset($this->EE->TMPL->tagparams['match']);
unset($this->EE->TMPL->tagparams['against']);
}
return $this->set();
}
} else {
// make sure this variable is marked as empty, so subsquent get_list() calls return no_results
if (FALSE === $overwrite) {
$this->_stash[$name] = '';
}
if ((bool) preg_match('/1|on|yes|y/i', $this->EE->TMPL->fetch_param('output'))) {
// optionally parse and return no_results tagdata
// note: output="yes" with set_list should only be used for debugging
return $this->_no_results();
} else {
// parse no_results tagdata, but don't output
// note: unless parse_tags="yes", no parsing would occur
$this->_no_results();
}
}
}
}