ExportBase

The Contact Form DB ExportBase class.

Defined (1)

The class is defined in the following location(s).

/ExportBase.php  
  1. class ExportBase { 
  2.  
  3. /** 
  4. * @var string 
  5. */ 
  6. var $defaultTableClass = 'cf7-db-table'; 
  7.  
  8. /** 
  9. * @var array 
  10. */ 
  11. var $options; 
  12.  
  13. /** 
  14. * @var bool 
  15. */ 
  16. var $debug = false; 
  17.  
  18. /** 
  19. * @var array 
  20. */ 
  21. var $showColumns; 
  22.  
  23. /** 
  24. * @var array 
  25. */ 
  26. var $hideColumns; 
  27.  
  28. /** 
  29. * @var string 
  30. */ 
  31. var $htmlTableId; 
  32.  
  33. /** 
  34. * @var string 
  35. */ 
  36. var $htmlTableClass; 
  37.  
  38. /** 
  39. * @var string 
  40. */ 
  41. var $style; 
  42.  
  43. /** 
  44. * @var array assoc array of column names to display names 
  45. */ 
  46. var $headers; 
  47.  
  48. /** 
  49. * @var CFDBEvaluator|CFDBFilterParser|CFDBSearchEvaluator 
  50. */ 
  51. var $rowFilter; 
  52.  
  53. /** 
  54. * @var CFDBEvaluator|CFDBFilterParser|CFDBSearchEvaluator 
  55. */ 
  56. var $rowTransformFilter; 
  57.  
  58. /** 
  59. * @var CFDBTransformParser 
  60. */ 
  61. var $transform; 
  62.  
  63. /** 
  64. * @var bool 
  65. */ 
  66. var $isFromShortCode = false; 
  67.  
  68. /** 
  69. * @var bool 
  70. */ 
  71. var $showSubmitField; 
  72.  
  73. /** 
  74. * @var CF7DBPlugin 
  75. */ 
  76. var $plugin; 
  77.  
  78. /** 
  79. * @var CFDBDataIterator|CFDBAbstractQueryResultsIterator 
  80. */ 
  81. var $dataIterator; 
  82.  
  83. function __construct() { 
  84. $this->plugin = new CF7DBPlugin(); 
  85.  
  86. /** 
  87. * This method is the first thing to call after construction to set state for other methods to work 
  88. * @param $options array|null 
  89. * @return void 
  90. */ 
  91. public function setOptions($options) { 
  92. $this->options = $options; 
  93.  
  94. public function dereferenceOption($optionName) { 
  95. if (isset($this->options[$optionName])) { 
  96. $dereferenceVars = new DereferenceShortcodeVars; 
  97. $this->options[$optionName] = $dereferenceVars->convert($this->options[$optionName]); 
  98.  
  99. public function setCommonOptions($htmlOptions = false) { 
  100.  
  101. if ($this->options && is_array($this->options)) { 
  102. foreach (array( 
  103. 'debug', 'permissionmsg', 'unbuffered', 'show', 'hide', 'class', 'style', 'id',  
  104. 'orderby', 'limit', 'tlimit', 'header', 'headers', 'content',  
  105. 'filter', 'tfilter', 'search', 'tsearch', 'trans') 
  106. as $optionName) { 
  107. $this->dereferenceOption($optionName); 
  108.  
  109. if (isset($this->options['debug']) && $this->options['debug'] != 'false') { 
  110. $this->debug = true; 
  111.  
  112. $this->isFromShortCode = isset($this->options['fromshortcode']) && 
  113. $this->options['fromshortcode'] === true; 
  114.  
  115. if (!isset($this->options['unbuffered'])) { 
  116. //$this->options['unbuffered'] = $this->isFromShortCode ? 'false' : 'true'; // todo 
  117. $this->options['unbuffered'] = 'false'; 
  118. } else { 
  119. if ($this->options['unbuffered'] == 'checked') { 
  120. $this->options['unbuffered'] = 'true'; 
  121.  
  122. if (isset($this->options['showColumns'])) { 
  123. $this->showColumns = $this->options['showColumns']; 
  124. else if (isset($this->options['show'])) { 
  125. $this->showColumns = preg_split('/, /', $this->options['show'], -1, PREG_SPLIT_NO_EMPTY); 
  126.  
  127. if (isset($this->options['hideColumns'])) { 
  128. $this->hideColumns = $this->options['hideColumns']; 
  129. else if (isset($this->options['hide'])) { 
  130. $this->hideColumns = preg_split('/, /', $this->options['hide'], -1, PREG_SPLIT_NO_EMPTY); 
  131.  
  132.  
  133. if ($htmlOptions) { 
  134. if (isset($this->options['class'])) { 
  135. $this->htmlTableClass = $this->options['class']; 
  136. else { 
  137. $this->htmlTableClass = $this->defaultTableClass; 
  138.  
  139. if (isset($this->options['id'])) { 
  140. $this->htmlTableId = $this->options['id']; 
  141. else { 
  142. $this->htmlTableId = 'cftble_' . rand(); 
  143.  
  144. if (isset($this->options['style'])) { 
  145. $this->style = $this->options['style']; 
  146.  
  147. $permittedFunctions = null; 
  148. if (isset($this->options['filter']) || isset($this->options['trans'])) { 
  149. require_once('CFDBPermittedFunctions.php'); 
  150. $permittedFunctions = CFDBPermittedFunctions::getInstance(); 
  151. $permitAll = $this->queryPermitAllFunctions(); 
  152. $permittedFunctions->setPermitAllFunctions($permitAll); 
  153.  
  154.  
  155. $filters = array(); 
  156. if (isset($this->options['filter'])) { 
  157. require_once('CFDBFilterParser.php'); 
  158. $aFilter = new CFDBFilterParser; 
  159. $aFilter->setComparisonValuePreprocessor(new DereferenceShortcodeVars); 
  160. $aFilter->setPermittedFilterFunctions($permittedFunctions); 
  161. $aFilter->parse($this->options['filter']); 
  162. if ($this->debug) { 
  163. echo '<pre>\'' . $this->options['filter'] . "'\n"; 
  164. print_r($aFilter->tree); 
  165. echo '</pre>'; 
  166. $filters[] = $aFilter; 
  167.  
  168. $transformFilters = array(); 
  169. if (isset($this->options['tfilter'])) { 
  170. require_once('CFDBFilterParser.php'); 
  171. $aFilter = new CFDBFilterParser; 
  172. $aFilter->setComparisonValuePreprocessor(new DereferenceShortcodeVars); 
  173. $aFilter->setPermittedFilterFunctions($permittedFunctions); 
  174. $aFilter->parse($this->options['tfilter']); 
  175. if ($this->debug) { 
  176. echo '<pre>\'' . $this->options['tfilter'] . "'\n"; 
  177. print_r($aFilter->tree); 
  178. echo '</pre>'; 
  179. $transformFilters[] = $aFilter; 
  180.  
  181. if (isset($this->options['search'])) { 
  182. require_once('CFDBSearchEvaluator.php'); 
  183. $aFilter = new CFDBSearchEvaluator; 
  184. $aFilter->setSearch($this->options['search']); 
  185. $filters[] = $aFilter; 
  186.  
  187. if (isset($this->options['tsearch'])) { 
  188. require_once('CFDBSearchEvaluator.php'); 
  189. $aFilter = new CFDBSearchEvaluator; 
  190. $aFilter->setSearch($this->options['tsearch']); 
  191. $transformFilters[] = $aFilter; 
  192.  
  193. $numFilters = count($filters); 
  194. if ($numFilters == 1) { 
  195. $this->rowFilter = $filters[0]; 
  196. else if ($numFilters > 1) { 
  197. require_once('CFDBCompositeEvaluator.php'); 
  198. $this->rowFilter = new CFDBCompositeEvaluator; 
  199. $this->rowFilter->setEvaluators($filters); 
  200.  
  201. $numTransformFilters = count($transformFilters); 
  202. if ($numTransformFilters == 1) { 
  203. $this->rowTransformFilter = $transformFilters[0]; 
  204. else if ($numTransformFilters > 1) { 
  205. require_once('CFDBCompositeEvaluator.php'); 
  206. $this->rowTransformFilter = new CFDBCompositeEvaluator; 
  207. $this->rowTransformFilter->setEvaluators($transformFilters); 
  208.  
  209. if (isset($this->options['trans'])) { 
  210. require_once('CFDBTransformParser.php'); 
  211. $this->transform = new CFDBTransformParser(); 
  212. $this->transform->setComparisonValuePreprocessor(new DereferenceShortcodeVars); 
  213. $this->transform->setPermittedFilterFunctions($permittedFunctions); 
  214.  
  215. $transformOption = $this->options['trans']; 
  216. // Set up "orderby" post-processing 
  217. if (isset($this->options['orderby'])) { 
  218. $orderByStrings = explode(', ', $this->options['orderby']); 
  219. foreach ($orderByStrings as $anOrderBy) { 
  220. $anOrderBy = trim($anOrderBy); 
  221. $ascOrDesc = null; 
  222. list($ascOrDesc, $anOrderBy) = $this->parseOrderBy($anOrderBy); 
  223. $ascOrDesc = trim($ascOrDesc); 
  224. if (empty($ascOrDesc)) { 
  225. $ascOrDesc = 'ASC'; 
  226. // Append a Sort transform 
  227. $transformOption .= '&&NaturalSortByField(' . $anOrderBy . ', ' . $ascOrDesc . ')'; 
  228.  
  229. $this->transform->parse($transformOption); 
  230. if ($this->debug) { 
  231. echo '<pre>\'' . $transformOption . "'\n"; 
  232. print_r($this->transform->tree); 
  233. echo '</pre>'; 
  234. $this->transform->setupTransforms(); 
  235.  
  236. if (isset($this->options['headers'])) { // e.g. "col1=Column 1 Display Name, col2=Column2 Display Name" 
  237. $headersList = preg_split('/, /', $this->options['headers'], -1, PREG_SPLIT_NO_EMPTY); 
  238. if (is_array($headersList)) { 
  239. $this->headers = array(); 
  240. foreach ($headersList as $nameEqualValue) { 
  241. $nameEqualsValueArray = explode('=', $nameEqualValue, 2); // col1=Column 1 Display Name 
  242. if (count($nameEqualsValueArray) >= 2) { 
  243. $this->headers[$nameEqualsValueArray[0]] = $nameEqualsValueArray[1]; 
  244.  
  245. /** 
  246. * @return bool 
  247. */ 
  248. protected function isAuthorized() { 
  249. if (!$this->isFromShortCode) { 
  250. return $this->plugin->canUserDoRoleOption('CanSeeSubmitData'); 
  251. else { 
  252. $isAuth = $this->plugin->canUserDoRoleOption('CanSeeSubmitDataViaShortcode'); 
  253. if ($isAuth && isset($this->options['role'])) { 
  254. $isAuth = $this->plugin->isUserRoleEqualOrBetterThan($this->options['role']); 
  255. return $isAuth; 
  256.  
  257. protected function assertSecurityErrorMessage() { 
  258. $showMessage = true; 
  259.  
  260. if (isset($this->options['role'])) { 
  261. // If role is being used, but default do not show the error message 
  262. $showMessage = false; 
  263.  
  264. if (isset($this->options['permissionmsg'])) { 
  265. $showMessage = $this->options['permissionmsg'] != 'false'; 
  266.  
  267. $errMsg = $showMessage ? __('You do not have sufficient permissions to access this data.', 'contact-form-7-to-database-extension') : ''; 
  268. if ($this->isFromShortCode) { 
  269. echo $errMsg; 
  270. else { 
  271. include_once('CFDBDie.php'); 
  272. CFDBDie::wp_die($errMsg); 
  273.  
  274.  
  275. /** 
  276. * @param string|array|null $headers mixed string header-string or array of header strings. 
  277. * E.g. Content-Type, Content-Disposition, etc. 
  278. * @return void 
  279. */ 
  280. protected function echoHeaders($headers = null) { 
  281. if (!headers_sent()) { 
  282. header('Expires: 0'); 
  283. header('Cache-Control: no-store, no-cache, must-revalidate'); 
  284. // Hoping to keep the browser from timing out if connection from Google SS Live Data 
  285. // script is calling this page to get information 
  286. header("Keep-Alive: timeout=60"); // Not a standard HTTP header; browsers may disregard 
  287.  
  288. if ($headers) { 
  289. if (is_array($headers)) { 
  290. foreach ($headers as $aheader) { 
  291. header($aheader); 
  292. else { 
  293. header($headers); 
  294. flush(); 
  295.  
  296. /** 
  297. * @param $dataColumns array 
  298. * @return array 
  299. */ 
  300. protected function &getColumnsToDisplay($dataColumns) { 
  301.  
  302. if (empty($dataColumns)) { 
  303. $retCols = array(); 
  304. return $retCols; 
  305.  
  306. //$dataColumns = array_merge(array('Submitted'), $dataColumns); 
  307. $showCols = empty($this->showColumns) ? $dataColumns : $this->matchColumns($this->showColumns, $dataColumns); 
  308. if (empty($this->hideColumns)) { 
  309. return $showCols; 
  310.  
  311. $hideCols = $this->matchColumns($this->hideColumns, $dataColumns); 
  312. if (empty($hideCols)) { 
  313. return $showCols; 
  314.  
  315. $retCols = array(); 
  316. foreach ($showCols as $aShowCol) { 
  317. if (!in_array($aShowCol, $hideCols)) { 
  318. $retCols[] = $aShowCol; 
  319. return $retCols; 
  320.  
  321. protected function matchColumns(&$patterns, &$subject) { 
  322. $returnCols = array(); 
  323. foreach ($patterns as $pCol) { 
  324. if (substr($pCol, 0, 1) == '/') { 
  325. // Show column value is a REGEX 
  326. foreach($subject as $sCol) { 
  327. if (preg_match($pCol, $sCol) && !in_array($sCol, $returnCols)) { 
  328. $returnCols[] = $sCol; 
  329. else { 
  330. $returnCols[] = $pCol; 
  331. return $returnCols; 
  332.  
  333. /** 
  334. * @return bool 
  335. */ 
  336. protected function getShowSubmitField() { 
  337. $showSubmitField = true; 
  338. if ($this->hideColumns != null && is_array($this->hideColumns) && in_array('Submitted', $this->hideColumns)) { 
  339. $showSubmitField = false; 
  340. else if ($this->showColumns != null && is_array($this->showColumns)) { 
  341. $showSubmitField = in_array('Submitted', $this->showColumns); 
  342. return $showSubmitField; 
  343.  
  344. /** 
  345. * Execute the query and set up the results iterator 
  346. * @param string|array $formName (if array, must be array of string) 
  347. * @param null|string $submitTimeKeyName 
  348. * @return void 
  349. */ 
  350. protected function setDataIterator($formName, $submitTimeKeyName = null) { 
  351.  
  352. $submitTimes = $this->queryRandomSubmitTimes($formName); 
  353.  
  354. $sql = $this->getPivotQuery($formName, false, $submitTimes); 
  355.  
  356. $queryOptions = array(); 
  357. if ($submitTimeKeyName) { 
  358. $queryOptions['submitTimeKeyName'] = $submitTimeKeyName; 
  359. if (isset($this->options['limit']) && $this->hasFilterOrTransform()) { 
  360. // have data iterator apply the limit if it is not already 
  361. // being applied in SQL directly, which we do when there are 
  362. // no filter constraints. 
  363. $queryOptions['limit'] = $this->options['limit']; 
  364. $unbuffered = false;; 
  365. if (isset($this->options['unbuffered'])) { 
  366. $queryOptions['unbuffered'] = $this->options['unbuffered']; 
  367. $unbuffered = $queryOptions['unbuffered'] == 'true'; 
  368.  
  369. if ($this->debug) { 
  370. $queryOptions['debug'] = 'true'; 
  371.  
  372. $this->dataIterator = CFDBQueryResultIteratorFactory::getInstance()->newQueryIterator($unbuffered); 
  373.  
  374. if ($this->transform && !empty($this->transform->transformIterators)) { 
  375. $postProcessOptions = $queryOptions; // make a copy 
  376.  
  377. // If we have a transform, then alternatively-named options like 'tlimit' are used 
  378. // in the actual query (CFDBQueryResultIterator) whereas the normally named 
  379. // ones are handled by the CFDBTransformEndpoint post-processor 
  380. unset($queryOptions['limit']); 
  381. if (isset($this->options['tlimit'])) { 
  382. $queryOptions['limit'] = $this->options['tlimit']; 
  383. unset($queryOptions['orderby']); 
  384. if (isset($this->options['torderby'])) { 
  385. $queryOptions['orderby'] = $this->options['torderby']; 
  386. // These aren't really needed b/c we have already setup $this->rowTransformFilter 
  387. unset($queryOptions['filter']); 
  388. if (isset($this->options['tfilter'])) { 
  389. $queryOptions['filter'] = $this->options['tfilter']; 
  390. unset($queryOptions['search']); 
  391. if (isset($this->options['tsearch'])) { 
  392. $queryOptions['search'] = $this->options['tsearch']; 
  393.  
  394. $this->dataIterator->query($sql, $this->rowTransformFilter, $queryOptions); 
  395. $queryDisplayColumns = $this->getColumnsToDisplay($this->dataIterator->columns); 
  396.  
  397. $this->transform->setTimezone(); 
  398. // Hookup query iterator as first transform, hookup last iterator as $this->dataIterator 
  399. $this->transform->setDataSource($this->dataIterator); 
  400. $this->dataIterator = $this->transform->getIterator(); 
  401.  
  402. // $this->dataIterator is a CFDBTransformEndpoint 
  403. $this->dataIterator->getPostProcessor()->query($sql, $this->rowFilter, $postProcessOptions); 
  404.  
  405. $displayColumns = $this->getColumnsToDisplay($this->dataIterator->getDisplayColumns()); 
  406.  
  407. // Not sure why I need to do this to make show/hide work in some cases 
  408. $this->dataIterator->displayColumns = empty($displayColumns) ? $queryDisplayColumns : $displayColumns; 
  409.  
  410. } else { 
  411. // No transform, just query 
  412. $this->dataIterator->query($sql, $this->rowFilter, $queryOptions); 
  413. $this->dataIterator->displayColumns = $this->getColumnsToDisplay($this->dataIterator->columns); 
  414.  
  415. // protected function &getFileMetaData($formName) { 
  416. // global $wpdb; 
  417. // $tableName = $this->plugin->getSubmitsTableName(); 
  418. // $rows = $wpdb->get_results( 
  419. // "select distinct `field_name` 
  420. //from `$tableName` 
  421. //where `form_name` = '$formName' 
  422. //and `file` is not null"); 
  423. // 
  424. // $fileColumns = array(); 
  425. // foreach ($rows as $aRow) { 
  426. // $files[] = $aRow->field_name; 
  427. // } 
  428. // return $fileColumns; 
  429. // } 
  430.  
  431. /** 
  432. * @param string|array $formName (if array, must be array of string) 
  433. * @param bool $count 
  434. * @param $submitTimes array of string submit_time values that are to be specifically queried 
  435. * @return string 
  436. */ 
  437. public function &getPivotQuery($formName, $count = false, $submitTimes = null) { 
  438. global $wpdb; 
  439. $tableName = $this->plugin->getSubmitsTableName(); 
  440.  
  441. $formNameClause = '1=1'; 
  442. if (is_array($formName)) { 
  443. $formNameArray = $this->escapeAndQuoteArrayValues($formName); 
  444. $formNameClause = '`form_name` in ( ' . implode(', ', $formNameArray) . ' )'; 
  445. else if ($formName !== null && $formName != '*') { // * => all forms 
  446. if (strpos($formName, ', ') !== false) { 
  447. $formNameArray = explode(', ', $formName); 
  448. $formNameArray[] = $formName; // in case the form name is literally the string with commas in it 
  449. $formNameArray = $this->escapeAndQuoteArrayValues($formNameArray); 
  450. $formNameClause = '`form_name` in ( ' . implode(', ', $formNameArray) . ' )'; 
  451. else { 
  452. $formNameClause = "`form_name` = '". $this->escapeString($formName) . "'"; 
  453.  
  454. $submitTimesClause = ''; 
  455. if (is_array($submitTimes) && !empty($submitTimes)) { 
  456. $submitTimesClause = 'AND submit_time in ( ' . implode(', ', $submitTimes) . ' )'; 
  457.  
  458. //$rows = $wpdb->get_results("SELECT DISTINCT `field_name`, `field_order` FROM `$tableName` WHERE $formNameClause ORDER BY field_order"); // Pagination bug 
  459. $rows = $wpdb->get_results("SELECT DISTINCT `field_name` FROM `$tableName` WHERE $formNameClause ORDER BY field_order"); 
  460. $fields = array(); 
  461. foreach ($rows as $aRow) { 
  462. if ($aRow->field_name && trim($aRow->field_name) != '') { 
  463. // Saw a case of a column name of '' and ' ' which caused query to fail 
  464. // and no date to be displayed. 
  465. $fields[] = $aRow->field_name; 
  466. $sql = ''; 
  467. if ($count) { 
  468. $sql .= 'SELECT count(*) as count FROM ('; 
  469. $sql .= "SELECT `submit_time` AS 'Submitted'"; 
  470. foreach ($fields as $aCol) { 
  471. // Escape single quotes in column name 
  472. $aCol = $this->escapeString($aCol); 
  473. $sql .= ", \n max(if(`field_name`='$aCol', `field_value`, null )) AS '$aCol'"; 
  474. if (!$count) { 
  475. $sql .= ", \n GROUP_CONCAT(if(`file` is null or length(`file`) = 0, null, `field_name`)) AS 'fields_with_file'"; 
  476. $sql .= "\nFROM `$tableName` \nWHERE $formNameClause $submitTimesClause \nGROUP BY `submit_time` "; 
  477. if ($count) { 
  478. $sql .= ') form'; 
  479. else { 
  480. $orderBys = array(); 
  481. if ($this->options && isset($this->options['orderby'])) { 
  482. $orderByStrings = explode(', ', $this->options['orderby']); 
  483. foreach ($orderByStrings as $anOrderBy) { 
  484. $anOrderBy = trim($anOrderBy); 
  485. $ascOrDesc = null; 
  486. list($ascOrDesc, $anOrderBy) = $this->parseOrderBy($anOrderBy); 
  487. if (in_array($anOrderBy, $fields) || $anOrderBy == 'submit_time') { 
  488. $orderBys[] = '`' . $anOrderBy . '`' . $ascOrDesc; 
  489. else { 
  490. // Want to add a different collation as a different sorting mechanism 
  491. // Actually doesn't work because MySQL does not allow COLLATE on a select that is a group function 
  492. $collateIdx = stripos($anOrderBy, ' COLLATE'); 
  493. if ($collateIdx > 0) { 
  494. $collatedField = substr($anOrderBy, 0, $collateIdx); 
  495. if (in_array($collatedField, $fields)) { 
  496. $orderBys[] = '`' . $collatedField . '`' . substr($anOrderBy, $collateIdx) . $ascOrDesc; 
  497. if (empty($orderBys)) { 
  498. $sql .= "\nORDER BY `submit_time` DESC"; 
  499. else { 
  500. $sql .= "\nORDER BY "; 
  501. $first = true; 
  502. foreach ($orderBys as $anOrderBy) { 
  503. if ($first) { 
  504. $sql .= $anOrderBy; 
  505. $first = false; 
  506. else { 
  507. $sql .= ', ' . $anOrderBy; 
  508.  
  509. if (!$this->hasFilterOrTransform() && $this->options && isset($this->options['limit'])) { 
  510. // If no filter constraints and have a limit, add limit to the SQL 
  511. $sql .= "\nLIMIT " . $this->options['limit']; 
  512. //echo $sql; // debug 
  513. return $sql; 
  514.  
  515. /** 
  516. * @param $anArray array 
  517. * @return array of quoted escaped values 
  518. */ 
  519. public function escapeAndQuoteArrayValues($anArray) { 
  520. $retArray = array(); 
  521. foreach ($anArray as $aValue) { 
  522. $retArray[] = '\'' . $this->escapeString($aValue) . '\''; 
  523. return $retArray; 
  524.  
  525. /** 
  526. * Simple alternative to the deprecated mysql_real_escape_string() function 
  527. * @param $text String 
  528. * @return String 
  529. */ 
  530. public function escapeString($text) { 
  531. // Taken from: http://www.gamedev.net/topic/448909-php-alternative-to-mysql_real_escape_string/ 
  532. return strtr($text, array( 
  533. "\x00" => '\x00',  
  534. "\n" => '\n',  
  535. "\r" => '\r',  
  536. '\\' => '\\\\',  
  537. "'" => "\'",  
  538. '"' => '\"',  
  539. "\x1a" => '\x1a' 
  540. )); 
  541.  
  542. /** 
  543. * @param string|array $formName (if array, must be array of string) 
  544. * @return int 
  545. */ 
  546. public function getDBRowCount($formName) { 
  547. global $wpdb; 
  548. $count = 0; 
  549. $rows = $wpdb->get_results($this->getPivotQuery($formName, true)); 
  550. foreach ($rows as $aRow) { 
  551. $count = $aRow->count; 
  552. break; 
  553. return $count; 
  554.  
  555. public function hasFilterOrTransform() { 
  556. return $this->rowFilter || $this->transform; 
  557.  
  558. /** 
  559. * Query for n random submit times if 'random' option is set indicting number of random 
  560. * values to return (n) 
  561. * @param $formName 
  562. * @return array|null array of n submit_times or null if not applicable 
  563. */ 
  564. protected function queryRandomSubmitTimes($formName) { 
  565. $submitTimes = null; 
  566.  
  567. if (isset($this->options['random'])) { 
  568. $numRandom = intval($this->options['random']); 
  569. if ($numRandom > 0) { 
  570. // Digression: query for n unique random submit_time values 
  571. $justSubmitTimes = new ExportBase(); 
  572. $justSubmitTimes->setOptions($this->options); 
  573. $justSubmitTimes->setCommonOptions(); 
  574. unset($justSubmitTimes->options['random']); 
  575. $justSubmitTimes->showColumns = array('submit_time'); 
  576. $jstSql = $justSubmitTimes->getPivotQuery($formName); 
  577. $justSubmitTimes->setDataIterator($formName, 'submit_time'); 
  578. $justSubmitTimes->dataIterator->query( 
  579. $jstSql,  
  580. $justSubmitTimes->rowFilter); 
  581.  
  582. $allSubmitTimes = null; 
  583. while ($justSubmitTimes->dataIterator->nextRow()) { 
  584. $allSubmitTimes[] = $justSubmitTimes->dataIterator->row['submit_time']; 
  585. if (!empty($allSubmitTimes)) { 
  586. if (count($allSubmitTimes) < $numRandom) { 
  587. $submitTimes = $allSubmitTimes; 
  588. return $submitTimes; 
  589. } else { 
  590. shuffle($allSubmitTimes); // randomize 
  591. $submitTimes = array_slice($allSubmitTimes, 0, $numRandom); 
  592. return $submitTimes; 
  593. return $submitTimes; 
  594. return $submitTimes; 
  595. return $submitTimes; 
  596.  
  597. /** 
  598. * @return bool 
  599. */ 
  600. public function queryPermitAllFunctions() { 
  601. return $this->plugin->getOption('FunctionsInShortCodes', 'false') === 'true'; 
  602.  
  603. /** 
  604. * @param $anOrderBy string a single order by clause like "field1 DESC" 
  605. * @return array 
  606. */ 
  607. protected function parseOrderBy($anOrderBy) { 
  608. $ascOrDesc = null; 
  609. if (strtoupper(substr($anOrderBy, -5)) == ' DESC') { 
  610. $ascOrDesc = ' DESC'; 
  611. $anOrderBy = trim(substr($anOrderBy, 0, -5)); 
  612. } else if (strtoupper(substr($anOrderBy, -4)) == ' ASC') { 
  613. $ascOrDesc = ' ASC'; 
  614. $anOrderBy = trim(substr($anOrderBy, 0, -4)); 
  615. if ($anOrderBy == 'Submitted') { 
  616. $anOrderBy = 'submit_time'; 
  617. return array($ascOrDesc, $anOrderBy); 
  618. return array($ascOrDesc, $anOrderBy); 
  619.