PageRenderTime 49ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/lib/LP/RecordCollection.php

https://github.com/radicaldesigns/jaguar
PHP | 336 lines | 254 code | 63 blank | 19 comment | 54 complexity | 29700878496e9173d12ff6ed15c2d910 MD5 | raw file
Possible License(s): MIT, LGPL-2.1
  1. <?php
  2. require_once('Record.php');
  3. require_once('RecordSearch.php');
  4. class RecordCollection extends Data {
  5. var $sort = array();
  6. var $limit;
  7. var $offset;
  8. var $_search_class = 'RecordSearch';
  9. var $_search_exact_values = array();
  10. var $_search_fulltext = array( );
  11. var $_id_field_lookups;
  12. var $source;
  13. //Data Management Functions
  14. function readData() {
  15. $sql = $this->_assembleSQL();
  16. AMP::debug_sql( $sql, get_class($this));
  17. if ($this->source = $this->dbcon->Execute($sql)) {
  18. return true;
  19. }
  20. trigger_error ( sprintf( "SQL failed for %s %s Error: %s SQL: %s", get_class( $this ), 'read', $this->dbcon->ErrorMsg(), $sql ));
  21. return false;
  22. }
  23. function getData() {
  24. if (!$this->hasData()) return false;
  25. return $this->source->FetchRow();
  26. }
  27. function isReady() {
  28. return $this->makeReady();
  29. }
  30. function refreshData() {
  31. $this->clearCache( );
  32. $this->readData();
  33. }
  34. function clearCache( ){
  35. $cached_sql = $this->_assembleSQL( );
  36. $this->dbcon->CacheFlush( $cached_sql );
  37. AMP::debug_sql( $cached_sql, get_class($this). ' cleared cache');
  38. }
  39. function makeReady() {
  40. if (!$this->hasData()) return false;
  41. $this->source->MoveFirst();
  42. return true;
  43. }
  44. function setSort( $expression_set, $hold_priority = true ) {
  45. if (!(is_array($expression_set) || is_string($expression_set)) ) return false;
  46. $this->sort = array();
  47. if (is_string($expression_set)) return $this->addSort( $expression_set, false );
  48. /*
  49. if ($hold_priority) {
  50. $expression_set = array_reverse( $expression_set, true );
  51. }
  52. */
  53. foreach ($expression_set as $exp) {
  54. $this->addSort ( $exp, false);
  55. }
  56. }
  57. function addSort ( $exp, $primary = true ) {
  58. if (!is_string($exp)) return false;
  59. if (array_search( $exp, $this->sort )!==FALSE) return true;
  60. if ($primary) return array_unshift( $this->sort, $exp );
  61. return ( $this->sort[] = $exp);
  62. return true;
  63. }
  64. function getSort() {
  65. if (empty($this->sort)) return false;
  66. reset ($this->sort);
  67. return current( $this->sort );
  68. }
  69. function _assembleSQL( $criteria = null ) {
  70. $sql = $this->_makeSelect();
  71. $sql .= $this->_makeSource();
  72. $sql .= isset( $criteria ) ?
  73. ' WHERE ' . $criteria
  74. : $this->_makeCriteria();
  75. $sql .= $this->_makeSort();
  76. $sql .= $this->_makeLimit();
  77. return $sql;
  78. }
  79. function deleteData($criteria) {
  80. if (!$criteria) return false;
  81. $sql = "DELETE" . $this->_makeSource(). " where " . $criteria;
  82. if($this->dbcon->Execute($sql)) {
  83. AMP::debug_sql( $sql, get_class($this));
  84. $cached_sql = $this->_assembleSql( $criteria ) ;
  85. $this->dbcon->CacheFlush( $cached_sql );
  86. AMP::debug_sql( $sql, get_class($this). ' cleared cache');
  87. return $this->dbcon->Affected_Rows();
  88. }
  89. trigger_error ( sprintf( AMP_TEXT_ERROR_DATABASE_SQL_FAILED, get_class( $this ), 'delete', $this->dbcon->ErrorMsg(), $sql ));
  90. return false;
  91. }
  92. function updateData( $update_actions, $criteria = "1" ) {
  93. if (!is_array( $update_actions )) return false;
  94. $sql = "UPDATE " . $this->datatable . " SET " . join( ", ", $update_actions ) .
  95. " where " . $criteria;
  96. if ($this->dbcon->Execute($sql)) {
  97. AMP::debug_sql( $sql, get_class($this) . ' update');
  98. return $this->dbcon->Affected_Rows();
  99. }
  100. trigger_error ( sprintf( AMP_TEXT_ERROR_DATABASE_SQL_FAILED, get_class( $this ), 'update', $this->dbcon->ErrorMsg(), $sql ));
  101. return false;
  102. }
  103. function insertData( $values ){
  104. $source = new Record( $this->dbcon );
  105. $source->setSource( $this->datatable );
  106. $source->set( $values );
  107. $sql = $source->debug_insertSQL( );
  108. if ($this->dbcon->Execute($sql)) {
  109. AMP::debug_sql( $sql, get_class($this) . ' insert');
  110. return $this->dbcon->Affected_Rows();
  111. }
  112. trigger_error ( sprintf( AMP_TEXT_ERROR_DATABASE_SQL_FAILED, get_class( $this ), 'insert', $this->dbcon->ErrorMsg(), $sql ));
  113. return false;
  114. }
  115. function _makeSort() {
  116. if (empty($this->sort)) return false;
  117. return " ORDER BY ". join(", ", $this->sort);
  118. }
  119. function _makeLimit() {
  120. if (!( isset($this->limit) && $this->limit )) return false;
  121. return " LIMIT " .$this->_buildLimit();
  122. }
  123. function _buildLimit() {
  124. if (!isset($this->offset)) return $this->limit;
  125. return $this->offset . ', ' . $this->limit;
  126. }
  127. function setLimit( $qty ) {
  128. $this->limit = $qty;
  129. }
  130. function setOffset( $offset ) {
  131. $this->offset = $offset;
  132. }
  133. function getGroupedIndex($column) {
  134. $sql = "SELECT $column, count(" . $this->id_field . ") as qty FROM "
  135. . $this->datatable . $this->_makeCriteria() . " GROUP BY $column";
  136. AMP::debug_sql( $sql, get_class($this) . ' index');
  137. $result = $this->dbcon->CacheGetAssoc($sql);
  138. if ( !$result && $db_error = $this->dbcon->ErrorMsg( )) {
  139. trigger_error( sprintf( AMP_TEXT_ERROR_LOOKUP_SQL_FAILED, get_class($this) . __FUNCTION__, $db_error ) . $sql );
  140. }
  141. return $result;
  142. }
  143. function RecordCount() {
  144. if (!is_object($this->source)) return false;
  145. return $this->source->RecordCount();
  146. }
  147. function NoLimitRecordCount() {
  148. $sql = "SELECT count(" . $this->id_field . ") as qty from "
  149. . $this->datatable . $this->_makeCriteria();
  150. $set = $this->dbcon->Execute( $sql );
  151. if ( !$set && $db_error = $this->dbcon->ErrorMsg( )) {
  152. trigger_error( sprintf( AMP_TEXT_ERROR_LOOKUP_SQL_FAILED, get_class($this) . __FUNCTION__, $db_error ) . $sql );
  153. return 0;
  154. }
  155. AMP::debug_sql( $sql, get_class($this) . ' count');
  156. return $set->Fields( 'qty' );
  157. }
  158. function getIdFieldLookups( ) {
  159. if ( isset( $this->_id_field_lookups )) return $this->_id_field_lookups;
  160. return $this->id_field;
  161. }
  162. function setIdFieldLookups( $field ) {
  163. $this->_id_field_lookups = $field;
  164. }
  165. function getLookup($field, $use_sort = false ) {
  166. $set = array();
  167. if( !$this->makeReady() ) {
  168. $sql = "SELECT " . $this->getIdFieldLookups( ). ", $field " . $this->_makeSource()
  169. . $this->_makeCriteria();
  170. if ( $use_sort ) {
  171. $sql .= $this->_makeSort( );
  172. }
  173. $set = $this->dbcon->CacheGetAssoc( $sql );
  174. AMP::debug_sql( $sql, get_class($this) . ' lookup');
  175. if ( !$set && $db_error = $this->dbcon->ErrorMsg( )) {
  176. trigger_error( sprintf( AMP_TEXT_ERROR_LOOKUP_SQL_FAILED, get_class($this) . __FUNCTION__, $db_error ) . $sql );
  177. }
  178. } else {
  179. while($record = $this->getData()) {
  180. $set[$record['id']] = $record[$field];
  181. }
  182. }
  183. return $set;
  184. }
  185. function filter( $fieldname, $value, $max_qty=null ) {
  186. if (!$this->makeReady()) return false;
  187. $result = array();
  188. while( $data = $this->getData() ) {
  189. if (isset($max_qty) && count($result)==$max_qty) break;
  190. if ($data[ $fieldname ] != $value) continue;
  191. $result[ $data[$this->id_field] ] = $data;
  192. }
  193. if (empty($result)) return false;
  194. return $result;
  195. }
  196. function getArray() {
  197. if (!$this->makeReady()) return false;
  198. return $this->source->GetArray();
  199. }
  200. function instantiateItems($rows, $class) {
  201. if(empty($rows) or !$rows or !$class or !(class_exists($class))) return false;
  202. $items = array();
  203. foreach ($rows as $row) {
  204. $object = new $class();
  205. $object->set_data_from_db($row);
  206. $items[$object->id] = $object;
  207. }
  208. return $items;
  209. }
  210. function applySearch( $search_values, $run_query=true ) {
  211. $search = &$this->getSearch( );
  212. $search->applyValues( $search_values );
  213. if ( $run_query ) $this->readData( );
  214. }
  215. function &getSearch() {
  216. if ( !isset( $this->_search )) {
  217. $this->_search = new $this->_search_class( $this );
  218. }
  219. return $this->_search;
  220. }
  221. /**
  222. * Returns an array of fields which should be searched via exact, rather than %contains% methods
  223. *
  224. * @access public
  225. * @return array
  226. */
  227. function &getLiteralCriteria( ){
  228. return $this->_search_exact_values;
  229. }
  230. /**
  231. * Search all defined text fields for relevance to a search string
  232. *
  233. * @param mixed $search_string
  234. * @access public
  235. * @return void
  236. */
  237. function addCriteriaFulltext( $search_string, $sortby_relevance = false ) {
  238. $search = &$this->getSearch( );
  239. $fulltext_criteria = $search->getCriteriaFulltext( $search_string );
  240. $this->addCriteria( $fulltext_criteria );
  241. if ( $sortby_relevance ) $this->addSort( $fulltext_criteria . ' DESC' );
  242. }
  243. function getFullTextFields( ){
  244. return $this->_search_fulltext;
  245. }
  246. function makeCriteriaTag( $tag_value ) {
  247. if ( !isset( $this->_item_type )) {
  248. trigger_error( sprintf( AMP_TEXT_ERROR_NOT_DEFINED, get_class( $this ), '_item_type' ));
  249. trigger_error( sprintf( AMP_TEXT_ERROR_CREATE_FAILED, get_class( $this ), 'tag criteria ' . $tag_value ));
  250. return false;
  251. }
  252. $lookup_type = AMP_pluralize( $this->_item_type ) . 'ByTag' ;
  253. $id_set = AMPSystem_Lookup::instance( $lookup_type, $tag_value );
  254. if ( !$id_set || empty( $id_set )) return 'FALSE';
  255. return $this->id_field . ' IN ( '. join( ',', array_keys( $id_set ) ) . ')';
  256. }
  257. function setSortAndLimit( $options ) {
  258. $order_by = isset( $options['sort']) && $options['sort'] ? $options['sort'] : false;
  259. $source_limit = isset( $options['limit']) && $options['limit'] ? $options['limit'] : false;
  260. $source_offset = isset( $options['offset']) && $options['offset'] ? $options['offset'] : false;
  261. if ( $order_by || $source_limit || $source_offset ) {
  262. if( $order_by ) {
  263. $this->setSort( $order_by );
  264. }
  265. if ( $source_limit ) {
  266. $this->setLimit( $source_limit );
  267. }
  268. if ( $source_offset ) {
  269. $this->setOffset( $source_offset );
  270. }
  271. }
  272. }
  273. }