PageRenderTime 106ms CodeModel.GetById 40ms app.highlight 18ms RepoModel.GetById 42ms app.codeStats 0ms

/components/com_sef/sef_ext/sef.ext.extended.php

https://bitbucket.org/organicdevelopment/joomla-2.5
PHP | 404 lines | 221 code | 73 blank | 110 comment | 72 complexity | a1a4748d6a1f2c09baa39f1b3a1bc7da MD5 | raw file
  1<?php
  2/**
  3 * SEF Extended extension for Joomla!
  4 *
  5 * @author      $Author: Organic Development
  6 * @copyright   Organic Development Ltd.
  7 * @package     JoomSEF
  8 */
  9
 10// Check to ensure this file is included in Joomla!
 11defined('_JEXEC') or die('Restricted access.');
 12
 13require_once dirname(__FILE__).'/../sef.ext.php';
 14abstract class SefExtExtended extends SefExt
 15{
 16	public $parts = array();
 17	public $includeVars= array('task');
 18	public $ignoreVars= array('option','Itemid');
 19	public $config;
 20	public $params;
 21	public $option;
 22	public $controller;
 23	public $view;	
 24	public $layout;
 25	public $task;
 26	public $id;
 27	public $limit;
 28	public $limitstart;
 29	public $lang;
 30	public $lookup = true;
 31	public static $lookups = array();
 32	
 33	protected $view_default = '';
 34	protected $layout_default = 'default';
 35	
 36	/**
 37	 * Clean ids like id:xxx
 38	 */
 39	protected function cleanId($id){
 40		$id = is_array($id) ? $id : explode(':', $id);
 41		return (int) $id[0];
 42	}
 43	
 44	
 45	/**
 46	 * Adds a variable to the include array
 47	 * @param string $var
 48	 */
 49	public function includeVar($var = null){
 50		if($var) $this->includeVars[$var] = $var;
 51	}
 52	
 53	/**
 54	 * Adds a variable to the ignore array
 55	 * @param string $var
 56	 */
 57	public function ignoreVar($var = null){
 58		if($var) $this->ignoreVars[$var] = $var;
 59	}
 60	
 61	/**
 62	 * Adds a variable to the nonsef vars array
 63	 * @param string $var
 64	 */
 65	public function nonSefVar($var, $value = ''){
 66		$this->nonSefVars[$var] = $value;
 67	}
 68	
 69	
 70	/**
 71	 * Adds a variable to the title array and include array
 72	 * Also looks up in the plugin params for an alternative string
 73	 * @param string $var
 74	 */
 75	public function addPart( $var, $part = '', $lang_lookup = 1){
 76		static $lang;
 77		
 78		//Include the variable
 79		$this->includeVar($var);
 80		
 81		//Lookup param string for title
 82		if($lang_lookup && $part){
 83			//Load language object			
 84			if(!$lang){
 85				$lang =& JFactory::getLanguage();
 86				$lang->load($this->option);
 87			}
 88			$option = strtoupper(preg_replace('/com_/','',$this->option));
 89			
 90			//Check if there is a language translation for this view
 91			$key = $option.'_SEF_'.strtoupper($var).'_'.strtoupper($part);
 92			$sef_title = $lang->hasKey($key) ? $lang->_($key) : '';
 93			
 94			//If there is, use that, if not see if there is a param translation,if not use the view var
 95			$part = $sef_title ? $sef_title : $this->params->get($var.'_'.$part, $part);					
 96		}
 97		
 98		if($part) $this->parts[] = $part;
 99	}
100	
101	/**
102	 * Remove a part from the array
103	 */
104	public function removePart($var){
105		$value = $this->uri->getVar($var);
106		$key = array_search($value, $this->parts);
107		if($key !== false){
108			unset($this->parts[$key]);
109			$this->parts = array_merge(array(), $this->parts);
110		} 		
111	}
112	
113	
114	
115	/**
116	 * Pre processing to extract item,cat,app id form url
117	 * @param object $uri
118	 * @return 
119	 */
120	public function beforeCreate(&$uri){
121		
122    	//Get the config
123    	$this->config =& SEFConfig::getConfig();
124
125        // Get key uri parts.	
126		$this->uri			=& $uri;	
127		$this->option 		= $uri->getVar('option');
128		$this->controller 	= $uri->getVar('controller');		
129		$this->layout 		= $uri->getVar('layout');
130		$this->task 		= $uri->getVar('task');		
131		$this->view 		= $uri->getVar('view', $this->task);
132		$this->id 			= $this->cleanId($uri->getVar('id'));
133		if($this->id)		$uri->setVar('id', $this->id);
134		$cid = (array) $uri->getVar('cid');
135		$this->uri 			=& $uri;
136		$this->limit	 	= $uri->getVar('list');
137		$this->limitstart	= $uri->getVar('limitstart');
138		$this->lang			= $uri->getVar('lang');
139		$this->itemid		= $uri->getVar('Itemid');
140		
141		/**
142		 * Controller & View Handling
143		 **/
144		
145		//If no controller and view, default controller is homepage
146		if(!$this->controller && !$this->view){
147			$this->view = $this->controller = $this->params->get('view_default', $this->view_default);
148			if($this->view) $uri->setVar('view',$this->view);
149			
150		//If controller is set and view isnt, set the view to the controller
151		} else if($this->controller && !$this->view){
152			$this->view = $this->controller;	
153			$uri->setVar('view', $this->view);			
154			$uri->delVar('controller');
155		
156		//If controller and view are the same, unset controller
157		}else if($this->controller == $this->view){
158			$uri->delVar('controller');	
159		}
160		
161		/**
162		 * Task & layout handling
163		 **/
164		//If layout is form and no task is set, set the task according to $this->id
165		if($this->layout == 'form' && !$this->task){
166			//Set the task
167			if($this->id) $this->task = 'edit';
168			else $this->task = 'add';
169			//Remove layout 
170			$this->layout = null;
171			$uri->delVar('layout');
172			$uri->setVar('task', $this->task);
173		}
174		
175		//Get the params
176		$this->params = SEFTools::getExtParams($this->option);		
177		
178		//Parse the lookups
179		$this->parseLookups();
180		
181		//Add title element
182		$this->addPart('jmenu', JoomSEF::_getMenuTitle($this->option, $this->task, $this->itemid));
183	}
184	
185	
186	/**
187	 * Parse the lookup info from the XML file
188	 */
189	public function parseLookups(){
190		static $lookups_parsed;
191		
192		if($lookups_parsed) return;
193		
194		$xml = & SEFTools::getExtXML($this->option);
195
196		//Check for a lookups node
197		if(isset($xml->document->lookups[0])){
198
199			//Loop through lookups
200			foreach($xml->document->lookups[0]->children() AS $lookup){
201				
202				//Get the attributes
203				$attribs = $lookup->attributes();
204
205				//Assign required items
206				$required = array('table','key','value');				
207				$tmp = new stdClass;
208				foreach($required AS $k){
209					$tmp->$k = JArrayHelper::getValue($attribs, $k);
210					unset($attribs[$k]);
211				}
212
213				//Check required items exist
214				if(!$tmp->table || !$tmp->key || !$tmp->value) continue;
215				
216				//Grab the ID variable
217				$tmp->id = JArrayHelper::getValue($attribs, 'id', $tmp->key);				
218				unset($attribs['id']);
219				
220				//If there are no more vars, theres nothing to match
221				if(empty($attribs)) continue;
222				
223				//Parse vars
224				$tmp->vars = $attribs;				
225				
226				//Add to lookups array
227				if(isset($tmp->vars['view'])){
228					if(!isset(self::$lookups['views'][$tmp->vars['view']])) self::$lookups[$tmp->vars['view']] = array();
229					
230					if(isset($tmp->vars['layout'])){
231						self::$lookups[$tmp->vars['view']][$tmp->vars['layout']] = $tmp;
232					}else{
233						self::$lookups[$tmp->vars['view']][] = $tmp;
234					}
235				}
236				else self::$lookups[] = $tmp;				
237			}
238		}
239		$lookups_parsed = true;
240	}
241	
242	
243	/**
244	 * Lookup attempts to match the request arguments with
245	 * lookup parameters parsed from earlier
246	 * If a match if found, the value is looked up from the DB
247	 */
248	public function lookup(){
249		static $lookups = array(), $looked_up = array();
250		
251		$vars = $this->uri->getQuery(true);
252		
253		//Check we have lookups
254		if(!count(self::$lookups)) return;		
255		unset($vars['option']);
256		
257		$var_hash = md5(serialize($vars));
258		
259		//Have we looked this url up before?
260		if(!isset($lookups[$var_hash])){
261		
262			$lookup = null;
263			
264			//Check if we have a view specific lookup
265			if($this->view && isset(self::$lookups[$this->view])){				
266
267				//Check if we have a view and layout specific lookup
268				if($this->layout && isset(self::$lookups[$this->view][$this->layout])){
269					$lookup = self::$lookups[$this->view][$this->layout];
270				}else{
271					//If no layout is supplied, loop through lookups and attempt to match
272					foreach(self::$lookups[$this->view] AS $k => $v){
273						if(is_int($k)){
274							$matches = array_diff_assoc($v->vars, $vars);
275							if(count($matches) == 0){
276								$lookup = $v;
277								break;
278							}
279						}
280					}
281				}								
282				
283			}else{
284				//if no view found loop through lookups and attempt to match
285				foreach(self::$lookups AS $k => $v){
286					if(is_int($k)){
287						$matches = array_diff_assoc($v->vars, $vars);
288						if(count($matches) == 0){
289							$lookup = $v;
290							break;
291						}
292					}
293				}
294			}
295			
296			//Add lookup
297			$lookups[$var_hash] = $lookup;
298		}else{
299			$lookup = $looked_up[$var_hash];
300		}
301		
302		
303		//If we found a lookup record, look it up in the DB
304		if($lookup && isset($lookup->value) && isset($lookup->table) && isset($lookup->key)){
305			$lookup_hash = md5(serialize($lookup));
306			
307			//Have we already done this lookup
308			if(!isset($looked_up[$lookup_hash])){
309				$id = $this->uri->getVar($lookup->id);
310				$db =& JFactory::getDBO();			
311				$db->setQuery(sprintf("SELECT `%s` FROM `%s` WHERE `%s` = '%s' LIMIT 1", $lookup->value, $lookup->table, $lookup->key, $id));
312				$result = $db->loadResult();
313				if($error = $db->getErrorMsg()){
314					JError::raiseWarning(500, JText::sprintf('SEF Lookup Error:: %s::%s()', __CLASS__, __FUNCTION__));
315					JError::raiseWarning(500, JText::sprintf('SEF Lookup Error::%s', $error));
316				}
317			}else{
318				$result = $looked_up[$lookup_hash];
319			}
320			//Add result if one retrieved
321			if($result){
322				$this->addPart($lookup->id, $result);
323			}
324		}
325	}
326	
327	protected function createStart(){}
328	protected function createEnd(){}	
329	
330	
331	/**
332	 * Main sef create function. This builds the url according to the rules below
333	 * @param object $uri
334	 * @return object $uri
335	 */
336    public function create(&$uri)
337    {
338    	//Before Processling
339    	$this->createStart();
340    	
341		//If controller is not equal to view then add controller to url
342		if($this->controller != $this->view){
343			$this->addPart( 'controller', $this->controller );
344		}
345
346		/**
347		 * Dynamic method call to a method called createLayout$this->view$this->layout() eg createLayoutContactsAll()
348		 * This allows for view specific functions to add to the url
349		 **/
350	
351		if($this->view || $this->layout){
352			//Construct the method for the layout
353			$method = $this->layout && $this->params->get('show_layout', 1) && $this->view ? 'createLayout'.ucfirst($this->view).ucfirst($this->layout) : null;
354			if($method && method_exists($this, $method)) $this->$method();
355			else{
356				
357				/**
358				 * Dynamic method call to a method called createView$this->view() eg createViewContacts()
359				 * This allows for view specific functions to add to the url
360				 **/ 		
361				if($this->view && $this->params->get('show_view', 1)){	
362					$method = 'createView'.ucfirst($this->view);
363					if(method_exists($this, $method)) $this->$method();
364					else if($this->params->get('show_view_'.$this->view, 1)) $this->addPart( 'view', $this->params->get('text_'.$this->view, $this->view ));
365				}	
366			 		
367				//Remove the layout if it matches the default
368				if($this->layout == $this->layout_default){
369					$this->uri->delVar('layout');
370				
371				//Else Add the layout part to the url
372				}else if($this->params->get('show_layout_'.$this->view.'_'.$this->layout, 1)){
373					$this->addPart( 'layout', $this->layout );
374				}
375			}
376		}		
377		
378
379		/**
380		 * Loop through vars and exclude the nonsef vars
381		 */		
382		foreach($this->uri->getQuery(true) AS $k => $v){			
383			if(!in_array($k, $this->includeVars) && !in_array($k, $this->ignoreVars) && $k != 'lang'){
384				$this->nonSefVars[$k] = $v;
385			}			
386		}			
387		
388		//Attempt to lookup
389		if($this->lookup) $this->lookup();
390		
391		//After processing
392		$this->createEnd();
393
394		//Create new uri object
395        $newUri = $this->uri;
396        if (count($this->parts) > 0) {
397            //Get the title
398            $newUri = JoomSEF::_sefGetLocation($this->uri, $this->parts, $this->task, $this->limit, $this->limitstart, $this->lang, $this->nonSefVars, $this->ignoreVars);
399        }    
400        
401        return $newUri;
402    }
403}
404