PageRenderTime 507ms CodeModel.GetById 10ms RepoModel.GetById 0ms app.codeStats 0ms

/administrator/components/com_joomfish/models/ContentElement.php

https://github.com/Shigaru/shigaru
PHP | 483 lines | 292 code | 59 blank | 132 comment | 67 complexity | 6f35a06416b70f4bdb526ee4f757c0ab MD5 | raw file
  1. <?php
  2. /**
  3. * Joom!Fish - Multi Lingual extention and translation manager for Joomla!
  4. * Copyright (C) 2003 - 2012, Think Network GmbH, Munich
  5. *
  6. * All rights reserved. The Joom!Fish project is a set of extentions for
  7. * the content management system Joomla!. It enables Joomla!
  8. * to manage multi lingual sites especially in all dynamic information
  9. * which are stored in the database.
  10. *
  11. * This program is free software; you can redistribute it and/or
  12. * modify it under the terms of the GNU General Public License
  13. * as published by the Free Software Foundation; either version 2
  14. * of the License, or (at your option) any later version.
  15. *
  16. * This program is distributed in the hope that it will be useful,
  17. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19. * GNU General Public License for more details.
  20. *
  21. * You should have received a copy of the GNU General Public License
  22. * along with this program; if not, write to the Free Software
  23. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,USA.
  24. *
  25. * The "GNU General Public License" (GPL) is available at
  26. * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
  27. * -----------------------------------------------------------------------------
  28. * $Id: ContentElement.php 1592 2012-01-20 12:51:08Z akede $
  29. * @package joomfish
  30. * @subpackage Models
  31. *
  32. */
  33. // Don't allow direct linking
  34. defined( '_JEXEC' ) or die( 'Restricted access' );
  35. include_once(dirname(__FILE__).DS."ContentElementTable.php");
  36. /**
  37. * Content element class based on the xml file
  38. *
  39. * @package joomfish
  40. * @subpackage administrator
  41. * @copyright 2003 - 2012, Think Network GmbH, Munich
  42. * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License
  43. * @version $Revision: 1592 $
  44. * @author Alex Kempkens
  45. */
  46. class ContentElement {
  47. private $_xmlFile;
  48. public $checked_out=false;
  49. public $Name='';
  50. public $Author='';
  51. public $Version='';
  52. public $Description='';
  53. public $PrimaryKey = "id";
  54. public $referenceInformation;
  55. /** field (if any) that keyword filters apply to*/
  56. private $_keywordFilter=null;
  57. private $_categoryFilter=null;
  58. private $_authorFilter=null;
  59. /** Standard constructor, which loads already standard information
  60. * for easy and direct access
  61. */
  62. public function __construct ( $xmlDoc ) {
  63. $this->_xmlFile = $xmlDoc;
  64. if( isset($this->_xmlFile) ) {
  65. $valueElement = $this->_xmlFile->getElementsByTagName('name')->item(0);
  66. $this->Name = trim($valueElement->textContent);
  67. $valueElement = $this->_xmlFile->getElementsByTagName('author')->item(0);
  68. $this->Author = trim($valueElement->textContent);
  69. $valueElement = $this->_xmlFile->getElementsByTagName('version')->item(0);
  70. $this->Version = trim($valueElement->textContent);
  71. $valueElement = $this->_xmlFile->getElementsByTagName('description')->item(0);
  72. $this->Description = trim($valueElement->textContent);
  73. }
  74. }
  75. /** Type of reference
  76. */
  77. public function getReferenceType() {
  78. if( !isset($this->referenceInformation["type"]) && isset($this->_xmlFile) ) {
  79. $tableElement = $this->_xmlFile->getElementsByTagName('reference')->item(0);
  80. $tableName = trim($tableElement->getAttribute( 'type' ));
  81. $this->referenceInformation["type"] = $tableName;
  82. }
  83. return $this->referenceInformation["type"];
  84. }
  85. /**
  86. * Public function to return array of filters included in contentelement file
  87. */
  88. public function getAllFilters(){
  89. $allFilters = array();
  90. if(isset($this->_xmlFile) ) {
  91. $fElement = $this->_xmlFile->getElementsByTagName('translationfilters')->item(0);
  92. if (!isset($fElement) || !$fElement->hasChildNodes()){
  93. return $allFilters;
  94. }
  95. foreach ($fElement->childNodes as $child){
  96. $type = $child->nodeName;
  97. $filter = "_$type"."Filter";
  98. $this->$filter=$child->textContent;
  99. $allFilters[$type]=trim($this->$filter);
  100. }
  101. }
  102. return $allFilters;
  103. }
  104. /**
  105. * function that returns filter string and handles getting filter info from xmlfile if needed
  106. *
  107. */
  108. public function getFilter($type){
  109. $filter = "_$type"."Filter";
  110. if( !isset($this->$filter) && isset($this->_xmlFile) ) {
  111. $xpath = new DOMXPath($this->_xmlFile);
  112. $fElement = $xpath->query('//translationfilters/'.$type);
  113. if (!isset($fElement)){
  114. $this->$filter=false;
  115. return $this->$filter;
  116. }
  117. $this->$filter=trim($fElement->textContent);
  118. }
  119. return $this->$filter;
  120. }
  121. /**
  122. * returns translation filter keyword field (if any)
  123. */
  124. public function getKeywordFilter() {
  125. return $this->_getFilter("keyword");
  126. }
  127. /**
  128. * returns category filter fieldname (if any)
  129. */
  130. public function getCategoryFilter() {
  131. return $this->_getFilter("category");
  132. }
  133. /**
  134. * returns author filter fieldname (if any)
  135. */
  136. public function getAuthorFilter() {
  137. return $this->_getFilter("author");
  138. }
  139. /** Name of the refering table
  140. */
  141. public function getTableName() {
  142. if( !isset($this->referenceInformation["tablename"]) && isset($this->_xmlFile) ) {
  143. $xpath = new DOMXPath($this->_xmlFile);
  144. $tableElement = $xpath->query('//reference/table')->item(0);
  145. $tableName = trim($tableElement->getAttribute( 'name' ));
  146. $this->referenceInformation["tablename"] = strtolower($tableName);
  147. }
  148. return $this->referenceInformation["tablename"];
  149. }
  150. /**
  151. * Name of reference id (in other words the primary key)
  152. */
  153. public function getReferenceId() {
  154. if( isset($this->referenceInformation["tablename"]) && isset($this->_xmlFile) ) {
  155. $xpath = new DOMXPath($this->_xmlFile);
  156. $tableElement = $xpath->query('//reference/table')->item(0);
  157. $tableFields = $tableElement->getElementsByTagName('field');
  158. foreach ($tableFields as $field) {
  159. if (trim($field->getAttribute('type'))=="referenceid") {
  160. $refid = trim($field->getAttribute('name'));
  161. if ($refid!=null) return $refid;
  162. else return "id";
  163. }
  164. }
  165. }
  166. return "id";
  167. }
  168. /** Array of the field elements in the table
  169. * @return reference to the table information
  170. */
  171. public function & getTable() {
  172. if( !isset($this->referenceInformation["table"]) && isset($this->_xmlFile) ) {
  173. $xpath = new DOMXPath($this->_xmlFile);
  174. $tableElement = $xpath->query('//reference/table')->item(0);
  175. $this->referenceInformation["table"] = new ContentElementTable( $tableElement );
  176. }
  177. return $this->referenceInformation["table"];
  178. }
  179. /** Generating the sql statement to retrieve the information
  180. * from the database
  181. */
  182. public function createContentSQL( $idLanguage=-1, $contentid=null, $limitStart=-1, $maxRows=-1 , $filters=array()) {
  183. $db = JFactory::getDBO();
  184. $sqlFields=null;
  185. $where=array();
  186. $order=null;
  187. $join=null;
  188. $contentTable = $this->getTable();
  189. foreach ($filters as $filter) {
  190. $sqlFilter= $filter->createFilter($this);
  191. if ($sqlFilter!="") $where[]=$sqlFilter;
  192. }
  193. foreach( $contentTable->Fields as $tableField ) {
  194. // Based on the types we might want to have special names ;-)
  195. switch ($tableField->Type) {
  196. case "referenceid":
  197. $contentid_exist = (isset($contentid) && $contentid!=-1 );
  198. if( strtolower($tableField->Name) != "id" ) {
  199. $sqlFields[] = 'c.' .$tableField->Name. ' as id';
  200. if( $contentid_exist) $where[] = 'c.' .$tableField->Name. '=' .$db->Quote($contentid );
  201. }
  202. else {
  203. if( $contentid_exist ) $where[] = 'c.id=' .$contentid ;
  204. }
  205. $join[] = 'c.' .$tableField->Name. '=jfc.reference_id';
  206. break;
  207. case "titletext":
  208. if( strtolower($tableField->Name) != "title" ) {
  209. $sqlFields[] = 'c.' .$tableField->Name. ' as title';
  210. }
  211. $join[] = "jfc.reference_field='" .$tableField->Name. "'";
  212. $order[] = 'c.' .$tableField->Name;
  213. break;
  214. case "modified_date":
  215. if( strtolower($tableField->Name) != "modified_date" ) {
  216. $sqlFields[] = 'c.' .$tableField->Name. ' as modified_date';
  217. }
  218. break;
  219. case "checked_out_by":
  220. if( strtolower($tableField->Name) != "check_out" ) {
  221. $sqlFields[] = 'c.' .$tableField->Name. ' as check_out';
  222. }
  223. break;
  224. }
  225. // I want to have each field with his original name in the select
  226. // so the special fields will be only addon's!
  227. // Reason: To grap the data later it's more easy to refer to the original names of the XML file
  228. $sqlFields[] = 'c.' .$tableField->Name. '';
  229. }
  230. $sqlFields[] = "jfc.id as jfc_id";
  231. $sqlFields[] = "jfc.value as titleTranslation";
  232. $sqlFields[] = "jfc.modified as lastchanged";
  233. $sqlFields[] = 'jfc.published as published';
  234. $sqlFields[] = 'jfc.language_id';
  235. $sqlFields[] = 'jfl.title as language';
  236. $sqlFields[] = "jfc.reference_id as jfc_refid";
  237. $join[] = "jfc.reference_table='$contentTable->Name'";
  238. // Now redundant
  239. /*
  240. if( isset($contentid) && $contentid!=-1 ) {
  241. $where[] = 'c.id=' .$contentid;
  242. }
  243. */
  244. if( isset($idLanguage) && $idLanguage!="" && $idLanguage!=-1 ) {
  245. if( $idLanguage=="NULL" ) {
  246. $where[] = "jfc.language_id IS NULL";
  247. } else {
  248. $join[] = "jfc.language_id=$idLanguage";
  249. }
  250. }
  251. if( $contentTable->Filter != '' ) {
  252. $where[] = $contentTable->Filter;
  253. }
  254. $sql = "SELECT " .implode( ', ', $sqlFields )
  255. . "\nFROM #__" .$contentTable->Name. ' as c'
  256. . "\nLEFT JOIN #__jf_content as jfc ON " .implode( ' AND ', $join )
  257. . "\nLEFT JOIN #__languages as jfl ON jfc.language_id=jfl.lang_id"
  258. . (count( $where ) ? "\nWHERE " . implode( ' AND ', $where ) : "")
  259. . (count( $order ) ? "\nORDER BY " . implode( ', ', $order ) : "");
  260. if( $limitStart!=-1 && $maxRows>0) {
  261. $sql .= "\nLIMIT $limitStart, $maxRows";
  262. }
  263. //echo "sql = <pre>$sql</pre><br />";
  264. return $sql;
  265. }
  266. /** Generating the sql statement to retrieve the orphans information from the database
  267. */
  268. public function createOrphanSQL( $idLanguage=-1, $contentid=null, $limitStart=-1, $maxRows=-1 , $filters=array()) {
  269. $sqlFields=null;
  270. $sqlFields[] = "jfc.id as jfc_id";
  271. $sqlFields[] = "jfc.reference_id as jfc_refid";
  272. $sqlFields[] = "jfc.value as titleTranslation";
  273. $sqlFields[] = "jfc.modified as lastchanged";
  274. $sqlFields[] = 'jfc.published as published';
  275. $sqlFields[] = 'jfc.language_id';
  276. $sqlFields[] = 'jfl.title as language';
  277. $sqlFields[] = 'jfc.original_text as original_text';
  278. $where=array();
  279. $order=null;
  280. $join=null;
  281. $contentTable = $this->getTable();
  282. foreach ($filters as $filter) {
  283. $sqlFilter= $filter->createFilter($this);
  284. if ($sqlFilter!="") $where[]=$sqlFilter;
  285. }
  286. foreach( $contentTable->Fields as $tableField ) {
  287. // Based on the types we might want to have special names ;-)
  288. switch ($tableField->Type) {
  289. case "referenceid":
  290. $contentid_exist = (isset($contentid) && $contentid!=-1 );
  291. if( strtolower($tableField->Name) != "id" ) {
  292. $sqlFields[] = 'c.' .$tableField->Name. ' as id';
  293. if( $contentid_exist) $where[] = 'c.' .$tableField->Name. '=' .$contentid ;
  294. }
  295. else {
  296. if( $contentid_exist ) $where[] = 'c.id=' .$contentid ;
  297. }
  298. $join[] = 'c.' .$tableField->Name. '=jfc.reference_id ';
  299. $where[] = 'c.' .$tableField->Name. ' IS NULL ';
  300. $sqlFields[] = 'c.' .$tableField->Name. '';
  301. break;
  302. case "titletext":
  303. if( strtolower($tableField->Name) != "title" ) {
  304. $sqlFields[] = 'c.' .$tableField->Name. ' as title';
  305. }
  306. //$join[] = "jfc.reference_field='" .$tableField->Name. "'";
  307. $where[] = "jfc.reference_field='" .$tableField->Name. "'";
  308. $sqlFields[] = 'c.' .$tableField->Name. '';
  309. // $order[] = 'c.' .$tableField->Name;
  310. break;
  311. }
  312. }
  313. //$join[] = "jfc.reference_table='$contentTable->Name'";
  314. $where[] = "jfc.reference_table='$contentTable->Name'";
  315. if( !isset($idLanguage) || ($idLanguage!="" && $idLanguage!=-1 )) {
  316. $where[] = "jfc.language_id=$idLanguage";
  317. }
  318. $sql = "SELECT " .implode( ', ', $sqlFields )
  319. . "\nFROM #__jf_content as jfc"
  320. . "\nLEFT JOIN #__" .$contentTable->Name. ' as c ON '.implode( ' AND ', $join )
  321. . "\nLEFT JOIN #__languages as jfl ON jfc.language_id=jfl.lang_id"
  322. . (count( $where ) ? "\nWHERE " . implode( ' AND ', $where ) : "")
  323. . (count( $order ) ? "\nORDER BY " . implode( ', ', $order ) : "");
  324. if( $limitStart!=-1 ) {
  325. $sql .= "\nLIMIT $limitStart, $maxRows";
  326. }
  327. //echo "orphansql = $sql<br />";
  328. return $sql;
  329. }
  330. /** Generating the sql statement to count the information
  331. */
  332. public function countContentSQL($idLanguage=-1, $filters=array()) {
  333. $contentTable = $this->getTable();
  334. /*
  335. $where=null;
  336. // Add standard filters
  337. foreach ($filters as $filter) {
  338. $sqlFilter= $filter->createFilter($this);
  339. if ($sqlFilter!="") $where[]=$sqlFilter;
  340. }
  341. if( $contentTable->Filter != '' ) {
  342. $where[] = $contentTable->Filter;
  343. }
  344. $sql = "SELECT *"
  345. . "\nFROM #__" .$contentTable->Name. ' as c'
  346. . (count( $where ) ? "\nWHERE " . implode( ' AND ', $where ) : "");
  347. */
  348. /* Try to simplify the count queries.
  349. Check only on original table including the standard filters as we assume that*/
  350. $join=null;
  351. $where=null;
  352. $referencefield = "";
  353. foreach( $contentTable->Fields as $tableField ) {
  354. // Based on the types we might want to have special names ;-)
  355. if ( $tableField->Type == "referenceid" ) {
  356. $join[] = 'c.' .$tableField->Name. '=jfc.reference_id';
  357. $referencefield ='c.' .$tableField->Name;
  358. }
  359. }
  360. $sqlFields[] = "COUNT(distinct $referencefield)";
  361. $join[] = "jfc.reference_table='$contentTable->Name'";
  362. if( isset($idLanguage) && $idLanguage!=-1 ) {
  363. if( $idLanguage=='NULL' ) {
  364. $where[] = "jfc.language_id IS NULL";
  365. } else {
  366. $join[] = "jfc.language_id=$idLanguage";
  367. }
  368. }
  369. foreach ($filters as $filter) {
  370. $sqlFilter= $filter->createFilter($this);
  371. if ($sqlFilter!="") $where[]=$sqlFilter;
  372. }
  373. if( $contentTable->Filter != '' ) {
  374. $where[] = $contentTable->Filter;
  375. }
  376. $sql = "SELECT " .implode( ', ', $sqlFields )
  377. . "\nFROM #__" .$contentTable->Name. ' as c'
  378. . "\nLEFT JOIN #__jf_content as jfc ON " .implode( ' AND ', $join )
  379. . (count( $where ) ? "\nWHERE " . implode( ' AND ', $where ) : "");
  380. //echo "<pre>count-sql = $sql</pre><br />";
  381. return $sql;
  382. }
  383. /**
  384. * Returing the number of elements corresponding with the information of the class
  385. * @return total number of elements
  386. */
  387. public function countReferences( $idLanguage=-1, $filters=array() ) {
  388. $db = JFactory::getDBO();
  389. /*
  390. $db->setQuery( $this->countContentSQL($idLanguage, $filters) );
  391. $result = $db->loadObjectList();
  392. echo $db->getErrorMsg();
  393. return count( $result );
  394. */
  395. $db->setQuery( $this->countContentSQL( $idLanguage, $filters ) );
  396. $count=$db->loadResult();
  397. //echo "count = $count<br/>";
  398. return $count;
  399. }
  400. /**
  401. * Returns the component specific information related the UI screen settings, options, ...
  402. * The information allow the direct translation module to interact with the admin form and allow instant access
  403. * to the specific translation screen
  404. * @return array of admin form parameters
  405. */
  406. public function getComponentInformation() {
  407. $componentInfo = array();
  408. if(isset($this->_xmlFile) ) {
  409. $xpath = new DOMXPath($this->_xmlFile);
  410. $componentElement = $xpath->query('//reference/component')->item(0);
  411. if (!isset($componentElement) || !$componentElement->hasChildNodes()){
  412. return $componentInfo;
  413. }
  414. $forms = $componentElement->getElementsByTagName( 'form' );
  415. foreach ($forms as $componentForm){
  416. $componentInfo[] = $componentForm->textContent;
  417. }
  418. }
  419. return $componentInfo;
  420. }
  421. }
  422. ?>