예제 #1
0
 /**
  * Constructor
  *
  * @access	public
  * @return	void
  */
 function Parse_url($str = '')
 {
     $EE =& get_instance();
     if ($str == '') {
         $str = $EE->TMPL->tagdata;
     }
     // ---------------------------------------
     //  Plugin Parameters
     // ---------------------------------------
     $autod = $EE->TMPL->fetch_param('find_uris', 'yes');
     $parts = $EE->TMPL->fetch_param('parts', 'scheme|host|path');
     $omit = $EE->TMPL->fetch_param('omit', '');
     $parts = trim($parts);
     $omit = explode('|', $omit);
     if (substr($parts, 0, 3) == 'not') {
         $not = explode('|', trim(substr($parts, 3)));
         $possible = array('scheme', 'user', 'pass', 'host', 'port', 'path', 'query', 'fragment');
         $parts = implode('|', array_diff($possible, $not));
     }
     // ---------------------------------------
     //  No auto-discovery? Just one big URL
     // ---------------------------------------
     if ($autod == 'no') {
         $str = trim($str);
         $str = $this->_parse_uri($str, $parts, $omit);
         $this->return_data = $str;
         return;
     }
     // ---------------------------------------
     //  Protect Any URLs in HTML
     // ---------------------------------------
     $easy = array();
     if (preg_match_all("/<.*?>/i", $str, $matches)) {
         $EE->load->helper('string');
         $hash = unique_marker('pi_parse_url');
         for ($i = 0, $s = count($matches['0']); $i < $s; $i++) {
             $easy[$hash . '_' . $i] = $matches['0'][$i];
             $str = str_replace($matches['0'][$i], $hash . '_' . $i, $str);
         }
     }
     // ---------------------------------------
     //  Find Any URLs Not in HTML
     // ---------------------------------------
     if (preg_match_all("#(http(s?)://|www\\.*)([a-z0-9@%_.~\\#\\/\\-\\?&=]+)[^\\s\\)\\<]+#i", $str, $matches)) {
         for ($i = 0, $s = count($matches['0']); $i < $s; $i++) {
             $uri = $this->_parse_uri($matches[0][$i], $parts, $omit);
             $str = str_replace($matches[0][$i], $uri, $str);
         }
     }
     // ---------------------------------------
     //  Replace Protected HTML
     // ---------------------------------------
     if (count($easy) > 0) {
         foreach ($easy as $key => $value) {
             $str = str_replace($key, $value, $str);
         }
     }
     $this->return_data = $str;
 }
예제 #2
0
 /**
  * Display an RTE field
  *
  * @param string $data       the RTE html content
  * @param string $field_name the field name for the RTE field
  * @param array $settings   field settings:
  * 					field_ta_rows - the number of textarea rows
  * 					field_text_direction - ltr or rtl
  * 					field_fmt - xhtml, br or none
  *
  * @return string
  */
 public function display_field($data, $field_name, $settings, $container = NULL)
 {
     if (!ee()->session->cache('rte', 'loaded')) {
         ee()->javascript->output(ee()->rte_lib->build_js(0, '.WysiHat-field', NULL, REQ == 'CP'));
         ee()->session->set_cache('rte', 'loaded', TRUE);
     }
     ee()->load->helper('form');
     $field = array('name' => $field_name, 'id' => $field_name, 'rows' => $settings['field_ta_rows'], 'dir' => $settings['field_text_direction']);
     // form prepped nonsense
     $code_marker = unique_marker('code');
     $code_chunks = array();
     $data = trim($data);
     $data = htmlspecialchars_decode($data, ENT_QUOTES);
     // Collapse tags and undo any existing newline formatting. Typography
     // will change it anyways and the rte will add its own. Having this here
     // prevents growing-newline syndrome in the rte and lets us switch
     // between rte and non-rte.
     $data = preg_replace('/<br( *\\/)?>\\n*/is', "<br>\n", $data);
     $data = preg_replace("/<\\/p>\n*<p>/is", "\n\n", $data);
     $data = preg_replace("/<br>\n/is", "\n", $data);
     // most newlines we should ever have is 2
     $data = preg_replace('/\\n\\n+/', "\n\n", $data);
     // remove code chunks
     if (preg_match_all("/\\[code\\](.+?)\\[\\/code\\]/si", $data, $matches)) {
         foreach ($matches[1] as $i => $chunk) {
             $code_chunks[$i] = trim($chunk);
             $data = str_replace($matches[0][$i], $code_marker . $i, $data);
         }
     }
     // Check the RTE module and user's preferences
     if (ee()->session->userdata('rte_enabled') == 'y' and ee()->config->item('rte_enabled') == 'y') {
         $field['class'] = 'WysiHat-field';
         foreach ($code_chunks as $i => $chunk) {
             $chunk = htmlentities($chunk, ENT_QUOTES, 'UTF-8');
             $chunk = str_replace("\n", '<br>', $chunk);
             $code_chunks[$i] = $chunk;
         }
         // xhtml vs br
         ee()->load->library('typography');
         $data = ee()->typography->auto_typography($data, TRUE);
         // remove non breaking spaces. typography likes to throw those
         // in when a list is indented.
         $data = str_replace('&nbsp;', ' ', $data);
     }
     // put code chunks back
     foreach ($code_chunks as $i => $chunk) {
         $data = str_replace($code_marker . $i, '[code]' . $chunk . '[/code]', $data);
     }
     // Swap {filedir_x} with the real URL. It will be converted back
     // upon submit by the RTE Image tool.
     ee()->load->model('file_upload_preferences_model');
     $dirs = ee()->file_upload_preferences_model->get_file_upload_preferences(ee()->session->userdata('group_id'));
     foreach ($dirs as $d) {
         // tag to replace
         $filedir = "{filedir_{$d['id']}}";
         $data = str_replace($filedir, $d['url'], $data);
     }
     $field['value'] = $data;
     $return_data = form_textarea($field);
     if ($container = 'grid') {
         $return_data = '<div class="grid_full_cell_container">' . $return_data . '</div>';
     }
     return $return_data;
 }
예제 #3
0
 /**
  * Initialize
  *
  * Reset all class properties - call after loading and before use
  * since CI will return the existing class when it's requested each time
  * inheriting the previous use's properties
  *
  * @return	void
  */
 public function initialize($config = array())
 {
     // reset class properties
     $this->single_line_pgfs = TRUE;
     // Whether to treat single lines as paragraphs in auto-xhtml
     $this->text_format = 'xhtml';
     // xhtml, markdown, br, none, or lite
     $this->html_format = 'safe';
     // safe, all, none
     $this->auto_links = 'y';
     $this->allow_img_url = 'n';
     $this->parse_images = TRUE;
     $this->allow_headings = TRUE;
     $this->encode_email = TRUE;
     $this->encode_type = 'javascript';
     // javascript or noscript
     $this->use_span_tags = TRUE;
     $this->popup_links = FALSE;
     $this->bounce = '';
     $this->smiley_array = FALSE;
     $this->parse_smileys = TRUE;
     $this->highlight_code = TRUE;
     $this->convert_curly = TRUE;
     // Convert Curly Brackets Into Entities
     $this->emoticon_url = '';
     $this->site_index = '';
     $this->word_censor = FALSE;
     $this->censored_words = array();
     $this->censored_replace = '';
     $this->text_fmt_types = array('xhtml', 'markdown', 'br', 'none', 'lite');
     $this->text_fmt_plugins = array();
     $this->html_fmt_types = array('safe', 'all', 'none');
     $this->yes_no_syntax = array('y', 'n');
     $this->code_chunks = array();
     $this->code_counter = 0;
     $this->http_hidden = unique_marker('typography_url_protect');
     // hash to protect URLs in [url] BBCode
     $this->safe_img_src_end = unique_marker('typography_img_src_end');
     // hash to mark end of image URLs during sanitizing of image tags
     foreach ($config as $key => $val) {
         $this->{$key} = $val;
     }
     /** -------------------------------------
     		/**  Allowed tags
     		/** -------------------------------------*/
     // Note: The decoding array is associative, allowing more precise mapping
     $this->safe_encode = array('b', 'i', 'em', 'del', 'ins', 'strong', 'pre', 'code', 'blockquote');
     $this->safe_decode = array('b' => 'b', 'i' => 'i', 'em' => 'em', 'del' => 'del', 'ins' => 'ins', 'strong' => 'strong', 'pre' => 'pre', 'code' => 'code', 'blockquote' => 'blockquote', 'quote' => 'blockquote', 'QUOTE' => 'blockquote');
     // enable quote protection within braces for EE {variable="attributes"}
     $this->protect_braced_quotes = TRUE;
     if ($this->allow_headings == TRUE) {
         foreach (array('h2', 'h3', 'h4', 'h5', 'h6') as $val) {
             $this->safe_encode[] = $val;
             $this->safe_decode[$val] = $val;
         }
     }
     /** -------------------------------------
     		/**  Fetch emoticon prefs
     		/** -------------------------------------*/
     if (ee()->config->item('enable_emoticons') == 'y') {
         $this->_fetch_emotions_prefs();
     }
     /* -------------------------------------------
     		/*	Hidden Configuration Variables
     		/*	- popup_link => Have links created by Typography class open in a new window (y/n)
     		/* -------------------------------------------*/
     if (ee()->config->item('popup_link') !== FALSE) {
         $this->popup_links = ee()->config->item('popup_link') == 'y' ? TRUE : FALSE;
     }
     /** -------------------------------------
     		/**  Fetch word censoring prefs
     		/** -------------------------------------*/
     if (ee()->config->item('enable_censoring') == 'y') {
         $this->_fetch_word_censor_prefs();
     }
     /** -------------------------------------
     		/**  Fetch plugins
     		/** -------------------------------------*/
     ee()->load->model('addons_model');
     $this->text_fmt_plugins = ee()->addons_model->get_plugin_formatting();
 }
