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