PageRenderTime 226ms CodeModel.GetById 25ms RepoModel.GetById 4ms app.codeStats 3ms

/components/com_fabrik/models/table.php

https://github.com/chrisinammo/arthurmcneil
PHP | 3994 lines | 2886 code | 400 blank | 708 comment | 677 complexity | b38126dd4abc91b2851f41221bc1ba95 MD5 | raw file
Possible License(s): LGPL-2.1, AGPL-1.0
  1. <?php
  2. /**
  3. * @package Joomla
  4. * @subpackage Fabrik
  5. * @copyright Copyright (C) 2005 Rob Clayburn. All rights reserved.
  6. * @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.php
  7. */
  8. // Check to ensure this file is included in Joomla!
  9. defined('_JEXEC') or die();
  10. require_once( COM_FABRIK_FRONTEND.DS.'helpers'.DS.'json.php' );
  11. require_once( COM_FABRIK_FRONTEND.DS.'helpers'.DS.'pagination.php' );
  12. require_once( COM_FABRIK_FRONTEND.DS.'helpers'.DS.'string.php' );
  13. class FabrikModelTable extends JModel {
  14. /** @var object the tables connection object */
  15. var $_oConn = null;
  16. /** @var object table Table */
  17. var $_table = null;
  18. /** @var array filters applied to table */
  19. var $_aFilter = null;
  20. /** @var array prefilters applied to the table */
  21. var $_aPrefilters = array();
  22. /** @var object table's database connection object (loaded from connection object) */
  23. var $_oConnDB = null;
  24. /** @var object table's form model */
  25. var $_oForm = null;
  26. /** @var array joins */
  27. var $_aJoins = null;
  28. /** @var array column calculations */
  29. var $_aRunCalculations = array();
  30. /** @var string table output format - set to rss to collect correct element data within function gettData()*/
  31. var $_outPutFormat = 'html';
  32. var $_isMambot = false;
  33. var $_admin = false;
  34. /** @var object to contain access rights **/
  35. var $_access = null;
  36. /** @var int the id of the last inserted record (or if updated the last record updated) **/
  37. var $_lastInsertId = null;
  38. /** @var bol determine if we apply prefilters (0 = yes, 1 = no )*/
  39. var $_togglePreFilters = 0;
  40. /** @var array store data to create joined records from */
  41. var $_joinsToProcess = array();
  42. /** @var array database fields */
  43. var $_dbFields = null;
  44. /** @var bol force reload table calculations **/
  45. var $_reloadCalculations = false;
  46. /** @var array data contains request data **/
  47. var $_aData = null;
  48. /** 'var array data to render the table with **/
  49. var $_tableData = null;
  50. /** @var string method to use when submitting form data // post or ajax*/
  51. var $_postMethod = 'post';
  52. /** @var int package id */
  53. var $_packageId = null;
  54. /** @var object plugin manager */
  55. var $_pluginManager = null;
  56. /** @var int id of table to load */
  57. var $_id = null;
  58. /** @var string join sql **/
  59. var $_joinsSQL = null;
  60. /** @var bol is the object inside a package? */
  61. //var $_inPackage = false;
  62. /** @var bol when getting the tableData this decides if only the elements published to the
  63. table view are loaded. Primarily used by visualization plugins to get all table data regardless
  64. of whether its published to the table view */
  65. var $_onlyTableData = true;
  66. var $_formGroupElementData = array();
  67. var $_joinsToThisKey = null;
  68. var $_real_filter_action = null;
  69. var $_aAsFields = null;
  70. /** array merged request and session data used to potentially filter the table **/
  71. var $_request = null;
  72. var $_aRow = null;
  73. /** array rows to delete **/
  74. vaR $_rowsToDelete = null;
  75. /**
  76. * Constructor
  77. *
  78. * @since 1.5
  79. */
  80. function __construct()
  81. {
  82. parent::__construct();
  83. $usersConfig = &JComponentHelper::getParams( 'com_fabrik' );
  84. $id = JRequest::getInt( 'tableid', $usersConfig->get( 'tableid' ) );
  85. $this->setId($id);
  86. $this->_access = new stdClass();
  87. }
  88. /**
  89. * main query to build table
  90. *
  91. */
  92. function render()
  93. {
  94. global $mainframe, $_PROFILER;
  95. $document =& JFactory::getDocument( );
  96. if (is_null( $this->_id ) || $this->_id == '0') {
  97. return JError::raiseError( 500, JText::_('Table id not set - can not render'));
  98. }
  99. $params =& $this->getParams();
  100. $session =& JFactory::getSession();
  101. $this->_outPutFormat = JRequest::getVar( 'format', 'html' );
  102. $pluginManager =& JModel::getInstance( 'Pluginmanager', 'FabrikModel' );
  103. $pluginManager->loadPlugInGroup( 'table' );
  104. if (!$pluginManager->runPlugins( 'onStartRender', $this, 'table' )) {
  105. return;
  106. }
  107. $table =& $this->getTable();
  108. //cant set time limit in safe mode so suppress warning
  109. @set_time_limit ( 800 );
  110. $this->_request = $this->getRequestData();
  111. $context = 'com_fabrik.table.'. $this->_id.'.list.';
  112. $limitLength = $mainframe->getUserStateFromRequest( $context.'limitLength', 'limit', $table->rows_per_page );
  113. $limitStart = $mainframe->getUserStateFromRequest($context.'limitstart', 'limitstart', 0, 'int');
  114. if ($this->_outPutFormat == 'feed') {
  115. $limitLength = JRequest::getVar( 'limit', $params->get( 'rsslimit',150 ) );
  116. $maxLimit = $params->get( 'rsslimitmax', 2500 );
  117. if ($limitLength > $maxLimit) {
  118. $limitLength = $maxLimit;
  119. }
  120. }
  121. $total = $this->getTotalRecords( );
  122. $this->_pageNav =& $this->_getPagination( $total, $limitStart, $limitLength );
  123. if ($limitLength == 0) {
  124. $pageNav->limit = 0;
  125. }
  126. $this->_tableData = $this->getData();
  127. $this->getCalculations( );
  128. $table->hit();
  129. }
  130. /**
  131. * this merges session data for the fromForm with any request data
  132. * allowing us to filter data results from both search forms and filters
  133. *
  134. * @return array
  135. */
  136. function getRequestData()
  137. {
  138. global $_SESSION;
  139. //session_destroy();
  140. if (isset($this->_request)) {
  141. return $this->_request;
  142. }
  143. $aData = JRequest::get( 'request' );
  144. $formModel =& $this->getForm();
  145. $table =& $this->getTable();
  146. if (is_array( $_SESSION )) {
  147. if (array_key_exists( "fabrik", $_SESSION )) {
  148. if (array_key_exists( 'fromForm', $_SESSION["fabrik"] )) {
  149. $fromForm = $_SESSION["fabrik"]['fromForm'];
  150. //only merge if the fromForm is not the same as the current table's form id
  151. if ($_SESSION["fabrik"]['fromForm'] != $formModel->_id) {
  152. $this->_oFromForm =& JModel::getInstance( 'Form', 'FabrikModel' );
  153. $this->_oFromForm->setId( $fromForm );
  154. $fromFormTable = $this->_oFromForm->getForm();
  155. $fromFormParams = $this->_oFromForm->getParams();
  156. //fudge the sesson so that any search form data's keys are the same as the current
  157. //tables
  158. if (array_key_exists( $fromForm, $_SESSION['fabrik'] )) {
  159. foreach ($_SESSION['fabrik'][$fromForm] as $k1=>$v) {
  160. //only unset if not done previously
  161. if (strstr( $k1, "___" )) {
  162. $k2 = $table->db_table_name . "___" . array_pop(explode("___", $k1));
  163. } else {
  164. $k2 = $table->db_table_name . "___" . $k1;
  165. }
  166. if (array_key_exists( $k2, $aData )) {
  167. //override search form session info with any posted filters
  168. $v = $aData[$k2];
  169. }
  170. $_SESSION['fabrik'][$fromForm][$k2] = $v;
  171. }
  172. }
  173. if (array_key_exists( $fromForm, $_SESSION["fabrik"])) {
  174. $aData = array_merge( $aData, $_SESSION["fabrik"][$fromForm] );
  175. }
  176. }
  177. //$$$rob since after 1.0.5.2 DONT unset as page nav no longer picks up the filter
  178. //unset( $_SESSION["fabrik"]['fromForm'] );
  179. }
  180. }
  181. }
  182. return $aData;
  183. }
  184. /**
  185. * get the table's data
  186. *
  187. * @return array of objects (rows)
  188. */
  189. function getData()
  190. {
  191. $fabrikDb =& $this->getDb();
  192. $query = $this->_buildQuery();
  193. $fabrikDb->setQuery( $query, $this->_pageNav->limitstart, $this->_pageNav->limit );
  194. if (JRequest::getBool( 'fabrikdebug', 0 ) == 1) {
  195. echo "<pre>"; echo $fabrikDb->getQuery();echo "</pre>";
  196. }
  197. $data = $fabrikDb->loadObjectList( );
  198. if ($data === false) {
  199. JError::raiseNotice(500, 'getData: ' . $fabrikDb->getErrorMsg( ) );
  200. }
  201. //append the cursor & total to the data
  202. if ($this->_outPutFormat == 'html' || $this->_outPutFormat == 'raw') {
  203. for ($i=0; $i<count($data); $i++) {
  204. $data[$i]->_cursor = $i + $this->_pageNav->limitstart;
  205. $data[$i]->_total = $this->_pageNav->total;
  206. }
  207. }
  208. $this->formatData( $data );
  209. return $data;
  210. }
  211. /**
  212. * run the table data through element filters
  213. *
  214. * @param array $data
  215. */
  216. function formatData( &$data )
  217. {
  218. jimport('joomla.filesystem.file');
  219. $form =& $this->getForm();
  220. $table =& $this->getTable();
  221. $pluginManager =& JModel::getInstance( 'Pluginmanager', 'FabrikModel' );
  222. $method = 'renderTableData_' . $this->_outPutFormat;
  223. $this->_aLinkElements = array();
  224. foreach ($form->_groups as $groupModel) {
  225. if (is_array( $groupModel->_aElements )) {
  226. foreach ($groupModel->_aElements as $elementModel) {
  227. $e =& $elementModel->getElement();
  228. $elementModel->setContext( $groupModel, $form, $this );
  229. $params =& $elementModel->getParams( );
  230. $col = $elementModel->getFullName( false, true, false );
  231. //check if there is a custom out put handler for the tables format
  232. // currently supports "renderTableData_csv", "renderTableData_rss", "renderTableData_html", "renderTableData_json"
  233. if (!empty( $data ) && array_key_exists( $col, $data[0] )) {
  234. if (method_exists( $elementModel, $method )) {
  235. for ($i=0; $i<count( $data ); $i++) {
  236. $thisRow = $data[$i];
  237. $coldata = $data->$col;
  238. $d = $elementModel->$method( $coldata, $col, $thisRow );
  239. $data[$i]->$col = $this->_addLink( $d, $elementModel, $thisRow );
  240. }
  241. } else {
  242. $ec = count( $data );
  243. for ( $i=0; $i< $ec; $i++ ) {
  244. $thisRow = $data[$i];
  245. $coldata = $thisRow->$col;
  246. $d = $elementModel->renderTableData( $coldata, $thisRow );
  247. $data[$i]->$col = $this->_addLink( $d, $elementModel, $thisRow );
  248. $rawCol = $col . "_raw";
  249. if (!array_key_exists( $rawCol, $thisRow)){
  250. $data[$i]->$rawCol = $elementModel->renderRawTableData( $coldata, $thisRow );
  251. }
  252. }
  253. // run a final function for each fo the elements (basically here to
  254. // avoid you doing extraneous sql calls in renderTableData
  255. // ie create sql query in rendertabledata, then run it in mergeTableData
  256. // currently used for advanced table joins only
  257. $elementModel->mergeTableData( $data, $this );
  258. }
  259. //see if we replace data with icons
  260. /*
  261. if ($params->get('icon_folder') != -1 && $params->get('icon_folder') != '') {
  262. jimport('joomla.filesystem.file');
  263. for ($i=0; $i<count( $data ); $i++) {
  264. $thisRow = $data[$i];
  265. $coldata = $thisRow->$col;
  266. $data[$i]->$col = $elementModel->replaceWithIcons( $coldata );
  267. }
  268. }
  269. */
  270. }
  271. }
  272. }
  273. }
  274. $this->_aGroupInfo = array();
  275. $groupTitle = array();
  276. //check if the data has a group by applied to it
  277. if ($table->group_by != '') {
  278. $groupedData = array();
  279. $thisGroupedData = array();
  280. $groupBy = $table->group_by;
  281. //see if we can use a raw value instead
  282. if (!empty( $data ) && array_key_exists( $groupBy . "_raw", $data[0] )) {
  283. $groupBy = $groupBy . "_raw";
  284. }
  285. $groupTitle = null;
  286. $aGroupTitles = array();
  287. $groupId = 0;
  288. for ( $i=0; $i<count( $data ); $i++ ) {
  289. if (!in_array( $data[$i]->$groupBy , $aGroupTitles )) {
  290. $aGroupTitles[] = $data[$i]->$groupBy;
  291. $groupedData[$data[$i]->$groupBy] = array();
  292. }
  293. $data[$i]->_groupId = $data[$i]->$groupBy;
  294. $gKey = $data[$i]->$groupBy;
  295. // if the group_by was added in in getAsFields remove it from the returned data set (to avoid mess in package view)
  296. if ($this->_group_by_added ){
  297. unset($data[$i]->$groupBy );
  298. }
  299. if ($this->_temp_db_key_addded ){
  300. $k = $table->db_primary_key;;
  301. }
  302. $groupedData[$gKey][] = $data[$i];
  303. }
  304. $data = $groupedData;
  305. } else {
  306. for( $i=0; $i<count( $data ); $i++ ){
  307. if ($this->_temp_db_key_addded ){
  308. $k = $table->db_primary_key;;
  309. }
  310. }
  311. //make sure that the none grouped data is in the same format
  312. $data = array( $data );
  313. }
  314. if ($this->_outPutFormat != 'pdf' && $this->_outPutFormat != 'csv' && $this->_outPutFormat != 'feed') {
  315. $this->addSelectBoxAndLinks( $data );
  316. if (JRequest::getVar( 'fabrikdebug' )) {
  317. echo "<pre>";print_r($data);echo"</pre>";
  318. }
  319. }
  320. }
  321. /**
  322. * add the select box and various links into the data array
  323. * @param array table row objects
  324. */
  325. function addSelectBoxAndLinks( &$data )
  326. {
  327. global $Itemid;
  328. $table =& $this->getTable();
  329. $db =& JFactory::getDBO();
  330. $params =& $this->getParams();
  331. $nextview = ($this->canEdit()) ? "form" : "details";
  332. $tmpKey = '__pk_val';
  333. $aExisitngLinkedTables = $params->get('linkedtable', '', '_default', 'array');
  334. $aExisitngLinkedForms = $params->get('linkedform', '', '_default', 'array');
  335. $linkedform_linktype = $params->get( 'linkedform_linktype', '', '_default', 'array' );
  336. $linkedtable_linktype = $params->get( 'linkedtable_linktype', '', '_default', 'array' );
  337. $aExistingTableHeaders = $params->get( 'linkedtableheader', '', '_default', 'array' );
  338. $aExistingFormHeaders = $params->get( 'linkedformheader', '', '_default', 'array' );
  339. //get a list of fabrik tables and ids for view table and form links
  340. $action = ($this->_admin) ? "task" : "view";
  341. $sql = "SELECT id, label FROM #__fabrik_tables";
  342. $db->setQuery( $sql );
  343. $aTableNames = $db->loadObjectList( 'label' );
  344. $cx = count($data);
  345. $viewLinkAdded = false;
  346. //for ($x=0; $x<$cx; $x++) { //if grouped data then the key is not numeric
  347. foreach ($data as $key=>$group) {
  348. //$group =& $data[$key]; //Messed up in php 5.1 group positioning in data became ambiguous
  349. $cg = count( $group );
  350. for( $i=0; $i < $cg; $i++ ){
  351. $row =& $data[$key][$i];
  352. $pKeyVal = (array_key_exists( $tmpKey, $row )) ? $row->$tmpKey : '';
  353. $row->fabrik_delete = ($this->canDelete()) ? '<input type="checkbox" id="id_'.$row->_cursor .'" name="ids['.$row->_cursor.']" value="' . $pKeyVal . '" />' : '';
  354. //add in some default links if no element choosen to be a link
  355. if (empty( $this->_aLinkElements ) and ($this->canView() || $this->canEdit())){
  356. $link = ( $this->_outPutFormat == 'json' ) ? "#" : JRoute::_("index.php?option=com_fabrik&c=form&$action=$nextview&Itemid=$Itemid&fabrik=" . $table->form_id . "&rowid=$pKeyVal&tableid=" .$this->_id . "&fabrik_cursor=" . $row->_cursor . "&fabrik_total=" . $row->_total );
  357. if ($this->canEdit()) {
  358. $row->fabrik_edit = "<a class='fabrik___rowlink' href='$link'>" . JText::_('Edit') . "</a>";
  359. } else {
  360. if($this->canViewDetails()){
  361. $viewLinkAdded = true;
  362. $row->fabrik_edit = "<a class='fabrik___rowlink' href='$link'>" . JText::_('View') . "</a>";
  363. } else {
  364. $row->fabrik_edit = '';
  365. }
  366. }
  367. }
  368. //@TODO: test if all of these are necessary
  369. if ($this->canViewDetails()) {
  370. $link = JRoute::_( "index.php?option=com_fabrik&c=form&$action=form&Itemid=$Itemid&fabrik=" . $table->form_id . "&rowid=$pKeyVal&tableid=" .$this->_id . "&fabrik_cursor=" . $row->_cursor . "&fabrik_total=" . $row->_total );
  371. $row->fabrik_view = "<a class='fabrik___rowlink' href='$link'>" . JText::_('View') . "</a>";
  372. }
  373. if ($this->canViewDetails( ) && $params->get( 'detaillink' ) == '1' && !$viewLinkAdded ) {
  374. $row->__details_link = $this->viewDetailsLink( $pKeyVal );
  375. }
  376. // create columns containing links which point to tables associated with this table
  377. $joinsToThisKey = $this->getJoinsToThisKey( );
  378. $f = 0;
  379. foreach ($joinsToThisKey as $element) {
  380. $linkedTable = array_key_exists($f, $aExisitngLinkedTables) ? $aExisitngLinkedTables[$f] : false;
  381. $popUpLink = array_key_exists($f, $linkedtable_linktype) ? $linkedtable_linktype[$f] : false;
  382. if ($linkedTable != '0') {
  383. if ($element->tablelabel == $table->label) { //if the link points to the same table
  384. $thiskey = $table->db_table_name.'.'.$this->_oTable->_tbl_key;
  385. $key = $element->element_name;
  386. $x = $element->element_name;
  387. $val = $row->$thiskey;
  388. } else {
  389. $linkKey = $element->db_table_name . "___" . $element->name;
  390. $key = $linkKey . "_table_heading";
  391. $val = $pKeyVal;
  392. }
  393. $element->table_id = ( array_key_exists( $element->tablelabel, $aTableNames)) ? $aTableNames[$element->tablelabel]->id : '';
  394. if ($popUpLink != '0') {
  395. //pop up window link
  396. $url = JRoute::_( "index.php?option=com_fabrik&tmpl=component&Itemid=$Itemid&view=table&tableid=$element->table_id&$linkKey" . "[value]=$val&fabrik_cursor=" . $row->_cursor . "&fabrik_total=" . $row->_total );
  397. FabrikHelperHTML::mocha( 'a.popupwin' );
  398. $group[$i]->$key = '<a rel="{\'maximizable\':true}" href="'. $url.'" class="popupwin">'. JText::_('View') .'</a>';
  399. } else {
  400. $url = JRoute::_( "index.php?option=com_fabrik&Itemid=$Itemid&$action=table&tableid=$element->table_id&$linkKey" . "[value]=$val&fabrik_cursor=" . $row->_cursor . "&fabrik_total=" . $row->_total );
  401. $group[$i]->$key = "<a href=\"$url\">" . JText::_('View'). "</a>";
  402. }
  403. }
  404. $f ++;
  405. }
  406. $linksToForms = $this->getLinksToThisKey( );
  407. $f = 0;
  408. //create columns containing links which point to forms assosciated with this table
  409. foreach ( $linksToForms as $element ) {
  410. if ($element != '') {
  411. $linkedForm = array_key_exists($f, $aExisitngLinkedForms) ? $aExisitngLinkedForms[$f] : false;
  412. $popUpLink = array_key_exists($f, $linkedform_linktype) ? $linkedform_linktype[$f] : false;
  413. $linkKey = $element->db_table_name . "___" . $element->name;
  414. $key = $linkKey . "_form_heading";
  415. if ($linkedForm != '0') {
  416. if ($popUpLink != '0') {
  417. $url = JRoute::_("index.php?option=com_fabrik&tmpl=component&Itemid=$Itemid&$action=form&tableid=$element->table_id&fabrik=$element->form_id&$linkKey" . "[value]=$val");
  418. FabrikHelperHTML::mocha( 'a.popupwin' );
  419. $group[$i]->$key = '<a rel="{\'maximizable\':true}" href="'. $url.'" class="popupwin">'. JText::_('Add') .'</a>';
  420. } else {
  421. $url = JRoute::_("index.php?option=com_fabrik&Itemid=$Itemid&$action=form&tableid=$element->table_id&fabrik=$element->form_id&$linkKey" . "[value]=$val");
  422. $group[$i]->$key = "<a href=\"$url\">" . JText::_('Add') . "</a>";
  423. }
  424. }
  425. }
  426. $f ++;
  427. }
  428. }
  429. }
  430. }
  431. /**
  432. * add a custom link to the element data
  433. *
  434. * @param string element $data
  435. * @param object element
  436. * @param object of all row data
  437. */
  438. function _addLink( $data, &$elementModel, &$row )
  439. {
  440. global $Itemid;
  441. if ($this->_outPutFormat == 'csv') {
  442. return $data;
  443. }
  444. $nextview = ($this->canEdit()) ? "form" : "details";
  445. $params =& $elementModel->getParams();
  446. $element =& $elementModel->getElement();
  447. $table =& $this->getTable();
  448. if ($element->link_to_detail == '1' && ( $this->canEdit() || $this->canView())) {
  449. $this->_aLinkElements = $element->name;
  450. if ($this->_postMethod == 'post') {
  451. $primaryKeyVal = $this->getKeyIndetifier( $row );
  452. if ($this->_admin) {
  453. $link = JRoute::_( "index.php?option=com_fabrik&c=form&task=$nextview&fabrik=" . $table->form_id . "$primaryKeyVal&fabrik_cursor=" . @$row->_cursor . "&fabrik_total=" . @$row->_total . "&tableid=" .$this->_id );
  454. } else {
  455. $link = JRoute::_( "index.php?option=com_fabrik&c=form&view=$nextview&Itemid=$Itemid&fabrik=" . $table->form_id . "$primaryKeyVal&fabrik_cursor=" . @$row->_cursor . "&fabrik_total=" . @$row->_total . "&tableid=" .$this->_id );
  456. }
  457. } else {
  458. $link = '#';
  459. }
  460. //try to remove any previously entered links
  461. $data = preg_replace( '/<a(.*?)>|<\/a>/', '', $data );
  462. $data = "<a class='fabrik___rowlink' href='$link'>$data</a>";
  463. } else {
  464. $customLink = $params->get( 'custom_link' );
  465. if ($customLink != '') {
  466. //$w = new FabrikWorker();
  467. //$customLink = $w->parseMessageForPlaceHolder($customLink, JArrayHelper::fromObject( $row ));
  468. $customLink = $this->parseMessageForRowHolder($customLink, JArrayHelper::fromObject( $row ));
  469. //try to remove any previously entered links
  470. $data = preg_replace( '/<a(.*?)>|<\/a>/', '', $data );
  471. $data = "<a class='fabrik___rowlink' href='$customLink'>$data</a>";
  472. }
  473. }
  474. return $data;
  475. }
  476. /**
  477. * get query to make records
  478. * @return string sql
  479. */
  480. function _buildQuery()
  481. {
  482. $query = $this->_buildQuerySelect();
  483. $query .= $this->_buildQueryJoin();
  484. $query .= $this->_buildQueryWhere();
  485. $query .= $this->_buildQueryOrder();
  486. return $query;
  487. }
  488. function _buildQuerySelect()
  489. {
  490. $form =& $this->getForm();
  491. $table =& $this->getTable();
  492. $form->getGroupsHiarachy( $this->_onlyTableData, true );
  493. $this->_getAsFields();
  494. $fields = (empty( $this->_aFields )) ? '' : implode( ", \n ", $this->_aFields ) . "\n ";
  495. if (trim( $table->db_primary_key ) != '' && ( $this->_outPutFormat == 'html' || $this->_outPutFormat == 'feed' ) ) {
  496. if ($this->isView()) {
  497. $strPKey = ''; //view dont have primary key!
  498. } else {
  499. $fields .= ", ";
  500. $strPKey = $table->db_primary_key . " AS __pk_val\n";
  501. }
  502. $query = 'SELECT DISTINCT ' . $fields . $strPKey;
  503. } else {
  504. $query = 'SELECT DISTINCT ' . trim($fields, ", \n") . "\n";
  505. }
  506. $query .= " FROM `$table->db_table_name` \n" ;
  507. return $query;
  508. }
  509. /**
  510. * get the part of the sql statement that orders the table data
  511. * @return string ordering part of sql statement
  512. */
  513. function _buildQueryOrder()
  514. {
  515. global $mainframe;
  516. $params = $this->getParams();
  517. if ($this->_outPutFormat == 'feed' )
  518. {
  519. $dateCol = $params->get( 'feed_date', '' );
  520. if( $dateCol != '' ){
  521. $this->order_dir = 'DESC';
  522. $this->order_by = $dateCol;
  523. return "\n ORDER BY `$dateCol` DESC";
  524. }
  525. }
  526. $session =& JFactory::getSession();
  527. $table =& $this->getTable();
  528. $postOrderBy = JRequest::getVar( 'orderby', '', 'post' );
  529. $postOrderBy = str_replace( ".", "___", $postOrderBy );
  530. $postOrderDir = JRequest::getVar( 'orderdir', '', 'post' );
  531. $arOrderVals = array('asc', 'desc', '-');
  532. if (in_array( $postOrderDir, $arOrderVals )) {
  533. $context = 'com_fabrik.table.'. $this->_id.'.order.'.$postOrderBy;
  534. $session->set( $context, $postOrderDir );
  535. }
  536. //build the order by statement from the session
  537. $strOrder = '';
  538. foreach ($this->_aAsFields as $field) {
  539. $field = str_replace('`', '', $field);
  540. $context = 'com_fabrik.table.'. $this->_id.'.order.'.$field;
  541. $dir = $session->get( $context );
  542. if ($dir != '' && $dir != '-' && trim( $dir ) != 'Array' ) {
  543. $field = str_replace( "___", ".", $field );
  544. if (!strstr( $field, '.' )) {
  545. $field = $table->db_table_name.'.'. $field ;
  546. }
  547. //ensure its quoted
  548. $field = explode( ".", $field );
  549. $field = "`" . $field[0] . "`.`" . $field[1] . "`";
  550. $strOrder == '' ? $strOrder = "\n ORDER BY " : $strOrder .= ',';
  551. $strOrder .= " $field $dir";
  552. }
  553. }
  554. //if nothing found in session use default ordering
  555. if ($strOrder == '' ) {
  556. if ($table->order_by != '') {
  557. $table->order_dir != ''? $dir = $table->order_dir : $dir = 'desc';
  558. $field = str_replace( "___", ".", $table->order_by );
  559. $field = explode( ".", $field );
  560. if(count($field) == 2 && $field[1] != '') {
  561. $field = "`" . $field[0] . "`.`" . $field[1] . "`";
  562. $strOrder = "\n ORDER BY $field $dir";
  563. }
  564. }
  565. }
  566. // apply group ordering
  567. $groupOrderBy = $params->get( 'group_by_order' );
  568. if ($groupOrderBy != '' && in_array( $groupOrderBy, $this->_aAsFields )) {
  569. $groupOrderDir = $this->_params->get( 'group_by_order_dir' );
  570. $strOrder == '' ? $strOrder = "\n ORDER BY " : $strOrder .= ',';
  571. $strOrder .= " `$groupOrderBy` $groupOrderDir ";
  572. }
  573. return $strOrder;
  574. }
  575. /**
  576. * get the part of the sql query that creates the joins
  577. * used when building the table's data
  578. *
  579. * @return string join sql
  580. */
  581. function _buildQueryJoin()
  582. {
  583. if (isset( $this->_joinSQL )) {
  584. return $this->_joinsSQL;
  585. }
  586. $sql = '';
  587. $joins =& $this->getJoins();
  588. $tableGroups = array();
  589. foreach ($joins as $join) {
  590. $sql .= strtoupper($join->join_type) ." JOIN `$join->table_join`" ;
  591. if ($join->table_join_alias == '') {
  592. /*$sql .= " ON `$join->table_join`.`$join->table_join_key` = " .
  593. "`$join->join_from_table`.`$join->table_key` \n";*/
  594. $sql .= " ON `$join->table_join`.`$join->table_join_key` = " .
  595. "`$join->keytable`.`$join->table_key` \n";
  596. } else {
  597. /*$sql .= " AS `" . $join->table_join_alias .
  598. "` ON `" . $join->table_join_alias . "`.`$join->table_join_key` = " .
  599. "`$join->join_from_table`.`$join->table_key` \n ";*/
  600. $sql .= " AS `" . $join->table_join_alias .
  601. "` ON `" . $join->table_join_alias . "`.`$join->table_join_key` = " .
  602. "`$join->keytable`.`$join->table_key` \n ";
  603. }
  604. }
  605. return $sql;
  606. }
  607. /**
  608. * get the part of the sql query that relates to the where statement
  609. *
  610. * @param bol $incFilters
  611. * @return string where query
  612. */
  613. function _buildQueryWhere( $incFilters = true )
  614. {
  615. if (isset( $this->_whereSQL )) {
  616. return $this->_whereSQL[$incFilters];
  617. }
  618. $aFilters =& $this->getFilterArray();
  619. $params =& $this->getParams();
  620. if (isset( $params ) && $this->_togglePreFilters == 0) {
  621. $aPrefilters = $this->getPrefilterArray( );
  622. } else {
  623. $aPrefilters = array();
  624. }
  625. $aOrSQL = array( );
  626. $aFoundOrGroupings = array( );
  627. $i = 0;
  628. $aSQLBits = array();
  629. if (is_array( $aFilters )) {
  630. /* stores sql for or statements */
  631. $c = 0;
  632. foreach ($aFilters as $key=>$val) {
  633. /*work through or columns first to build sql ( col = val or col = val...)
  634. * then remove them from the rest of the array
  635. */
  636. if ( isset( $val['aOrCols'] ) ) {
  637. $aOrColumns = $val['aOrCols'] ;
  638. $filterVal = isset( $val['value'] ) ? $val['value'] : '';
  639. /* check if we've already performed it elsewhere */
  640. $done = false;
  641. foreach ($aFoundOrGroupings as $aFoundOrGroupSet) {
  642. $a = filter_unused( $aFoundOrGroupSet, $aOrColumns );
  643. if (empty( $a )){
  644. $done = true;
  645. }
  646. }
  647. if (!$done) {
  648. /*
  649. * ok we havent processed this group -
  650. * lets add it to the groups the we have processed
  651. */
  652. $aFoundOrGroupings[] = $aOrColumns;
  653. /*
  654. *now lets build that query string!
  655. */
  656. $orSql ='(';
  657. foreach ($aOrColumns as $col) {
  658. $col = FabrikWorker::getDbSafeName( $col );
  659. $orSql .= "`$col` = '$filterVal' OR " ;
  660. }
  661. $orSql = substr($orSql, 0, strlen($orSql)-3) . ')';
  662. $aOrSQL[] = $orSql;
  663. }
  664. /* ok, even if its been done before we still need to remove it from the filter array */
  665. unset ( $aFilters[$key] );
  666. $c++;
  667. }
  668. }
  669. foreach ($aFilters as $key=>$val) {
  670. $filterType = isset( $val['type'] ) ? $val['type']: 'dropdown';
  671. $filterVal = isset( $val['value'] ) ? $val['value'] : '';
  672. $filterExactMatch = isset( $val['match'] ) ? $val['match'] : '';
  673. $fullWordsOnly = isset( $val['full_words_only'] )? $val['full_words_only'] : '0';
  674. if (array_key_exists( $key, $aPrefilters )){
  675. if (array_key_exists( 'sqlCond' , $aPrefilters[$key] )) {
  676. $sqlCond = "( " .$val['sqlCond'] . " AND " . $aPrefilters[$key]['sqlCond'] . " )";
  677. } else {
  678. //$$$rob used for prefilter and table - "Tables with database join elements linking to this table " pointing to same prefilter opt
  679. $sqlCond = "( " .$val['sqlCond'];
  680. foreach ($aPrefilters[$key] as $tmpC) {
  681. $sqlCond .= " AND " . $tmpC['sqlCond'];
  682. }
  683. $sqlCond .= " )";
  684. }
  685. unset( $aPrefilters[$key] );
  686. } else {
  687. $sqlCond = $val['sqlCond'];
  688. }
  689. if ( $filterVal != "" ) {
  690. $aSQLBits[] = " AND ";
  691. $aSQLBits[] = $sqlCond;
  692. $i ++;
  693. }
  694. }
  695. }
  696. //add in any prefiltres not duplicated by filters
  697. //put them at the beginning of query as well
  698. $aSQLBits2 = array();
  699. foreach ($aPrefilters as $key=>$ar) {
  700. if ($key !== '') {
  701. $aSQLBits2[] = $ar['concat'];
  702. $aSQLBits2[] = $ar['sqlCond'];
  703. }
  704. }
  705. // $$$rob work out the where statment minus any filters (so only include prefilters)
  706. // this is needed to ensure that the filter drop downs contain the correct info.
  707. $sqlNoFilter = '';
  708. if (!empty( $aSQLBits2 )) {
  709. $aSQLBits2[0] = "WHERE";
  710. $sqlNoFilter .= implode( ' ', $aSQLBits2 );
  711. if (count( $aOrSQL ) > 0) {
  712. if (empty( $aSQLBits2 )) {
  713. $sqlNoFilter .= " WHERE " . implode( ' AND ', $aOrSQL );
  714. } else {
  715. $sqlNoFilter .= ' AND ' . implode( ' AND ', $aOrSQL );
  716. }
  717. }
  718. }
  719. //apply advanced filter query
  720. $advancedFilter = JRequest::getVar('advancedFilterContainer', array('value' => ''), 'default', 'none', 2);
  721. $sql = '';
  722. $aSQLBits = array_merge( $aSQLBits2, $aSQLBits );
  723. if (!empty( $aSQLBits )) {
  724. $aSQLBits[0] = "WHERE";
  725. $sql .= implode( ' ', $aSQLBits );
  726. if (count( $aOrSQL ) > 0) {
  727. if (empty( $aSQLBits )) {
  728. $sql .= " WHERE " . implode( ' AND ', $aOrSQL );
  729. } else {
  730. $sql .= ' AND ' . implode( ' AND ', $aOrSQL );
  731. }
  732. }
  733. }
  734. if ($advancedFilter['value'] != '') {
  735. $sql .= empty( $sql ) ? " WHERE " : " AND ";
  736. $sql .= trim( trim( $advancedFilter['value'], "AND" ), "OR" );
  737. }
  738. $this->_whereSQL = array( '0'=>$sqlNoFilter, '1'=>$sql );
  739. return $this->_whereSQL[$incFilters];
  740. }
  741. /**
  742. * get the part of the table sql statement that selects which fields to load
  743. * (both this_>_aASFields and this->_aFields)
  744. *
  745. * @return array field names to select in getelement data sql query
  746. */
  747. function &_getAsFields()
  748. {
  749. if (!is_null( $this->_aAsFields )) {
  750. return $this->_aAsFields;
  751. }
  752. $form =& $this->getForm();
  753. $table =& $this->getTable();
  754. $aJoinObjs =& $this->getJoins();
  755. $this->_aAsFields = array();
  756. $this->_aFields = array();
  757. $this->_temp_db_key_addded = false;
  758. foreach ($form->_groups as $groupModel) {
  759. $table_name = $table->db_table_name;
  760. $group =& $groupModel->getGroup();
  761. if ($group->is_join) {
  762. foreach ($aJoinObjs as $join) {
  763. //also ignore any joins that are elements
  764. if (array_key_exists( 'group_id', $join ) && $join->group_id == $group->id && $join->element_id == 0 ) {
  765. $table_name = $join->table_join;
  766. }
  767. }
  768. }
  769. foreach ($groupModel->_aElements as $elementModel) {
  770. if (!$this->_onlyTableData || $elementModel->inTableFields( $this )) {
  771. $method = "getAsField_" . $this->_outPutFormat;
  772. if (!method_exists( $elementModel, $method )) {
  773. $method = "getAsField_html";
  774. }
  775. $elementModel->$method( $this->_aFields, $this->_aAsFields, $table_name );
  776. }
  777. }
  778. }
  779. //temporaraily add in the db key so that the edit links work, must remove it before final return
  780. // of getData();
  781. if (!$this->isView()) {
  782. if (!$this->_temp_db_key_addded && $table->db_primary_key != '') {
  783. $str = str_replace( '___', '.', $table->db_primary_key ) . " AS " . str_replace( '.', '___', $table->db_primary_key );
  784. //if we are quoting the priamry key in the db then we need to remove these quotes
  785. $str = str_replace( '`___`', '___', $str );
  786. $this->_aFields[] = $str;
  787. $this->_aAsFields[] = $table->db_primary_key;
  788. }
  789. }
  790. //for raw data in packages
  791. if ($this->_outPutFormat == 'raw') {
  792. $str = str_replace( '___', '.', $table->db_primary_key ) . " AS __pk_val";
  793. $str = str_replace( '`___`', '___', $str );
  794. $this->_aFields[] = $str;
  795. }
  796. //end
  797. $this->_group_by_added = false;
  798. //if the group by element isnt in the fields add it (otherwise group by wont work)
  799. if (!in_array( $table->group_by, $this->_aAsFields ) && trim( $table->group_by ) != '') {
  800. $this->_aFields[] = str_replace( '___', '.', $table->group_by ) . " AS `$table->group_by`";
  801. $this->_aAsFields[] = $table->group_by;
  802. $this->_group_by_added = true;
  803. }
  804. return $this->_aAsFields;
  805. }
  806. /**
  807. * checks if the params object has been created and if not creates and returns it
  808. * @return object params
  809. */
  810. function &getParams()
  811. {
  812. $table =& $this->getTable();
  813. if (!isset( $this->_params )) {
  814. $this->_params = &new fabrikParams( $table->attribs, JPATH_SITE . '/administrator/components/com_fabrik/models/table.xml', 'component' );
  815. }
  816. return $this->_params;
  817. }
  818. /**
  819. * Method to set the table id
  820. *
  821. * @access public
  822. * @param int table ID number
  823. */
  824. function setId( $id )
  825. {
  826. $this->_id = $id;
  827. }
  828. /**
  829. * sets the instances admin state
  830. * @param bol admin state
  831. */
  832. function setAdmin( $bol )
  833. {
  834. $this->_admin = $bol;
  835. }
  836. /**
  837. * get the table object for the models _id
  838. *
  839. * @return object table
  840. */
  841. function &getTable()
  842. {
  843. if (is_null( $this->_table )) {
  844. JTable::addIncludePath( JPATH_ADMINISTRATOR.DS.'components'.DS.'com_fabrik'.DS.'tables' );
  845. $row = JTable::getInstance( 'table', 'Table' );
  846. $row->load( $this->_id );
  847. $this->_table =& $row;
  848. }
  849. return $this->_table;
  850. }
  851. /**
  852. * load the database associated with the table
  853. *@return object database
  854. */
  855. function &getDb()
  856. {
  857. if (!isset( $this->_oConnDB )) {
  858. $cnn =& $this->getConnection();
  859. if (!is_object( $cnn )) {
  860. return JError::raiseError( 500, JText::_( 'Fabrik was unable to load the database object for this table' ) );
  861. }
  862. $this->_oConnDB =& $cnn->getDb( );
  863. }
  864. return $this->_oConnDB;
  865. }
  866. /**
  867. * function get the tables connection object
  868. * sets $this->_oConn to the tables connection
  869. * @return object connection
  870. */
  871. function &getConnection( )
  872. {
  873. $config =& JFactory::getConfig();
  874. if (!isset( $this->_oConn )) {
  875. $table =& $this->getTable();
  876. $connectionModel =& JModel::getInstance( 'connection', 'FabrikModel' );
  877. $connId = ( is_null( $table->connection_id ) ) ? JRequest::getVar( 'connection_id', null ) : $table->connection_id;
  878. $connectionModel->setId( $connId );
  879. if ($connId == '' || is_null( $connId ) || $connId == '-1' ){ //-1 for creating new table
  880. $connectionModel->loadDefaultConnection();
  881. $connectionModel->setId( $connectionModel->_connection->id );
  882. }
  883. $connection =& $connectionModel->getConnection( );
  884. // if its the default connection then load from the
  885. // config file
  886. if ($connectionModel->isDefault() ){
  887. $connection->host = $config->getValue('config.host');
  888. $connection->user = $config->getValue('config.user');
  889. $connection->password = $config->getValue('config.password');
  890. $connection->database = $config->getValue('config.db');
  891. }
  892. $this->_oConn =& $connectionModel;
  893. }
  894. return $this->_oConn;
  895. }
  896. /**
  897. * is the table published
  898. *
  899. * @return bol published state
  900. */
  901. function canPublish()
  902. {
  903. $table =& $this->getTable();
  904. global $mainframe;
  905. $db =& JFactory::getDBO();
  906. if (method_exists( $db, 'getNullDate' )) {
  907. $nullDate = $db->getNullDate( );
  908. } else {
  909. $nullDate = $this->getNullDate( );
  910. }
  911. $publishup =& JFactory::getDate($table->publish_up, $mainframe->getCfg('offset'));
  912. $publishup = $publishup->toUnix();
  913. $publishdown =& JFactory::getDate($table->publish_down, $mainframe->getCfg('offset'));
  914. $publishdown = $publishdown->toUnix();
  915. $jnow =& JFactory::getDate();
  916. $now = $jnow->toUnix();
  917. if ($table->state == '1') {
  918. if ($now >= $publishup || $table->publish_up == '' || $table->publish_up == $nullDate) {
  919. if ($now <= $publishdown || $table->publish_down == '' || $table->publish_down == $nullDate) {
  920. return true;
  921. }
  922. }
  923. }
  924. return false;
  925. return $table->state;
  926. }
  927. /**
  928. *
  929. */
  930. function canEmpty()
  931. {
  932. $user =& JFactory::getUser();
  933. $acl =& JFactory::getACL();
  934. $table =& $this->getTable();
  935. $params =& $this->getParams();
  936. $a = $params->get( 'allow_drop', 0 );
  937. if ($a == '29'|| $a == ''|| $a == 0) {
  938. $this->_access->allow_drop = true;
  939. } else {
  940. if (!is_object( $this->_access ) || !array_key_exists( 'allow_drop', $this->_access )) {
  941. $groupNames =& FabrikWorker::getACLGroups( $a );
  942. foreach ($groupNames as $name) {
  943. FabrikWorker::setACL( 'action', 'allow_drop', 'fabrik', $name, 'components', null );
  944. }
  945. if ($acl->acl_check( 'action', 'allow_drop', 'fabrik', $user->get(' usertype' ), 'components', null )) {
  946. $this->_access->allow_drop = true;
  947. } else {
  948. $this->_access->allow_drop = false;
  949. }
  950. }
  951. }
  952. return $this->_access->allow_drop;
  953. }
  954. /**
  955. * check if the user can view the detailed records
  956. *
  957. * @return bol
  958. */
  959. function canViewDetails()
  960. {
  961. $user =& JFactory::getUser();
  962. $acl =& JFactory::getACL();
  963. $table =& $this->getTable();
  964. $params =& $this->getParams();
  965. $a = $params->get( 'allow_view_details', 0 );
  966. if ($a == '29'|| $a == ''|| $a == 0) {
  967. $this->_access->viewdetails = true;
  968. } else {
  969. if (!is_object( $this->_access ) || !array_key_exists( 'viewdetails', $this->_access )) {
  970. $groupNames =& FabrikWorker::getACLGroups( $a );
  971. foreach ($groupNames as $name) {
  972. FabrikWorker::setACL( 'action', 'viewdetails', 'fabrik', $name, 'components', null );
  973. }
  974. if ($acl->acl_check( 'action', 'viewdetails', 'fabrik', $user->get(' usertype' ), 'components', null )) {
  975. $this->_access->viewdetails = true;
  976. } else {
  977. $this->_access->viewdetails = false;
  978. }
  979. }
  980. }
  981. return $this->_access->viewdetails;
  982. }
  983. /**
  984. * checks user access for editing records
  985. *
  986. * @return bol access allowed
  987. */
  988. function canEdit()
  989. {
  990. $user =& JFactory::getUser();
  991. $acl =& JFactory::getACL();
  992. $table =& $this->getTable();
  993. $params =& $this->getParams();
  994. $a = $params->get( 'allow_edit_details', 25 );
  995. if ($a == '29'|| $a == ''|| $a == 0) {
  996. $this->_access->edit = true;
  997. } else {
  998. if(!is_object($this->_access) || !array_key_exists('edit', $this->_access)){
  999. $groupNames = FabrikWorker::getACLGroups( $a );
  1000. foreach ($groupNames as $name) {
  1001. FabrikWorker::setACL( 'action', 'edit', 'fabrik', $name, 'components', null );
  1002. }
  1003. if ($acl->acl_check( 'action', 'edit', 'fabrik', $user->get( 'usertype' ), 'components', null )) {
  1004. $this->_access->edit = true;
  1005. } else {
  1006. $this->_access->edit = false;
  1007. }
  1008. }
  1009. }
  1010. return $this->_access->edit;
  1011. }
  1012. /**
  1013. * checks user access for deleting records
  1014. *
  1015. * @return bol access allowed
  1016. */
  1017. function canDelete()
  1018. {
  1019. $user = &JFactory::getUser();
  1020. $acl =& JFactory::getACL();
  1021. $table =& $this->getTable();
  1022. $params =& $this->getParams();
  1023. $a = $params->get( 'allow_delete', 25 );
  1024. if ($a == '29'|| $a == '' || $a == 0 ){
  1025. $this->_access->delete = true;
  1026. } else {
  1027. if (!is_object( $this->_access ) || !array_key_exists( 'delete', $this->_access )) {
  1028. $groupNames = FabrikWorker::getACLGroups( $a );
  1029. foreach ($groupNames as $name) {
  1030. FabrikWorker::setACL( 'action', 'delete', 'fabrik', $name, 'components', null );
  1031. }
  1032. if ($acl->acl_check( 'action', 'delete', 'fabrik', $user->get( 'usertype' ), 'components', null )) {
  1033. $this->_access->delete = true;
  1034. } else {
  1035. $this->_access->delete = false;
  1036. }
  1037. }
  1038. }
  1039. return $this->_access->delete;
  1040. }
  1041. /**
  1042. * checks user access for adding records
  1043. *
  1044. * @return bol access allowed
  1045. */
  1046. function canAdd()
  1047. {
  1048. $user =& JFactory::getUser();
  1049. $acl =& JFactory::getACL();
  1050. $params =& $this->getParams();
  1051. $table =& $this->getTable();
  1052. $a = $params->get( 'allow_add', 25 );
  1053. if ($a == '29' || $a == ''|| $a == 0){
  1054. $this->_access->add = true;
  1055. } else {
  1056. if (!is_object( $this->_access ) || !array_key_exists( 'add', $this->_access )) {
  1057. $groupNames = FabrikWorker::getACLGroups( $a );
  1058. foreach ($groupNames as $name) {
  1059. FabrikWorker::setACL( 'action', 'add', 'fabrik', $name, 'components', null );
  1060. }
  1061. if ($acl->acl_check( 'action', 'add', 'fabrik', $user->get( 'usertype' ), 'components', null )) {
  1062. $this->_access->add = true;
  1063. } else {
  1064. $this->_access->add = false;
  1065. }
  1066. }
  1067. }
  1068. return $this->_access->add;
  1069. }
  1070. /**
  1071. * check use can view the table
  1072. * @return bol can view or not
  1073. */
  1074. function canView( ){
  1075. $user =& JFactory::getUser();
  1076. $acl =& JFactory::getACL();
  1077. $table =& $this->getTable();
  1078. if ($table->access == '29'|| $table->access == '' || $table->access == 0) {
  1079. $this->_access->view = true;
  1080. } else {
  1081. if (!is_object($this->_access) || !array_key_exists('view', $this->_access)) {
  1082. $groupNames = FabrikWorker::getACLGroups( $table->access );
  1083. foreach ($groupNames as $name) {
  1084. FabrikWorker::setACL( 'action', 'view', 'fabrik', $name, 'components', null );
  1085. }
  1086. if ($acl->acl_check( 'action', 'view', 'fabrik', $user->get('usertype'), 'components', null )) {
  1087. $this->_access->view = true;
  1088. } else {
  1089. $this->_access->view = false;
  1090. }
  1091. }
  1092. }
  1093. return $this->_access->view;
  1094. }
  1095. /**
  1096. * load the table from the form_id value
  1097. * @param int $formId
  1098. * @return object table row
  1099. */
  1100. function loadFromFormId( $formId ){
  1101. JTable::addIncludePath( JPATH_ADMINISTRATOR.DS.'components'.DS.'com_fabrik'.DS.'table' );
  1102. $row = JTable::getInstance( 'table', 'Table' );
  1103. $origKey = $row->_tbl_key;
  1104. $row->_tbl_key = "form_id";
  1105. $row->load( $formId );
  1106. $this->_table = $row;
  1107. $row->_tbl_key = $origKey;
  1108. $this->setId( $row->id );
  1109. return $row;
  1110. }
  1111. /**
  1112. * alias to loadJoins - should be used instead
  1113. * @return array join objects (table rows - not table objects or models)
  1114. */
  1115. function &getJoins()
  1116. {
  1117. if (!isset( $this->_aJoins )) {
  1118. $form =& $this->getForm();
  1119. $form->getGroupsHiarachy( false );
  1120. $ids = $form->getElementIds();
  1121. $table =& $this->getTable();
  1122. $db =& JFactory::getDBO();
  1123. $sql = "SELECT * FROM #__fabrik_joins WHERE table_id = '$this->_id'";
  1124. if (!empty( $ids )) {
  1125. $sql .= " OR element_id IN ( " . implode(", ", $ids) .")";
  1126. }
  1127. //maybe we will have to order by element_id asc to ensure that table joins are loaded
  1128. //before element joins (if an element join is in a table join then its 'join_from_table' key needs to be updated
  1129. $sql .= " ORDER BY id";
  1130. $db->setQuery( $sql );
  1131. $this->_aJoins = $db->loadObjectList( );
  1132. if ($db->getErrorNum()) {
  1133. JError::raiseError( 500, $db->stderr());
  1134. }
  1135. $aliases = array();
  1136. $tableGroups = array();
  1137. foreach ($this->_aJoins as $join) {
  1138. //if their 'table_join' has been used then update with an alais
  1139. if (in_array( $join->table_join, $aliases )) {
  1140. $base = $join->table_join;
  1141. $a = $base;
  1142. $c = 0;
  1143. while (in_array( $a, $aliases )) {
  1144. $a = "{$base}_{$c}";
  1145. $c ++;
  1146. }
  1147. $join->table_join_alias = $a;
  1148. } else {
  1149. $join->table_join_alias = $join->table_join;
  1150. }
  1151. $aliases[] = $join->table_join;
  1152. //if they are element joins add in this tables name as the calling joining table.
  1153. if ($join->join_from_table == '') {
  1154. $join->join_from_table = $table->db_table_name;
  1155. }
  1156. // test case:
  1157. /*
  1158. * you have a talbe that joins to a 2nd table
  1159. * in that 2nd table there is a database join element
  1160. * that 2nd elements key needs to point to the 2nd tables name and not the first
  1161. *
  1162. * e.g. when you want to create a n-n relationship
  1163. *
  1164. * events -> (table join) events_artists -> (element join) artist
  1165. */
  1166. $join->keytable = $join->join_from_table;
  1167. if (!array_key_exists( $join->group_id, $tableGroups )) {
  1168. $tableGroups[$join->group_id] = $join->table_join_alias;
  1169. } else {
  1170. if ($join->element_id != 0) {
  1171. $join->keytable = $tableGroups[$join->group_id];
  1172. }
  1173. }
  1174. }
  1175. }
  1176. return $this->_aJoins;
  1177. }
  1178. /**
  1179. * gets the field names for the given table
  1180. * @param string table name
  1181. * @return array table fields
  1182. */
  1183. function getDBFields( $tbl = null )
  1184. {
  1185. if (is_null( $tbl )) {
  1186. $table =& $this->getTable();
  1187. $tbl = $table->db_table_name ;
  1188. }
  1189. if (!strstr( $tbl, '`' )) {
  1190. $tbl = "`$tbl`";
  1191. }
  1192. if (!isset( $this->_dbFields[$tbl] ) ){
  1193. $db =& $this->getDb();
  1194. $db->setQuery( "DESCRIBE $tbl" );
  1195. $this->_dbFields[$tbl] = $db->loadObjectList( );
  1196. }
  1197. return $this->_dbFields[$tbl];
  1198. }
  1199. /**
  1200. * add or update a database column via sql
  1201. * @param object element plugin
  1202. * @param bol is new
  1203. * @param string origional field name
  1204. */
  1205. function alterStructure( &$elementModel, $new, $origColName=null )
  1206. {
  1207. $db =& JFactory::getDBO();
  1208. $element =& $elementModel->getElement();
  1209. $pluginManager =& JModel::getInstance( 'Pluginmanager', 'FabrikModel' );
  1210. $basePlugIn =& $pluginManager->getPlugIn( $element->plugin, 'element' );
  1211. $fbConfig = JComponentHelper::getParams( 'com_fabrik' );
  1212. $fabrikDb =$this->getDb();
  1213. $table =& $this->getTable();
  1214. $tableName = $table->db_table_name;
  1215. $objtype = $basePlugIn->getFieldDescription();
  1216. $dbdescriptions = $this->getDBFields( $tableName );
  1217. if (!$fbConfig->get( 'fbConf_alter_existing_db_cols' )) {
  1218. foreach ($dbdescriptions as $f) {
  1219. if ($f->Field == $origColName) {
  1220. $objtype = $f->Type;
  1221. }
  1222. }
  1223. }
  1224. if (!is_null( $objtype )) {
  1225. foreach ($dbdescriptions as $dbdescription) {
  1226. $fieldname = $dbdescription->Field;
  1227. $exitingfields[] = strtolower($fieldname);
  1228. }
  1229. $lastfield = $fieldname;
  1230. if (in_array( strtolower($element->name), $exitingfields )) {
  1231. return ;
  1232. }
  1233. FabrikString::safeColName( $element->name );
  1234. FabrikString::safeColName( $tableName );
  1235. FabrikString::safeColName( $lastfield );
  1236. if (( $new && !in_array( strtolower($element->name), $exitingfields) ) || !in_array( strtolower($origColName), $exitingfields )) {
  1237. $sql = "ALTER TABLE $tableName ADD COLUMN $element->name $objtype AFTER $lastfield";
  1238. } else {
  1239. if ($origColName == null) {
  1240. $origColName = $element->name;
  1241. }
  1242. FabrikString::safeColName( $origColName );
  1243. $sql = "ALTER TABLE $tableName CHANGE $origColName " . $element->name ;
  1244. $sql .= " $objtype";
  1245. }
  1246. $fabrikDb->setQuery( $sql );
  1247. if (!$fabrikDb->query( )) {
  1248. return JError::raiseError( 500, 'alter structure: ' . $fabrikDb->getErrorMsg( ));
  1249. }
  1250. $this->createCacheQuery();
  1251. }
  1252. return true;
  1253. }
  1254. /**
  1255. * if not loaded this loads in the table's form object
  1256. * also binds a reference of the table to the form.
  1257. * @return object form model with form table loaded
  1258. */
  1259. function &getForm()
  1260. {
  1261. if (is_null( $this->_oForm )) {
  1262. $this->_oForm =& JModel::getInstance( 'Form', 'FabrikModel' );
  1263. $table =& $this->getTable();
  1264. $this->_oForm->setId( $table->form_id );
  1265. $this->_oForm->getForm();
  1266. $this->_oForm->setTableModel( $this );
  1267. //ensure joins are loaded
  1268. }
  1269. return $this->_oForm;
  1270. }
  1271. /**
  1272. * tests if the table is in fact a view
  1273. * @returns true if table is a view
  1274. */
  1275. function isView()
  1276. {
  1277. $params =& $this->getParams();
  1278. $isview = $params->get('isview', null);
  1279. if (is_null($isview)) {
  1280. $db =& JFactory::getDBO();
  1281. $table =& $this->getTable();
  1282. $cn = $this->getConnection();
  1283. $c = $cn->getConnection();
  1284. $dbname = $c->database;
  1285. $sql = "show table status like '$table->db_table_name'";
  1286. $sql = " select table_name, table_type, engine from INFORMATION_SCHEMA.tables ".
  1287. "where table_name = '$table->db_table_name' and table_type = 'view' and table_schema = '$dbname'";
  1288. $db->setQuery( $sql );
  1289. $row = $db->loadObjectList();
  1290. $isview = empty($row) ? false : true;
  1291. $intisview = $isview ? 1 : 0;
  1292. //store and save param for following tests
  1293. $params->set('isview', $isview);
  1294. $table->attribs .= "\nisview=$intisview\n";
  1295. $table->store();
  1296. }
  1297. return $isview;
  1298. }
  1299. /** DEPRECIATED SHOULD NOT BE NEEDED NOW
  1300. function _loadJoinOnce( $join )
  1301. {
  1302. return $join->table_join;
  1303. }
  1304. **/
  1305. /**
  1306. * filter array is created in $this->_loadFilterArray
  1307. *@return array filters
  1308. */
  1309. function &getFilterArray( )
  1310. {
  1311. if (isset( $this->_aFilter )) {
  1312. return $this->_aFilter;
  1313. }
  1314. $user = &JFactory::getUser();
  1315. $request = $this->getRequestData();
  1316. $this->_aFilter = array();
  1317. $this->_aPrefilters =& $this->getPrefilterArray();
  1318. $form =& $this->getForm();
  1319. $filterCondSQL = '';
  1320. $aPostFilters = array();
  1321. $useFullName = JRequest::getBool( 'fullName', 1 );
  1322. if (is_null( $form->_groups )) {
  1323. $form->getGroupsHiarachy();
  1324. }
  1325. foreach ($form->_groups as $groupModel) {
  1326. $group =& $groupModel->getGroup();
  1327. foreach ($groupModel->_aElements as $elementModel) {
  1328. $element =& $elementModel->getElement();
  1329. $thisData = $this->_aData;
  1330. if ($group->is_join) {
  1331. if (@array_key_exists( 'join', $request ) && @is_array( $request['join'][$group->join_id] )) {
  1332. $thisData = $this->_aData['join'][$group->join_id];
  1333. }
  1334. $key = $elementModel->getFilterFullName( false, true, false );
  1335. } else {
  1336. $key = $elementModel->getFilterFullName( true, true, false );
  1337. }
  1338. $dbKey = str_replace( "___", ".", $key );
  1339. $dbKey = FabrikWorker::getDbSafeName( $dbKey );
  1340. if (array_key_exists( $key, $request )) {
  1341. $safeKey = FabrikWorker::getDbSafeName( $dbKey );
  1342. $arr = $elementModel->getFilterConditionSQL( $request[$key], $this->_aFilter, $safeKey, $key );
  1343. $arr['no-filter-setup'] = ($element->filter_type == '') ? 1 : 0;
  1344. $arr['ellabel'] = $element->label;
  1345. if (!empty( $arr['sqlCond'] )) {
  1346. $sqlCond = "( " . $arr['sqlCond'] ;
  1347. //check if the filter has a corresponding prefilter set.
  1348. if (array_key_exists( $key, $this->_aPrefilters )) {
  1349. $sqlCond .= " AND " . $this->_aPrefilters[$key]['sqlCond'];
  1350. unset( $this->_aPrefilters[$key] );
  1351. }
  1352. $sqlCond .= ")";
  1353. $arr['sqlCond'] = $sqlCond;
  1354. $arr['type'] = 'postfilter';
  1355. //TODO: make this and/or choice somehow for use perhaps?
  1356. $arr['concat'] = ' AND ';
  1357. $arr['grouped_to_previous'] = false;
  1358. $this->_aFilter[$key] = $arr;
  1359. }
  1360. }
  1361. }
  1362. }
  1363. $this->_searchesNoFilterSetup = array();
  1364. return $this->_aFilter;
  1365. }
  1366. /**
  1367. * creates array of prefilters
  1368. * @return array prefilter
  1369. */
  1370. function &getPrefilterArray( )
  1371. {
  1372. $params =& $this->getParams();
  1373. $afilterJoins = $params->get( 'filter-join', '', '_default', 'array' );
  1374. $afilterFields = $params->get( 'filter-fields', '', '_default', 'array' );
  1375. $afilterConditions = $params->get( 'filter-conditions', '', '_default', 'array' );
  1376. $afilterValues = $params->get( 'filter-value', '', '_default', 'array' );
  1377. $afilterAccess = $params->get( 'filter-access', '', '_default', 'array' );
  1378. $afilterEval = $params->get( 'filter-eval', '', '_default', 'array' );
  1379. $afilterGrouped = $params->get( 'filter-grouped', '', '_default', 'array' );
  1380. $appliedPrefilters = 0;
  1381. $selJoin = 'WHERE';
  1382. $aReturn = array();
  1383. $w = new FabrikWorker();
  1384. for ( $i=0;$i<count( $afilterFields );$i++ ) {
  1385. if (!array_key_exists(0, $afilterJoins) || $afilterJoins[0] == '' ){
  1386. $afilterJoins[0] = 'and';
  1387. }
  1388. $selJoin = $afilterJoins[$i];
  1389. if (trim( strtolower( $selJoin ) ) == 'where' ) {
  1390. $selJoin = "AND";
  1391. }
  1392. $selFilter = $afilterFields[$i];
  1393. $selCondition = $afilterConditions[$i];
  1394. $selValue = $afilterValues[$i];
  1395. $filerEval = $afilterEval[$i]; // "" or "1"
  1396. $filterGrouped= $afilterGrouped[$i];
  1397. if ($filerEval == '1' ){
  1398. $selValue = stripslashes( htmlspecialchars_decode( $selValue, ENT_QUOTES ) );
  1399. $selValue = eval( $selValue );
  1400. }
  1401. $selAccess = $afilterAccess[$i];
  1402. if (!$this->mustApplyFilter( $selAccess, $i )) {
  1403. continue;
  1404. }
  1405. $selValue = $this->_prefilterParse( $selValue );
  1406. $selValue = $w->parseMessageForPlaceHolder( $selValue );
  1407. //strip any quotes from the selValue (replaced back in the switch beneath)
  1408. if (!in_array( $selCondition, array( '>', '&gt;', ' > ', '<', '&lt;' ))) {
  1409. $selValue = ltrim( $selValue, "'" );
  1410. $selValue = rtrim( $selValue, "'" );
  1411. $selValue = ltrim( $selValue, '"' );
  1412. $selValue = rtrim( $selValue, '"' );
  1413. }
  1414. switch( $selCondition ){
  1415. case 'notequals':
  1416. $selCondition = " <> ";
  1417. $selValue = "'$selValue'";
  1418. break;
  1419. case 'equals':
  1420. $selCondition = " = ";
  1421. $selValue = "'$selValue'";
  1422. break;
  1423. case 'begins':
  1424. $selCondition = " LIKE ";
  1425. //if its a quoted string put the % inside the quote
  1426. if ($string{0} == '"' || $string{0} == '"') {
  1427. $selValue = substr(0, -1) . "%" . $string{0};
  1428. } else {
  1429. $selValue = "'$selValue%'";
  1430. }
  1431. break;
  1432. case 'ends':
  1433. $selCondition = " LIKE ";
  1434. if ($string{0} == '"' || $string{0} == '"') {
  1435. $selValue = $string{0} . "%" . substr(0, 1) ;
  1436. } else {
  1437. $selValue = "'%$selValue'";
  1438. }
  1439. break;
  1440. case 'contains':
  1441. $selCondition = " LIKE ";
  1442. if ($string{0} == '"' || $string{0} == '"') {
  1443. $selValue = $string{0} . "%" . substr(0, 1) ;
  1444. } else {
  1445. $selValue = "'%$selValue%'";
  1446. }
  1447. break;
  1448. case '>':
  1449. case '&gt;':
  1450. $selCondition = ' > ';
  1451. break;
  1452. case '<':
  1453. case '&lt;':
  1454. $selCondition = ' < ';
  1455. break;
  1456. }
  1457. if ($selCondition == ' = ' && $selValue == "'_null_'") {
  1458. $strCond = " $selFilter IS NULL ";
  1459. } else {
  1460. $strCond = " $selFilter $selCondition $selValue ";
  1461. }
  1462. $aReturn[] = array('type' => '', 'value' =>$selValue, 'filterVal' => $selValue, 'sqlCond' => $strCond, 'concat' => $selJoin,
  1463. 'type' => 'prefilter', 'grouped_to_previous' => $filterGrouped);
  1464. $appliedPrefilters ++;
  1465. }
  1466. return $aReturn;
  1467. }
  1468. /**
  1469. * get the total number of records in the table
  1470. * @return int total number of records
  1471. */
  1472. function getTotalRecords( )
  1473. {
  1474. $db =& $this->getDb();
  1475. $table = $this->getTable();
  1476. $formModel =& $this->getForm();
  1477. $this->getFormGroupElementData( );
  1478. $count = "DISTINCT " . $table->db_primary_key;
  1479. foreach ( $formModel->_groups as $groupModel ) {
  1480. foreach ( $groupModel->_aElements as $elementModel ) {
  1481. $element =& $elementModel->getElement();
  1482. if ( $element->show_in_table_summary && $element->plugin == "fabrikDatabasejoin" ) {
  1483. $count = "*";
  1484. }
  1485. }
  1486. }
  1487. $totalSql = "SELECT COUNT(" . $count . ") AS t FROM " . $table->db_table_name . " " . $this->_buildQueryJoin( );
  1488. $totalSql .= " " . $this->_buildQueryWhere();
  1489. $db->setQuery( $totalSql );
  1490. $total = $db->loadResult( );
  1491. return $total;
  1492. }
  1493. /**
  1494. * load in the elements for the table's form
  1495. * If no form loaded for the table object then one is loaded
  1496. * @param bol if true only those elements marked as 'show_in_table_view' are returned (leave null for default admin behaviour)
  1497. * @param bol if true only those elements that are published are returned
  1498. * @return array element objects
  1499. */
  1500. function &getFormGroupElementData( $tableViewOnly = null, $excludeUnpublished = true )
  1501. {
  1502. $formModel =& $this->getForm( );
  1503. if (is_null( $tableViewOnly )) {
  1504. $tableViewOnly = true;
  1505. }
  1506. $k = $tableViewOnly.'.'.$excludeUnpublished;
  1507. if (!array_key_exists( $k, $this->_formGroupElementData)) {
  1508. $formModel->setTableModel( $this );
  1509. $this->_formGroupElementData[$k] =& $formModel->getGroupsHiarachy( $tableViewOnly, $excludeUnpublished );
  1510. }
  1511. return $this->_formGroupElementData[$k];
  1512. }
  1513. /**
  1514. * require the correct pagenav class based on template
  1515. *
  1516. * @param int total
  1517. * @param int start
  1518. * @param int length
  1519. * @return object pageNav
  1520. */
  1521. function &_getPagination( $total, $limitstart, $limit ){
  1522. $o =& new FPagination( $total, $limitstart, $limit );
  1523. $o->_postMethod = $this->_postMethod;
  1524. return $o;
  1525. }
  1526. /**
  1527. * used to determine which filter action to use
  1528. *if a filter is a range then override tables setting with onsubmit
  1529. */
  1530. function getFilterAction()
  1531. {
  1532. if (!isset( $this->_real_filter_action )) {
  1533. $form =& $this->getForm();
  1534. $table =& $this->getTable();
  1535. $this->_real_filter_action = $table->filter_action;
  1536. foreach ($form->_groups as $groupModel) {
  1537. foreach ($groupModel->_aElements as $elementModel) {
  1538. $element =& $elementModel->getElement();
  1539. if ($element->filter_type <> '') {
  1540. if ($elementModel->canView() && $elementModel->canUseFilter() && $element->show_in_table_summary == '1' ) {
  1541. if($element->filter_type == 'range'){
  1542. $this->_real_filter_action = 'submitform';
  1543. return $this->_real_filter_action;
  1544. }
  1545. }
  1546. }
  1547. }
  1548. }
  1549. }
  1550. return $this->_real_filter_action;
  1551. }
  1552. /**
  1553. * gets the part of a url to describe the key that the link links to
  1554. * if a table this is rowid=x
  1555. * if a view this is view_primary_key={where statement}
  1556. *
  1557. * @param object row $data
  1558. * @return string
  1559. */
  1560. function getKeyIndetifier( $data )
  1561. {
  1562. $table =& $this->getTable();
  1563. if (!$this->isView()) {
  1564. return "&rowid=$data->__pk_val";
  1565. } else {
  1566. $k = array();
  1567. $fields = $this->_fetchFields();
  1568. foreach ($fields as $f) {
  1569. if ($f->primary_key == 1){
  1570. $y = "{$f->table}___{$f->name}";
  1571. $k[] = "{$f->table}.{$f->name} = " . $data->$y;
  1572. }
  1573. }
  1574. $k = implode(' AND ', $k);
  1575. $k = "&view_primary_key=" . urlencode($k);
  1576. return $k;
  1577. }
  1578. }
  1579. /**
  1580. * *get detailed info on each of the tables fields
  1581. *
  1582. * @return unknown
  1583. */
  1584. function _fetchFields()
  1585. {
  1586. $table =& $this->getTable();
  1587. $db =& $this->getDb();
  1588. $db->setQuery("select * from $table->db_table_name limit 1");
  1589. if (!($result = $db->query())) {
  1590. return null;
  1591. }
  1592. $fields = array();
  1593. $num_fields = mysql_num_fields($result);
  1594. for ($i = 0; $i < $num_fields; $i++) {
  1595. $fields[] = mysql_fetch_field($result, $i);
  1596. }
  1597. return $fields;
  1598. }
  1599. /**
  1600. * @return array of element objects that are database joins and that
  1601. * use this table's key as their foregin key
  1602. *
  1603. */
  1604. function getJoinsToThisKey()
  1605. {
  1606. if (is_null( $this->_joinsToThisKey )) {
  1607. $db =& JFactory::getDBO();
  1608. $table =& $this->getTable();
  1609. if ($table->id == 0 ) {
  1610. $this->_joinsToThisKey = array();
  1611. } else {
  1612. $sql = "SELECT *, t.label AS tablelabel, t.db_table_name FROM #__fabrik_elements AS el " .
  1613. "LEFT JOIN #__fabrik_formgroup AS fg
  1614. ON fg.group_id = el.group_id
  1615. LEFT JOIN #__fabrik_forms AS f
  1616. ON f.id = fg.form_id
  1617. LEFT JOIN #__fabrik_tables AS t
  1618. ON t.form_id = f.id " .
  1619. "WHERE " .
  1620. " plugin = 'fabrikDatabasejoin' AND" .
  1621. " el.attribs like '%join_db_name=".$table->db_table_name."%' " .
  1622. "AND el.attribs like '%join_conn_id=".$table->connection_id."%' ";
  1623. $db->setQuery( $sql );
  1624. $this->_joinsToThisKey = $db->loadObjectList( );
  1625. }
  1626. }
  1627. return $this->_joinsToThisKey;
  1628. }
  1629. /**
  1630. * get an array of elements that point to a form where their data will be filtered
  1631. * @return array
  1632. */
  1633. function getLinksToThisKey()
  1634. {
  1635. $params =& $this->getParams();
  1636. $aExisitngLinked = $params->get( 'linkedform', '', '_default', 'array' );
  1637. $aAllJoinsToThisKey = $this->getJoinsToThisKey( );
  1638. $aJoinsToThisKey= array();
  1639. foreach ( $aAllJoinsToThisKey as $join ) {
  1640. if ( in_array( $join->db_table_name, $aExisitngLinked )){
  1641. $aJoinsToThisKey[] = $join;
  1642. } else {
  1643. $aJoinsToThisKey[] = '';
  1644. }
  1645. }
  1646. return $aJoinsToThisKey;
  1647. }
  1648. /**
  1649. * creates an array of html code for each filter
  1650. * @param object database
  1651. * @param string table name
  1652. * @param array current filter states
  1653. * @return array of html code for each filter
  1654. */
  1655. function &makeFilters( )
  1656. {
  1657. $aFilters = array();
  1658. $this->getFilterArray( );
  1659. $form =& $this->getForm();
  1660. $table =& $this->getTable();
  1661. foreach ($form->_groups as $k => $val) {
  1662. $groupModel =& $form->_groups[$k];
  1663. foreach ($groupModel->_aElements as $kk => $val2) {
  1664. $elementModel = $groupModel->_aElements[$kk]; //dont do with =& as this foobars up the last elementMOdel
  1665. $element =& $elementModel->getElement();
  1666. if ($element->filter_type <> '') {
  1667. if ($elementModel->canView() && $elementModel->canUseFilter() && $element->show_in_table_summary == '1' ) {
  1668. //force the correct group model into the element model to ensure no wierdness in getting the element name
  1669. $elementModel->_group =& $groupModel;
  1670. $aFilters[$element->label] = $elementModel->getFilter( );
  1671. }
  1672. }
  1673. }
  1674. }
  1675. //check for search form filters - if they exists create hidden elements for them
  1676. foreach( $this->_aFilter as $key=>$f) {
  1677. if ($f['no-filter-setup']) {
  1678. $name = str_replace('.', '___', $key) . "[value]";
  1679. $aFilters[$f['ellabel']] = "<input class='fabrik_filter' type='hidden' name='$name' value='" . $f['filterVal'] . "' />" . $f['filterVal'];
  1680. }
  1681. }
  1682. //new moved advanced filters to table settings
  1683. $params =& $this->getParams();
  1684. if ($params->get( 'advanced-filter', '0' )) {
  1685. $fieldNames[] = JHTML::_( 'select.option', '', JText::_( 'Please select' ) );
  1686. $longLabel = false;
  1687. foreach ($form->_groups as $groupModel) {
  1688. $group =& $groupModel->getGroup();
  1689. if ($group->is_join) {
  1690. $longLabel = true;
  1691. }
  1692. }
  1693. foreach ($form->_groups as $groupModel) {
  1694. foreach ($groupModel->_aElements as $elementModel) {
  1695. $element =& $elementModel->getElement();
  1696. $elParams =& $elementModel->getParams();
  1697. if ($elParams->get('inc_in_adv_search', 1)) {
  1698. $elName = $elementModel->getFullName( false, false, false );
  1699. //@TODO add a switch to use $elName as the label??
  1700. $l = $longLabel ? $elName : $element->label;
  1701. $fieldNames[] = JHTML::_( 'select.option', $elName, $l );
  1702. }
  1703. }
  1704. }
  1705. $fields = FastJSON::encode($fieldNames);
  1706. //todo: make database join elements filtereable on all their join table's fields
  1707. $advancedFilters = JRequest::getVar( 'advancedFilterContainer', array(), 'default', 'none', 2 );
  1708. $document =& JFactory::getDocument();
  1709. FabrikHelperHTML::mocha( 'a.popupwin' );
  1710. $url = '#';
  1711. $advancedSearch = '<a rel="{\'id\':\'advanced-search-win\',\'width\':690,\'loadMethod\':\'html\', \'title\':\'' . JText::_('Advanced search') . '\', \'maximizable\':\'1\',\'contentType\':\'html\'}" href="'. $url.'" class="popupwin">'. JText::_('Advanced search') .'</a>';
  1712. $aWords = (array_key_exists( 'value', $advancedFilters )) ? explode( " ", $advancedFilters['value'] ) : array('');
  1713. if (!($aWords[0] == "AND" || $aWords[0] == "OR" )) {
  1714. array_unshift( $aWords, "AND" );
  1715. }
  1716. $aGroupedAdvFilters = array();
  1717. $g = 0;
  1718. $tmp = array();
  1719. foreach ($aWords as $word) {
  1720. $tmp[] = $word;
  1721. if ($g == 3) {
  1722. $aGroupedAdvFilters[] = $tmp;
  1723. $tmp = array();
  1724. $g = 0;
  1725. } else {
  1726. $g ++;
  1727. }
  1728. }
  1729. $searchOpts = "$fields, ";
  1730. $searchOpts .= empty($aGroupedAdvFilters) ? 'true' : 'false';
  1731. $searchOpts .= ( $table->filter_action != 'submitform') ? ', true' : ', false';
  1732. $searchOpts .=",{
  1733. tableid:'$table->id'
  1734. }";
  1735. $script = "mochaSearch.conf($searchOpts);";
  1736. foreach ($aGroupedAdvFilters as $bits) {
  1737. $selJoin = $bits[0];
  1738. if ($bits[0] != "AND" && $bits[0] != "OR") {
  1739. array_unshift($bits, "WHERE");
  1740. }
  1741. $selJoin = $bits[0];
  1742. $selFilter = $bits[1];
  1743. $selCondition = $bits[2];
  1744. $selValue = $bits[3];
  1745. switch( $selCondition )
  1746. {
  1747. case "<>":
  1748. $jsSel = 'NOT EQUALS';
  1749. break;
  1750. case "=":
  1751. $jsSel = 'EQUALS';
  1752. break;
  1753. case "<":
  1754. $jsSel = 'LESS THAN';
  1755. break;
  1756. case ">":
  1757. $jsSel = 'GREATER THAN';
  1758. break;
  1759. default:
  1760. $firstChar = substr( $selValue, 1, 1 );
  1761. $lastChar = substr( $selValue, -2, 1 );
  1762. switch( $firstChar )
  1763. {
  1764. case "%":
  1765. $jsSel =( $lastChar == "%")? 'CONTAINS' : $jsSel = 'ENDS WITH';
  1766. break;
  1767. default:
  1768. if( $lastChar == "%"){
  1769. $jsSel = 'BEGINS WITH';
  1770. }
  1771. break;
  1772. }
  1773. break;
  1774. }
  1775. $selValue = trim( trim( $selValue, '"' ), "%" );
  1776. $script .= "\n mochaSearch.addFilterOption('$selJoin', '$selFilter', '$jsSel', '$selValue');\n";
  1777. }
  1778. $document->addScriptDeclaration( $script );
  1779. $aFilters[''] = $advancedSearch . "<input type='hidden' name=\"advancedFilterContainer[value]\" value='' id=\"advancedFilterContainer\" />";
  1780. }
  1781. return $aFilters;
  1782. }
  1783. /**
  1784. * returns the table headings, seperated from writetable function as
  1785. * when group_by is selected mutliple tables are written
  1786. * @return array (table headings, array columns, $aLinkElements)
  1787. */
  1788. function _getTableHeadings( )
  1789. {
  1790. global $mainframe;
  1791. $table =& $this->getTable();
  1792. $aLinkElements = array();
  1793. $aNamedTableHeadings = array( );
  1794. $aTableHeadings = array();
  1795. $aCols = array();
  1796. $session =& JFactory::getSession();
  1797. //$session->destroy();
  1798. $formModel =& $this->getForm();
  1799. foreach ($formModel->_groups as $groupModel) {
  1800. foreach ($groupModel->_aElements as $key => $elementModel) {
  1801. $viewLinkAdded = false;
  1802. $element =& $elementModel->getElement();
  1803. if (!$element->show_in_table_summary) {
  1804. continue;
  1805. }
  1806. //hide any elements that should not be access by the user for their group id
  1807. if (!$elementModel->canView( )) {
  1808. continue;
  1809. }
  1810. $key = $elementModel->getFullName( false, true, false );
  1811. $orderKey = $elementModel->getOrderbyFullName( false, false );
  1812. $aCols[$key] = '';
  1813. if ($element->link_to_detail == '1') {
  1814. $aLinkElements[] = $key;
  1815. }
  1816. if ($element->can_order == '1' && $this->_outPutFormat != 'csv' ) {
  1817. $context = 'com_fabrik.table.' . $this->_id . '.order.' . $key;
  1818. $orderDir = $session->get( $context );
  1819. $class = "";
  1820. $currentOrderDir = $orderDir;
  1821. switch ($orderDir) {
  1822. case "desc":
  1823. $orderDir = "-";
  1824. $class = "class='fabrikorder-desc'";
  1825. break;
  1826. case "asc":
  1827. $orderDir = "desc";
  1828. $class = "class='fabrikorder-asc'";
  1829. break;
  1830. case "":
  1831. case "-":
  1832. $orderDir = "asc";
  1833. $class = "class='fabrikorder'";
  1834. break;
  1835. }
  1836. if ($class == '') {
  1837. if ($table->order_by == $key) {
  1838. if (strtolower( $table->order_dir ) == 'desc') {
  1839. $class = "class='fabrikorder-desc'";
  1840. }
  1841. }
  1842. }
  1843. $orderjs = "oPackage.fabrikNavOrder( $table->id, ";
  1844. $heading = "<a $class href='#'>$element->label</a>";
  1845. } else {
  1846. $heading = $element->label;
  1847. }
  1848. $aTableHeadings[$key] = $heading;
  1849. $aNamedTableHeadings[$key . "_heading"] = $heading;
  1850. }
  1851. }
  1852. if ( $this->_outPutFormat != 'pdf' && $this->_outPutFormat != 'csv' ){
  1853. if ($this->canDelete()) {
  1854. $delete = '<label><input type="checkbox" id="table_' . $this->_id . '_checkAll" />' . JText::_('Delete') . "</label>";
  1855. $aTableHeadings['fabrik_delete'] = $delete;
  1856. $aNamedTableHeadings['fabrik_delete_heading'] = $delete;
  1857. }
  1858. //if no elements linking to the edit form add in a edit column (only if we have the right to edit/view of course!)
  1859. if (empty( $aLinkElements ) and ($this->canView() || $this->canEdit())) {
  1860. if ($this->canEdit()) {
  1861. $aTableHeadings['fabrik_edit'] = JText::_('Edit');
  1862. $aNamedTableHeadings['fabrik_edit_heading'] = JText::_('Edit');
  1863. } else {
  1864. if ($this->canViewDetails()) {
  1865. $aTableHeadings['fabrik_edit'] = 'View';
  1866. $viewLinkAdded = true;
  1867. $aNamedTableHeadings['fabrik_edit_heading'] = JText::_('View');
  1868. }
  1869. }
  1870. }
  1871. if ($this->canViewDetails() && $this->_params->get( 'detaillink' ) == '1' && !$viewLinkAdded ) {
  1872. $aTableHeadings['__details_link'] = JText::_( 'View' );
  1873. $aNamedTableHeadings['__details_link'] = JText::_( 'View' );
  1874. }
  1875. // create columns containing links which point to tables associated with this table
  1876. $params =& $this->getParams();
  1877. $aExisitngLinkedTables = $params->get('linkedtable', '', '_default', 'array');
  1878. $aExistingTableHeaders = $params->get( 'linkedtableheader', '', '_default', 'array' );
  1879. $joinsToThisKey = $this->getJoinsToThisKey( );
  1880. $f = 0;
  1881. foreach ($joinsToThisKey as $element) {
  1882. if (is_object( $element )) {
  1883. $linkedTable = array_key_exists( $f, $aExisitngLinkedTables ) ? $aExisitngLinkedTables[$f] : false;
  1884. $heading = array_key_exists( $f, $aExistingTableHeaders ) ? $aExistingTableHeaders[$f] : false;
  1885. if ($linkedTable != '0') {
  1886. $prefix = ( $element->tablelabel == $table->label ) ? $table->db_primary_key : $element->db_table_name . "___" . $element->name;
  1887. $aTableHeadings[$prefix . "_table_heading"] = empty($heading) ? $element->tablelabel . " " . JText::_('Table') : $heading;
  1888. $aNamedTableHeadings[ $prefix . "_table_heading"] = empty($heading) ? $element->tablelabel . " " . JText::_('Table') : $heading;
  1889. }
  1890. }
  1891. $f ++;
  1892. }
  1893. $linksToForms = $this->getLinksToThisKey( );
  1894. $aExisitngLinkedForms = $params->get( 'linkedform', '', '_default', 'array' );
  1895. $aExistingFormHeaders = $params->get( 'linkedformheader', '_default', '', 'array' );
  1896. $f = 0;
  1897. foreach ($linksToForms as $element ) {
  1898. $linkedForm = array_key_exists( $f, $aExisitngLinkedForms ) ? $aExisitngLinkedForms[$f] : false;
  1899. if ($linkedForm != '0') {
  1900. $heading = array_key_exists( $f, $aExistingFormHeaders ) ? $aExistingFormHeaders[$f] : '';
  1901. $prefix = $element->db_table_name . "___" . $element->name;
  1902. $aTableHeadings[$prefix . "_form_heading"] = empty($heading) ? $element->tablelabel . " " . JText::_('Form') : $heading;
  1903. $aNamedTableHeadings[ $prefix . "_form_heading"] = empty($heading) ? $element->tablelabel . " " . JText::_('Form') : $heading ;
  1904. }
  1905. $f ++;
  1906. }
  1907. }
  1908. return array( $aTableHeadings, $aCols, $aLinkElements, $aNamedTableHeadings );
  1909. }
  1910. /**
  1911. * return mathematical column calculations (run at doCalculations() on for submission)
  1912. */
  1913. function getCalculations( ){
  1914. $user = &JFactory::getUser();
  1915. $aCalculations = array();
  1916. $formModel =& $this->getForm();
  1917. $aAvgs = array();
  1918. $aSums = array();
  1919. $aMedians = array();
  1920. $aCounts = array();
  1921. if ( !is_array($formModel->_groups ) ){
  1922. $formModel->getGroupsHiarachy( );
  1923. }
  1924. if ( is_array( $formModel->_groups ) ){
  1925. foreach ($formModel->_groups as $groupModel ){
  1926. if ( is_array( $groupModel->_aElements ) ){
  1927. foreach( $groupModel->_aElements as $elementModel ){
  1928. $params = $elementModel->getParams();
  1929. $elName = $elementModel->getFullName( false, true, false );
  1930. $sum = $params->get( 'sum_on', '0' );
  1931. $avg = $params->get( 'avg_on', '0' );
  1932. $median = $params->get( 'median_on', '0' );
  1933. $countOn = $params->get( 'count_on', '0' );
  1934. $sumAccess = $params->get( 'sum_access', 0 );
  1935. $avgAccess = $params->get( 'avg_access', 0 );
  1936. $medianAccess = $params->get( 'median_access', 0 );
  1937. $countAccess = $params->get( 'count_access', 0 );
  1938. if ($sumAccess <= $user->get('gid') && $params->get('sum_value', '') != ''){
  1939. $aSums[ $elName ] = $params->get('sum_value', '');
  1940. $aSums[ $elName . "_obj" ] = unserialize($params->get('sum_value_serialized'));
  1941. }
  1942. if ($avgAccess <= $user->get('gid') && $params->get('avg_value', '') != ''){
  1943. $aAvgs[ $elName ] = $params->get('avg_value', '');
  1944. $aSums[ $elName . "_obj" ] = unserialize($params->get('avg_value_serialized'));
  1945. }
  1946. if ($medianAccess <= $user->get('gid') && $params->get('median_value', '') != ''){
  1947. $aMedians[ $elName ] = $params->get('median_value', '');
  1948. }
  1949. if ($countAccess <= $user->get('gid') && $params->get('count_value', '') != ''){
  1950. $aCounts[ $elName ] = $params->get('count_value', '');
  1951. $aSums[ $elName . "_obj" ] = unserialize($params->get('count_value_serialized'));
  1952. }
  1953. }
  1954. }
  1955. }
  1956. }
  1957. $aCalculations['sums'] = $aSums;
  1958. $aCalculations['avgs'] = $aAvgs;
  1959. $aCalculations['medians'] = $aMedians;
  1960. $aCalculations['count'] = $aCounts;
  1961. $this->_aRunCalculations =& $aCalculations;
  1962. return $aCalculations;
  1963. }
  1964. /**
  1965. * get table headings to pass into table js oject
  1966. *
  1967. * @return string headings tablename___name
  1968. */
  1969. function _jsonHeadings()
  1970. {
  1971. $aHeadings = array();
  1972. $table =& $this->getTable();
  1973. $formModel =& $this->getForm();
  1974. foreach ($formModel->_groups as $groupModel) {
  1975. foreach ($groupModel->_aElements as $elementModel) {
  1976. $element =& $elementModel->getElement();
  1977. if ($element->show_in_table_summary) {
  1978. $aHeadings[] = $table->db_table_name . '___' . $element->name;
  1979. }
  1980. }
  1981. }
  1982. return "['" . implode("','", $aHeadings) . "']";
  1983. }
  1984. /**
  1985. * when form saved (and set to record in database)
  1986. * this is run to see if there is any table join data, if there is it stores it in $this->_joinsToProcess
  1987. *
  1988. * @param array form post data
  1989. * @param int row id (of main database table atm - need to test this out)
  1990. * @param string to split up table___col data with
  1991. * @return array [joinid] = array(join, group array);
  1992. */
  1993. function preProcessJoin( $aData, $rowId, $split='___' )
  1994. {
  1995. $this->_joinsToProcess = array( );
  1996. $formModel = $this->getForm( );
  1997. if (!is_array( $formModel->_groups )) {
  1998. $formModel->getGroupsHiarachy( );
  1999. }
  2000. $aJoinGroups = array( );
  2001. foreach ($formModel->_groups as $groupModel) {
  2002. $group =& $groupModel->getGroup();
  2003. if ($group->is_join) {
  2004. $joinModel =& JModel::getInstance( 'Join', 'FabrikModel' );
  2005. $join = $joinModel->loadFromGroupId( $group->id, $this->_id );
  2006. if (!array_key_exists( $join->id, $aJoinGroups )) {
  2007. $aJoinGroups[$join->id] = array("join"=>$join, "groups"=>array($groupModel));
  2008. } else {
  2009. $aJoinGroups[$join->id]["groups"][] = $groupModel;
  2010. }
  2011. }
  2012. }
  2013. return $aJoinGroups;
  2014. }
  2015. /**
  2016. * check to see if a table exists
  2017. * @param string name of table (ovewrites form_id val to test)
  2018. * @param object database that contains the table if null then default $db object used
  2019. * @return boolean false if no table fodund true if table found
  2020. */
  2021. function databaseTableExists( $tableName = null, $fabrikDatabase = null ){
  2022. $db =& $this->getDb();
  2023. if ($tableName === '') {
  2024. return false;
  2025. }
  2026. $table =& $this->getTable();
  2027. if (is_null( $tableName )) {
  2028. $tableName = $table->db_table_name;
  2029. }
  2030. $sql = "SHOW TABLES LIKE '$tableName'";
  2031. /* use the default Joomla database if no table database specified */
  2032. if (is_null( $fabrikDatabase ) || !is_object( $fabrikDatabase )) {
  2033. $fabrikDatabase = $this->getDb();
  2034. }
  2035. $fabrikDatabase->setQuery( $sql );
  2036. $total = $fabrikDatabase->loadResult();
  2037. if ($total == "") {
  2038. return false;
  2039. } else {
  2040. return true;
  2041. }
  2042. }
  2043. /**
  2044. * strip the table names from the front of the key
  2045. * @param array data to strip
  2046. * @return array stripped data
  2047. */
  2048. function removeTableNameFromSaveData( $data, $split='___' ){
  2049. foreach ($data as $key=>$val) {
  2050. $akey = explode( $split, $key);
  2051. if (count($akey) > 1) {
  2052. $newKey = $akey[1];
  2053. unset($data[$key]);
  2054. } else {
  2055. $newKey = $akey[0];
  2056. }
  2057. $data[$newKey] = $val;
  2058. }
  2059. return $data;
  2060. }
  2061. /**
  2062. * saves posted form data into a table, you can supply table name etc to override the objects
  2063. * variables, this is needed to allow form class to use this object to save to a database table
  2064. * that doesnt have a table view associated with it
  2065. * @param array data to save
  2066. * @param int row id to edit/updated
  2067. * @param bol is the data being saved into a join table
  2068. * @param string table name (optional - if not supplied uses the objects db_table_name
  2069. * @return bol true if saved ok
  2070. */
  2071. function storeRow( $data, $rowId, $isJoin = false, $table = null )
  2072. {
  2073. //dont save a record if no data collected
  2074. if ($isJoin && implode( $data ) == '') {
  2075. return;
  2076. }
  2077. $fabrikDb =& $this->getDb();
  2078. if (is_null( $table )) {
  2079. $table = $this->_table->db_table_name;
  2080. }
  2081. FabrikString::safeColName( $table );
  2082. $formModel =& $this->getForm();
  2083. if ($isJoin) {
  2084. $this->getFormGroupElementData( false, false );
  2085. }
  2086. $oRecord = new stdClass();
  2087. $noRepeatFields = array();
  2088. $c = 0;
  2089. foreach ($formModel->_groups as $groupModel) {
  2090. $group =& $groupModel->getGroup();
  2091. if (($isJoin && $group->is_join) || (!$isJoin && !$group->is_join)) {
  2092. foreach ($groupModel->_aElements as $elementModel) {
  2093. $element = $elementModel->getElement();
  2094. $key = $element->name;
  2095. if ($elementModel->recordInDatabase( $data )) {
  2096. if (array_key_exists( $key, $data ) && !in_array( $key, $noRepeatFields )) {
  2097. $noRepeatFields[] = $key;
  2098. $lastKey = $key;
  2099. $oRecord->$key = $elementModel->storeDatabaseFormat( $data[$key], $data, $key );
  2100. $c++;
  2101. }
  2102. }
  2103. }
  2104. }
  2105. }
  2106. $primaryKey = $this->_shortKey();
  2107. if ($rowId != '' && $c == 1 && $lastKey == $primaryKey) {
  2108. return;
  2109. }
  2110. if($isJoin){
  2111. // echo trim( $primaryKey, '`' ). " $table ";print_r($oRecord);exit;
  2112. }
  2113. if ($rowId == '' || $rowId == 0) {
  2114. $ok = $fabrikDb->insertObject( $table, $oRecord, trim( $primaryKey, '`' ), false );
  2115. } else {
  2116. $ok = $fabrikDb->updateObject( $table, $oRecord, trim( $primaryKey, '`' ), false );
  2117. }
  2118. $this->_tmpSQL = $fabrikDb->getQuery();
  2119. if (!$ok) {
  2120. return JError::raiseWarning( 500, 'Store row failed: ' . $fabrikDb->getQuery() ) ;
  2121. } else {
  2122. $this->_lastInsertId = $fabrikDb->insertid() ;
  2123. return true;
  2124. }
  2125. }
  2126. /**
  2127. * get the short version of the primary key, e.g if key = table.key return "key"
  2128. *
  2129. * @return string short version of the primary key
  2130. */
  2131. function _shortKey( $key = null, $removeQuotes = false ){
  2132. if (is_null( $key )) {
  2133. $key = $this->_table->db_primary_key;
  2134. }
  2135. if (strstr( $key, "." )) {
  2136. $bits = explode( ".", $key );
  2137. $key = array_pop( $bits );
  2138. }
  2139. if($removeQuotes){
  2140. $key = str_replace("`", "", $key );
  2141. }
  2142. return $key;
  2143. }
  2144. /**
  2145. * called when the form is submitted to perform calculations
  2146. */
  2147. function doCalculations()
  2148. {
  2149. $db =& JFactory::getDBO();
  2150. $formModel =& $this->getForm();
  2151. if (!is_array( $formModel->_groups )) {
  2152. $formModel->getGroupsHiarachy( );
  2153. }
  2154. foreach ($formModel->_groups as $groupModel) {
  2155. foreach ($groupModel->_aElements as $elementModel) {
  2156. $params =& $elementModel->getParams();
  2157. $update = false;
  2158. if ($params->get( 'sum_on', 0 )) {
  2159. $aSumCals = $elementModel->sum( $this );
  2160. $params->set( 'sum_value_serialized', serialize( $aSumCals[1] ) );
  2161. $params->set( 'sum_value', $aSumCals[0] );
  2162. $update = true;
  2163. }
  2164. if ($params->get( 'avg_on', 0 )) {
  2165. $aAvgCals = $elementModel->avg( $this );
  2166. $params->set( 'avg_value_serialized', serialize( $aAvgCals[1] ) );
  2167. $params->set( 'avg_value', $aAvgCals[0] );
  2168. $update = true;
  2169. }
  2170. if ($params->get( 'median_on', 0 )) {
  2171. $params->set( 'median_value', $this->median( $elementModel->median( $this ) ));
  2172. $update = true;
  2173. }
  2174. if ($params->get( 'count_on', 0 )) {
  2175. $aCountCals = $elementModel->avg( $this );
  2176. $params->set( 'count_value_serialized', serialize( $aCountCals[1] ) );
  2177. $params->set( 'count_value', $aCountCals[0] );
  2178. $update = true;
  2179. }
  2180. if ($update) {
  2181. $element =& $elementModel->getElement();
  2182. $element->attribs = $params->updateAttribsFromParams( $params->toArray() );
  2183. $element->store();
  2184. }
  2185. }
  2186. }
  2187. }
  2188. /**
  2189. * calculate the median of an array of data values
  2190. * @param array data to use
  2191. * @return int median value
  2192. */
  2193. function median( $aData ){
  2194. sort( $aData );
  2195. if ((count( $aData ) % 2)==1){
  2196. /* odd */
  2197. $midKey = floor( count( $aData ) / 2);
  2198. return $aData[$midKey];
  2199. } else {
  2200. $midKey = floor( count( $aData ) / 2) - 1;
  2201. $midKey2 = floor( count( $aData ) / 2) ;
  2202. return ($aData[$midKey] + $aData[$midKey2]) / 2;
  2203. }
  2204. }
  2205. /**
  2206. * check to see if prefilter should be applied
  2207. * Kind of an inverse access lookup
  2208. * @param int group id to check against
  2209. * @param string ref for filter
  2210. * @return bol must apply filter - true, ignore filter (user has enough access rights) false;
  2211. */
  2212. function mustApplyFilter( $gid, $ref )
  2213. {
  2214. $user =& JFactory::getUser();
  2215. $acl =& JFactory::getACL();
  2216. if ($user->get( 'gid' ) == 0 || $gid == 100 ) {
  2217. return true;
  2218. }
  2219. $groupNames = FabrikWorker::getACLGroups( $gid, '<=' );
  2220. foreach ($groupNames as $name) {
  2221. FabrikWorker::setACL( 'action', 'prefilter' . $ref, 'fabrik', $name, 'components', null );
  2222. }
  2223. if ($acl->acl_check( 'action', 'prefilter' . $ref, 'fabrik', $user->get('usertype'), 'components', null )) {
  2224. return true;
  2225. } else {
  2226. return false;
  2227. }
  2228. }
  2229. /**
  2230. * set the connection id - used when creating a new table
  2231. * @param int connection id
  2232. */
  2233. function setConnectionId( $id )
  2234. {
  2235. $this->_table->connection_id = $id;
  2236. }
  2237. /**
  2238. * run each time a table is saved (plus when an element is saved )
  2239. * builds the sql query that the table getData function will use
  2240. * stores it in the cache/fabrik folder
  2241. * retrieved by getData when table rendered
  2242. */
  2243. function createCacheQuery()
  2244. {
  2245. $q = $this->_buildQuery();
  2246. $cache = &JFactory::getCache( 'com_fabrik' );
  2247. $cache->store( $q, 'tablequery' . $this->_id );
  2248. }
  2249. /**
  2250. * return the default set of attributes when creating a new
  2251. * fabrik table
  2252. *
  2253. * @return string attributes
  2254. */
  2255. function getDefaultAttribs()
  2256. {
  2257. return "detaillink=0
  2258. empty_data_msg=
  2259. advanced-filter=0
  2260. show-table-nav=1
  2261. pdf=
  2262. rss=0
  2263. feed_title=
  2264. feed_date=
  2265. rsslimit=150
  2266. rsslimitmax=2500
  2267. csv_import_frontend=0
  2268. csv_export_frontend=0
  2269. csvfullname=0
  2270. access=0
  2271. allow_view_details=0
  2272. allow_edit_details=0
  2273. allow_add=0
  2274. allow_delete=0
  2275. group_by_order=
  2276. group_by_order_dir=ASC
  2277. prefilter_query=";
  2278. }
  2279. /**
  2280. * save the table from admin
  2281. *
  2282. * @return bol true if saved ok
  2283. */
  2284. function save( )
  2285. {
  2286. $db =& JFactory::getDBO();
  2287. $user =& JFactory::getUser();
  2288. $config =& JFactory::getConfig();
  2289. $id = JRequest::getInt( 'id', 0, 'post' );
  2290. $this->setId( $id );
  2291. $row =& $this->getTable();
  2292. $formModel =& JModel::getInstance( 'Form', 'FabrikModel' );
  2293. $post = JRequest::get( 'post' );
  2294. if (!$row->bind( $post )) {
  2295. return JError::raiseWarning( 500, $row->getError() );
  2296. }
  2297. $filter = new JFilterInput( null, null, 1, 1 );
  2298. $introduction = JRequest::getVar( 'introduction', '', 'post', 'string', JREQUEST_ALLOWRAW );
  2299. $row->introduction =$filter->clean( $introduction );
  2300. $details = JRequest::getVar( 'details', array(), 'post', 'array' );
  2301. $row->bind( $details );
  2302. if ($id == 0) {
  2303. $newtable = trim( JRequest::getVar( '_database_name', '', 'post' ));
  2304. //check the entered database table doesnt already exist
  2305. if ($newtable != '' && $this->databaseTableExists( $newtable )) {
  2306. return JError::raiseWarning( 500, JText::_( 'Database table already exists' ) );
  2307. }
  2308. //create fabrik form
  2309. $formModel =& $this->_createLinkedForm( );
  2310. //create fabrik group
  2311. $groupData = array( "name" => $row->label , "label" => $row->label );
  2312. JRequest::setVar( '_createGroup', 1, 'post' );
  2313. $groupId = $this->_createLinkedGroup( $groupData, false );
  2314. if ($newtable != '') {
  2315. $connectionModel =& JModel::getInstance( 'Connection', 'FabrikModel' );
  2316. $connectionModel->setId( JRequest::getInt( 'connection_id', -1, 'post' ) );
  2317. $fabrikDb =& $connectionModel->getDb();
  2318. //update some default table values
  2319. $row->db_table_name = $newtable;
  2320. $row->db_primary_key = "`".$newtable.'`.`fabrik_internal_id`';
  2321. $row->auto_inc = 1;
  2322. $this->createDBTable( $formModel, $newtable, $fabrikDb );
  2323. } else {
  2324. //new fabrik table but existing db table
  2325. $this->_createLinkedElements( $groupId, $post );
  2326. }
  2327. // set the tables form id
  2328. $this->_updateFormId( $formModel->_form->id );
  2329. }
  2330. // save params - this file no longer exists? do we use models/table.xml instead??
  2331. $params = new fabrikParams( $row->attribs, JPATH_COMPONENT.DS.'xml'.DS.'table.xml' );
  2332. $row->attribs = $params->updateAttribsFromParams( JRequest::getVar( 'params', array(), 'post', 'array' ) );
  2333. $row->rows_per_page = JRequest::getInt( 'rows_per_page', 10, 'post' );
  2334. $row->auto_inc = JRequest::getInt( 'auto_inc', 1, 'post' );
  2335. FabrikHelperFabrik::publishDown( $row->publish_down );
  2336. $pk = JRequest::getVar( 'db_primary_key' );
  2337. if ($pk == '') {
  2338. $aKey = $this->getPrimaryKeyAndExtra();
  2339. $row->db_primary_key = "`".$row->db_table_name . "`.`" . $aKey['colname'] . "`";
  2340. }
  2341. if (!strstr( $row->order_by, $row->db_table_name . "___" )) {
  2342. $row->order_by = $row->db_table_name . "___" . $row->order_by;
  2343. }
  2344. if (!$row->store( )) {
  2345. return JError::raiseWarning( 500, $row->getError() );
  2346. }
  2347. // load in all the tables data - even if it wasnt in the post data
  2348. $table =& $this->getTable();
  2349. //needed if saving a table for first time (otherwise id = 0)
  2350. $this->setId( $table->id );
  2351. $this->updateJoins( );
  2352. if (!$this->isView()) {
  2353. // this was only run on a new table - but I've put it here so that if you upload a new table you can ensure that its columns are fixed
  2354. $this->makeSafeTableColumns( );
  2355. $this->updatePrimaryKey( $row->db_primary_key, $row->auto_inc );
  2356. }
  2357. $row->checkin( );
  2358. $this->createCacheQuery();
  2359. return true;
  2360. }
  2361. /**
  2362. * when saving a table that links to a database for the first time we
  2363. * automatically create a form to allow the update/creation of that tables
  2364. * records
  2365. * @access private
  2366. * @return object form model
  2367. */
  2368. function &_createLinkedForm( )
  2369. {
  2370. $config =& JFactory::getConfig();
  2371. $user =& JFactory::getUser();
  2372. jimport('joomla.utilities.date');
  2373. $createdate =& JFactory::getDate();
  2374. $createdate = $createdate->toMySQL();
  2375. $form = JTable::getInstance( 'Form', 'Table' );
  2376. $table =& $this->getTable();
  2377. $form->label = $table->label;
  2378. $form->record_in_database = 1;
  2379. $form->created = $createdate;
  2380. $form->created_by = $user->get( 'id' );
  2381. $form->created_by_alias = $user->get( 'username' );
  2382. $form->error = JText::_( 'Some parts of your form have not been fully filled in, please check the specific error messages below and try again' );
  2383. // @TODO : fabrik : 0.5 : create a overall fabrik params admin page
  2384. //which sets the default settings for all forms, from which these settings below can be populated
  2385. $form->submit_button_label = JText::_( 'Save' );
  2386. $form->state = $table->state;
  2387. $form->form_template = 'default';
  2388. $form->view_only_template = 'default';
  2389. if(! $form->store() ){
  2390. return JError::raiseError( 500, $form->getError() );
  2391. }
  2392. $this->_oForm =& JModel::getInstance( 'Form', 'FabrikModel' );
  2393. $this->_oForm->setId( $form->id );
  2394. $this->_oForm->getForm();
  2395. return $this->_oForm;
  2396. }
  2397. /**
  2398. * create a group
  2399. * used when creating a fabrik table from an existing db table
  2400. *
  2401. * NEW also creates the formgroup
  2402. *
  2403. * @access private
  2404. * @param array group data
  2405. * @param bol is the group a join default false
  2406. * @return int group id
  2407. */
  2408. function _createLinkedGroup( $data, $isJoin = false ) {
  2409. $user =& JFactory::getUser();
  2410. //jimport( 'joomla.utilities.date' );
  2411. $createdate = JFactory::getDate();
  2412. $createdate = $createdate->toMySQL();
  2413. $group =& JTable::getInstance( 'Group', 'Table' );
  2414. $group->bind( $data );
  2415. $group->created = $createdate;
  2416. $group->created_by = $user->get('id');
  2417. $group->created_by_alias = $user->get('username');
  2418. $group->state = 1;
  2419. $group->attribs = "repeat_group_button=0
  2420. repeat_group_show_first=1
  2421. repeat_group_js_add=
  2422. repeat_group_js_delete=";
  2423. $group->is_join = ($isJoin == true) ? 1 : 0;
  2424. $group->store( );
  2425. if (!$group->store()) {
  2426. JError::raiseError( 500, $group->getError() );
  2427. }
  2428. //create form group
  2429. $formid = $this->_oForm->_id;
  2430. $formGroup = JTable::GetInstance( 'FormGroup', 'Table' );
  2431. $formGroup->form_id = $formid;
  2432. $formGroup->group_id = $group->id;
  2433. $formGroup->ordering = 999999;
  2434. if (!$formGroup->store()) {
  2435. JError::raiseError( 500, $formGroup->getError() );
  2436. }
  2437. $formGroup->reorder( " form_id = '$formid'" );
  2438. return $group->id;
  2439. }
  2440. /**
  2441. * Create a table to store the forms' data depending upon what groups are assigned to the form
  2442. * @param object form model
  2443. * @param string table name - taken from the table oject linked to the form
  2444. * @param obj tables database object
  2445. */
  2446. function createDBTable( &$formModel, $dbTableName = null, $tableDatabase = null ){
  2447. $db =& JFactory::getDBO();
  2448. if (is_null( $tableDatabase )) {
  2449. $tableDatabase = $db;
  2450. }
  2451. $user =& JFactory::getUser();
  2452. $config =& JFactory::getConfig();
  2453. if (is_null( $dbTableName )) {
  2454. $dbTableName = $this->_table->db_table_name;
  2455. }
  2456. $sql = "CREATE TABLE `$dbTableName` ( " ;
  2457. $db->setQuery( "SELECT group_id FROM #__fabrik_formgroup WHERE form_id = $formModel->_id" );
  2458. $groupIds = $db->loadResultArray( );
  2459. /* create elements for the internal id and time_date fields */
  2460. $element =& JTable::getInstance( 'Element', 'Table' );
  2461. $element->name = "fabrik_internal_id";
  2462. $element->label = "id";
  2463. $element->plugin = 'fabrikinternalid';
  2464. $element->hidden = 1;
  2465. $element->group_id = $groupIds[0];
  2466. $element->primary_key = 1;
  2467. $element->auto_increment = 1;
  2468. $element->created = JHTML::_( 'date', date( '%Y-%m-%d %H:%M:%S' ), '%Y-%m-%d %H:%M:%S', - $config->getValue( 'offset' ) );
  2469. $element->created_by = $user->get( 'id' );
  2470. $element->created_by_alias = $user->get( 'username' );
  2471. $element->state = '1';
  2472. $element->show_in_table_summary = '1';
  2473. $element->link_to_detail = '1';
  2474. $element->width = '30';
  2475. $element->ordering = 0;
  2476. if (!$element->store()) {
  2477. return JError::raiseWarning( 500, $element->getError() );
  2478. }
  2479. $element =& JTable::getInstance( 'Element', 'Table' );
  2480. $element->name = "time_date";
  2481. $element->label = "time_date";
  2482. $element->plugin = 'fabrikdate';
  2483. $element->hidden = 1;
  2484. $element->eval = 1;
  2485. $element->default = "return date('Y-m-d h:i:s');";
  2486. $element->group_id = $groupIds[0];
  2487. $element->primary_key = 0;
  2488. $element->auto_increment = 0;
  2489. $element->created = JHTML::_( 'date', date( '%Y-%m-%d %H:%M:%S' ), '%Y-%m-%d %H:%M:%S', - $config->getValue( 'offset' ) );
  2490. $element->created_by = $user->get( 'id' );
  2491. $element->created_by_alias = $user->get( 'username' );
  2492. $element->state = '1';
  2493. $element->show_in_table_summary = '1';
  2494. $element->width = '30';
  2495. $element->ordering = 1;
  2496. if (!$element->store( )) {
  2497. return JError::raiseWarning( 500, $element->getError() );
  2498. }
  2499. $formModel->_loadGroupIds();
  2500. $aGroups = $formModel->getGroupsHiarachy( false, false );
  2501. $arAddedObj = array();
  2502. //these two should be real elements not hacked in here
  2503. $pluginManager =& JModel::getInstance('Pluginmanager', 'FabrikModel');
  2504. foreach ($aGroups as $groupModel) {
  2505. foreach ($groupModel->_aElements as $obj) {
  2506. $element = $obj->getElement( );
  2507. /* replace all non alphanumeric characters with _ */
  2508. $objname = preg_replace( "/[^A-Za-z0-9]/", "_", $element->name );
  2509. /* any elements that are names the same (eg radio buttons) can not be entered twice into the database */
  2510. if (!in_array( $objname, $arAddedObj )) {
  2511. $arAddedObj[] = $objname;
  2512. $objtype = $obj->getFieldDescription();
  2513. if ($objname != "" && !is_null( $objtype )) {
  2514. if (stristr( $objtype, 'not null')) {
  2515. $sql .= " `$objname` $objtype, ";
  2516. } else {
  2517. $sql .= " `$objname` $objtype null, ";
  2518. }
  2519. }
  2520. }
  2521. }
  2522. }
  2523. $sql .= " primary key (fabrik_internal_id))";
  2524. $tableDatabase->setQuery( $sql );
  2525. if (!$tableDatabase->query()) {
  2526. return JError::raiseWarning( 500, $db->getErrorMsg() );
  2527. }
  2528. }
  2529. /**
  2530. * when saving a table that links to a database for the first time we
  2531. * need to create all the elements based on the database table fields and their
  2532. * column type
  2533. *
  2534. * @access private
  2535. * @param int group id
  2536. * @param array newly created table data
  2537. * @param array of element objects - if this is not empty then we've come from the csv import and the elements
  2538. * have already been defined, use this instead of the field analysis to create correctly typed elements
  2539. */
  2540. function _createLinkedElements( $groupId, $aTableData, $aSpecificElements = array() )
  2541. {
  2542. $db =& JFactory::getDBO();
  2543. $user = &JFactory::getUser();
  2544. $config =& JFactory::getConfig();
  2545. $createdate = JFactory::getDate();
  2546. $createdate = $createdate->toMySQL();
  2547. $tableName = JRequest::getVar( 'db_table_name' );
  2548. $ordering = 0;
  2549. $fabrikDb =& $this->getDb();
  2550. if (!empty( $aSpecificElements )) {
  2551. //we're asking the method to create predefined elements - e.g. when installing sample data.
  2552. foreach ($aSpecificElements as $elementModel) {
  2553. $element =& $element->getElement();
  2554. if ($element->label == 'id' || $element->label == 'fabrik_internal_id') {
  2555. $element->hidden = '1';
  2556. $element->primary_key = '1';
  2557. $element->auto_increment = '1';
  2558. } else {
  2559. $element->hidden = '0';
  2560. }
  2561. $element->name = strtolower(str_replace(' ', '', $element->name ));
  2562. $element->group_id = $groupId;
  2563. $element->created = $createdate;
  2564. $element->created_by = $user->get('id');
  2565. $element->created_by_alias = $user->get('username');
  2566. $element->state = '1';
  2567. $element->show_in_table_summary = '1';
  2568. $element->width = '30';
  2569. $element->height = '6';
  2570. $element->ordering = 99999;
  2571. $element->store( );
  2572. $where = " group_id = '" . $element->group_id . "'";
  2573. $element->updateOrder( $where );
  2574. }
  2575. } else {
  2576. //here we're importing directly from the database schema
  2577. $db->setQuery( "SELECT id FROM #__fabrik_tables WHERE `db_table_name` = '$tableName'" );
  2578. $id = $db->loadResult();
  2579. if ($id) {
  2580. //a fabrik table already exists - so we can copy the formatting of its elements
  2581. $groupTableModel = JModel::getInstance('table', 'FabrikModel' );
  2582. $groupTableModel->setId($id);
  2583. $table = $groupTableModel->getTable();
  2584. //$this->_oForm = null; //reset form so that it loads new table form
  2585. $groups = $groupTableModel->getFormGroupElementData( false, false );
  2586. foreach ($groups as $groupModel) {
  2587. foreach ($groupModel->_aElements as $elementModel) {
  2588. $element =& $elementModel->getElement();
  2589. $copy = $elementModel->copyRow( $element->id, '', $groupId );
  2590. }
  2591. }
  2592. } else {
  2593. $fields = $fabrikDb->getTableFields( array ("`$tableName`") );
  2594. $fields = $fields["`$tableName`"];
  2595. // no existing fabrik table so we take a guess at the most
  2596. //relavent element types to create
  2597. foreach ($fields as $label => $type) {
  2598. $element =& JTable::getInstance( 'Element', 'Table' );
  2599. $element->label = str_replace( "_", " ", $label );
  2600. switch ( $type )
  2601. {
  2602. case "int" :
  2603. case "tinyint" :
  2604. case "varchar" :
  2605. $plugin = 'fabrikfield';
  2606. break;
  2607. case "text" :
  2608. case "tinytext" :
  2609. case "mediumtext" :
  2610. case "longtext" :
  2611. $plugin = 'fabriktextarea';
  2612. break;
  2613. case "datetime" :
  2614. case "date" :
  2615. case "time" :
  2616. case "timestamp" :
  2617. $plugin = 'fabrikdate';
  2618. break;
  2619. default :
  2620. $plugin = 'fabrikfield';
  2621. break;
  2622. }
  2623. $element->plugin = $plugin;
  2624. $element->hidden = ( $element->label == 'id' )? '1' : '0';
  2625. $element->group_id = $groupId;
  2626. $element->name = $label;
  2627. $element->created = JHTML::_('date', date('%Y-%m-%d %H:%M:%S'), '%Y-%m-%d %H:%M:%S', - $config->getValue('offset'));
  2628. $element->created_by = $user->get('id');
  2629. $element->created_by_alias = $user->get('username');
  2630. $element->state = '1';
  2631. $element->show_in_table_summary = '1';
  2632. $element->width = ($plugin == 'fabriktextarea') ? '60' : '30';
  2633. $element->height = '6';
  2634. $element->ordering = $ordering;
  2635. if (!$element->store( )) {
  2636. return JError::raiseError( 500, $element->getError() );
  2637. }
  2638. $ordering ++;
  2639. }
  2640. }
  2641. }
  2642. }
  2643. /**
  2644. * updates the table record to point to the newly created form
  2645. * @params int form id
  2646. */
  2647. function _updateFormId( $formId )
  2648. {
  2649. $db =& JFactory::getDBO();
  2650. $table =& $this->getTable();
  2651. $table->form_id = $formId;
  2652. if (!$table->store()) {
  2653. return JError::raiseWarning( 500, $db->getError() );
  2654. }
  2655. }
  2656. /**
  2657. * get the tables primary key and if the primary key is auto increment
  2658. * @return mixed if ok returns array (key, extra, type, name) otherwise
  2659. * returns false
  2660. */
  2661. function getPrimaryKeyAndExtra( )
  2662. {
  2663. $origColNames = $this->getDBFields( );
  2664. if (is_array( $origColNames )) {
  2665. foreach ($origColNames as $origColName) {
  2666. $colName = $origColName->Field;
  2667. $key = $origColName->Key;
  2668. $extra = $origColName->Extra;
  2669. $type = $origColName->Type;
  2670. if ($key == "PRI") {
  2671. return array( "key"=>$key, "extra"=>$extra, "type"=>$type, "colname"=>$colName );
  2672. }
  2673. }
  2674. }
  2675. return false;
  2676. }
  2677. /**
  2678. * deals with ensuring joins are managed correctly when table is saved
  2679. */
  2680. function updateJoins( )
  2681. {
  2682. $db =& JFactory::getDBO();
  2683. // $$$rob getJoins adds in element joins as well - dont use as we can get ids to delete that
  2684. //arent table joins
  2685. //$aOldJoins = $this->getJoins( );
  2686. $db->setQuery("SELECT * FROM #__fabrik_joins WHERE table_id = '$this->_id'");
  2687. $aOldJoins = $db->loadObjectList( );
  2688. $aOldJoinsToKeep = array( );
  2689. $joinModel =& JModel::getInstance( 'Join', 'FabrikModel' );
  2690. $joinIds = JRequest::getVar( 'join_id', array(), 'post' );
  2691. $joinTypes = JRequest::getVar( 'join_type', array(), 'post' );
  2692. $joinTableFrom = JRequest::getVar( 'join_from_table', array(), 'post' );
  2693. $joinTable = JRequest::getVar( 'table_join', array(), 'post' );
  2694. $tableKey = JRequest::getVar( 'table_key', array(), 'post' );
  2695. $joinTableKey = JRequest::getVar( 'table_join_key', array(), 'post' );
  2696. $groupIds = JRequest::getVar( 'group_id', array(), 'post' );
  2697. for ($i = 0;$i < count( $joinTypes );$i++) {
  2698. $existingJoin = false;
  2699. foreach ($aOldJoins as $oOldJoin ){
  2700. if ($joinIds[$i] == $oOldJoin->id) {
  2701. $existingJoin = true;
  2702. }
  2703. }
  2704. if (!$existingJoin) {
  2705. $this->_makeNewJoin( $tableKey[$i], $joinTableKey[$i], $joinTypes[$i], $joinTable[$i], $joinTableFrom[$i] );
  2706. } else {
  2707. /* load in the exisitng join
  2708. * if the table_join has changed we need to create a new join and mark the loaded one as to be deleted
  2709. */
  2710. $joinModel->setId( $joinIds[$i] );
  2711. $join =& $joinModel->getJoin();
  2712. if ($join->table_join != $joinTable[$i]) {
  2713. $this->_makeNewJoin( $tableKey[$i], $joinTableKey[$i], $joinTypes[$i], $joinTable[$i], $joinTableFrom[$i] );
  2714. } else {
  2715. //the talbe_join has stayed the same so we simply update the join info
  2716. $join->table_key = $tableKey[$i];
  2717. $join->table_join_key = $joinTableKey[$i];
  2718. $join->join_type = $joinTypes[$i];
  2719. $join->store();
  2720. $aOldJoinsToKeep[] = $joinIds[$i];
  2721. }
  2722. }
  2723. }
  2724. /* remove non exisiting joins */
  2725. if (is_array( $aOldJoins )) {
  2726. foreach ($aOldJoins as $oOldJoin) {
  2727. if (!in_array( $oOldJoin->id, $aOldJoinsToKeep )) {
  2728. /* delete join */
  2729. $join =& JTable::getInstance( 'Join', 'Table' );
  2730. $joinModel->setId( $oOldJoin->id );
  2731. $joinModel->getJoin();
  2732. $joinModel->deleteAll( $oOldJoin->group_id );
  2733. }
  2734. }
  2735. }
  2736. }
  2737. /**
  2738. * run the prefilter sql and replace any placeholders in the subsequent prefilter
  2739. *
  2740. * @param string prefilter condition
  2741. * @return string prefilter condition
  2742. */
  2743. function _prefilterParse( $selValue )
  2744. {
  2745. $preSQL = htmlspecialchars_decode( $this->_params->get('prefilter_query'), ENT_QUOTES );
  2746. if (trim( $preSQL ) != '') {
  2747. $db =& JFactory::getDBO();
  2748. $w = new FabrikWorker();
  2749. $preSQL = $w->parseMessageForPlaceHolder( $preSQL );
  2750. $db->setQuery( $preSQL );
  2751. $q = $db->loadObject( );
  2752. }
  2753. if (isset( $q )) {
  2754. foreach ( $q as $key=>$val ) {
  2755. if (substr( $key, 0, 1 ) != '_') {
  2756. $found = false;
  2757. if (strstr( $selValue, '{$q-&gt;'. $key )) {
  2758. $found = true;
  2759. $pattern = '{$q-&gt;'. $key. "}";
  2760. }
  2761. if (strstr( $selValue, '{$q->' . $key )) {
  2762. $found = true;
  2763. $pattern = '{$q->'. $key . "}";
  2764. }
  2765. if ($found) {
  2766. $selValue = str_replace( $pattern, $val, $selValue );
  2767. }
  2768. }
  2769. }
  2770. } else {
  2771. //parse for default values only
  2772. $pattern = "/({[^}]+}).*}?/s";
  2773. $ok = preg_match( $pattern, $selValue, $matches );
  2774. foreach ($matches as $match) {
  2775. $matchx = substr( $match, 1, strlen( $match ) - 2 );
  2776. //a default option was set so lets use that
  2777. if (strstr( $matchx, '|' )) {
  2778. $bits = explode( '|', $matchx );
  2779. $selValue = str_replace( $match, $bits[1], $selValue );
  2780. }
  2781. }
  2782. }
  2783. return $selValue;
  2784. }
  2785. /**
  2786. * replaces the table column names with a safer name - ie removes white
  2787. * space and none alpha numeric characters
  2788. */
  2789. function makeSafeTableColumns()
  2790. {
  2791. $db = $this->getDb();
  2792. $table =& $this->getTable();
  2793. $origColNames = $this->getDBFields( );
  2794. foreach ($origColNames as $origColName) {
  2795. $colName = strtolower($origColName->Field);
  2796. $type = $origColName->Type;
  2797. $newColName = preg_replace("/[^A-Za-z0-9]/", "_", $colName);
  2798. if ( $colName != $newColName ) {
  2799. $sql = "ALTER TABLE `$table->db_table_name` CHANGE `$colName` `$newColName` $type";
  2800. $db->setQuery( $sql );
  2801. if (!$db->query( )) {
  2802. JError::raiseWarning( 500, $db->getErrorMsg( ));
  2803. }
  2804. }
  2805. }
  2806. }
  2807. /**
  2808. * adds a primary key to the database table
  2809. * @param string the column name to make into the primary key
  2810. * @param bol is the column an auto incrementing number
  2811. * @param string column type definition (eg varchar(255))
  2812. */
  2813. function updatePrimaryKey( $fieldName, $autoIncrement, $type = 'int(11)' )
  2814. {
  2815. $fbConfig =& JComponentHelper::getParams( 'com_fabrik' );
  2816. if (!$fbConfig->get( 'fbConf_alter_existing_db_cols' )) {
  2817. $fabrikDatabase =& $this->getDb( );
  2818. $aPriKey = $this->getPrimaryKeyAndExtra( );
  2819. if (!$aPriKey) { // no primary key set so we should set it
  2820. $this->_addKey( $fieldName, $autoIncrement, $type );
  2821. } else {
  2822. $shortKey = $this->_shortKey( $fieldName );
  2823. if ($fieldName != $aPriKey['colname'] && $shortKey != $aPriKey['colname']) {
  2824. $this->_dropKey( $aPriKey ); // primary key already exists so we should drop it
  2825. $this->_addKey( $fieldName, $autoIncrement, $aPriKey['type'] );
  2826. } else {
  2827. //update the key
  2828. $this->_updateKey( $fieldName, $autoIncrement, $type );
  2829. }
  2830. }
  2831. }
  2832. }
  2833. /**
  2834. * internal function: update an exisitng key in the table
  2835. * @param string primary key column name
  2836. * @param bol is the column auto incrementing
  2837. * @param string the primary keys column type
  2838. */
  2839. function _updateKey( $fieldName, $autoIncrement, $type = "INT(11)" ){
  2840. $db =& $this->getDb();
  2841. if(strstr($fieldName, '.')){
  2842. $fieldName = array_pop(explode(".", $fieldName));
  2843. }
  2844. $table =& $this->getTable();
  2845. $sql = "ALTER TABLE `$table->db_table_name` CHANGE `$fieldName` `$fieldName` $type NOT NULL ";
  2846. /* update primary key */
  2847. if ( $autoIncrement ){
  2848. $sql .= " AUTO_INCREMENT";
  2849. }
  2850. $db->setQuery( $sql );
  2851. if(!$db->query( )){
  2852. JError::raiseWarning( 500, 'update key:'.$db->getErrorMsg( ));
  2853. }
  2854. }
  2855. /**
  2856. * internal function: add a key to the table
  2857. * @param string primary key column name
  2858. * @param bol is the column auto incrementing
  2859. * @param string the primary keys column type
  2860. */
  2861. function _addKey( $fieldName, $autoIncrement, $type = "INT(11)" ){
  2862. $db =& $this->getDb();
  2863. $table =& $this->getTable();
  2864. if(strstr($fieldName, '.')){
  2865. $fieldName = array_pop(explode(".", $fieldName));
  2866. }
  2867. $sql = "ALTER TABLE `$table->db_table_name` ADD PRIMARY KEY ($fieldName)";
  2868. /* add a primary key */
  2869. $db->setQuery( $sql );
  2870. if(!$db->query( )){
  2871. JError::raiseWarning(500, $db->getErrorMsg( ));
  2872. }
  2873. if ( $autoIncrement ){
  2874. $sql = "ALTER TABLE `$table->db_table_name` CHANGE $fieldName $fieldName " . $type . " NOT NULL AUTO_INCREMENT"; //add the autoinc
  2875. $db->setQuery( $sql );
  2876. if (!$db->query( ) ){
  2877. return JError::raiseError( 500, 'add key: ' . $db->getErrorMsg( ));
  2878. }
  2879. }
  2880. }
  2881. /**
  2882. * internal function: drop the table's key
  2883. * @param array existing key data
  2884. * @param object fabrik database object
  2885. * @return bol true if ke droped
  2886. */
  2887. function _dropKey( $aPriKey, $fabrikDatabase ){
  2888. $db = $this->getDb();
  2889. $table =& $this->getTable();
  2890. $sql = "ALTER TABLE `$table->db_table_name` CHANGE `" . $aPriKey['colname'] . '` `'. $aPriKey['colname'] . '` ' . $aPriKey['type'] . " NOT NULL";
  2891. /* removes the autoinc */
  2892. $db->setQuery( $sql );
  2893. if(!$db->query( )){
  2894. JError::raiseWarning( 500, $db->getErrorMsg()) ;
  2895. return false;
  2896. }
  2897. $sql = "ALTER TABLE `$table->db_table_name` DROP PRIMARY KEY";
  2898. /* drops the primary key */
  2899. $db->setQuery( $sql );
  2900. if(!$db->query( )){
  2901. JError::raiseWarning( 500, 'alter table: ' . $db->getErrorMsg()) ;
  2902. return false;
  2903. }
  2904. return true;
  2905. }
  2906. /**
  2907. * deletes records from a table
  2908. * @param string key value to delete
  2909. * @param string key to use (leave empty to default to the table's key)
  2910. * @return string error message
  2911. */
  2912. function deleteTableRows( $val, $key = '' )
  2913. {
  2914. $table =& $this->getTable();
  2915. $db =& $this->getDb();
  2916. if ($key == '') {
  2917. $key = $table->db_primary_key;
  2918. if ($key == '') {
  2919. return JError::raisWarning( JText::_( "no key found for this table" ));
  2920. }
  2921. }
  2922. if (is_array( $val )) {
  2923. $c = count($val);
  2924. $val = implode("','", $val);
  2925. } else {
  2926. $c = 1;
  2927. }
  2928. //@todo: run element->onDeleteRow()
  2929. //load in rows to be deleted#
  2930. $this->_pageNav =& $this->_getPagination( $c, 0, $c );
  2931. $this->_whereSQL[true] = " WHERE " . $key . " IN ('" . $val . "')";
  2932. $rows = $this->getData( );
  2933. $this->_rowsToDelete =& $rows;
  2934. $groups = $this->getFormGroupElementData( false, false );
  2935. foreach ($groups as $group) {
  2936. foreach ($group->_aElements as $element) {
  2937. $element->onDeleteRows( $rows );
  2938. }
  2939. }
  2940. $pluginManager =& JModel::getInstance( 'Pluginmanager', 'FabrikModel' );
  2941. $pluginManager->loadPlugInGroup( 'table' );
  2942. if (!$pluginManager->runPlugins( 'onDeleteRows', $this, 'table' )) {
  2943. return;
  2944. }
  2945. $sql = "DELETE FROM `" . $table->db_table_name . "` WHERE " . $key . " IN ('" . $val . "')";
  2946. $db->setQuery( $sql );
  2947. if ( !$db->query( ) ) {
  2948. return JError::raisWarning( $db->getErrorMsg( ) );
  2949. }
  2950. return true;
  2951. }
  2952. /**
  2953. * remove all records from the table
  2954. */
  2955. function dropData()
  2956. {
  2957. $db =& $this->getDb();
  2958. $sql = "DELETE FROM " . $this->db_table_name;
  2959. $db->setQuery( $sql );
  2960. $msg= '';
  2961. if (!$db->query( )) {
  2962. return JError::raisWarning( JText::_($db->getErrorMsg( ) ));
  2963. }
  2964. return '';
  2965. }
  2966. /**
  2967. * drop the table containing the fabriktables data
  2968. */
  2969. function drop()
  2970. {
  2971. $db =& $this->getDb();
  2972. $sql = "DROP TABLE IF EXISTS `$this->db_table_name`;";
  2973. $db->setQuery( $sql );
  2974. if ( !$db->query( ) ) {
  2975. return JError::raisWarning( JText::_($db->getErrorMsg( ) ));
  2976. }
  2977. return '';
  2978. }
  2979. function truncate()
  2980. {
  2981. $db =& $this->getDb();
  2982. $table =& $this->getTable();
  2983. $db->setQuery( "TRUNCATE `$table->db_table_name`");
  2984. $db->query();
  2985. }
  2986. /**
  2987. * new join make the group, group elements and formgroup entries for the join data
  2988. * @param string table key
  2989. * @param string join to table key
  2990. * @param string join type
  2991. * @param string join to table
  2992. * @param string join table
  2993. */
  2994. function _makeNewJoin( $tableKey, $joinTableKey, $joinType, $joinTable, $joinTableFrom )
  2995. {
  2996. $db =& JFactory::getDBO();
  2997. $formModel =& $this->getForm( );
  2998. $aData = array(
  2999. "name" => $this->_table->label ."- [" .$joinTable. "]",
  3000. "label" => $joinTable,
  3001. );
  3002. $groupId = $this->_createLinkedGroup( $aData, true );
  3003. $origTable = JRequest::getVar( 'db_table_name' );
  3004. JRequest::setVar( 'db_table_name', $joinTable );
  3005. $this->_createLinkedElements( $groupId, array() );
  3006. JRequest::setVar('db_table_name', $origTable);
  3007. $join =& JTable::getInstance( 'Join', 'Table');
  3008. $join->table_id = $this->_id;
  3009. $join->join_from_table = $joinTableFrom;
  3010. $join->table_join = $joinTable;
  3011. $join->table_join_key = $joinTableKey;
  3012. $join->table_key = $tableKey;
  3013. $join->join_type = $joinTypes;
  3014. $join->group_id = $groupId;
  3015. if(!$join->store( )){
  3016. return JError::raiseWarning( 500, $join->getError() );
  3017. }
  3018. }
  3019. /**
  3020. * Alter the forms' data collection table when the forms' groups and/or
  3021. * elements are altered
  3022. * @param object form
  3023. * @param string table name
  3024. * @param object database connection object
  3025. */
  3026. function ammendTable( &$oForm, $tableName = null, $tableDatabase = null ){
  3027. $db =& JFactory::getDBO();
  3028. $user =& JFactory::getUser();
  3029. $table =& $this->getTable();
  3030. $pluginManager =& JModel::getInstance( 'Pluginmanager', 'FabrikModel' );
  3031. $ammend = false;
  3032. if (is_null( $tableName )) {
  3033. $tableName = $table->db_table_name;
  3034. }
  3035. if (is_null( $tableDatabase ) || !is_object( $tableDatabase )) {
  3036. $tableDatabase = $db;
  3037. }
  3038. $dbdescriptions = $this->getDBFields( $tableName );
  3039. //@TODO: test (was strtolower($dbdescription->Field)) if this is going to cause issues, think fields should be case insenitvely compared as some joomla core fields are mixed case
  3040. foreach ($dbdescriptions as $dbdescription) {
  3041. $exitingfields[] = ($dbdescription->Field);
  3042. }
  3043. $lastfield = $exitingfields[count($exitingfields)-1];
  3044. $sql = "ALTER TABLE `$tableName` " ;
  3045. if (!isset( $_POST['current_groups_str'] )) {
  3046. /* get a list of groups used by the form */
  3047. $groupsql = "SELECT group_id FROM #__fabrik_formgroup WHERE form_id = '" . $oForm->_id . "'";
  3048. $db->setQuery( $groupsql );
  3049. $groups = $db->loadObjectList( );
  3050. if (!$groups) {
  3051. JError::raiseWarning(500, 'ammendTable: ' . $fabrikDb->getErrorMsg( ) );
  3052. }
  3053. $arGroups = array( );
  3054. foreach ($groups as $g) {
  3055. $arGroups[] = $g->group_id;
  3056. }
  3057. } else {
  3058. $current_groups_str = JRequest::getVar( 'current_groups_str' );
  3059. $arGroups = explode( ",", $current_groups_str );
  3060. }
  3061. $arAddedObj = array();
  3062. foreach ($arGroups as $group_id) {
  3063. $group = JTable::getInstance( 'Group', 'Table' );
  3064. $group->load( $group_id );
  3065. if ($group->is_join == '0'){
  3066. $groupsql = "SELECT * FROM #__fabrik_elements WHERE group_id = '$group_id'";
  3067. $db->setQuery( $groupsql );
  3068. $elements = $db->loadObjectList( );
  3069. foreach ($elements as $obj) {
  3070. $objname = strtolower(preg_replace("/[^A-Za-z0-9]/", "_", $obj->name));
  3071. /* replace all non alphanumeric characters with _*/
  3072. if (!in_array( $objname, $exitingfields )) {
  3073. /* make sure that the object is not already in the table*/
  3074. if(!in_array( $objname, $arAddedObj )) {
  3075. /* any elements that are names the same (eg radio buttons) can not be entered twice into the database*/
  3076. $arAddedObj[] = $objname;
  3077. $objtypeid = $obj->plugin;
  3078. $pluginClassName = $obj->plugin;
  3079. $plugin = $pluginManager->loadPlugIn( $pluginClassName, 'element' );
  3080. $objtype = $plugin->getFieldDescription();
  3081. if ($objname != "" && !is_null( $objtype )) {
  3082. $ammend = true;
  3083. $sql .= ", ADD COLUMN `$objname` $objtype null AFTER `$lastfield`";
  3084. }
  3085. }
  3086. }
  3087. }
  3088. }
  3089. }
  3090. if ($ammend) {
  3091. $tableDatabase->setQuery( $sql );
  3092. if (!$tableDatabase->query()) {
  3093. return JError::raiseWarning( 500, 'amend table: ' . $tableDatabase->getErrorMsg() ) ;
  3094. }
  3095. $this->createCacheQuery();
  3096. }
  3097. }
  3098. /**
  3099. * @param int connection id to use
  3100. * @param string table to load fields for
  3101. * @param string show "please select" top option
  3102. * @param bol append field name values with table name
  3103. * @param string name of drop down
  3104. * @param string selected option
  3105. * @param string class name
  3106. * @return string html to be added to DOM
  3107. */
  3108. function getFieldsDropDown( $cnnId, $tbl, $incSelect, $incTableName = false, $selectListName = 'order_by', $selected = null, $className = "inputbox" ){
  3109. $this->setConnectionId( $cnnId );
  3110. $aFields = $this->getDBFields( $tbl );
  3111. $fieldNames = array( );
  3112. if ($incSelect != '') {
  3113. $fieldNames[] = JHTML::_('select.option', '', $incSelect );
  3114. }
  3115. if (is_array( $aFields ) ) {
  3116. foreach( $aFields as $oField ) {
  3117. if ($incTableName ){
  3118. $fieldNames[] = JHTML::_('select.option', $tbl . "___" . $oField->Field, $oField->Field );
  3119. } else {
  3120. $fieldNames[] = JHTML::_('select.option', $oField->Field );
  3121. }
  3122. }
  3123. }
  3124. $fieldDropDown = JHTML::_('select.genericlist', $fieldNames, $selectListName, "class=\"$className\" size=\"1\" ", 'value', 'text', $selected );
  3125. return str_replace("\n", "", $fieldDropDown);
  3126. }
  3127. /**
  3128. * used in advanced search
  3129. * @param bol add slashes to reutrn data
  3130. */
  3131. function getFilterJoinDd( $addSlashes = true, $name = 'join' ){
  3132. $aConditions = array( );
  3133. $aConditions[] = JHTML::_('select.option', 'AND' );
  3134. $aConditions[] = JHTML::_('select.option', 'OR' );
  3135. $dd = str_replace("\n", "", JHTML::_('select.genericlist', $aConditions, $name, "class=\"inputbox\" size=\"1\" ", 'value', 'text', '' ));
  3136. if ($addSlashes ){
  3137. $dd = addslashes( $dd );
  3138. }
  3139. return $dd;
  3140. }
  3141. /**
  3142. *used in advanced search
  3143. *@param bol add slashes to reutrn data
  3144. *@param string name of the drop down
  3145. *@param int mode - states what values get put into drop down
  3146. */
  3147. function getFilterConditionDd( $addSlashes = true, $name = 'conditions', $mode = 1 ){
  3148. $aConditions = array( );
  3149. switch ($mode){
  3150. case 1:
  3151. /* used for search filter */
  3152. $aConditions[] = JHTML::_('select.option', '<>', 'NOT EQUALS' );
  3153. $aConditions[] = JHTML::_('select.option', '=', 'EQUALS' );
  3154. $aConditions[] = JHTML::_('select.option', 'like', 'BEGINS WITH' );
  3155. $aConditions[] = JHTML::_('select.option', 'like', 'CONTAINS' );
  3156. $aConditions[] = JHTML::_('select.option', 'like', 'ENDS WITH' );
  3157. $aConditions[] = JHTML::_('select.option', '>', 'GREATER THAN' );
  3158. $aConditions[] = JHTML::_('select.option', '<', 'LESS THAN' );
  3159. break;
  3160. case 2:
  3161. /* used for prefilter */
  3162. $aConditions[] = JHTML::_('select.option', 'equals', 'EQUALS' );
  3163. $aConditions[] = JHTML::_('select.option', 'notequals', 'NOT EQUAL TO' );
  3164. $aConditions[] = JHTML::_('select.option', 'begins', 'BEGINS WITH' );
  3165. $aConditions[] = JHTML::_('select.option', 'contains', 'CONTAINS' );
  3166. $aConditions[] = JHTML::_('select.option', 'ends', 'ENDS WITH' );
  3167. $aConditions[] = JHTML::_('select.option', '>', 'GREATER THAN' );
  3168. $aConditions[] = JHTML::_('select.option', '<', 'LESS THAN' );
  3169. $aConditions[] = JHTML::_('select.option', 'IS NULL', 'IS NULL' );
  3170. break;
  3171. }
  3172. $dd = str_replace("\n", "", JHTML::_('select.genericlist', $aConditions, $name, "class=\"inputbox\" size=\"1\" ", 'value', 'text', '' ));
  3173. if ($addSlashes ) {
  3174. $dd = addslashes( $dd );
  3175. }
  3176. return $dd;
  3177. }
  3178. /**
  3179. * create the RSS href link to go in the table template
  3180. * @return string RSS link
  3181. */
  3182. function getRSSFeedLink( )
  3183. {
  3184. global $Itemid;
  3185. $link = '';
  3186. if ($this->_params->get('rss') == '1' ) {
  3187. $link = 'index.php?option=com_fabrik&view=table&format=feed&tableid=' . $this->_id . '&Itemid=' . $Itemid . '&type=rss';
  3188. if (!$this->_admin) {
  3189. $link = JRoute::_( $link );
  3190. }
  3191. }
  3192. return $link;
  3193. }
  3194. /**
  3195. * iterates through string to replace every
  3196. * {placeholder} with row data
  3197. * (added by hugh, does the same thing as parseMessageForPlaceHolder in parent
  3198. * class, but for rows instead of forms)
  3199. * @param string text to parse
  3200. */
  3201. function parseMessageForRowHolder( $msg, $row ){
  3202. $this->_aRow = $row;
  3203. $msg = FabrikWorker::_replaceWithUserData( $msg );
  3204. $msg = FabrikWorker::_replaceWithGlobals( $msg );
  3205. $msg = preg_replace( "/{}/", "", $msg );
  3206. /* replace {element name} with form data */
  3207. $msg = preg_replace_callback( "/{[^}]+}/i", array($this,'_replaceWithRowData'), $msg );
  3208. return $msg;
  3209. }
  3210. /**
  3211. * PRVIATE:
  3212. * called from parseMessageForRowHolder to iterate through string to replace
  3213. * {placeholder} with row data
  3214. * @param string placeholder e.g. {placeholder}
  3215. * @param array row
  3216. * @return string posted data that corresponds with placeholder
  3217. */
  3218. function _replaceWithRowData( $matches ){
  3219. $match = $matches[0];
  3220. /* strip the {} */
  3221. $match = substr( $match, 1, strlen($match) - 2 );
  3222. $match = strtolower( $match );
  3223. $match = str_replace('.','___',$match);
  3224. // $$$ hugh - allow use of {$rowpk} or {rowpk} to mean the rowid of the rwo within a table
  3225. if ($match == 'rowpk' or $match == '$rowpk')
  3226. {
  3227. $match = $this->_table->db_primary_key;
  3228. $match = preg_replace('#^(\w+\.)#','',$match);
  3229. }
  3230. $match = preg_replace( "/ /", "_", $match );
  3231. return($this->_aRow[$match]);
  3232. }
  3233. /**
  3234. * get the link to view the records details
  3235. * @param int record id
  3236. * @param int record cursor
  3237. */
  3238. function viewDetailsLink( $id, $cursor = 0 )
  3239. {
  3240. global $Itemid;
  3241. $link = '';
  3242. if($this->canViewDetails()){
  3243. //TODO: test this in admin table & front end
  3244. $table =& $this->getTable();
  3245. $action = $this->_admin ? 'task' : 'view';
  3246. $link = 'index.php?option=com_fabrik&c=form&'.$action.'=details&tableid=' . $this->_id . '&fabrik=' . $table->form_id . '&rowid=' . $id . '&Itemid=' . $Itemid;
  3247. if (!$this->_admin) {
  3248. $link = JRoute::_( $link );
  3249. }
  3250. $link = "<a href=\"$link\">" . JText::_('View') . "</a>";
  3251. }
  3252. return $link;
  3253. }
  3254. /**
  3255. * make the drop slq statement for the table
  3256. * @return string drop table sql
  3257. */
  3258. function getDropTableSQL()
  3259. {
  3260. $genTable = $this->getGenericTableName( );
  3261. $sql = "DROP TABLE IF EXISTS `$genTable`;";
  3262. return $sql;
  3263. }
  3264. function getGenericTableName()
  3265. {
  3266. global $mainframe;
  3267. $table = $this->getTable();
  3268. return str_replace( $mainframe->getCfg('dbprefix'), '#__', $table->db_table_name );
  3269. }
  3270. /**
  3271. * make the create sql statement for the table
  3272. * @return string sql to drop & or create table
  3273. */
  3274. function getCreateTableSQL( )
  3275. {
  3276. $table = $this->getGenericTableName( );
  3277. $fields = $this->getDBFields( );
  3278. $primaryKey = "";
  3279. $sql = "";
  3280. FabrikString::safeColName( $table );
  3281. if (is_array( $fields )) {
  3282. $sql .= "CREATE table " . $table ." (\n";
  3283. foreach ( $fields as $field ) {
  3284. FabrikString::safeColName( $field->Field );
  3285. if ($field->Key == 'PRI'){
  3286. $primaryKey = "PRIMARY KEY ($field->Field)";
  3287. }
  3288. $sql .= "$field->Field ";
  3289. if ($field->Key == 'PRI'){
  3290. $sql .= ' INT(6) ';
  3291. } else {
  3292. $sql .= ' ' . $field->Type . ' ';
  3293. }
  3294. if ($field->Null == '' ) {
  3295. $sql .= " NOT NULL ";
  3296. }
  3297. if ($field->Default != '' && $field->Key != 'PRI' ) {
  3298. if($field->Default == 'CURRENT_TIMESTAMP'){
  3299. $sql .= "DEFAULT $field->Default";
  3300. } else {
  3301. $sql .= "DEFAULT '$field->Default'";
  3302. }
  3303. }
  3304. if ($field->Key == 'PRI') {
  3305. $sql .= " AUTO_INCREMENT ";
  3306. }
  3307. $sql .= $field->Extra . ",\n";
  3308. }
  3309. if ($primaryKey == '') {
  3310. $sql = rtrim($sql,",\n" );
  3311. }
  3312. $sql .= $primaryKey . ");";
  3313. }
  3314. return $sql;
  3315. }
  3316. /**
  3317. * make the create sql statement for inserting the table data
  3318. * used in package export
  3319. * @param object exporter
  3320. * @return string sql to drop & or create table
  3321. */
  3322. function getInsertRowsSQL( $oExporter )
  3323. {
  3324. @set_time_limit(300);
  3325. $table =& $this->getTable();
  3326. $memoryLimit = ini_get( 'memory_limit' );
  3327. $db =& $this->getDb();
  3328. //dont load in all the table data as on large tables this gives a memory error
  3329. //in fact this wasnt the problem, but rather the $sql var becomes too large to hold in memory
  3330. //going to try saving to a file on the server and then compressing that and sending it as a header for download
  3331. $db->setQuery( "SELECT $table->db_primary_key FROM `$table->db_table_name`" );
  3332. $keys = $db->loadResultArray( );
  3333. $sql = "";
  3334. $dump_buffer_len = 0;
  3335. if (is_array( $keys )) {
  3336. foreach ($keys as $id) {
  3337. $db->setQuery( "SELECT * FROM `$table->db_table_name` WHERE $table->db_primary_key = $id" );
  3338. $row = $db->loadObject();
  3339. $fmtsql = "\t<query>INSERT INTO $table->db_table_name ( %s ) VALUES ( %s )</query>";
  3340. $values = array();
  3341. $fields = array();
  3342. foreach ( $row as $k => $v) {
  3343. $fields[] = $db->NameQuote( $k );
  3344. $values[] = $db->Quote( $v );
  3345. }
  3346. $sql .= sprintf( $fmtsql, implode( ",", $fields ) , implode( ",", $values ) );
  3347. $sql .= "\n";
  3348. $dump_buffer_len += strlen( $sql );
  3349. if ($dump_buffer_len > $memoryLimit) {
  3350. $oExporter->writeExportBuffer( $sql );
  3351. $sql = "";
  3352. $dump_buffer_len = 0;
  3353. }
  3354. unset( $values );
  3355. unset( $fmtsql );
  3356. }
  3357. }
  3358. $oExporter->writeExportBuffer( $sql );
  3359. }
  3360. /**
  3361. * records data from a fabrik RSS feed into the table
  3362. * feeds need to be in <dl> format
  3363. * @param string html containing <dl> list
  3364. * @return string out come message can be'saved','error saving',return 'duplicate', 'error'
  3365. */
  3366. function recordFromRSSFeed( $html )
  3367. {
  3368. $table =& $this->getTable();
  3369. $db =& JFactory::getDBO();
  3370. require_once(JPATH_SITE . '/includes/domit/xml_domit_lite_include.php');
  3371. //strip cdata text from html
  3372. $html = str_replace( array(']]>', '<![CDATA['), '', $html );
  3373. $xmlDoc = new DOMIT_Lite_Document();
  3374. $ok = $xmlDoc->parseXML($html);
  3375. $aData = array('test');
  3376. if ($ok ){
  3377. $key = '';
  3378. $val = '';
  3379. $debug = '';
  3380. $aPseudoKeys = array();
  3381. $isPseudoKey = false;
  3382. $numDefinitionLists = count($xmlDoc->documentElement->childNodes);
  3383. for ( $i = 0; $i < $numDefinitionLists; $i++ ) {
  3384. $currentChannel =& $xmlDoc->documentElement->childNodes[$i];
  3385. if (($i % 2) == 0){ // even so its the col heading
  3386. $label = $currentChannel->firstChild->nodeValue;
  3387. $key = $currentChannel->getAttribute("value");
  3388. $isPseudoKey = $currentChannel->getAttribute("key");
  3389. } else {
  3390. $val = $currentChannel->firstChild->nodeValue;
  3391. if ($key != $table->db_primary_key && $key != '') {
  3392. $aData[$key] = $val;
  3393. }
  3394. if ($isPseudoKey == '1' ) {
  3395. $aPseudoKeys[] = "$key = '$val'";
  3396. }
  3397. }
  3398. }
  3399. //test if record already exists?
  3400. $res = 0;
  3401. if (count( $aPseudoKeys ) > 0) {
  3402. $sql = "SELECT count(*) FROM $table->db_table_name WHERE " . implode( ' AND ', $aPseudoKeys );
  3403. $db->setQuery( $sql );
  3404. $res = $db->loadResult( );
  3405. }
  3406. if ($res == 0) {
  3407. if ($this->storeRow( $aData, 0 ) ) {
  3408. return 'saved';
  3409. } else {
  3410. return 'error saving';
  3411. }
  3412. } else {
  3413. return 'duplicate';
  3414. }
  3415. }
  3416. return 'error';
  3417. }
  3418. /**
  3419. * ajax get record specified by row id
  3420. */
  3421. function xRecord($id)
  3422. {
  3423. $cursor = JRequest::getInt( 'cursor', 1 );
  3424. $this->getConnection( );
  3425. $this->_outPutFormat = 'json';
  3426. //$pageNav = new fabrikPageNav( 1, 0, 1 );
  3427. $this->_pageNav =& $this->_getPagination( 1, 0, 1 );
  3428. $data = $this->getData( );
  3429. return FastJSON::encode($data);
  3430. }
  3431. /**
  3432. * ajax get next record
  3433. * @return string json object representing record/row
  3434. */
  3435. function nextRecord()
  3436. {
  3437. $cursor = JRequest::getInt( 'cursor', 1 );
  3438. $this->getConnection( );
  3439. $this->_outPutFormat = 'json';
  3440. $this->_pageNav =& $this->_getPagination( 1, $cursor, 1 );
  3441. $data = $this->getData( );
  3442. echo FastJSON::encode($data);
  3443. }
  3444. /**
  3445. * ajax get previous record
  3446. * @return string json object representing record/row
  3447. */
  3448. function previousRecord()
  3449. {
  3450. $cursor = JRequest::getInt( 'cursor', 1 );
  3451. $this->getConnection( );
  3452. $this->_outPutFormat = 'json';
  3453. $this->_pageNav =& $this->_getPagination( 1, $cursor-2, 1 );
  3454. $data = $this->getData( );
  3455. return FastJSON::encode( $data );
  3456. }
  3457. /**
  3458. * ajax get first record
  3459. * @return string json object representing record/row
  3460. */
  3461. function firstRecord()
  3462. {
  3463. $cursor = JRequest::getInt( 'cursor', 1 );
  3464. $this->getConnection( );
  3465. $this->_outPutFormat = 'json';
  3466. $this->_pageNav =& $this->_getPagination( 1, 0, 1 );
  3467. $data = $this->getData( );
  3468. return FastJSON::encode( $data );
  3469. }
  3470. /**
  3471. * ajax get last record
  3472. * @return string json object representing record/row
  3473. */
  3474. function lastRecord()
  3475. {
  3476. $total = JRequest::getInt( 'total', 0 );
  3477. $this->getConnection( );
  3478. $this->_outPutFormat = 'json';
  3479. $this->_pageNav =& $this->_getPagination( 1, $total-1, 1 );
  3480. $data = $this->getData( );
  3481. return FastJSON::encode( $data );
  3482. }
  3483. /**
  3484. * get a single column of data from the table, test for element filters
  3485. * @param string column to get
  3486. * @return array values for the column
  3487. */
  3488. function getColumnData( $col )
  3489. {
  3490. $table =& $this->getTable();
  3491. $db =& $this->getDb();
  3492. FabrikString::safeColName( $col );
  3493. $tablename = $table->db_table_name;
  3494. FabrikString::safeColName( $tablename );
  3495. $query = "SELECT DISTINCT($col) FROM " . $tablename . ' ' . $this->_buildQueryJoin();
  3496. $query .= $this->_buildQueryWhere( false );
  3497. $db->setQuery( $query );
  3498. $res = $db->loadResultArray( );
  3499. if ($db->getErrorNum()) {
  3500. JError::raiseError( 500, $db->getErrorMsg() );
  3501. }
  3502. return $res;
  3503. }
  3504. function importCSV( )
  3505. {
  3506. $db =& JFactory::getDBO();
  3507. $oImport = new FabrikModelImportCsv();
  3508. $formModel =& $this->getForm();
  3509. $table =& $this->getTable();
  3510. $oImport->checkUpload();
  3511. $db->setQuery( "SELECT plugin AS value, name AS text FROM #__fabrik_plugins" );
  3512. $elementTypes = $db->loadObjectList();
  3513. $_SESSION['fabrik']['csvImportData'] = $oImport->data;
  3514. $_SESSION['fabrik']['csvImportHeadings'] = $oImport->headings;
  3515. $fabrik_table = 0;
  3516. $pKey = '';
  3517. $table = $table->label;
  3518. $this->getFormGroupElementData( false, false );
  3519. $lists['matchedHeadings'] = array();
  3520. $lists['newHeadings'] = array();
  3521. $pKey = $oTable->db_primary_key;
  3522. //
  3523. $pluginManager =& JModel::getInstance( 'Pluginmanager', 'FabrikModel' );
  3524. $pluginManager->loadPlugInGroup( 'table' );
  3525. $aUsedElements = array();
  3526. foreach ( $oImport->headings as $heading ) {
  3527. foreach ( $formModel->_groups as $groupModel ) {
  3528. $found = false;
  3529. foreach ($groupModel->_aElements as $elementModel) {
  3530. $element =& $elementModel->getElement();
  3531. $fullName = $elementModel->getFullName( true, true, false );
  3532. if (strtolower( $heading ) == strtolower( $element->name ) || strtolower( $heading ) == $fullName) {
  3533. /** heading found in table */
  3534. $lists['matchedHeadings'][] = strtolower( $heading );
  3535. $aUsedElements[strtolower( $heading )] = $elementModel;
  3536. $found = true;
  3537. }
  3538. }
  3539. if (!$found) {
  3540. $lists['newHeadings'][] = $heading;
  3541. }
  3542. }
  3543. }
  3544. $intKey= 0;
  3545. foreach ( $aUsedElements as $elementModel ) {
  3546. $oImport->data = $elementModel->prepareCSVData( $oImport->data, $intKey );
  3547. $intKey ++;
  3548. }
  3549. if (!empty( $lists['newHeading'] )) {
  3550. return false;
  3551. }
  3552. $dropData = JRequest::getInt( 'drop_data', 0, 'post' );
  3553. $overWrite = JRequest::getInt( 'overwrite', 0, 'post' );
  3554. if ($dropData) {
  3555. $this->dropData();
  3556. }
  3557. $key = str_replace( ".", "___", $table->db_primary_key );
  3558. $key2 = str_replace( $table->db_table_name . "___", "", $key );
  3559. //get a list of exisitng primary key vals
  3560. $db =& $this->getDb();
  3561. $db->setQuery( "SELECT $table->db_primary_key FROM $table->db_table_name" );
  3562. $aExistingKeys = $db->loadResultArray();
  3563. foreach ($oImport->data as $data) {
  3564. $aRow = array();
  3565. if ($overWrite) {
  3566. $ch = count( $lists['matchedHeadings'] );
  3567. for ($i=0; $i < $ch; $i++) {
  3568. $tmpKey = $lists['matchedHeadings'][$i];
  3569. if ($tmpKey != $key && $tmpKey != $key2 ) {
  3570. $pkVal = $data[$i];
  3571. }
  3572. $aRow[$tmpKey] = $data[$i];
  3573. }
  3574. $aRow = $this->removeTableNameFromSaveData( $aRow );
  3575. if (in_array( $pkVal, $aExistingKeys )) {
  3576. $this->storeRow( $aRow, $pkVal );
  3577. } else {
  3578. $this->storeRow( $aRow, 0 );
  3579. }
  3580. } else {
  3581. for ($i=0;$i<count($lists['matchedHeadings']);$i++) {
  3582. $tmpKey = $lists['matchedHeadings'][$i];
  3583. if ($tmpKey != $key && $tmpKey != $key2 ) {
  3584. $aRow[$tmpKey] = $data[$i];
  3585. }
  3586. }
  3587. $aRow = $this->removeTableNameFromSaveData( $aRow );
  3588. $this->storeRow( $aRow, 0 );
  3589. }
  3590. }
  3591. return true;
  3592. }
  3593. }
  3594. ?>