예제 #4
0
 /**
  * Run the main parsing loop.
  *
  * Takes the data row, the preparsed tagdata, and any additonal
  * options and delegates to the proper parsing components.
  *
  * @param	array	The data row.
  * @param	array	Config items
  *
  *		disable:   array of components to turn off
  *		callbacks: array of callbacks to register
  *
  * @return	string	Parsed tagdata
  */
 public function parse($data, $config = array())
 {
     $this->_data = $data;
     $pre = $this->_preparser;
     // data options
     $entries = $this->data('entries', array());
     $absolute_offset = $this->data('absolute_offset', 0);
     $absolute_results = $this->data('absolute_results');
     // config options
     $disabled = isset($config['disable']) ? $config['disable'] : array();
     $callbacks = isset($config['callbacks']) ? $config['callbacks'] : array();
     $pairs = $pre->pairs;
     $singles = $pre->singles;
     $prefix = $this->_prefix;
     $channel = $this->_channel;
     $subscriber_totals = $pre->subscriber_totals;
     $total_results = count($entries);
     $site_pages = config_item('site_pages');
     foreach (ee()->TMPL->site_ids as $site_id) {
         if ($site_id != ee()->config->item('site_id')) {
             $pages = ee()->config->site_pages($site_id);
             $site_pages[$site_id] = $pages[$site_id];
         }
     }
     $result = '';
     // final template
     // If custom fields are enabled, notify them of the data we're about to send
     if (!empty($channel->cfields)) {
         $this->_send_custom_field_data_to_fieldtypes($entries);
     }
     $count = 0;
     $orig_tagdata = $this->_parser->tagdata();
     $parser_components = $this->_parser->components();
     $dt = 0;
     ee()->load->library('typography');
     ee()->typography->initialize(array('convert_curly' => FALSE));
     ee()->load->helper('date');
     foreach ($entries as $row) {
         $tagdata = $orig_tagdata;
         $this->_count = $count;
         $row['count'] = $count + 1;
         $row['page_uri'] = '';
         $row['page_url'] = '';
         $row['total_results'] = $total_results;
         $row['absolute_count'] = $absolute_offset + $row['count'];
         $row['absolute_results'] = $absolute_results === NULL ? $total_results : $absolute_results;
         $row['comment_subscriber_total'] = isset($subscriber_totals[$row['entry_id']]) ? $subscriber_totals[$row['entry_id']] : 0;
         if ($site_pages !== FALSE && isset($site_pages[$row['site_id']]['uris'][$row['entry_id']])) {
             $row['page_uri'] = $site_pages[$row['site_id']]['uris'][$row['entry_id']];
             $row['page_url'] = ee()->functions->create_page_url($site_pages[$row['site_id']]['url'], $site_pages[$row['site_id']]['uris'][$row['entry_id']]);
         }
         // -------------------------------------------------------
         // Loop start callback. Do what you want.
         // Currently in use in the channel module for the
         // channel_entries_tagdata hook.
         // -------------------------------------------------------
         if (isset($callbacks['tagdata_loop_start'])) {
             $tagdata = call_user_func($callbacks['tagdata_loop_start'], $tagdata, $row);
         }
         // -------------------------------------------------------
         // Row data callback. Do what you want.
         // Currently in use in the channel module for the
         // channel_entries_row hook.
         // -------------------------------------------------------
         if (isset($callbacks['entry_row_data'])) {
             $row = call_user_func($callbacks['entry_row_data'], $tagdata, $row);
         }
         // Reset custom date fields
         // Since custom date fields columns are integer types by default, if they
         // don't contain any data they return a zero.
         // This creates a problem if conditionals are used with those fields.
         // For example, if an admin has this in a template:  {if mydate == ''}
         // Since the field contains a zero it would never evaluate TRUE.
         // Therefore we'll reset any zero dates to nothing.
         if (isset($channel->dfields[$row['site_id']]) && count($channel->dfields[$row['site_id']]) > 0) {
             foreach ($channel->dfields[$row['site_id']] as $dkey => $dval) {
                 // While we're at it, kill any formatting
                 $row['field_ft_' . $dval] = 'none';
                 if (isset($row['field_id_' . $dval]) and $row['field_id_' . $dval] == 0) {
                     $row['field_id_' . $dval] = '';
                 }
             }
         }
         $this->_row = $row;
         // conditionals!
         $cond = $this->_get_conditional_data($row, $prefix, $channel);
         //  Parse Variable Pairs
         foreach ($pairs as $key => $val) {
             $this->_tag = $key;
             $this->_tag_options = $val;
             foreach ($parser_components->pair() as $k => $component) {
                 if (!$pre->is_disabled($component)) {
                     $tagdata = $component->replace($tagdata, $this, $pre->pair_data($component));
                 }
             }
         }
         // Run parsers that just process tagdata once (relationships, for example)
         foreach ($parser_components->once() as $k => $component) {
             if (!$pre->is_disabled($component)) {
                 $tagdata = $component->replace($tagdata, $this, $pre->once_data($component));
             }
         }
         // We swap out the conditionals after pairs are parsed so they don't interfere
         // with the string replace
         $tagdata = ee()->functions->prep_conditionals($tagdata, $cond);
         //  Parse individual variable tags
         foreach ($singles as $key => $val) {
             $this->_tag = $key;
             $this->_tag_options = $val;
             foreach ($parser_components->single() as $k => $component) {
                 if (!$pre->is_disabled($component)) {
                     $tagdata = $component->replace($tagdata, $this, $pre->single_data($component));
                 }
             }
         }
         // do we need to replace any curly braces that we protected in custom fields?
         if (strpos($tagdata, unique_marker('channel_bracket_open')) !== FALSE) {
             $tagdata = str_replace(array(unique_marker('channel_bracket_open'), unique_marker('channel_bracket_close')), array('{', '}'), $tagdata);
         }
         // -------------------------------------------------------
         // Loop end callback. Do what you want.
         // Used by relationships to parse children and by the
         // channel module for the channel_entries_tagdata_end hook
         // -------------------------------------------------------
         if (isset($callbacks['tagdata_loop_end'])) {
             $tagdata = call_user_func($callbacks['tagdata_loop_end'], $tagdata, $row);
         }
         $result .= $tagdata;
         $count++;
     }
     return $result;
 }
 /**
  * Prep conditionals
  *
  * @access	public
  * @param	string
  * @param	string
  * @param	string
  * @param	string
  * @return	array
  */
 function prep_conditionals($str, $vars, $safety = 'n', $prefix = '')
 {
     if (isset(ee()->TMPL->embed_vars)) {
         // If this is being called from a module tag, embedded variables
         // aren't going to be available yet.  So this is a quick workaround
         // to ensure advanced conditionals using embedded variables can do
         // their thing in mod tags.
         $vars = array_merge($vars, ee()->TMPL->embed_vars);
     }
     if (count($vars) == 0) {
         return $str;
     }
     $switch = array();
     $protect = array();
     $prep_id = $this->random('alpha', 3);
     $embedded_tags = stristr($str, LD . 'exp:') ? TRUE : FALSE;
     $valid = array('!=', '==', '<=', '>=', '<', '>', '<>', '%', 'AND', 'XOR', 'OR', '&&', '||', ')', '(', 'TRUE', 'FALSE');
     $str = str_replace(LD . 'if:else' . RD, unique_marker('if_else_safety'), $str);
     // The ((else)*if) is actually faster than (elseif|if) in PHP 5.0.4,
     // but only by a half a thousandth of a second.  However, why not be
     // as efficient as possible?  It also gives me a chance to catch some
     // user error mistakes.
     if (preg_match_all("/" . preg_quote(LD) . "((if:else)*if)\\s+(.*?)" . preg_quote(RD) . "/s", $str, $matches)) {
         // PROTECT QUOTED TEXT
         // That which is in quotes should be protected and ignored as it will screw
         // up the parsing if the variable is found within a string
         if (preg_match_all('/([\\"\'])([^\\1]*?)\\1/s', implode(' ', $matches[3]), $quote_matches)) {
             foreach ($quote_matches[0] as $ii => $quote_match) {
                 $md5_key = (string) hexdec($prep_id . md5($quote_match));
                 $protect[$quote_match] = $md5_key;
                 // To better protect quotes inside conditional quotes, we need to
                 // determine which kind of quote to surround the newly-encoded string
                 $surrounding_quote = surrounding_character($quote_match);
                 if ($surrounding_quote != '"' and $surrounding_quote != "'" or $surrounding_quote === FALSE) {
                     $surrounding_quote = '"';
                 }
                 // We do these conversions on variables below, so we need
                 // to also do them on the hardcoded values to make sure
                 // the conditionals resolve as expected.
                 // e.g. {if location == "pony's house"}
                 $quote_match = $surrounding_quote . str_replace(array("'", '"', '(', ')', '$', '{', '}', "\n", "\r", '\\'), array('&#39;', '&#34;', '&#40;', '&#41;', '&#36;', '', '', '', '', '&#92;'), $quote_matches[2][$ii]) . $surrounding_quote;
                 $switch[$md5_key] = $quote_match;
             }
             $matches[3] = str_replace(array_keys($protect), array_values($protect), $matches[3]);
             // Remove quoted values altogether to find variables...
             $matches['t'] = str_replace($valid, ' ', str_replace(array_values($protect), '', $matches[3]));
         } else {
             $matches['t'] = str_replace($valid, ' ', $matches[3]);
         }
         // Find what we need, nothing more!!
         $data = array();
         foreach ($matches['t'] as $cond) {
             if (trim($cond) == '') {
                 continue;
             }
             $x = preg_split("/\\s+/", trim($cond));
             $i = 0;
             do {
                 if (array_key_exists($x[$i], $vars)) {
                     $data[$x[$i]] = trim($vars[$x[$i]]);
                 } elseif ($embedded_tags === TRUE && !is_numeric($x[$i])) {
                     $data[$x[$i]] = $x[$i];
                 } elseif (strncmp($x[$i], 'embed:', 6) == 0) {
                     $data[$x[$i]] = '';
                 }
                 if ($i > 500) {
                     break;
                 }
                 ++$i;
             } while (isset($x[$i]));
         }
         // This should prevent, for example, the variable 'comment' from
         // overwriting the variable 'comments'.
         uksort($data, array($this, 'reverse_key_sort'));
         if ($safety == 'y') {
             // Make sure we have the same amount of opening conditional tags
             // as closing conditional tags.
             $tstr = preg_replace("/<script.*?" . ">.*?<\\/script>/is", '', $str);
             $opening = substr_count($tstr, LD . 'if') - substr_count($tstr, LD . 'if:elseif');
             $closing = substr_count($tstr, LD . '/if' . RD);
             if ($opening > $closing) {
                 $str .= str_repeat(LD . '/if' . RD, $opening - $closing);
             }
         }
         // Prep the data array to remove characters we do not want
         // And also just add the quotes around the value for good measure.
         foreach ($data as $key => &$value) {
             if (is_array($value)) {
                 continue;
             }
             // TRUE AND FALSE values are for short hand conditionals,
             // like {if logged_in} and so we have no need to remove
             // unwanted characters and we do not quote it.
             if ($value != 'TRUE' && $value != 'FALSE' && ($key != $value or $embedded_tags !== TRUE)) {
                 $value = '"' . str_replace(array("'", '"', '(', ')', '$', '{', '}', "\n", "\r", '\\'), array('&#39;', '&#34;', '&#40;', '&#41;', '&#36;', '', '', '', '', '&#92;'), strlen($value) > 100 ? substr(htmlspecialchars($value), 0, 100) : $value) . '"';
             }
             $md5_key = (string) hexdec($prep_id . md5($key));
             $protect[$key] = $md5_key;
             $switch[$md5_key] = $value;
             if ($prefix != '') {
                 $md5_key = (string) hexdec($prep_id . md5($prefix . $key));
                 $protect[$prefix . $key] = $md5_key;
                 $switch[$md5_key] = $value;
             }
         }
         // Example:
         //
         //     {if entry_date < current_time}FUTURE{/if}
         //     {if "{entry_date format='%Y%m%d'}" ==  "{current_time format='%Y%m%d'}"}Today{/if}
         //
         // The above used to fail because the second conditional would turn into something like:
         //
         //     {if "{"1343930801" format='%Y%m%d'}
         //
         // So here, we make sure the value we're replacing doesn't ALSO happen to appear in the
         // middle of something that looks like a date field with a format parameter
         //
         // It also failed on conditionals with similar prefixes, which tends to happen with
         // relationship fields, e.g:
         //
         //     {if parent:count == 1}one{/if}
         //     {if parent:parent:count == 1}one{/if}
         //
         // In the second parent loop, this would evaluate as:
         //
         //     {if "2" == 1}one{/if}
         //     {if parent:"2" == 1}one{/if}
         //
         foreach ($matches[3] as &$match) {
             foreach ($protect as $key => $value) {
                 // Make sure $key doesn't appear as "{$key " or ":$key "
                 if (strpos($match, LD . $key . ' ') === FALSE and strpos($match, ':' . $key) === FALSE) {
                     $match = str_replace($key, $value, $match);
                 }
             }
         }
         if ($safety == 'y') {
             $matches['s'] = str_replace($protect, '^', $matches[3]);
             $matches['s'] = preg_replace('/"(.*?)"/s', '^', $matches['s']);
             $matches['s'] = preg_replace("/'(.*?)'/s", '^', $matches['s']);
             $matches['s'] = str_replace($valid, '  ', $matches['s']);
             $matches['s'] = preg_replace("/(^|\\s+)[0-9]+(\\s|\$)/", ' ', $matches['s']);
             // Remove unquoted numbers
             $done = array();
         }
         for ($i = 0, $s = count($matches[0]); $i < $s; ++$i) {
             if ($safety == 'y' && !in_array($matches[0][$i], $done)) {
                 $done[] = $matches[0][$i];
                 //  Make sure someone did put in an {if:else conditional}
                 //  when they likely meant to have an {if:elseif conditional}
                 if ($matches[2][$i] == '' && substr($matches[3][$i], 0, 5) == ':else' && $matches[1][$i] == 'if') {
                     $matches[3][$i] = substr($matches[3][$i], 5);
                     $matches[2][$i] == 'elseif';
                     trigger_error('Invalid Conditional, Assumed ElseIf : ' . str_replace(' :else', ':else', $matches[0][$i]), E_USER_WARNING);
                 }
                 //  If there are parentheses, then we
                 //  try to make sure they match up correctly.
                 $left = substr_count($matches[3][$i], '(');
                 $right = substr_count($matches[3][$i], ')');
                 if ($left > $right) {
                     $matches[3][$i] .= str_repeat(')', $left - $right);
                 } elseif ($right > $left) {
                     $matches[3][$i] = str_repeat('(', $right - $left) . $matches[3][$i];
                 }
                 // Check for unparsed variables
                 if (trim($matches['s'][$i]) != '' && trim($matches['s'][$i]) != '^') {
                     $x = preg_split("/\\s+/", trim($matches['s'][$i]));
                     for ($j = 0, $sj = count($x); $j < $sj; ++$j) {
                         if ($x[$j] == '^') {
                             continue;
                         }
                         if (substr($x[$j], 0, 1) != '^') {
                             // We have an unset variable in the conditional.
                             // Set the unparsed variable to FALSE
                             $matches[3][$i] = str_replace($x[$j], 'FALSE', $matches[3][$i]);
                             if ($this->conditional_debug === TRUE) {
                                 trigger_error('Unset EE Conditional Variable (' . $x[$j] . ') : ' . $matches[0][$i], E_USER_WARNING);
                             }
                         } else {
                             // There is a partial variable match being done
                             // because they are doing something like segment_11
                             // when there is no such variable but there is a segment_1
                             // echo  $x[$j]."\n<br />\n";
                             trigger_error('Invalid EE Conditional Variable: ' . $matches[0][$i], E_USER_WARNING);
                             // Set entire conditional to FALSE since it fails
                             $matches[3][$i] = 'FALSE';
                         }
                     }
                 }
             }
             $matches[3][$i] = LD . $matches[1][$i] . ' ' . trim($matches[3][$i]) . RD;
         }
         $str = str_replace($matches[0], $matches[3], $str);
         $str = str_replace(array_keys($switch), array_values($switch), $str);
     }
     unset($data);
     unset($switch);
     unset($matches);
     unset($protect);
     $str = str_replace(unique_marker('if_else_safety'), LD . 'if:else' . RD, $str);
     return $str;
 }
