PageRenderTime 43ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/administrator/components/com_sh404sef/models/duplicates.php

https://bitbucket.org/saltwaterdev/offshorefinancial.com
PHP | 347 lines | 180 code | 59 blank | 108 comment | 21 complexity | 7e28ee0fdf6c454e194645e7bb67d418 MD5 | raw file
Possible License(s): GPL-2.0, GPL-3.0, 0BSD, MIT, Apache-2.0, LGPL-2.1
  1. <?php
  2. /**
  3. * sh404SEF - SEO extension for Joomla!
  4. *
  5. * @author Yannick Gaultier
  6. * @copyright (c) Yannick Gaultier - Weeblr llc - 2018
  7. * @package sh404SEF
  8. * @license http://www.gnu.org/copyleft/gpl.html GNU/GPL
  9. * @version 4.13.1.3756
  10. * @date 2017-12-22
  11. */
  12. // Security check to ensure this file is being included by a parent file.
  13. if (!defined('_JEXEC')) die('Direct Access to this location is not allowed.');
  14. class Sh404sefModelDuplicates extends Sh404sefClassBaselistmodel
  15. {
  16. protected $_defaultTable = 'urls';
  17. /**
  18. * Layout value
  19. *
  20. * @var string
  21. */
  22. private $_layout = 'default';
  23. /**
  24. * Object holding the url record
  25. * for which we are handling duplicates
  26. *
  27. * @var object
  28. */
  29. private $_sefUrl = null;
  30. /**
  31. * Method to get lists item data
  32. * Make sure we load the url data for the url
  33. * we are handling duplicates for
  34. *
  35. * WARNING : this is not necesarily the MAIN url
  36. *
  37. * @access public
  38. * @param object holding options
  39. * @param boolea $returnZeroElement . If true, and the list returned is empty, a null object will be returned (as an array)
  40. * @return array
  41. */
  42. public function getList($options = null, $returnZeroElement = false, $forcedLimitstart = null, $forcedLimit = null)
  43. {
  44. // make sure we use latest user state
  45. $this->_updateContextData();
  46. // Lets load the content if it doesn't already exist
  47. if (is_null($this->_data))
  48. {
  49. // do we have a cid ? if not, nothing we can do
  50. $sefId = intval($this->getState('sefId'));
  51. if (!empty($sefId))
  52. {
  53. $this->_sefUrl = $this->getById($sefId);
  54. if (!empty($this->_sefUrl))
  55. {
  56. $query = $this->_buildListQuery($options);
  57. $this->_data = $this->_getList($query);
  58. }
  59. }
  60. }
  61. if ($returnZeroElement && empty($this->_data))
  62. {
  63. // create an empty record and return it
  64. $zeroObject = JTable::getInstance($this->_defaultTable, 'Sh404sefTable');
  65. return array($zeroObject);
  66. }
  67. return $this->_data;
  68. }
  69. /**
  70. * Get details of the currently registered
  71. * main url for which we handle duplicates
  72. */
  73. public function getMainUrl()
  74. {
  75. return $this->_sefUrl;
  76. }
  77. /**
  78. * Make the url with id = $cid the main url
  79. * in case of duplicates. Also set the previous
  80. * main url as secondary, swapping their rank
  81. *
  82. * @param integer $cid
  83. */
  84. public function makeMainUrl($cid)
  85. {
  86. // get this url record
  87. $newMain = $this->getById($cid);
  88. $error = $this->getError();
  89. if (!empty($error))
  90. {
  91. return;
  92. }
  93. // is this already the main url ?
  94. if ($newMain->rank == 0)
  95. {
  96. return;
  97. }
  98. // now get the current main url
  99. $options = array('rank' => 0, 'oldurl' => $newMain->oldurl);
  100. $previousMains = $this->getByAttr($options);
  101. try
  102. {
  103. // store current hit counter. We will report all hits to the new main URL
  104. $hitsCounter = $newMain->cpt;
  105. // do the swapping
  106. if (!empty($previousMains))
  107. {
  108. foreach ($previousMains as $previousMain)
  109. {
  110. $hitsCounter += $previousMain->cpt;
  111. ShlDbHelper::update($this->_getTableName(), array('rank' => $newMain->rank, 'cpt' => 0), array('id' => $previousMain->id));
  112. // another thing we have to do is attach any meta data to the new
  113. // main url, so that they keep showing. Meta data are attached to
  114. // a NON-sef url, which has the benefit of keeping the attachement
  115. // whenever sef url creations are modified and sef urls recreated
  116. // but require a bit more work in that case
  117. // 1 - delete any meta data attached to the new main URL, to avoid possible duplicates
  118. ShlDbHelper::delete('#__sh404sef_metas', array('newurl' => $newMain->newurl));
  119. // attach currently active meta to the new main URL
  120. ShlDbHelper::update('#__sh404sef_metas', array('newurl' => $newMain->newurl), array('newurl' => $previousMain->newurl));
  121. // likewise for the aliases
  122. ShlDbHelper::delete('#__sh404sef_aliases', array('newurl' => $newMain->newurl));
  123. ShlDbHelper::update('#__sh404sef_aliases', array('newurl' => $newMain->newurl), array('newurl' => $previousMain->newurl));
  124. }
  125. }
  126. // finally make it the main url
  127. ShlDbHelper::update($this->_getTableName(), array('rank' => 0, 'cpt' => $hitsCounter), array('id' => $newMain->id));
  128. }
  129. catch (Exception $e)
  130. {
  131. $this->setError('Internal database error # ' . $e->getMessage());
  132. }
  133. }
  134. /**
  135. * Gets alist of current filters and sort options which have
  136. * been applied when building up the data
  137. * @override
  138. * @return object the list ov values as object properties
  139. */
  140. public function getDisplayOptions()
  141. {
  142. $options = parent::getDisplayOptions();
  143. // get additional options vs base class
  144. // component used in url
  145. $options->filter_component = $this->_getState('filter_component');
  146. // show all/only with aliases/only w/o aliases
  147. $options->filter_alias = $this->_getState('filter_alias');
  148. // show all/only custom/only automatic
  149. $options->filter_url_type = $this->_getState('filter_url_type');
  150. // show all/only one language
  151. $options->filter_language = $this->_getState('filter_language');
  152. // return cached instance
  153. return $options;
  154. }
  155. protected function _buildListSelect($options)
  156. {
  157. // array to hold select clause parts
  158. $select = array();
  159. // get the layout option from params
  160. $layout = $this->_getOption('layout', $options);
  161. switch ($layout)
  162. {
  163. default:
  164. $select[] = ' select u1.*, pg.pageid as pageid, count(a.`alias`) as aliases';
  165. break;
  166. }
  167. // add from clause
  168. $select[] = 'from ' . $this->_getTableName() . ' as u1';
  169. // aggregate clauses
  170. $select = (count($select) ? implode(' ', $select) : '');
  171. return $select;
  172. }
  173. protected function _buildListJoin($options)
  174. {
  175. // array to hold join clause parts
  176. $join = array();
  177. // count aliases
  178. $join[] = 'left join ' . $this->_db->quoteName('#__sh404sef_aliases') . ' as a';
  179. $join[] = 'on a.' . $this->_db->quoteName('newurl') . ' = u1.' . $this->_db->quoteName('newurl');
  180. // get page ids
  181. $join[] = 'left join ' . $this->_db->quoteName('#__sh404sef_pageids') . ' as pg';
  182. $join[] = 'on pg.' . $this->_db->quoteName('newurl') . ' = u1.' . $this->_db->quoteName('newurl');
  183. // aggregate clauses
  184. $join = (count($join) ? ' ' . implode(' ', $join) : '');
  185. return $join;
  186. }
  187. protected function _buildListWhere($options)
  188. {
  189. // get set of filters applied to the current view
  190. $filters = $this->getDisplayOptions();
  191. // array to hold where clause parts
  192. $where = array();
  193. // get the layout options from param
  194. $layout = $this->_getOption('layout', $options);
  195. // various cases of layouts
  196. switch ($layout)
  197. {
  198. default:
  199. if (!empty($this->_sefUrl->oldurl))
  200. {
  201. $where[] = 'u1.' . $this->_db->quoteName('oldurl') . ' = '
  202. . $this->_db->Quote($this->_sefUrl->oldurl);
  203. }
  204. break;
  205. }
  206. // do not include 404s in possible "main non-sef" targets
  207. $where[] = "u1.newurl != ''";
  208. // add search all urls term if any
  209. if (!empty($filters->search_all))
  210. { // V 1.2.4.q added search URL feature
  211. jimport('joomla.utilities.string');
  212. $searchTerm = $this->_cleanForQuery(JString::strtolower($filters->search_all));
  213. $where[] = "LOWER(u1.newurl) LIKE '%" . $searchTerm . "%'";
  214. }
  215. // components check
  216. if (!empty($filters->filter_component))
  217. {
  218. $where[] = "LOWER(u1.newurl) LIKE '%option=" . $this->_cleanForQuery($filters->filter_component) . "%'";
  219. }
  220. // language check
  221. if (!empty($filters->filter_language))
  222. {
  223. $where[] = "LOWER(u1.newurl) LIKE '%lang=" . $this->_cleanForQuery(Sh404sefHelperLanguage::getUrlCodeFromTag($filters->filter_language)) . "%'";
  224. }
  225. // custom or automatic ?
  226. if (!empty($filters->filter_url_type))
  227. {
  228. switch ($filters->filter_url_type)
  229. {
  230. case Sh404sefHelperGeneral::COM_SH404SEF_ONLY_CUSTOM:
  231. $where[] = 'u1.dateadd <> ' . $this->_db->Quote('0000-00-00');
  232. break;
  233. case Sh404sefHelperGeneral::COM_SH404SEF_ONLY_AUTO:
  234. $where[] = 'u1.dateadd = ' . $this->_db->Quote('0000-00-00');
  235. break;
  236. }
  237. }
  238. // aggregate clauses
  239. $where = (count($where) ? ' WHERE ' . implode(' AND ', $where) : '');
  240. return $where;
  241. }
  242. protected function _buildListGroupBy($options)
  243. {
  244. // build query fragment
  245. $groupBy = ' group by u1.' . $this->_db->quoteName('newurl');
  246. return $groupBy;
  247. }
  248. protected function _buildListOrderBy($options)
  249. {
  250. $orderBy = parent::_buildListOrderBy($options);
  251. // get set of filters applied to the current view
  252. $filters = $this->getDisplayOptions();
  253. // always add a secondary sort by SEF urls, unless it is already the primary
  254. if ($filters->filter_order != 'oldurl')
  255. {
  256. // build query fragment
  257. $orderBy .= ', ' . $this->_db->quoteName('oldurl');
  258. }
  259. return $orderBy;
  260. }
  261. protected function _getTableName()
  262. {
  263. return '#__sh404sef_urls';
  264. }
  265. /**
  266. * Provides context data definition, to be used by context handler
  267. * Should be overriden by descendant
  268. */
  269. protected function _getContextDataDef()
  270. {
  271. $contextData = parent::_getContextDataDef();
  272. // define context data to be retrieved. Cannot be done at class level,
  273. // as some default values are dynamic
  274. $addedContextData = array(
  275. // redefined default sort order
  276. array('name' => 'filter_order', 'html_name' => 'filter_order', 'default' => 'rank', 'type' => 'string')
  277. // component used in url
  278. , array('name' => 'filter_component', 'html_name' => 'filter_component', 'default' => '', 'type' => 'string')
  279. // show all/only with aliases/only w/o aliases
  280. , array('name' => 'filter_alias', 'html_name' => 'filter_alias', 'default' => 0, 'type' => 'int')
  281. // show all/only custom/only automatic
  282. , array('name' => 'filter_url_type', 'html_name' => 'filter_url_type', 'default' => 0, 'type' => 'int')
  283. // show all/only one language
  284. , array('name' => 'filter_language', 'html_name' => 'filter_language', 'default' => '', 'type' => 'string')
  285. );
  286. return array_merge($contextData, $addedContextData);
  287. }
  288. }