public function get($params = '', $type = 'variable', $scope = 'user')
{
/* Sample use
---------------------------------------------------------
{exp:stash:get name="title"}
OR static call within PHP enabled templates or other add-on:
<?php echo stash::get('title') ?>
--------------------------------------------------------- */
// is this method being called directly?
if (func_num_args() > 0) {
if (!(isset($this) && get_class($this) == __CLASS__)) {
return self::_api_static_call(__FUNCTION__, $params, $type, $scope);
} else {
return $this->_api_call(__FUNCTION__, $params, $type, $scope);
}
}
if ($this->process !== 'inline') {
if ($out = $this->_post_parse(__FUNCTION__)) {
return $out;
}
}
$name = $this->EE->TMPL->fetch_param('name');
$default = $this->EE->TMPL->fetch_param('default', NULL);
// default value
$dynamic = (bool) preg_match('/1|on|yes|y/i', $this->EE->TMPL->fetch_param('dynamic'));
$save = (bool) preg_match('/1|on|yes|y/i', $this->EE->TMPL->fetch_param('save'));
$scope = strtolower($this->EE->TMPL->fetch_param('scope', $this->default_scope));
// local|user|site
$bundle = $this->EE->TMPL->fetch_param('bundle', NULL);
// save in a bundle?
$match = $this->EE->TMPL->fetch_param('match', NULL);
// regular expression to test value against
$filter = $this->EE->TMPL->fetch_param('filter', NULL);
// regex pattern to search for
// do we want this tag to return the value, or just set the variable quietly in the background?
$output = (bool) preg_match('/1|on|yes|y/i', $this->EE->TMPL->fetch_param('output', 'yes'));
// parse any vars in the $name parameter?
if ($this->parse_vars) {
$name = $this->_parse_template_vars($name);
}
// low search support - do we have a query string?
$low_query = $this->EE->TMPL->fetch_param('low_query', NULL);
// context handling
$context = $this->EE->TMPL->fetch_param('context', NULL);
$global_name = $name;
if ($context !== NULL && count(explode(':', $name) == 1)) {
$name = $context . ':' . $name;
$this->EE->TMPL->tagparams['context'] = NULL;
}
// parse '@' context pointers
$name_in_context = $this->_parse_context($name);
// read from file?
$file = (bool) preg_match('/1|on|yes|y/i', $this->EE->TMPL->fetch_param('file'));
$file_name = $this->EE->TMPL->fetch_param('file_name', FALSE);
// default value
// when to parse the variable if reading from a file and saving:
// before we save it to database (set) or when we retrieve it (get), or on set and get (both)
$parse_stage = strtolower($this->EE->TMPL->fetch_param('parse_stage', 'set'));
// set|get|both
if (!!$file_name) {
$file = TRUE;
} else {
$file_name = $name;
}
// the variable value
$value = NULL;
// do we want to set the variable?
$set = FALSE;
// is it a segment? We need to support these in stash template files
if (strncmp($name, 'segment_', 8) === 0) {
$seg_index = substr($name, 8);
$value = $this->EE->uri->segment($seg_index);
} elseif (is_string($name) && array_key_exists($name, $this->_stash)) {
$value = $this->_stash[$name];
} elseif (is_string($name_in_context) && array_key_exists($name_in_context, $this->_stash)) {
$value = $this->_stash[$name_in_context];
$name = $name_in_context;
} else {
// has it been bundled?
if (!is_null($bundle) && isset(self::$bundles[$bundle][$name])) {
$value = $this->_stash[$name] = self::$bundles[$bundle][$name];
} elseif (!$this->_update && !($dynamic && !$save) && $scope !== 'local') {
// let's look in the database table cache, but only if if we're not
// appending/prepending or trying to register a global without saving it
// narrow the scope to user?
$session_id = $scope === 'user' ? $this->_session_id : '_global';
// replace '@' placeholders with the current context
$stash_key = $this->_parse_context($name);
// look for our key
if ($parameters = $this->EE->stash_model->get_key($stash_key, $this->bundle_id, $session_id, $this->site_id)) {
// save to session
$value = $this->_stash[$name] = $parameters;
}
}
// Are we looking for a superglobal or uri segment?
if ($dynamic && $value === NULL || $dynamic && $this->replace) {
$from_global = FALSE;
// low search support
if ($low_query !== NULL) {
// has the query string been supplied or is it in POST?
if (strncmp($low_query, 'stash:', 6) == 0) {
$low_query = substr($low_query, 6);
$low_query = $this->_stash[$low_query];
}
$low_query = @unserialize(base64_decode(str_replace('_', '/', $low_query)));
if (isset($low_query[$global_name])) {
$from_global = $low_query[$global_name];
unset($low_query);
} else {
// set to empty value
$from_global = '';
}
}
// or is it in the $_POST or $_GET superglobals ( run through xss_clean() )?
if ($from_global === FALSE) {
$from_global = $this->EE->input->get_post($global_name, TRUE);
}
if ($from_global === FALSE) {
// no, so let's check the uri segments
$segs = $this->EE->uri->segment_array();
foreach ($segs as $index => $segment) {
if ($segment == $global_name && array_key_exists($index + 1, $segs)) {
$from_global = $segs[$index + 1];
break;
}
}
}
if ($from_global !== FALSE) {
// save to stash, and optionally to database, if save="yes"
$value = $from_global;
$set = TRUE;
}
}
// Are we reading a file?
if ($file && $value === NULL || $file && $this->replace || $file && $this->file_sync) {
// extract and remove the file extension, if provided
$ext = 'html';
// default extension
# PHP 5.3+ only
# $file_ext = preg_filter('/^.*\./', '', $file_name);
$file_ext = NULL;
if (preg_match('/^.*\\./', $file_name)) {
$file_ext = preg_replace('/^.*\\./', '', $file_name);
}
// make sure the extension is allowed
if (!is_null($file_ext)) {
if (in_array($file_ext, $this->file_extensions)) {
$ext = $file_ext;
}
}
// strip file ext (if any) and make sure we have a safe url encoded file path
$file_path = preg_replace('/\\.[^.]*$/', '', $file_name);
#$file_path = explode(':', $file_path);
$file_path = preg_split("/[:\\/]+/", $file_path);
foreach ($file_path as &$part) {
// make sure it's a valid url title
$part = str_replace('.', '', $part);
// insist upon alphanumeric characters and - or _
$part = trim(preg_replace('/[^a-z0-9\\-\\_]+/', '-', strtolower($part)), '-');
}
unset($part);
// remove reference
// remove any empty url parts
$file_path = array_filter($file_path);
$file_path = $this->path . implode('/', $file_path) . '.' . $ext;
if (file_exists($file_path)) {
$this->EE->TMPL->log_item("Stash: reading file " . $file_path);
$value = str_replace("\r\n", "\n", file_get_contents($file_path));
$set = TRUE;
// disable tag parsing on set when parse_stage is 'get'
if ($parse_stage == 'get') {
$this->parse_complete = TRUE;
}
} else {
$this->EE->output->show_user_error('general', sprintf($this->EE->lang->line('stash_file_not_found'), $file_path));
return;
}
}
}
// set to default value if it NULL or empty string (this permits '0' to be a valid value)
if (($value === NULL || $value === '') && !is_null($default)) {
$value = $default;
$set = TRUE;
}
// create/update value of variable if required
// note: don't save if we're updating a variable (to avoid recursion)
if ($set && !$this->_update) {
$this->EE->TMPL->tagparams['name'] = $name;
$this->EE->TMPL->tagparams['output'] = 'yes';
$this->EE->TMPL->tagdata = $value;
$this->replace = TRUE;
$value = $this->set();
}
$this->EE->TMPL->log_item('Stash: RETRIEVED ' . $name . ' with value ' . $value);
// save to bundle
if ($bundle !== NULL) {
if (!isset(self::$bundles[$bundle])) {
self::$bundles[$bundle] = array();
}
self::$bundles[$bundle][$name] = $value;
}
// are we outputting the variable?
if ($output) {
if (!$file) {
$value = $this->_parse_output($value, $match, $filter, $default);
} else {
// If this is a variable loaded originally from a file, parse if the desired parse stage is on retrieval (parse_stage="get|both")
if ($parse_stage == 'get' || $parse_stage == 'both') {
$this->parse_complete = FALSE;
// enable parsing
$this->parse_vars = TRUE;
// ensure early global and stash vars are always fully parsed
$value = $this->_parse_output($value, $match, $filter, $default);
} else {
// ensure early global vars are always parsed
$value = $this->_parse_template_vars($value);
}
}
return $value;
}
}