예제 #6
0
파일: mod.wiki.php 프로젝트: stb74/eeguide
 /** -------------------------------------
 	/**  Prevents EE Tags and Variables from being parsed
 	/** -------------------------------------*/
 function convert_curly_brackets($str)
 {
     /** ------------------------------------
     		/**  Protect <script> tags
     		/** ------------------------------------*/
     $protected = array();
     $front_protect = unique_marker('wiki_front_protect');
     $back_protect = unique_marker('wiki_back_protect');
     if (stristr($str, '<script') && preg_match_all("/<script.*?" . ">.*?<\\/script>/is", $str, $matches)) {
         for ($i = 0, $s = count($matches['0']); $i < $s; ++$i) {
             $protected[$front_protect . $i . $back_protect] = $matches['0'][$i];
         }
         $str = str_replace(array_values($protected), array_keys($protected), $str);
     }
     /** ------------------------------------
     		/**  Encode all other curly brackets
     		/** ------------------------------------*/
     $str = str_replace(array(LD, RD), array('&#123;', '&#125;'), $str);
     /** ------------------------------------
     		/**  Convert back and return
     		/** ------------------------------------*/
     if (count($protected) > 0) {
         $str = str_replace(array_keys($protected), array_values($protected), $str);
     }
     return $str;
 }
예제 #7
0
파일: Rte_lib.php 프로젝트: vigm/advancedMD
 /**
  * Display an RTE field
  *
  * @param string $data       the RTE html content
  * @param string $field_name the field name for the RTE field
  * @param array $settings   field settings:
  * 					field_ta_rows - the number of textarea rows
  * 					field_text_direction - ltr or rtl
  * 					field_fmt - xhtml, br or none
  *
  * @return string
  */
 public function display_field($data, $field_name, $settings, $container = NULL)
 {
     if (!ee()->session->cache('rte', 'loaded')) {
         ee()->javascript->output(ee()->rte_lib->build_js(0, '.WysiHat-field', NULL, REQ == 'CP'));
         ee()->session->set_cache('rte', 'loaded', TRUE);
     }
     ee()->load->helper('form');
     $field = array('name' => $field_name, 'id' => $field_name, 'rows' => $settings['field_ta_rows'], 'dir' => $settings['field_text_direction'], 'class' => 'has-rte');
     // form prepped nonsense
     $code_marker = unique_marker('code');
     $code_chunks = array();
     $data = trim($data);
     $data = htmlspecialchars_decode($data, ENT_QUOTES);
     $data = $this->clean_data($data);
     // Check the RTE module and user's preferences
     if (ee()->session->userdata('rte_enabled') == 'y' and ee()->config->item('rte_enabled') == 'y') {
         $field['class'] .= ' WysiHat-field';
         foreach ($code_chunks as $i => $chunk) {
             $chunk = htmlentities($chunk, ENT_QUOTES, 'UTF-8');
             $chunk = str_replace("\n", '<br>', $chunk);
             $code_chunks[$i] = $chunk;
         }
         // xhtml vs br
         ee()->load->library('typography');
         $data = ee()->typography->auto_typography($data, TRUE);
         // remove non breaking spaces. typography likes to throw those
         // in when a list is indented.
         $data = str_replace('&nbsp;', ' ', $data);
     }
     // put code chunks back
     foreach ($code_chunks as $i => $chunk) {
         $data = str_replace($code_marker . $i, '[code]' . $chunk . '[/code]', $data);
     }
     // Swap {filedir_x} with the real URL. It will be converted back
     // upon submit by the RTE Image tool.
     ee()->load->model('file_upload_preferences_model');
     $dirs = ee()->file_upload_preferences_model->get_file_upload_preferences(ee()->session->userdata('group_id'));
     foreach ($dirs as $d) {
         // tag to replace
         $filedir = "{filedir_{$d['id']}}";
         $data = str_replace($filedir, $d['url'], $data);
     }
     $field['value'] = $data;
     $return_data = form_textarea($field);
     return $return_data;
 }
 /**
  * Replace all of the custom channel fields.
  *
  * @param String	The tagdata to be parsed
  * @param Object	The channel parser object
  * @param Mixed		The results from the preparse method
  *
  * @return String	The processed tagdata
  */
 public function replace($tagdata, EE_Channel_data_parser $obj, $ft_api)
 {
     $tag = $obj->tag();
     $data = $obj->row();
     $prefix = $obj->prefix();
     $site_id = $data['site_id'];
     $cfields = $obj->channel()->cfields;
     $rfields = $obj->channel()->rfields;
     $rfields = isset($rfields[$site_id]) ? $rfields[$site_id] : array();
     $cfields = isset($cfields[$site_id]) ? $cfields[$site_id] : array();
     $cfields = array_diff_key($cfields, $rfields);
     if (empty($cfields)) {
         return $tagdata;
     }
     $field = ee()->api_channel_fields->get_single_field($tag, $prefix);
     if (isset($cfields[$field['field_name']])) {
         $entry = '';
         $field_id = $cfields[$field['field_name']];
         if (isset($data['field_id_' . $field_id]) && $data['field_id_' . $field_id] !== '') {
             $modifier = $field['modifier'];
             $parse_fnc = $modifier ? 'replace_' . $modifier : 'replace_tag';
             $obj = $ft_api->setup_handler($field_id, TRUE);
             if ($obj) {
                 $_ft_path = $ft_api->ft_paths[$ft_api->field_type];
                 ee()->load->add_package_path($_ft_path, FALSE);
                 $obj->_init(array('row' => $data, 'content_id' => $data['entry_id'], 'content_type' => 'channel'));
                 $data = $ft_api->apply('pre_process', array($data['field_id_' . $field_id]));
                 if (method_exists($obj, $parse_fnc)) {
                     $entry = $ft_api->apply($parse_fnc, array($data, $field['params'], FALSE));
                 } elseif (method_exists($obj, 'replace_tag_catchall')) {
                     $entry = $ft_api->apply('replace_tag_catchall', array($data, $field['params'], FALSE, $modifier));
                 }
                 ee()->load->remove_package_path($_ft_path);
             } else {
                 // Couldn't find a fieldtype
                 $entry = ee()->typography->parse_type(ee()->functions->encode_ee_tags($data['field_id_' . $field_id]), array('text_format' => $data['field_ft_' . $field_id], 'html_format' => $data['channel_html_formatting'], 'auto_links' => $data['channel_auto_link_urls'], 'allow_img_url' => $data['channel_allow_img_urls']));
             }
             // prevent accidental parsing of other channel variables in custom field data
             if (strpos($entry, '{') !== FALSE) {
                 $entry = str_replace(array('{', '}'), array(unique_marker('channel_bracket_open'), unique_marker('channel_bracket_close')), $entry);
             }
             $tagdata = str_replace(LD . $tag . RD, $entry, $tagdata);
         }
         $tagdata = str_replace(LD . $tag . RD, '', $tagdata);
     }
     return $tagdata;
 }
예제 #9
0
 /**
  * Protect compressed javascript.
  *
  * @see `$this->enableProtectJavascript()` for why we do this.
  *
  * @param String $str The raw template string
  * @return String     The template string with javascript escaped
  */
 private function protectJavascript($str)
 {
     if ($this->protect_javascript === FALSE) {
         return $str;
     }
     $js_protect = unique_marker('tmpl_script');
     if (stristr($str, '<script') && preg_match_all('/<script.*?>.*?<\\/script>/is', $str, $matches)) {
         foreach ($matches[0] as $i => $match) {
             $this->protected_javascript[$js_protect . $i] = $match;
         }
         $str = str_replace(array_values($this->protected_javascript), array_keys($this->protected_javascript), $str);
     }
     return $str;
 }
