Example #1
0
 /** -------------------------------------
     /**  Class/Method handler
     /** -------------------------------------*/
 function class_handler()
 {
     global $FNS, $TMPL, $DB, $PREFS;
     $classes = array();
     // Fill an array with the names of all the classes that we previously extracted from the tags
     for ($i = 0; $i < count($this->tag_data); $i++) {
         // Should we use the tag cache file?
         if ($this->tag_data[$i]['cache'] == 'CURRENT') {
             // If so, replace the marker in the tag with the cache data
             $this->log_item("Tag Cached and Cache is Current");
             $this->replace_marker($i, $this->get_cache_file($this->tag_data[$i]['cfile']));
         } else {
             // Is a module or plug-in being requested?
             if (!in_array($this->tag_data[$i]['class'], $this->modules)) {
                 if (!in_array($this->tag_data[$i]['class'], $this->plugins)) {
                     global $LANG, $PREFS, $OUT;
                     $this->log_item("Invalid Tag");
                     if ($PREFS->ini('debug') >= 1) {
                         if ($this->tag_data[$i]['tagparts']['0'] == $this->tag_data[$i]['tagparts']['1'] && !isset($this->tag_data[$i]['tagparts']['2'])) {
                             unset($this->tag_data[$i]['tagparts']['1']);
                         }
                         $error = $LANG->line('error_tag_syntax');
                         $error .= '<br /><br />';
                         $error .= htmlspecialchars(LD);
                         $error .= 'exp:' . implode(':', $this->tag_data[$i]['tagparts']);
                         $error .= htmlspecialchars(RD);
                         $error .= '<br /><br />';
                         $error .= $LANG->line('error_fix_syntax');
                         $OUT->fatal_error($error);
                     } else {
                         return false;
                     }
                 } else {
                     $classes[] = 'pi.' . $this->tag_data[$i]['class'];
                     $this->log_item("Plugin Tag: " . ucfirst($this->tag_data[$i]['class']) . '/' . $this->tag_data[$i]['method']);
                 }
             } else {
                 $classes[] = $this->tag_data[$i]['class'];
                 $this->log_item("Module Tag: " . ucfirst($this->tag_data[$i]['class']) . '/' . $this->tag_data[$i]['method']);
             }
         }
     }
     // Remove duplicate class names and re-order the array
     $classes = array_values(array_unique($classes));
     // Dynamically require the file that contains each class
     $this->log_item("Including Files for Tag and Modules");
     for ($i = 0; $i < count($classes); $i++) {
         // But before we do, make sure it hasn't already been included...
         if (!class_exists($classes[$i])) {
             if (substr($classes[$i], 0, 3) == 'pi.') {
                 require_once PATH_PI . $classes[$i] . EXT;
             } else {
                 require_once PATH_MOD . $classes[$i] . '/mod.' . $classes[$i] . EXT;
             }
         }
     }
     /** -----------------------------------
         /**  Only Retrieve Data if Not Done Before and Modules Being Called
         /** -----------------------------------*/
     if (sizeof($this->module_data) == 0 && sizeof(array_intersect($this->modules, $classes)) > 0) {
         $query = $DB->query("SELECT module_version, module_name FROM exp_modules");
         foreach ($query->result as $row) {
             $this->module_data[$row['module_name']] = array('version' => $row['module_version']);
         }
     }
     // Final data processing
     // Loop through the master array containing our extracted template data
     $this->log_item("Beginning Final Tag Data Processing");
     reset($this->tag_data);
     for ($i = 0; $i < count($this->tag_data); $i++) {
         if ($this->tag_data[$i]['cache'] != 'CURRENT') {
             $this->log_item("Calling Class/Method: " . ucfirst($this->tag_data[$i]['class']) . "/" . $this->tag_data[$i]['method']);
             /* ---------------------------------
             			/*  Plugin as Parameter
             			/*
             			/*  - Example: weblog="{exp:some_plugin}"
             			/*  - A bit of a hidden feature.  Has been tested but not quite
             			/*  ready to say it is ready for prime time as I might want to 
             			/*  move it to earlier in processing so that if there are 
             			/*  multiple plugins being used as parameters it is only called
             			/*  once instead of for every single parameter. - Paul
             			/* ---------------------------------*/
             if (substr_count($this->tag_data[$i]['tag'], LD . 'exp') > 1 && isset($this->tag_data[$i]['params']['parse']) && $this->tag_data[$i]['params']['parse'] == 'inward') {
                 foreach ($this->tag_data[$i]['params'] as $name => $param) {
                     if (stristr($this->tag_data[$i]['params'][$name], LD . 'exp')) {
                         $this->log_item("Plugin in Parameter, Processing Plugin First");
                         $TMPL2 = $FNS->clone_object($this);
                         while (is_int(strpos($TMPL2->tag_data[$i]['params'][$name], LD . 'exp:'))) {
                             $TMPL = new Template();
                             $TMPL->start_microtime = $this->start_microtime;
                             $TMPL->template = $TMPL2->tag_data[$i]['params'][$name];
                             $TMPL->tag_data = array();
                             $TMPL->var_single = array();
                             $TMPL->var_cond = array();
                             $TMPL->var_pair = array();
                             $TMPL->plugins = $TMPL2->plugins;
                             $TMPL->modules = $TMPL2->modules;
                             $TMPL->parse_template();
                             $TMPL->class_handler();
                             $TMPL->loop_count = 0;
                             $TMPL2->tag_data[$i]['params'][$name] = $TMPL->template;
                             $TMPL2->log = array_merge($TMPL2->log, $TMPL->log);
                         }
                         foreach (get_object_vars($TMPL2) as $key => $value) {
                             $this->{$key} = $value;
                         }
                         unset($TMPL2);
                         $TMPL = $this;
                     }
                 }
             }
             /** ---------------------------------
             				/**  Nested Plugins...
             				/** ---------------------------------*/
             if (in_array($this->tag_data[$i]['class'], $this->plugins) && strpos($this->tag_data[$i]['block'], LD . 'exp:') !== false) {
                 if (!isset($this->tag_data[$i]['params']['parse']) or $this->tag_data[$i]['params']['parse'] != 'inward') {
                     $this->log_item("Nested Plugins in Tag, Parsing Outward First");
                     $TMPL2 = $FNS->clone_object($this);
                     while (is_int(strpos($TMPL2->tag_data[$i]['block'], LD . 'exp:'))) {
                         $TMPL = new Template();
                         $TMPL->start_microtime = $this->start_microtime;
                         $TMPL->template = $TMPL2->tag_data[$i]['block'];
                         $TMPL->tag_data = array();
                         $TMPL->var_single = array();
                         $TMPL->var_cond = array();
                         $TMPL->var_pair = array();
                         $TMPL->plugins = $TMPL2->plugins;
                         $TMPL->modules = $TMPL2->modules;
                         $TMPL->parse_template();
                         $TMPL->class_handler();
                         $TMPL->loop_count = 0;
                         $TMPL2->tag_data[$i]['block'] = $TMPL->template;
                         $TMPL2->log = array_merge($TMPL2->log, $TMPL->log);
                     }
                     foreach (get_object_vars($TMPL2) as $key => $value) {
                         $this->{$key} = $value;
                     }
                     unset($TMPL2);
                     $TMPL = $this;
                 }
             }
             // Assign the data chunk, parameters
             // We moved the no_results_block here because of nested tags. The first
             // parsed tag has priority for that conditional.
             $this->tagdata = str_replace($this->tag_data[$i]['no_results_block'], '', $this->tag_data[$i]['block']);
             $this->tagparams = $this->tag_data[$i]['params'];
             $this->tagchunk = $this->tag_data[$i]['chunk'];
             $this->tagproper = $this->tag_data[$i]['tag'];
             $this->tagparts = $this->tag_data[$i]['tagparts'];
             $this->no_results = $this->tag_data[$i]['no_results'];
             $this->search_fields = $this->tag_data[$i]['search_fields'];
             /** -------------------------------------
             				/**  Assign Sites for Tag
             				/** -------------------------------------*/
             $this->_fetch_site_ids();
             /** -------------------------------------
             				/**  Relationship Data Pulled Out
             				/** -------------------------------------*/
             // If the weblog:entries tag or search:search_results is being called
             // we need to extract any relationship data that might be present.
             // Note: This needs to happen before extracting the variables
             // in the tag so it doesn't get confused as to which entry the
             // variables belong to.
             if ($this->tag_data[$i]['class'] == 'weblog' and $this->tag_data[$i]['method'] == 'entries' or $this->tag_data[$i]['class'] == 'search' and $this->tag_data[$i]['method'] == 'search_results') {
                 $this->tagdata = $this->assign_relationship_data($this->tagdata);
             }
             // Fetch the variables for this particular tag
             $vars = $FNS->assign_variables($this->tag_data[$i]['block']);
             if (count($this->related_markers) > 0) {
                 foreach ($this->related_markers as $mkr) {
                     if (!isset($vars['var_single'][$mkr])) {
                         $vars['var_single'][$mkr] = $mkr;
                     }
                 }
                 $this->related_markers = array();
             }
             $this->var_single = $vars['var_single'];
             $this->var_pair = $vars['var_pair'];
             //  Redundant see above loop for related_markers - R.S.
             //if ($this->related_id != '')
             //{
             //	$this->var_single[$this->related_id] = $this->related_id;
             //	$this->related_id = '';
             //}
             //  Assign Conditional Variables
             if (!in_array($this->tag_data[$i]['class'], $this->native_modules)) {
                 $this->var_cond = $FNS->assign_conditional_variables($this->tag_data[$i]['block'], SLASH, LD, RD);
             }
             // Assign the class name and method name
             $class_name = ucfirst($this->tag_data[$i]['class']);
             if ($class_name == 'Commerce') {
                 // The Commerce module is special in that it has its own modules and its
                 // constructor handles everything for us
                 $meth_name = 'commerce';
             } else {
                 $meth_name = $this->tag_data[$i]['method'];
             }
             // Dynamically instantiate the class.
             // If module, only if it is installed...
             if (in_array($this->tag_data[$i]['class'], $this->modules) && !isset($this->module_data[$class_name])) {
                 $this->log_item("Problem Processing Module: Module Not Installed");
             } else {
                 $this->log_item(" -> Class Called: " . $class_name);
                 $EE = new $class_name();
             }
             /** ----------------------------------
             				/**  Does method exist?  Is This A Module and Is It Installed?
             				/** ----------------------------------*/
             if (in_array($this->tag_data[$i]['class'], $this->modules) && !isset($this->module_data[$class_name]) or !method_exists($EE, $meth_name)) {
                 global $LANG, $PREFS, $OUT;
                 $this->log_item("Tag Not Processed: Method Inexistent or Module Not Installed");
                 if ($PREFS->ini('debug') >= 1) {
                     if ($this->tag_data[$i]['tagparts']['0'] == $this->tag_data[$i]['tagparts']['1'] && !isset($this->tag_data[$i]['tagparts']['2'])) {
                         unset($this->tag_data[$i]['tagparts']['1']);
                     }
                     $error = $LANG->line('error_tag_module_processing');
                     $error .= '<br /><br />';
                     $error .= htmlspecialchars(LD);
                     $error .= 'exp:' . implode(':', $this->tag_data[$i]['tagparts']);
                     $error .= htmlspecialchars(RD);
                     $error .= '<br /><br />';
                     $error .= str_replace('%x', $this->tag_data[$i]['class'], str_replace('%y', $meth_name, $LANG->line('error_fix_module_processing')));
                     $OUT->fatal_error($error);
                 } else {
                     return;
                 }
             }
             /*
                             
                             OK, lets grab the data returned from the class.
                             
                             First, however, lets determine if the tag has one or two segments.  
                             If it only has one, we don't want to call the constructor again since
                             it was already called during instantiation.
                      
                             Note: If it only has one segment, only the object constructor will be called.
                             Since constructors can't return a value just by initialializing the object
                             the output of the class must be assigned to a variable called $this->return_data
             */
             $this->log_item(" -> Method Called: " . $meth_name);
             if (strtolower($class_name) == $meth_name) {
                 $return_data = isset($EE->return_data) ? $EE->return_data : '';
             } else {
                 $return_data = $EE->{$meth_name}();
             }
             /** ----------------------------------
                 /**  404 Page Triggered, Cease All Processing of Tags From Now On
                 /** ----------------------------------*/
             if ($this->cease_processing === TRUE) {
                 return;
             }
             $this->log_item(" -> Data Returned");
             // Write cache file if needed
             if ($this->tag_data[$i]['cache'] == 'EXPIRED') {
                 $this->write_cache_file($this->tag_data[$i]['cfile'], $return_data);
             }
             // Replace the temporary markers we added earlier with the fully parsed data
             $this->replace_marker($i, $return_data);
             // Initialize data in case there are susequent loops
             $this->var_single = array();
             $this->var_cond = array();
             $this->var_pair = array();
             unset($return_data);
             unset($class_name);
             unset($meth_name);
             unset($EE);
         }
     }
 }