예제 #10
0
 /**
  *  Parse channel entries
  */
 public function parse_channel_entries()
 {
     $switch = array();
     $processed_member_fields = array();
     //  Set default date header variables
     $heading_date_hourly = 0;
     $heading_flag_hourly = 0;
     $heading_flag_weekly = 1;
     $heading_date_daily = 0;
     $heading_flag_daily = 0;
     $heading_date_monthly = 0;
     $heading_flag_monthly = 0;
     $heading_date_yearly = 0;
     $heading_flag_yearly = 0;
     // Fetch the "category chunk"
     // We'll grab the category data now to avoid processing cycles in the foreach loop below
     $cat_chunk = array();
     if (strpos($this->EE->TMPL->tagdata, LD . '/categories' . RD) !== FALSE) {
         if (preg_match_all("/" . LD . "categories(.*?)" . RD . "(.*?)" . LD . '\\/' . 'categories' . RD . "/s", $this->EE->TMPL->tagdata, $matches)) {
             for ($j = 0; $j < count($matches[0]); $j++) {
                 $cat_chunk[] = array($matches[2][$j], $this->EE->functions->assign_parameters($matches[1][$j]), $matches[0][$j]);
             }
         }
     }
     //  Fetch all the date-related variables
     $entry_date = array();
     $gmt_date = array();
     $gmt_entry_date = array();
     $edit_date = array();
     $gmt_edit_date = array();
     $expiration_date = array();
     $week_date = array();
     // We do this here to avoid processing cycles in the foreach loop
     $date_vars = array('entry_date', 'gmt_date', 'gmt_entry_date', 'edit_date', 'gmt_edit_date', 'expiration_date', 'recent_comment_date', 'week_date');
     $date_variables_exist = FALSE;
     foreach ($date_vars as $val) {
         if (strpos($this->EE->TMPL->tagdata, LD . $val) === FALSE) {
             continue;
         }
         if (preg_match_all("/" . LD . $val . "\\s+format=([\"'])([^\\1]*?)\\1" . RD . "/s", $this->EE->TMPL->tagdata, $matches)) {
             $date_variables_exist = TRUE;
             for ($j = 0; $j < count($matches[0]); $j++) {
                 $matches[0][$j] = str_replace(array(LD, RD), '', $matches[0][$j]);
                 switch ($val) {
                     case 'entry_date':
                         $entry_date[$matches[0][$j]] = $this->EE->localize->fetch_date_params($matches[2][$j]);
                         break;
                     case 'gmt_date':
                         $gmt_date[$matches[0][$j]] = $this->EE->localize->fetch_date_params($matches[2][$j]);
                         break;
                     case 'gmt_entry_date':
                         $gmt_entry_date[$matches[0][$j]] = $this->EE->localize->fetch_date_params($matches[2][$j]);
                         break;
                     case 'edit_date':
                         $edit_date[$matches[0][$j]] = $this->EE->localize->fetch_date_params($matches[2][$j]);
                         break;
                     case 'gmt_edit_date':
                         $gmt_edit_date[$matches[0][$j]] = $this->EE->localize->fetch_date_params($matches[2][$j]);
                         break;
                     case 'expiration_date':
                         $expiration_date[$matches[0][$j]] = $this->EE->localize->fetch_date_params($matches[2][$j]);
                         break;
                     case 'recent_comment_date':
                         $recent_comment_date[$matches[0][$j]] = $this->EE->localize->fetch_date_params($matches[2][$j]);
                         break;
                     case 'week_date':
                         $week_date[$matches[0][$j]] = $this->EE->localize->fetch_date_params($matches[2][$j]);
                         break;
                 }
             }
         }
     }
     // Are any of the custom fields dates?
     $custom_date_fields = array();
     if (count($this->dfields) > 0) {
         foreach ($this->dfields as $site_id => $dfields) {
             foreach ($dfields as $key => $value) {
                 if (strpos($this->EE->TMPL->tagdata, LD . $key) === FALSE) {
                     continue;
                 }
                 if (preg_match_all("/" . LD . $key . "\\s+format=[\"'](.*?)[\"']" . RD . "/s", $this->EE->TMPL->tagdata, $matches)) {
                     for ($j = 0; $j < count($matches[0]); $j++) {
                         $matches[0][$j] = str_replace(array(LD, RD), '', $matches[0][$j]);
                         $custom_date_fields[$matches[0][$j]] = $this->EE->localize->fetch_date_params($matches[1][$j]);
                     }
                 }
             }
         }
     }
     // And the same again for reverse related entries
     $reverse_markers = array();
     if (preg_match_all("/" . LD . "REV_REL\\[([^\\]]+)\\]REV_REL" . RD . "/", $this->EE->TMPL->tagdata, $matches)) {
         for ($j = 0; $j < count($matches['0']); $j++) {
             $reverse_markers[$matches['1'][$j]] = '';
         }
     }
     // "Search by Member" link
     // We use this with the {member_search_path} variable
     $result_path = preg_match("/" . LD . "member_search_path\\s*=(.*?)" . RD . "/s", $this->EE->TMPL->tagdata, $match) ? $match[1] : 'search/results';
     $result_path = str_replace(array('"', "'"), "", $result_path);
     $search_link = $this->EE->functions->fetch_site_index(0, 0) . QUERY_MARKER . 'ACT=' . $this->EE->functions->fetch_action_id('Search', 'do_search') . '&amp;result_path=' . $result_path . '&amp;mbr=';
     // Start the main processing loop
     // For our hook to work, we need to grab the result array
     $query_result = $this->query->result_array();
     // Ditch everything else
     $this->query->free_result();
     unset($this->query);
     // -------------------------------------------
     // 'channel_entries_query_result' hook.
     //  - Take the whole query result array, do what you wish
     //  - added 1.6.7
     //
     if ($this->EE->extensions->active_hook('channel_entries_query_result') === TRUE) {
         $query_result = $this->EE->extensions->call('channel_entries_query_result', $this, $query_result);
         if ($this->EE->extensions->end_script === TRUE) {
             return $this->EE->TMPL->tagdata;
         }
     }
     //
     // -------------------------------------------
     $total_results = count($query_result);
     $site_pages = $this->EE->config->item('site_pages');
     // Fetch Custom Field Chunks
     // If any of our custom fields are tag pair fields, we'll grab those chunks now
     // Moved below hook in 2.6
     $pfield_chunk = array();
     if (count($this->pfields) > 0) {
         foreach ($this->pfields as $site_id => $pfields) {
             $pfield_names = array_intersect($this->cfields[$site_id], array_keys($pfields));
             foreach ($pfield_names as $field_name => $field_id) {
                 $offset = 0;
                 while (($end = strpos($this->EE->TMPL->tagdata, LD . '/' . $field_name . RD, $offset)) !== FALSE) {
                     // This hurts soo much. Using custom fields as pair and single vars in the same
                     // channel tags could lead to something like this: {field}...{field}inner{/field}
                     // There's no efficient regex to match this case, so we'll find the last nested
                     // opening tag and re-cut the chunk.
                     if (preg_match("/" . LD . "{$field_name}(.*?)" . RD . "(.*?)" . LD . '\\/' . "{$field_name}(.*?)" . RD . "/s", $this->EE->TMPL->tagdata, $matches, 0, $offset)) {
                         $chunk = $matches[0];
                         $params = $matches[1];
                         $inner = $matches[2];
                         // We might've sandwiched a single tag - no good, check again (:sigh:)
                         if (strpos($chunk, LD . $field_name, 1) !== FALSE && preg_match_all("/" . LD . "{$field_name}(.*?)" . RD . "/s", $chunk, $match)) {
                             // Let's start at the end
                             $idx = count($match[0]) - 1;
                             $tag = $match[0][$idx];
                             // Reassign the parameter
                             $params = $match[1][$idx];
                             // Cut the chunk at the last opening tag (PHP5 could do this with strrpos :-( )
                             while (strpos($chunk, $tag, 1) !== FALSE) {
                                 $chunk = substr($chunk, 1);
                                 $chunk = strstr($chunk, LD . $field_name);
                                 $inner = substr($chunk, strlen($tag), -strlen(LD . '/' . $field_name . RD));
                             }
                         }
                         $chunk_array = array($inner, $this->EE->functions->assign_parameters($params), $chunk);
                         // Grab modifier if it exists and add it to the chunk array
                         if (substr($params, 0, 1) == ':') {
                             $chunk_array[] = str_replace(':', '', $params);
                         }
                         $pfield_chunk[$site_id][$field_name][] = $chunk_array;
                     }
                     $offset = $end + 1;
                 }
                 /*
                 if (($end = strpos($this->EE->TMPL->tagdata, LD.'/'.$field_name.RD)) !== FALSE)
                 {
                 	// This hurts soo much. Using custom fields as pair and single vars in the same
                 	// channel tags could lead to something like this: {field}...{field}inner{/field}
                 	// There's no efficient regex to match this case, so we'll find the last nested
                 	// opening tag and re-cut the chunk.
                 
                 	if (preg_match_all("/".LD."{$field_name}(.*?)".RD."(.*?)".LD.'\/'.$field_name.RD."/s", $this->EE->TMPL->tagdata, $matches))
                 	{
                 		for ($j = 0; $j < count($matches[0]); $j++)
                 		{
                 			$chunk = $matches[0][$j];
                 			$params = $matches[1][$j];
                 			$inner = $matches[2][$j];
                 
                 			// We might've sandwiched a single tag - no good, check again (:sigh:)
                 			if ((strpos($chunk, LD.$field_name, 1) !== FALSE) && preg_match_all("/".LD."{$field_name}(.*?)".RD."/s", $chunk, $match))
                 			{
                 				// Let's start at the end
                 				$idx = count($match[0]) - 1;
                 				$tag = $match[0][$idx];
                 
                 				// Cut the chunk at the last opening tag (PHP5 could do this with strrpos :-( )
                 				while (strpos($chunk, $tag, 1) !== FALSE)
                 				{
                 					$chunk = substr($chunk, 1);
                 					$chunk = strstr($chunk, LD.$field_name);
                 					$inner = substr($chunk, strlen($tag), -strlen(LD.'/'.$field_name.RD));
                 				}
                 			}
                 
                 			$pfield_chunk[$site_id][$field_name][] = array($inner, $this->EE->functions->assign_parameters($params), $chunk);
                 		}
                 	}
                 }
                 */
             }
         }
     }
     // One more preloop check - custom fields with modifiers in conditionals
     $all_field_names = array();
     foreach ($this->cfields as $site_id => $fields) {
         $all_field_names = array_unique(array_merge($all_field_names, $fields));
     }
     $modified_field_options = implode('|', array_keys($all_field_names));
     $modified_conditionals = array();
     if (preg_match_all("/" . preg_quote(LD) . "((if:(else))*if)\\s+(({$modified_field_options}):(\\w+))(.*?)" . preg_quote(RD) . "/s", $this->EE->TMPL->tagdata, $matches)) {
         foreach ($matches[5] as $match_key => $field_name) {
             $modified_conditionals[$field_name][] = $matches[6][$match_key];
         }
     }
     $modified_conditionals = array_map('array_unique', $modified_conditionals);
     unset($all_field_names, $modified_field_options);
     // If custom fields are enabled, notify them of the data we're about to send
     if (!empty($this->cfields)) {
         $this->_send_custom_field_data_to_fieldtypes($query_result);
     }
     foreach ($query_result as $count => $row) {
         // Fetch the tag block containing the variables that need to be parsed
         $tagdata = $this->EE->TMPL->tagdata;
         $row['count'] = $count + 1;
         $row['page_uri'] = '';
         $row['page_url'] = '';
         $row['total_results'] = $total_results;
         $row['absolute_count'] = $this->pagination->offset + $row['count'];
         $row['absolute_results'] = $this->absolute_results === NULL ? $total_results : $this->absolute_results;
         if ($site_pages !== FALSE && isset($site_pages[$row['site_id']]['uris'][$row['entry_id']])) {
             $row['page_uri'] = $site_pages[$row['site_id']]['uris'][$row['entry_id']];
             $row['page_url'] = $this->EE->functions->create_page_url($site_pages[$row['site_id']]['url'], $site_pages[$row['site_id']]['uris'][$row['entry_id']]);
         }
         // -------------------------------------------
         // 'channel_entries_tagdata' hook.
         //  - Take the entry data and tag data, do what you wish
         //
         if ($this->EE->extensions->active_hook('channel_entries_tagdata') === TRUE) {
             $tagdata = $this->EE->extensions->call('channel_entries_tagdata', $tagdata, $row, $this);
             if ($this->EE->extensions->end_script === TRUE) {
                 return $tagdata;
             }
         }
         //
         // -------------------------------------------
         // -------------------------------------------
         // 'channel_entries_row' hook.
         //  - Take the entry data, do what you wish
         //  - added 1.6.7
         //
         if ($this->EE->extensions->active_hook('channel_entries_row') === TRUE) {
             $row = $this->EE->extensions->call('channel_entries_row', $this, $row);
             if ($this->EE->extensions->end_script === TRUE) {
                 return $tagdata;
             }
         }
         //
         // -------------------------------------------
         //  Adjust dates if needed
         // If the "dst_enabled" item is set in any given entry
         // we need to offset to the timestamp by an hour
         if (!isset($row['dst_enabled'])) {
             $row['dst_enabled'] = 'n';
         }
         /**--
         			/**  Reset custom date fields
         			/**--*/
         // Since custom date fields columns are integer types by default, if they
         // don't contain any data they return a zero.
         // This creates a problem if conditionals are used with those fields.
         // For example, if an admin has this in a template:  {if mydate == ''}
         // Since the field contains a zero it would never evaluate TRUE.
         // Therefore we'll reset any zero dates to nothing.
         if (isset($this->dfields[$row['site_id']]) && count($this->dfields[$row['site_id']]) > 0) {
             foreach ($this->dfields[$row['site_id']] as $dkey => $dval) {
                 // While we're at it, kill any formatting
                 $row['field_ft_' . $dval] = 'none';
                 if (isset($row['field_id_' . $dval]) and $row['field_id_' . $dval] == 0) {
                     $row['field_id_' . $dval] = '';
                 }
             }
         }
         // While we're at it, do the same for related entries.
         if (isset($this->rfields[$row['site_id']]) && count($this->rfields[$row['site_id']]) > 0) {
             foreach ($this->rfields[$row['site_id']] as $rkey => $rval) {
                 $row['field_ft_' . $rval] = 'none';
             }
         }
         // Reverse related markers
         $j = 0;
         foreach ($reverse_markers as $k => $v) {
             $this->reverse_related_entries[$row['entry_id']][$j] = $k;
             $tagdata = str_replace(LD . "REV_REL[" . $k . "]REV_REL" . RD, LD . "REV_REL[" . $k . "][" . $row['entry_id'] . "]REV_REL" . RD, $tagdata);
             $j++;
         }
         // Conditionals
         $cond = $row;
         $cond['logged_in'] = $this->EE->session->userdata('member_id') == 0 ? 'FALSE' : 'TRUE';
         $cond['logged_out'] = $this->EE->session->userdata('member_id') != 0 ? 'FALSE' : 'TRUE';
         if ($row['comment_expiration_date'] > 0 && $this->EE->localize->now > $row['comment_expiration_date'] && $this->EE->config->item('comment_moderation_override') !== 'y' or $row['allow_comments'] == 'n' or isset($row['comment_system_enabled']) && $row['comment_system_enabled'] == 'n') {
             $cond['allow_comments'] = 'FALSE';
         } else {
             $cond['allow_comments'] = 'TRUE';
         }
         foreach (array('avatar_filename', 'photo_filename', 'sig_img_filename') as $pv) {
             if (!isset($row[$pv])) {
                 $row[$pv] = '';
             }
         }
         $cond['signature_image'] = ($row['sig_img_filename'] == '' or $this->EE->config->item('enable_signatures') == 'n' or $this->EE->session->userdata('display_signatures') == 'n') ? 'FALSE' : 'TRUE';
         $cond['avatar'] = ($row['avatar_filename'] == '' or $this->EE->config->item('enable_avatars') == 'n' or $this->EE->session->userdata('display_avatars') == 'n') ? 'FALSE' : 'TRUE';
         $cond['photo'] = ($row['photo_filename'] == '' or $this->EE->config->item('enable_photos') == 'n' or $this->EE->session->userdata('display_photos') == 'n') ? 'FALSE' : 'TRUE';
         $cond['forum_topic'] = empty($row['forum_topic_id']) ? 'FALSE' : 'TRUE';
         $cond['not_forum_topic'] = !empty($row['forum_topic_id']) ? 'FALSE' : 'TRUE';
         $cond['category_request'] = $this->cat_request === FALSE ? 'FALSE' : 'TRUE';
         $cond['not_category_request'] = $this->cat_request !== FALSE ? 'FALSE' : 'TRUE';
         $cond['channel'] = $row['channel_title'];
         $cond['channel_short_name'] = $row['channel_name'];
         $cond['author'] = $row['screen_name'] != '' ? $row['screen_name'] : $row['username'];
         $cond['photo_url'] = $this->EE->config->slash_item('photo_url') . $row['photo_filename'];
         $cond['photo_image_width'] = $row['photo_width'];
         $cond['photo_image_height'] = $row['photo_height'];
         $cond['avatar_url'] = $this->EE->config->slash_item('avatar_url') . $row['avatar_filename'];
         $cond['avatar_image_width'] = $row['avatar_width'];
         $cond['avatar_image_height'] = $row['avatar_height'];
         $cond['signature_image_url'] = $this->EE->config->slash_item('sig_img_url') . $row['sig_img_filename'];
         $cond['signature_image_width'] = $row['sig_img_width'];
         $cond['signature_image_height'] = $row['sig_img_height'];
         $cond['relative_date'] = $this->EE->localize->format_timespan($this->EE->localize->now - $row['entry_date']);
         if (isset($this->cfields[$row['site_id']])) {
             foreach ($this->cfields[$row['site_id']] as $key => $value) {
                 $cond[$key] = !isset($row['field_id_' . $value]) ? '' : $row['field_id_' . $value];
                 // Is this field used with a modifier anywhere?
                 if (isset($modified_conditionals[$key]) && count($modified_conditionals[$key])) {
                     $this->EE->load->library('api');
                     $this->EE->api->instantiate('channel_fields');
                     if ($this->EE->api_channel_fields->setup_handler($value)) {
                         foreach ($modified_conditionals[$key] as $modifier) {
                             $this->EE->api_channel_fields->apply('_init', array(array('row' => $row)));
                             $data = $this->EE->api_channel_fields->apply('pre_process', array($cond[$key]));
                             if ($this->EE->api_channel_fields->check_method_exists('replace_' . $modifier)) {
                                 $cond[$key . ':' . $modifier] = $this->EE->api_channel_fields->apply('replace_' . $modifier, array($data, array(), FALSE));
                             } else {
                                 $cond[$key . ':' . $modifier] = FALSE;
                                 $this->EE->TMPL->log_item('Unable to find parse type for custom field conditional: ' . $key . ':' . $modifier);
                             }
                         }
                     }
                 }
             }
         }
         foreach ($this->mfields as $key => $value) {
             $cond[$key] = !array_key_exists('m_field_id_' . $value[0], $row) ? '' : $row['m_field_id_' . $value[0]];
             //( ! isset($row['m_field_id_'.$value[0]])) ? '' : $row['m_field_id_'.$value[0]];
         }
         //$tagdata = $this->EE->functions->prep_conditionals($tagdata, $cond);
         // Reset custom variable pair cache
         $parsed_custom_pairs = array();
         //  Parse Variable Pairs
         foreach ($this->EE->TMPL->var_pair as $key => $val) {
             //  parse categories
             if (strncmp($key, 'categories', 10) == 0) {
                 if (isset($this->categories[$row['entry_id']]) and is_array($this->categories[$row['entry_id']]) and count($cat_chunk) > 0) {
                     // Get category ID from URL for {if active} conditional
                     $this->EE->load->helper('segment');
                     $active_cat = $this->pagination->dynamic_sql && $this->cat_request ? parse_category($this->query_string) : FALSE;
                     foreach ($cat_chunk as $catkey => $catval) {
                         $cats = '';
                         $i = 0;
                         //  We do the pulling out of categories before the "prepping" of conditionals
                         //  So, we have to do it here again too.  How annoying...
                         $catval[0] = $this->EE->functions->prep_conditionals($catval[0], $cond);
                         $catval[2] = $this->EE->functions->prep_conditionals($catval[2], $cond);
                         $not_these = array();
                         $these = array();
                         $not_these_groups = array();
                         $these_groups = array();
                         if (isset($catval[1]['show'])) {
                             if (strncmp($catval[1]['show'], 'not ', 4) == 0) {
                                 $not_these = explode('|', trim(substr($catval[1]['show'], 3)));
                             } else {
                                 $these = explode('|', trim($catval[1]['show']));
                             }
                         }
                         if (isset($catval[1]['show_group'])) {
                             if (strncmp($catval[1]['show_group'], 'not ', 4) == 0) {
                                 $not_these_groups = explode('|', trim(substr($catval[1]['show_group'], 3)));
                             } else {
                                 $these_groups = explode('|', trim($catval[1]['show_group']));
                             }
                         }
                         foreach ($this->categories[$row['entry_id']] as $k => $v) {
                             if (in_array($v[0], $not_these) or isset($v[5]) && in_array($v[5], $not_these_groups)) {
                                 continue;
                             } elseif (count($these) > 0 && !in_array($v[0], $these) or count($these_groups) > 0 && isset($v[5]) && !in_array($v[5], $these_groups)) {
                                 continue;
                             }
                             $temp = $catval[0];
                             if (preg_match_all("#" . LD . "path=(.+?)" . RD . "#", $temp, $matches)) {
                                 foreach ($matches[1] as $match) {
                                     if ($this->use_category_names == TRUE) {
                                         $temp = preg_replace("#" . LD . "path=.+?" . RD . "#", $this->EE->functions->remove_double_slashes($this->EE->functions->create_url($match) . '/' . $this->reserved_cat_segment . '/' . $v[6]), $temp, 1);
                                     } else {
                                         $temp = preg_replace("#" . LD . "path=.+?" . RD . "#", $this->EE->functions->remove_double_slashes($this->EE->functions->create_url($match) . '/C' . $v[0]), $temp, 1);
                                     }
                                 }
                             } else {
                                 $temp = preg_replace("#" . LD . "path=.+?" . RD . "#", $this->EE->functions->create_url("SITE_INDEX"), $temp);
                             }
                             $this->EE->load->library('file_field');
                             $cat_image = $this->EE->file_field->parse_field($v[3]);
                             $cat_vars = array('category_name' => $v[2], 'category_url_title' => $v[6], 'category_description' => isset($v[4]) ? $v[4] : '', 'category_group' => isset($v[5]) ? $v[5] : '', 'category_image' => $cat_image['url'], 'category_id' => $v[0], 'parent_id' => $v[1], 'active' => $active_cat == $v[0] || $active_cat == $v[6]);
                             // add custom fields for conditionals prep
                             foreach ($this->catfields as $cv) {
                                 $cat_vars[$cv['field_name']] = !isset($v['field_id_' . $cv['field_id']]) ? '' : $v['field_id_' . $cv['field_id']];
                             }
                             $temp = $this->EE->functions->prep_conditionals($temp, $cat_vars);
                             $temp = str_replace(array(LD . "category_id" . RD, LD . "category_name" . RD, LD . "category_url_title" . RD, LD . "category_image" . RD, LD . "category_group" . RD, LD . 'category_description' . RD, LD . 'parent_id' . RD), array($v[0], $v[2], $v[6], $cat_image['url'], isset($v[5]) ? $v[5] : '', isset($v[4]) ? $v[4] : '', $v[1]), $temp);
                             foreach ($this->catfields as $cv2) {
                                 if (isset($v['field_id_' . $cv2['field_id']]) and $v['field_id_' . $cv2['field_id']] != '') {
                                     $field_content = $this->EE->typography->parse_type($v['field_id_' . $cv2['field_id']], array('text_format' => $v['field_ft_' . $cv2['field_id']], 'html_format' => $v['field_html_formatting'], 'auto_links' => 'n', 'allow_img_url' => 'y'));
                                     $temp = str_replace(LD . $cv2['field_name'] . RD, $field_content, $temp);
                                 } else {
                                     // garbage collection
                                     $temp = str_replace(LD . $cv2['field_name'] . RD, '', $temp);
                                 }
                                 $temp = $this->EE->functions->remove_double_slashes($temp);
                             }
                             $cats .= $temp;
                             if (is_array($catval[1]) && isset($catval[1]['limit']) && $catval[1]['limit'] == ++$i) {
                                 break;
                             }
                         }
                         if (is_array($catval[1]) and isset($catval[1]['backspace'])) {
                             $cats = substr($cats, 0, -$catval[1]['backspace']);
                         }
                         // Check to see if we need to parse {filedir_n}
                         if (strpos($cats, '{filedir_') !== FALSE) {
                             $this->EE->load->library('file_field');
                             $cats = $this->EE->file_field->parse_string($cats);
                         }
                         $tagdata = str_replace($catval[2], $cats, $tagdata);
                     }
                 } else {
                     $tagdata = $this->EE->TMPL->delete_var_pairs($key, 'categories', $tagdata);
                 }
             }
             // END CATEGORIES
             // parse custom field pairs (file, checkbox, multiselect)
             // First we need the key name out of the {name foo=bar|baz} mess
             $key_name = $key;
             $parse_fnc_catchall = 'replace_tag_catchall';
             if (($spc = strpos($key, ' ')) !== FALSE) {
                 $key_name = substr($key, 0, $spc);
             }
             if (($cln = strpos($key, ':')) !== FALSE) {
                 $key_name = substr($key_name, 0, $cln);
             }
             // Is it a custom field?
             if (isset($this->cfields[$row['site_id']][$key_name]) && !in_array($key_name, $parsed_custom_pairs)) {
                 // We parse all chunks, but TMPL->var_pairs will still have the others
                 // so we'll keep track of these and bail if we've parsed it
                 $parsed_custom_pairs[] = $key_name;
                 // Is this custom field part of the current channel row?
                 if (isset($row['field_id_' . $this->cfields[$row['site_id']][$key_name]]) && isset($this->pfields[$row['site_id']][$this->cfields[$row['site_id']][$key_name]])) {
                     $this->EE->load->library('api');
                     $this->EE->api->instantiate('channel_fields');
                     if ($this->EE->api_channel_fields->setup_handler($this->cfields[$row['site_id']][$key_name])) {
                         $this->EE->api_channel_fields->apply('_init', array(array('row' => $row)));
                         // Preprocess
                         $data = $this->EE->api_channel_fields->apply('pre_process', array($row['field_id_' . $this->cfields[$row['site_id']][$key_name]]));
                         // Blast through all the chunks
                         if (isset($pfield_chunk[$row['site_id']][$key_name])) {
                             foreach ($pfield_chunk[$row['site_id']][$key_name] as $chk_data) {
                                 // Set up parse function name based on whether or not
                                 // we have a modifier
                                 $parse_fnc = isset($chk_data[3]) ? 'replace_' . $chk_data[3] : 'replace_tag';
                                 if ($this->EE->api_channel_fields->check_method_exists($parse_fnc)) {
                                     $tpl_chunk = $this->EE->api_channel_fields->apply($parse_fnc, array($data, $chk_data[1], $chk_data[0]));
                                 } elseif ($this->EE->api_channel_fields->check_method_exists($parse_fnc_catchall) and isset($chk_data[3])) {
                                     $tpl_chunk = $this->EE->api_channel_fields->apply($parse_fnc_catchall, array($data, $chk_data[1], $chk_data[0], $chk_data[3]));
                                 } else {
                                     $tpl_chunk = '';
                                     $this->EE->TMPL->log_item('Unable to find parse type for custom field: ' . $key_name);
                                 }
                                 // Replace the chunk
                                 $tagdata = str_replace($chk_data[2], $tpl_chunk, $tagdata);
                             }
                         }
                     } else {
                         $this->EE->TMPL->log_item('Unable to find field type for custom field: ' . $key);
                         $tagdata = $this->EE->TMPL->delete_var_pairs($key, $key_name, $tagdata);
                     }
                 } else {
                     $tagdata = $this->EE->TMPL->delete_var_pairs($key, $key_name, $tagdata);
                 }
             }
             // END CUSTOM FIELD PAIRS
             //  parse date heading
             if (strncmp($key, 'date_heading', 12) == 0) {
                 // Set the display preference
                 $display = (is_array($val) and isset($val['display'])) ? $val['display'] : 'daily';
                 //  Hourly header
                 if ($display == 'hourly') {
                     $heading_date_hourly = gmdate('YmdH', $this->EE->localize->set_localized_time($row['entry_date']));
                     if ($heading_date_hourly == $heading_flag_hourly) {
                         $tagdata = $this->EE->TMPL->delete_var_pairs($key, 'date_heading', $tagdata);
                     } else {
                         $tagdata = $this->EE->TMPL->swap_var_pairs($key, 'date_heading', $tagdata);
                         $heading_flag_hourly = $heading_date_hourly;
                     }
                 } elseif ($display == 'weekly') {
                     $temp_date = $this->EE->localize->set_localized_time($row['entry_date']);
                     // date()'s week variable 'W' starts weeks on Monday per ISO-8601.
                     // By default we start weeks on Sunday, so we need to do a little dance for
                     // entries made on Sundays to make sure they get placed in the right week heading
                     if (strtolower($this->EE->TMPL->fetch_param('start_day')) != 'monday' && gmdate('w', $this->EE->localize->set_localized_time($row['entry_date'])) == 0) {
                         // add 7 days to toss us into the next ISO-8601 week
                         $heading_date_weekly = gmdate('YW', $temp_date + 604800);
                     } else {
                         $heading_date_weekly = gmdate('YW', $temp_date);
                     }
                     if ($heading_date_weekly == $heading_flag_weekly) {
                         $tagdata = $this->EE->TMPL->delete_var_pairs($key, 'date_heading', $tagdata);
                     } else {
                         $tagdata = $this->EE->TMPL->swap_var_pairs($key, 'date_heading', $tagdata);
                         $heading_flag_weekly = $heading_date_weekly;
                     }
                 } elseif ($display == 'monthly') {
                     $heading_date_monthly = gmdate('Ym', $this->EE->localize->set_localized_time($row['entry_date']));
                     if ($heading_date_monthly == $heading_flag_monthly) {
                         $tagdata = $this->EE->TMPL->delete_var_pairs($key, 'date_heading', $tagdata);
                     } else {
                         $tagdata = $this->EE->TMPL->swap_var_pairs($key, 'date_heading', $tagdata);
                         $heading_flag_monthly = $heading_date_monthly;
                     }
                 } elseif ($display == 'yearly') {
                     $heading_date_yearly = gmdate('Y', $this->EE->localize->set_localized_time($row['entry_date']));
                     if ($heading_date_yearly == $heading_flag_yearly) {
                         $tagdata = $this->EE->TMPL->delete_var_pairs($key, 'date_heading', $tagdata);
                     } else {
                         $tagdata = $this->EE->TMPL->swap_var_pairs($key, 'date_heading', $tagdata);
                         $heading_flag_yearly = $heading_date_yearly;
                     }
                 } else {
                     $heading_date_daily = gmdate('Ymd', $this->EE->localize->set_localized_time($row['entry_date']));
                     if ($heading_date_daily == $heading_flag_daily) {
                         $tagdata = $this->EE->TMPL->delete_var_pairs($key, 'date_heading', $tagdata);
                     } else {
                         $tagdata = $this->EE->TMPL->swap_var_pairs($key, 'date_heading', $tagdata);
                         $heading_flag_daily = $heading_date_daily;
                     }
                 }
             }
             // END DATE HEADING
             //  parse date footer
             if (strncmp($key, 'date_footer', 11) == 0) {
                 // Set the display preference
                 $display = (is_array($val) and isset($val['display'])) ? $val['display'] : 'daily';
                 //  Hourly footer
                 if ($display == 'hourly') {
                     if (!isset($query_result[$row['count']]) or gmdate('YmdH', $this->EE->localize->set_localized_time($row['entry_date'])) != gmdate('YmdH', $this->EE->localize->set_localized_time($query_result[$row['count']]['entry_date']))) {
                         $tagdata = $this->EE->TMPL->swap_var_pairs($key, 'date_footer', $tagdata);
                     } else {
                         $tagdata = $this->EE->TMPL->delete_var_pairs($key, 'date_footer', $tagdata);
                     }
                 } elseif ($display == 'weekly') {
                     if (!isset($query_result[$row['count']]) or gmdate('YW', $this->EE->localize->set_localized_time($row['entry_date'])) != gmdate('YW', $this->EE->localize->set_localized_time($query_result[$row['count']]['entry_date']))) {
                         $tagdata = $this->EE->TMPL->swap_var_pairs($key, 'date_footer', $tagdata);
                     } else {
                         $tagdata = $this->EE->TMPL->delete_var_pairs($key, 'date_footer', $tagdata);
                     }
                 } elseif ($display == 'monthly') {
                     if (!isset($query_result[$row['count']]) or gmdate('Ym', $this->EE->localize->set_localized_time($row['entry_date'])) != gmdate('Ym', $this->EE->localize->set_localized_time($query_result[$row['count']]['entry_date']))) {
                         $tagdata = $this->EE->TMPL->swap_var_pairs($key, 'date_footer', $tagdata);
                     } else {
                         $tagdata = $this->EE->TMPL->delete_var_pairs($key, 'date_footer', $tagdata);
                     }
                 } elseif ($display == 'yearly') {
                     if (!isset($query_result[$row['count']]) or gmdate('Y', $this->EE->localize->set_localized_time($row['entry_date'])) != gmdate('Y', $this->EE->localize->set_localized_time($query_result[$row['count']]['entry_date']))) {
                         $tagdata = $this->EE->TMPL->swap_var_pairs($key, 'date_footer', $tagdata);
                     } else {
                         $tagdata = $this->EE->TMPL->delete_var_pairs($key, 'date_footer', $tagdata);
                     }
                 } else {
                     if (!isset($query_result[$row['count']]) or gmdate('Ymd', $this->EE->localize->set_localized_time($row['entry_date'])) != gmdate('Ymd', $this->EE->localize->set_localized_time($query_result[$row['count']]['entry_date']))) {
                         $tagdata = $this->EE->TMPL->swap_var_pairs($key, 'date_footer', $tagdata);
                     } else {
                         $tagdata = $this->EE->TMPL->delete_var_pairs($key, 'date_footer', $tagdata);
                     }
                 }
             }
             // END DATE FOOTER
         }
         // END VARIABLE PAIRS
         // We swap out the conditionals after pairs are parsed so they don't interfere
         // with the string replace
         $tagdata = $this->EE->functions->prep_conditionals($tagdata, $cond);
         //  Parse "single" variables
         foreach ($this->EE->TMPL->var_single as $key => $val) {
             /**--------
             			/**  parse simple conditionals: {body|more|summary}
             			/**--------*/
             // Note:  This must happen first.
             if (strpos($key, '|') !== FALSE && is_array($val)) {
                 foreach ($val as $item) {
                     // Basic fields
                     if (isset($row[$item]) and $row[$item] != "") {
                         $tagdata = $this->EE->TMPL->swap_var_single($key, $row[$item], $tagdata);
                         continue;
                     }
                     // Custom channel fields
                     if (isset($this->cfields[$row['site_id']][$item]) and isset($row['field_id_' . $this->cfields[$row['site_id']][$item]]) and $row['field_id_' . $this->cfields[$row['site_id']][$item]] != "") {
                         $entry = $this->EE->typography->parse_type($row['field_id_' . $this->cfields[$row['site_id']][$item]], array('text_format' => $row['field_ft_' . $this->cfields[$row['site_id']][$item]], 'html_format' => $row['channel_html_formatting'], 'auto_links' => $row['channel_auto_link_urls'], 'allow_img_url' => $row['channel_allow_img_urls']));
                         $tagdata = $this->EE->TMPL->swap_var_single($key, $entry, $tagdata);
                         continue;
                     }
                 }
                 // Garbage collection
                 $val = '';
                 $tagdata = $this->EE->TMPL->swap_var_single($key, "", $tagdata);
             }
             //  parse {switch} variable
             if (preg_match("/^switch\\s*=.+/i", $key)) {
                 $sparam = $this->EE->functions->assign_parameters($key);
                 $sw = '';
                 if (isset($sparam['switch'])) {
                     $sopt = explode("|", $sparam['switch']);
                     $sw = $sopt[($count + count($sopt)) % count($sopt)];
                 }
                 $tagdata = $this->EE->TMPL->swap_var_single($key, $sw, $tagdata);
             }
             //  parse entry date
             if (isset($entry_date[$key])) {
                 $val = str_replace($entry_date[$key], $this->EE->localize->convert_timestamp($entry_date[$key], $row['entry_date'], TRUE), $val);
                 $tagdata = $this->EE->TMPL->swap_var_single($key, $val, $tagdata);
             }
             //  Recent Comment Date
             if (isset($recent_comment_date[$key])) {
                 if ($row['recent_comment_date'] != 0) {
                     $val = str_replace($recent_comment_date[$key], $this->EE->localize->convert_timestamp($recent_comment_date[$key], $row['recent_comment_date'], TRUE), $val);
                     $tagdata = $this->EE->TMPL->swap_var_single($key, $val, $tagdata);
                 } else {
                     $tagdata = str_replace(LD . $key . RD, '', $tagdata);
                 }
             }
             //  GMT date - entry date in GMT
             if (isset($gmt_entry_date[$key])) {
                 $val = str_replace($gmt_entry_date[$key], $this->EE->localize->convert_timestamp($gmt_entry_date[$key], $row['entry_date'], FALSE), $val);
                 $tagdata = $this->EE->TMPL->swap_var_single($key, $val, $tagdata);
             }
             if (isset($gmt_date[$key])) {
                 $val = str_replace($gmt_date[$key], $this->EE->localize->convert_timestamp($gmt_date[$key], $row['entry_date'], FALSE), $val);
                 $tagdata = $this->EE->TMPL->swap_var_single($key, $val, $tagdata);
             }
             //  parse "last edit" date
             if (isset($edit_date[$key])) {
                 $val = str_replace($edit_date[$key], $this->EE->localize->convert_timestamp($edit_date[$key], $this->EE->localize->timestamp_to_gmt($row['edit_date']), TRUE), $val);
                 $tagdata = $this->EE->TMPL->swap_var_single($key, $val, $tagdata);
             }
             //  "last edit" date as GMT
             if (isset($gmt_edit_date[$key])) {
                 $val = str_replace($gmt_edit_date[$key], $this->EE->localize->convert_timestamp($gmt_edit_date[$key], $this->EE->localize->timestamp_to_gmt($row['edit_date']), FALSE), $val);
                 $tagdata = $this->EE->TMPL->swap_var_single($key, $val, $tagdata);
             }
             //  parse expiration date
             if (isset($expiration_date[$key])) {
                 if ($row['expiration_date'] != 0) {
                     $val = str_replace($expiration_date[$key], $this->EE->localize->convert_timestamp($expiration_date[$key], $row['expiration_date'], TRUE), $val);
                     $tagdata = $this->EE->TMPL->swap_var_single($key, $val, $tagdata);
                 } else {
                     $tagdata = str_replace(LD . $key . RD, "", $tagdata);
                 }
             }
             //  "week_date"
             if (isset($week_date[$key])) {
                 // Subtract the number of days the entry is "into" the week to get zero (Sunday)
                 // If the entry date is for Sunday, and Monday is being used as the week's start day,
                 // then we must back things up by six days
                 $offset = 0;
                 if (strtolower($this->EE->TMPL->fetch_param('start_day')) == 'monday') {
                     $day_of_week = $this->EE->localize->convert_timestamp('%w', $row['entry_date'], TRUE);
                     if ($day_of_week == '0') {
                         $offset = -518400;
                         // back six days
                     } else {
                         $offset = 86400;
                         // plus one day
                     }
                 }
                 $week_start_date = $row['entry_date'] - $this->EE->localize->convert_timestamp('%w', $row['entry_date'], TRUE) * 60 * 60 * 24 + $offset;
                 $val = str_replace($week_date[$key], $this->EE->localize->convert_timestamp($week_date[$key], $week_start_date, TRUE), $val);
                 $tagdata = $this->EE->TMPL->swap_var_single($key, $val, $tagdata);
             }
             //  parse profile path
             if (strncmp($key, 'profile_path', 12) == 0) {
                 $tagdata = $this->EE->TMPL->swap_var_single($key, $this->EE->functions->create_url($this->EE->functions->extract_path($key) . '/' . $row['member_id']), $tagdata);
             }
             //  {member_search_path}
             if (strncmp($key, 'member_search_path', 18) == 0) {
                 $tagdata = $this->EE->TMPL->swap_var_single($key, $search_link . $row['member_id'], $tagdata);
             }
             //  parse comment_path
             if (strncmp($key, 'comment_path', 12) == 0 or strncmp($key, 'entry_id_path', 13) == 0) {
                 $path = ($this->EE->functions->extract_path($key) != '' and $this->EE->functions->extract_path($key) != 'SITE_INDEX') ? $this->EE->functions->extract_path($key) . '/' . $row['entry_id'] : $row['entry_id'];
                 $tagdata = $this->EE->TMPL->swap_var_single($key, $this->EE->functions->create_url($path), $tagdata);
             }
             //  parse URL title path
             if (strncmp($key, 'url_title_path', 14) == 0) {
                 $path = ($this->EE->functions->extract_path($key) != '' and $this->EE->functions->extract_path($key) != 'SITE_INDEX') ? $this->EE->functions->extract_path($key) . '/' . $row['url_title'] : $row['url_title'];
                 $tagdata = $this->EE->TMPL->swap_var_single($key, $this->EE->functions->create_url($path), $tagdata);
             }
             //  parse title permalink
             if (strncmp($key, 'title_permalink', 15) == 0) {
                 $path = ($this->EE->functions->extract_path($key) != '' and $this->EE->functions->extract_path($key) != 'SITE_INDEX') ? $this->EE->functions->extract_path($key) . '/' . $row['url_title'] : $row['url_title'];
                 $tagdata = $this->EE->TMPL->swap_var_single($key, $this->EE->functions->create_url($path, FALSE), $tagdata);
             }
             //  parse permalink
             if (strncmp($key, 'permalink', 9) == 0) {
                 $path = ($this->EE->functions->extract_path($key) != '' and $this->EE->functions->extract_path($key) != 'SITE_INDEX') ? $this->EE->functions->extract_path($key) . '/' . $row['entry_id'] : $row['entry_id'];
                 $tagdata = $this->EE->TMPL->swap_var_single($key, $this->EE->functions->create_url($path, FALSE), $tagdata);
             }
             //  {comment_auto_path}
             if ($key == "comment_auto_path") {
                 $path = $row['comment_url'] == '' ? $row['channel_url'] : $row['comment_url'];
                 $tagdata = $this->EE->TMPL->swap_var_single($key, $path, $tagdata);
             }
             //  {comment_url_title_auto_path}
             if ($key == "comment_url_title_auto_path") {
                 $path = $row['comment_url'] == '' ? $row['channel_url'] : $row['comment_url'];
                 $tagdata = $this->EE->TMPL->swap_var_single($key, reduce_double_slashes($path . '/' . $row['url_title']), $tagdata);
             }
             //  {comment_entry_id_auto_path}
             if ($key == "comment_entry_id_auto_path") {
                 $path = $row['comment_url'] == '' ? $row['channel_url'] : $row['comment_url'];
                 $tagdata = $this->EE->TMPL->swap_var_single($key, reduce_double_slashes($path . '/' . $row['entry_id']), $tagdata);
             }
             //  {author}
             if ($key == "author") {
                 $tagdata = $this->EE->TMPL->swap_var_single($val, $row['screen_name'] != '' ? $row['screen_name'] : $row['username'], $tagdata);
             }
             //  {channel}
             if ($key == "channel") {
                 $tagdata = $this->EE->TMPL->swap_var_single($val, $row['channel_title'], $tagdata);
             }
             //  {channel_short_name}
             if ($key == "channel_short_name") {
                 $tagdata = $this->EE->TMPL->swap_var_single($val, $row['channel_name'], $tagdata);
             }
             //  {relative_date}
             if ($key == "relative_date") {
                 $tagdata = $this->EE->TMPL->swap_var_single($val, $this->EE->localize->format_timespan($this->EE->localize->now - $row['entry_date']), $tagdata);
             }
             //  {trimmed_url} - used by Atom feeds
             if ($key == "trimmed_url") {
                 $channel_url = (isset($row['channel_url']) and $row['channel_url'] != '') ? $row['channel_url'] : '';
                 $channel_url = str_replace(array('http://', 'www.'), '', $channel_url);
                 $xe = explode("/", $channel_url);
                 $channel_url = current($xe);
                 $tagdata = $this->EE->TMPL->swap_var_single($val, $channel_url, $tagdata);
             }
             //  {relative_url} - used by Atom feeds
             if ($key == "relative_url") {
                 $channel_url = (isset($row['channel_url']) and $row['channel_url'] != '') ? $row['channel_url'] : '';
                 $channel_url = str_replace('http://', '', $channel_url);
                 if ($x = strpos($channel_url, "/")) {
                     $channel_url = substr($channel_url, $x + 1);
                 }
                 $channel_url = rtrim($channel_url, '/');
                 $tagdata = $this->EE->TMPL->swap_var_single($val, $channel_url, $tagdata);
             }
             //  {url_or_email}
             if ($key == "url_or_email") {
                 $tagdata = $this->EE->TMPL->swap_var_single($val, $row['url'] != '' ? $row['url'] : $row['email'], $tagdata);
             }
             //  {url_or_email_as_author}
             if ($key == "url_or_email_as_author") {
                 $name = $row['screen_name'] != '' ? $row['screen_name'] : $row['username'];
                 if ($row['url'] != '') {
                     $tagdata = $this->EE->TMPL->swap_var_single($val, "<a href=\"" . $row['url'] . "\">" . $name . "</a>", $tagdata);
                 } else {
                     $tagdata = $this->EE->TMPL->swap_var_single($val, $this->EE->typography->encode_email($row['email'], $name), $tagdata);
                 }
             }
             //  {url_or_email_as_link}
             if ($key == "url_or_email_as_link") {
                 if ($row['url'] != '') {
                     $tagdata = $this->EE->TMPL->swap_var_single($val, "<a href=\"" . $row['url'] . "\">" . $row['url'] . "</a>", $tagdata);
                 } else {
                     $tagdata = $this->EE->TMPL->swap_var_single($val, $this->EE->typography->encode_email($row['email']), $tagdata);
                 }
             }
             //  {signature}
             if ($key == "signature") {
                 if ($this->EE->session->userdata('display_signatures') == 'n' or $row['signature'] == '' or $this->EE->session->userdata('display_signatures') == 'n') {
                     $tagdata = $this->EE->TMPL->swap_var_single($key, '', $tagdata);
                 } else {
                     $tagdata = $this->EE->TMPL->swap_var_single($key, $this->EE->typography->parse_type($row['signature'], array('text_format' => 'xhtml', 'html_format' => 'safe', 'auto_links' => 'y', 'allow_img_url' => $this->EE->config->item('sig_allow_img_hotlink'))), $tagdata);
                 }
             }
             if ($key == "signature_image_url") {
                 if ($this->EE->session->userdata('display_signatures') == 'n' or $row['sig_img_filename'] == '' or $this->EE->session->userdata('display_signatures') == 'n') {
                     $tagdata = $this->EE->TMPL->swap_var_single($key, '', $tagdata);
                     $tagdata = $this->EE->TMPL->swap_var_single('signature_image_width', '', $tagdata);
                     $tagdata = $this->EE->TMPL->swap_var_single('signature_image_height', '', $tagdata);
                 } else {
                     $tagdata = $this->EE->TMPL->swap_var_single($key, $this->EE->config->slash_item('sig_img_url') . $row['sig_img_filename'], $tagdata);
                     $tagdata = $this->EE->TMPL->swap_var_single('signature_image_width', $row['sig_img_width'], $tagdata);
                     $tagdata = $this->EE->TMPL->swap_var_single('signature_image_height', $row['sig_img_height'], $tagdata);
                 }
             }
             if ($key == "avatar_url") {
                 if ($this->EE->session->userdata('display_avatars') == 'n' or $row['avatar_filename'] == '' or $this->EE->session->userdata('display_avatars') == 'n') {
                     $tagdata = $this->EE->TMPL->swap_var_single($key, '', $tagdata);
                     $tagdata = $this->EE->TMPL->swap_var_single('avatar_image_width', '', $tagdata);
                     $tagdata = $this->EE->TMPL->swap_var_single('avatar_image_height', '', $tagdata);
                 } else {
                     $tagdata = $this->EE->TMPL->swap_var_single($key, $this->EE->config->slash_item('avatar_url') . $row['avatar_filename'], $tagdata);
                     $tagdata = $this->EE->TMPL->swap_var_single('avatar_image_width', $row['avatar_width'], $tagdata);
                     $tagdata = $this->EE->TMPL->swap_var_single('avatar_image_height', $row['avatar_height'], $tagdata);
                 }
             }
             if ($key == "photo_url") {
                 if ($this->EE->session->userdata('display_photos') == 'n' or $row['photo_filename'] == '' or $this->EE->session->userdata('display_photos') == 'n') {
                     $tagdata = $this->EE->TMPL->swap_var_single($key, '', $tagdata);
                     $tagdata = $this->EE->TMPL->swap_var_single('photo_image_width', '', $tagdata);
                     $tagdata = $this->EE->TMPL->swap_var_single('photo_image_height', '', $tagdata);
                 } else {
                     $tagdata = $this->EE->TMPL->swap_var_single($key, $this->EE->config->slash_item('photo_url') . $row['photo_filename'], $tagdata);
                     $tagdata = $this->EE->TMPL->swap_var_single('photo_image_width', $row['photo_width'], $tagdata);
                     $tagdata = $this->EE->TMPL->swap_var_single('photo_image_height', $row['photo_height'], $tagdata);
                 }
             }
             //  parse {title}
             if ($key == 'title') {
                 $row['title'] = str_replace(array('{', '}'), array('&#123;', '&#125;'), $row['title']);
                 $tagdata = $this->EE->TMPL->swap_var_single($val, $this->EE->typography->format_characters($row['title']), $tagdata);
             }
             //  parse basic fields (username, screen_name, etc.)
             //  Use array_key_exists to handle null values
             if ($val and array_key_exists($val, $row)) {
                 $tagdata = $this->EE->TMPL->swap_var_single($val, $row[$val], $tagdata);
             }
             //  parse custom date fields
             if (isset($custom_date_fields[$key]) && isset($this->dfields[$row['site_id']])) {
                 foreach ($this->dfields[$row['site_id']] as $dkey => $dval) {
                     if (strncmp($key . ' ', $dkey . ' ', strlen($dkey . ' ')) !== 0) {
                         continue;
                     }
                     if ($row['field_id_' . $dval] == 0 or $row['field_id_' . $dval] == '') {
                         $tagdata = $this->EE->TMPL->swap_var_single($key, '', $tagdata);
                         continue;
                     }
                     // use a temporary variable in case the custom date variable is used
                     // multiple times with different formats; prevents localization from
                     // occurring multiple times on the same value
                     $temp_val = $row['field_id_' . $dval];
                     $localize = TRUE;
                     if (isset($row['field_dt_' . $dval]) and $row['field_dt_' . $dval] != '') {
                         $localize = TRUE;
                         if ($row['field_dt_' . $dval] != '') {
                             $temp_val = $this->EE->localize->simpl_offset($temp_val, $row['field_dt_' . $dval]);
                             $localize = FALSE;
                         }
                     }
                     $val = str_replace($custom_date_fields[$key], $this->EE->localize->convert_timestamp($custom_date_fields[$key], $temp_val, $localize), $val);
                     $tagdata = $this->EE->TMPL->swap_var_single($key, $val, $tagdata);
                 }
             }
             //  Assign Related Entry IDs
             // When an entry has related entries within it, since the related entry ID
             // is stored in the custom field itself we need to pull it out and set it
             // aside so that when the related stuff is parsed out we'll have it.
             // We also need to modify the marker in the template so that we can replace
             // it with the right entry
             if (isset($this->rfields[$row['site_id']][$val])) {
                 // No relationship?  Ditch the marker
                 if (!isset($row['field_id_' . $this->cfields[$row['site_id']][$val]]) or $row['field_id_' . $this->cfields[$row['site_id']][$val]] == 0 or !preg_match_all("/" . LD . "REL\\[" . $val . "\\](.+?)REL" . RD . "/", $tagdata, $match)) {
                     // replace the marker with the {if no_related_entries} content
                     preg_match_all("/" . LD . "REL\\[" . $val . "\\](.+?)REL" . RD . "/", $tagdata, $matches);
                     foreach ($matches[1] as $match) {
                         $tagdata = preg_replace("/" . LD . "REL\\[" . $val . "\\](.+?)REL" . RD . "/", $this->EE->TMPL->related_data[$match]['no_rel_content'], $tagdata);
                     }
                 } else {
                     for ($j = 0; $j < count($match[1]); $j++) {
                         $this->related_entries[] = $row['field_id_' . $this->cfields[$row['site_id']][$val]] . '_' . $match[1][$j];
                         $tagdata = preg_replace("/" . LD . "REL\\[" . $val . "\\](.+?)REL" . RD . "/", LD . "REL[" . $row['field_id_' . $this->cfields[$row['site_id']][$val]] . "][" . $val . "]\\1REL" . RD, $tagdata);
                     }
                     $tagdata = $this->EE->TMPL->swap_var_single($val, '', $tagdata);
                 }
             }
             // Clean up any unparsed relationship fields
             if (isset($this->rfields[$row['site_id']]) && count($this->rfields[$row['site_id']]) > 0) {
                 $tagdata = preg_replace("/" . LD . "REL\\[" . preg_quote($val, '/') . "\\](.+?)REL" . RD . "/", "", $tagdata);
             }
             // parse custom channel fields
             $params = array();
             $parse_fnc = 'replace_tag';
             $parse_fnc_catchall = 'replace_tag_catchall';
             $replace = $key;
             if (($spc = strpos($key, ' ')) !== FALSE) {
                 $params = $this->EE->functions->assign_parameters($key);
                 $val = $key = substr($key, 0, $spc);
             }
             if (($cln = strpos($key, ':')) !== FALSE) {
                 $modifier = substr($key, $cln + 1);
                 $parse_fnc = 'replace_' . $modifier;
                 $val = $key = substr($key, 0, $cln);
             }
             if (isset($this->cfields[$row['site_id']][$key])) {
                 if (!isset($row['field_id_' . $this->cfields[$row['site_id']][$val]]) or $row['field_id_' . $this->cfields[$row['site_id']][$val]] == '') {
                     $entry = '';
                 } else {
                     $this->EE->load->library('api');
                     $this->EE->api->instantiate('channel_fields');
                     $field_id = $this->cfields[$row['site_id']][$key];
                     if ($this->EE->api_channel_fields->setup_handler($field_id)) {
                         $this->EE->api_channel_fields->apply('_init', array(array('row' => $row)));
                         $data = $this->EE->api_channel_fields->apply('pre_process', array($row['field_id_' . $field_id]));
                         if ($this->EE->api_channel_fields->check_method_exists($parse_fnc)) {
                             $entry = $this->EE->api_channel_fields->apply($parse_fnc, array($data, $params, FALSE));
                         } elseif ($this->EE->api_channel_fields->check_method_exists($parse_fnc_catchall)) {
                             $entry = $this->EE->api_channel_fields->apply($parse_fnc_catchall, array($data, $params, FALSE, $modifier));
                         } else {
                             $entry = '';
                             $this->EE->TMPL->log_item('Unable to find parse type for custom field: ' . $parse_fnc);
                         }
                     } else {
                         // Couldn't find a fieldtype
                         $entry = $this->EE->typography->parse_type($this->EE->functions->encode_ee_tags($row['field_id_' . $this->cfields[$row['site_id']][$val]]), array('text_format' => $row['field_ft_' . $this->cfields[$row['site_id']][$val]], 'html_format' => $row['channel_html_formatting'], 'auto_links' => $row['channel_auto_link_urls'], 'allow_img_url' => $row['channel_allow_img_urls']));
                     }
                 }
                 // prevent accidental parsing of other channel variables in custom field data
                 if (strpos($entry, '{') !== FALSE) {
                     $this->EE->load->helper('string');
                     $tagdata = $this->EE->TMPL->swap_var_single($replace, str_replace(array('{', '}'), array(unique_marker('channel_bracket_open'), unique_marker('channel_bracket_close')), $entry), $tagdata);
                 } else {
                     $tagdata = $this->EE->TMPL->swap_var_single($replace, $entry, $tagdata);
                 }
             }
             //  parse custom member fields
             if (isset($this->mfields[$val]) && array_key_exists('m_field_id_' . $value[0], $row)) {
                 if (!isset($processed_member_fields[$row['member_id']]['m_field_id_' . $this->mfields[$val][0]])) {
                     $processed_member_fields[$row['member_id']]['m_field_id_' . $this->mfields[$val][0]] = $this->EE->typography->parse_type($row['m_field_id_' . $this->mfields[$val][0]], array('text_format' => $this->mfields[$val][1], 'html_format' => 'safe', 'auto_links' => 'y', 'allow_img_url' => 'n'));
                 }
                 $tagdata = $this->EE->TMPL->swap_var_single($val, $processed_member_fields[$row['member_id']]['m_field_id_' . $this->mfields[$val][0]], $tagdata);
             }
         }
         // END SINGLE VARIABLES
         // do we need to replace any curly braces that we protected in custom fields?
         if (strpos($tagdata, unique_marker('channel_bracket_open')) !== FALSE) {
             $tagdata = str_replace(array(unique_marker('channel_bracket_open'), unique_marker('channel_bracket_close')), array('{', '}'), $tagdata);
         }
         // -------------------------------------------
         // 'channel_entries_tagdata_end' hook.
         //  - Take the final results of an entry's parsing and do what you wish
         //
         if ($this->EE->extensions->active_hook('channel_entries_tagdata_end') === TRUE) {
             $tagdata = $this->EE->extensions->call('channel_entries_tagdata_end', $tagdata, $row, $this);
             if ($this->EE->extensions->end_script === TRUE) {
                 return $tagdata;
             }
         }
         //
         // -------------------------------------------
         $this->return_data .= $tagdata;
     }
     // END FOREACH LOOP
     // Kill multi_field variable
     if (strpos($this->return_data, 'multi_field=') !== FALSE) {
         $this->return_data = preg_replace("/" . LD . "multi_field\\=[\"'](.+?)[\"']" . RD . "/s", "", $this->return_data);
     }
     // Do we have backspacing?
     if ($back = $this->EE->TMPL->fetch_param('backspace')) {
         if (is_numeric($back)) {
             $this->return_data = substr($this->return_data, 0, -$back);
         }
     }
 }
예제 #11
0
 /**
  * Process Advanced Conditionals
  *
  * The syntax is generally: {if whatever = ""}Dude{if:elseif something != ""}Yo{if:else}
  *
  * The final processing of Advanced Conditionals.  Takes all of the member variables and uncachable
  * variables and preps the conditionals with them.  Then, it converts the conditionals to PHP so that
  * PHP can do all of the really heavy lifting for us.
  *
  * @param	string
  * @return	string
  */
 public function advanced_conditionals($str)
 {
     if (stristr($str, LD . 'if') === FALSE) {
         return $str;
     }
     /* ---------------------------------
     		/*	Hidden Configuration Variables
     		/*  - protect_javascript => Prevents advanced conditional parser from processing anything in <script> tags
     		/* ---------------------------------*/
     if (ee()->config->item('protect_javascript') == 'n') {
         $this->protect_javascript = FALSE;
     }
     $user_vars = array('member_id', 'group_id', 'group_description', 'group_title', 'username', 'screen_name', 'email', 'ip_address', 'location', 'total_entries', 'total_comments', 'private_messages', 'total_forum_posts', 'total_forum_topics', 'total_forum_replies');
     for ($i = 0, $s = count($user_vars), $data = array(); $i < $s; ++$i) {
         $data[$user_vars[$i]] = ee()->session->userdata[$user_vars[$i]];
         $data['logged_in_' . $user_vars[$i]] = ee()->session->userdata[$user_vars[$i]];
     }
     // Define an alternate variable for {group_id} since some tags use
     // it natively, causing it to be unavailable as a global
     $data['member_group'] = $data['logged_in_member_group'] = ee()->session->userdata['group_id'];
     // Logged in and logged out variables
     $data['logged_in'] = ee()->session->userdata['member_id'] == 0 ? 'FALSE' : 'TRUE';
     $data['logged_out'] = ee()->session->userdata['member_id'] != 0 ? 'FALSE' : 'TRUE';
     // current time
     $data['current_time'] = ee()->localize->now;
     // Member Group in_group('1') function, Super Secret!  Shhhhh!
     if (preg_match_all("/in_group\\(([^\\)]+)\\)/", $str, $matches)) {
         $groups = is_array(ee()->session->userdata['group_id']) ? ee()->session->userdata['group_id'] : array(ee()->session->userdata['group_id']);
         for ($i = 0, $s = count($matches[0]); $i < $s; ++$i) {
             $check = explode('|', str_replace(array('"', "'"), '', $matches[1][$i]));
             $str = str_replace($matches[0][$i], count(array_intersect($check, $groups)) > 0 ? 'TRUE' : 'FALSE', $str);
         }
     }
     // Final Prep, Safety On
     $str = ee()->functions->prep_conditionals($str, array_merge($this->segment_vars, $this->embed_vars, ee()->config->_global_vars, $data), 'y');
     // Protect Already Existing Unparsed PHP
     $opener = unique_marker('tmpl_php_open');
     $closer = unique_marker('tmpl_php_close');
     $str = str_replace(array('<?', '?' . '>'), array($opener . '?', '?' . $closer), $str);
     // Protect <script> tags
     $protected = array();
     $front_protect = unique_marker('tmpl_script_open');
     $back_protect = unique_marker('tmpl_script_close');
     if ($this->protect_javascript !== FALSE && stristr($str, '<script') && preg_match_all("/<script.*?" . ">.*?<\\/script>/is", $str, $matches)) {
         for ($i = 0, $s = count($matches[0]); $i < $s; ++$i) {
             $protected[$front_protect . $i . $back_protect] = $matches[0][$i];
         }
         $str = str_replace(array_values($protected), array_keys($protected), $str);
     }
     // Convert EE Conditionals to PHP
     $str = str_replace(array(LD . '/if' . RD, LD . 'if:else' . RD), array('<?php endif; ?' . '>', '<?php else : ?' . '>'), $str);
     if (strpos($str, LD . 'if') !== FALSE) {
         $str = preg_replace("/" . preg_quote(LD) . "((if:(else))*if)\\s+(.*?)" . preg_quote(RD) . "/s", '<?php \\3if(\\4) : ?' . '>', $str);
     }
     $str = $this->parse_template_php($str);
     // Unprotect <script> tags
     if (count($protected) > 0) {
         $str = str_replace(array_keys($protected), array_values($protected), $str);
     }
     // Unprotect Already Existing Unparsed PHP
     $str = str_replace(array($opener . '?', '?' . $closer), array('<' . '?', '?' . '>'), $str);
     return $str;
 }
예제 #12
0
 /**
  * Display an RTE field
  * 
  * @param string $data       the RTE html content
  * @param string $field_name the field name for the RTE field
  * @param array $settings   field settings:
  * 					field_ta_rows - the number of textarea rows
  * 					field_text_direction - ltr or rtl
  * 					field_fmt - xhtml, br or none
  * 
  * @return string	
  */
 public function display_field($data, $field_name, $settings)
 {
     $this->EE->load->helper('form');
     $field = array('name' => $field_name, 'id' => $field_name, 'rows' => $settings['field_ta_rows'], 'dir' => $settings['field_text_direction']);
     // form prepped nonsense
     $data = htmlspecialchars_decode($data, ENT_QUOTES);
     $code_marker = unique_marker('code');
     $code_chunks = array();
     $field_ft = isset($settings['field_fmt']) ? $settings['field_fmt'] : '';
     if ($field_ft == 'xhtml') {
         $data = trim($data);
         // Undo any existing newline formatting. Typography will change
         // it anyways and the rtf will add its own. Having this here
         // prevents growing-newline syndrome in the rtf and lets us switch
         // between rtf and non-rtf.
         $data = preg_replace("/<\\/p>\n*<p>/is", "\n\n", $data);
         $data = preg_replace("/<br( \\/)?>\n/is", "\n", $data);
     }
     // remove code chunks
     if (preg_match_all("/\\[code\\](.+?)\\[\\/code\\]/si", $data, $matches)) {
         foreach ($matches[1] as $i => $chunk) {
             $code_chunks[] = trim($chunk);
             $data = str_replace($matches[0][$i], $code_marker . $i, $data);
         }
     }
     // Check the RTE module and user's preferences
     if ($this->EE->session->userdata('rte_enabled') == 'y' and $this->EE->config->item('rte_enabled') == 'y') {
         $field['class'] = 'WysiHat-field';
         foreach ($code_chunks as &$chunk) {
             $chunk = htmlentities($chunk, ENT_QUOTES, 'UTF-8');
             $chunk = str_replace("\n", '<br>', $chunk);
         }
         // xhtml vs br
         if ($settings['field_fmt'] == 'xhtml') {
             $this->EE->load->library('typography');
             $data = $this->EE->typography->_format_newlines($data);
             // Remove double paragraph tags
             $data = preg_replace("/(<\\/?p>)\\1/is", "\\1", $data);
         }
     }
     // put code chunks back
     foreach ($code_chunks as $i => $chunk) {
         $data = str_replace($code_marker . $i, '[code]' . $chunk . '[/code]', $data);
     }
     // Swap {filedir_x} with the real URL. It will be converted back
     // upon submit by the RTE Image tool.
     $this->EE->load->model('file_upload_preferences_model');
     $dirs = $this->EE->file_upload_preferences_model->get_file_upload_preferences($this->EE->session->userdata('group_id'));
     foreach ($dirs as $d) {
         // tag to replace
         $filedir = "{filedir_{$d['id']}}";
         $data = str_replace($filedir, $d['url'], $data);
     }
     $data = htmlspecialchars($data, ENT_QUOTES);
     $field['value'] = $data;
     return form_textarea($field);
 }