PageRenderTime 45ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 1ms

/classes/mysql.collection.class.php

https://github.com/magedeveloper/frosted-mysql-library
PHP | 743 lines | 360 code | 135 blank | 248 comment | 40 complexity | c52ef757dadefa28a4061df5f15a484d MD5 | raw file
  1. <?php
  2. /**
  3. * MySQL Collection Class
  4. * - - - - - - - - - -
  5. * Collection to further handle or filter mysql results by mysqlClass.
  6. * - - - - - - - - - -
  7. * Licensed under MIT license
  8. * - - - - - - - - - -
  9. * @Creator Daniel 'Eisbehr' Kern
  10. * @Require PHP5
  11. * @Version 3.0
  12. * @Date 01.08.2013
  13. * @Update 01.08.2013
  14. * - - - - - - - - - -
  15. */
  16. class mysqlClass_Collection implements IteratorAggregate, Countable, ArrayAccess
  17. {
  18. /**
  19. * collection rows
  20. * @var mysqlClass_CollectionItem array
  21. */
  22. private $rows = array();
  23. /**
  24. * active filters
  25. * @var array
  26. */
  27. private $filters = array();
  28. /**
  29. * active filters
  30. * @var boolean
  31. */
  32. private $isFiltersLoaded = true;
  33. /**
  34. * total records
  35. * @var integer
  36. */
  37. private $totalRecords = 0;
  38. /**
  39. * logical operators
  40. * @var string
  41. */
  42. const LOGIC_EQ = "eq";
  43. const LOGIC_SEQ = "seq";
  44. const LOGIC_NEQ = "neq";
  45. const LOGIC_SNEQ = "sneq";
  46. const LOGIC_LT = "lt";
  47. const LOGIC_GT = "gt";
  48. const LOGIC_LTE = "lte";
  49. const LOGIC_GTE = "gte";
  50. const LOGIC_LIKE = "like";
  51. const LOGIC_IN = "in";
  52. /*
  53. ** public
  54. */
  55. /**
  56. * destructor
  57. */
  58. public function __destruct()
  59. {
  60. unset($this->rows);
  61. unset($this->filters);
  62. }
  63. /*
  64. ** item getter
  65. */
  66. /**
  67. * get all collection items as array
  68. * @return array
  69. */
  70. public function getItems()
  71. {
  72. return $this->rows;
  73. }
  74. /**
  75. * get collection size
  76. * @return integer
  77. */
  78. public function getSize()
  79. {
  80. return $this->totalRecords;
  81. }
  82. /**
  83. * gets an specific collection item by position
  84. * @param int $position
  85. * @return mysqlClass_CollectionItem
  86. */
  87. public function getItem($position)
  88. {
  89. if( $position >= 0 && $position < $this->totalRecords )
  90. {
  91. return array_slice($this->rows, $position, 1);
  92. }
  93. return false;
  94. }
  95. /**
  96. * get collection item by id
  97. * @param mixed $id
  98. * @return mysqlClass_CollectionItem
  99. */
  100. public function getItemById($id)
  101. {
  102. if( isset($this->rows[$id]) )
  103. {
  104. return $this->rows[$id];
  105. }
  106. return false;
  107. }
  108. /**
  109. * get first item in collection
  110. * @return mysqlClass_CollectionItem
  111. */
  112. public function getFirstItem()
  113. {
  114. if( !empty($this->rows) )
  115. {
  116. return array_slice($this->rows, 0, 1);
  117. }
  118. return false;
  119. }
  120. /**
  121. * get last item in collection
  122. * @return mysqlClass_CollectionItem
  123. */
  124. public function getLastItem()
  125. {
  126. if( !empty($this->rows) )
  127. {
  128. return array_slice($this->rows, -1, 1);
  129. }
  130. return false;
  131. }
  132. /**
  133. * get first collection item by column value
  134. * @param string $column
  135. * @param mixed $value
  136. * @return mysqlClass_CollectionItem
  137. */
  138. public function getItemByColumnValue($column, $value)
  139. {
  140. foreach( $this->rows as $item )
  141. {
  142. if( $item instanceof mysqlClass_CollectionItem && $item->getData($column) === $value )
  143. {
  144. return $item;
  145. }
  146. }
  147. return false;
  148. }
  149. /**
  150. * get all collection items by column value
  151. * @param string $column
  152. * @param mixed $value
  153. * @return array
  154. */
  155. public function getItemsByColumnValue($column, $value)
  156. {
  157. $items = array();
  158. foreach( $this->rows as $item )
  159. {
  160. if( $item instanceof mysqlClass_CollectionItem && $item->getData($column) === $value )
  161. {
  162. $items[] = $item;
  163. }
  164. }
  165. return $items;
  166. }
  167. /**
  168. * retrieve empty collection item
  169. * @return mysqlClass_CollectionItem
  170. */
  171. public function getNewEmptyItem()
  172. {
  173. return new mysqlClass_CollectionItem();
  174. }
  175. /**
  176. * get a new collection item with default data
  177. * @param array $data
  178. * @return mysqlClass_CollectionItem
  179. */
  180. public function getNewItemWithData($data = array())
  181. {
  182. $item = new mysqlClass_CollectionItem();
  183. foreach( $data as $key => $value )
  184. if( !empty($key) )
  185. $item->setData($key, $value);
  186. return $item;
  187. }
  188. /*
  189. ** getter
  190. */
  191. /**
  192. * retrieve all item ids
  193. * @return array
  194. */
  195. public function getAllIds()
  196. {
  197. return array_keys($this->rows);
  198. }
  199. /**
  200. * retrieve column values from all collection items
  201. * @param string $columnName
  202. * @param boolean $unique
  203. * @return array
  204. */
  205. public function getColumnValues($columnName, $unique = false)
  206. {
  207. $columnValues = array();
  208. foreach( $this->rows as $item )
  209. {
  210. if( !($item instanceof mysqlClass_CollectionItem) )
  211. continue;
  212. $value = $item->getData($columnName);
  213. if( $unique )
  214. {
  215. if( !in_array($value, $columnValues) ) $columnValues[] = $value;
  216. }
  217. else
  218. {
  219. $columnValues[] = $value;
  220. }
  221. }
  222. return $columnValues;
  223. }
  224. /**
  225. * implementation of IteratorAggregate
  226. * @return ArrayIterator
  227. */
  228. public function getIterator()
  229. {
  230. return new ArrayIterator($this->rows);
  231. }
  232. /*
  233. ** public methods
  234. */
  235. /**
  236. * add an item to collection
  237. * @param mysqlClass_CollectionItem $item
  238. * @throws Exception
  239. * @return mysqlClass_Collection
  240. */
  241. public function addItem($item)
  242. {
  243. $itemId = $item->getData("id");
  244. if( !is_null($itemId) )
  245. {
  246. if( isset($this->rows[$itemId]) )
  247. {
  248. throw new Exception("item with the same id '" . $itemId . "' already exists");
  249. }
  250. $this->rows[$itemId] = $item;
  251. }
  252. else
  253. {
  254. $this->rows[] = $item;
  255. }
  256. $this->totalRecords++;
  257. return $this;
  258. }
  259. /**
  260. * set data for all collection items
  261. * @param string $key
  262. * @param mixed $value
  263. * @return mysqlClass_Collection
  264. */
  265. public function setDataToAll($key, $value=null)
  266. {
  267. if( is_array($key) )
  268. {
  269. foreach( $key as $_key => $_value )
  270. {
  271. $this->setDataToAll($_key, $_value);
  272. }
  273. return $this;
  274. }
  275. foreach( $this->rows as $item )
  276. {
  277. if( $item instanceof mysqlClass_CollectionItem)
  278. $item->setData($key, $value);
  279. }
  280. return $this;
  281. }
  282. /**
  283. * return the index of given object or id
  284. * @param mysqlClass_CollectionItem|string|integer $object
  285. * @return integer
  286. */
  287. public function indexOf($object)
  288. {
  289. $position = 0;
  290. if( $object instanceof mysqlClass_CollectionItem )
  291. {
  292. $object = $object->getData("id");
  293. }
  294. foreach( $this->rows as $id => $item)
  295. {
  296. if( $id === $object )
  297. {
  298. return $position;
  299. }
  300. ++$position;
  301. }
  302. return false;
  303. }
  304. /**
  305. * check if item id exists in collection
  306. * @param integer|string $id
  307. * @return boolean
  308. */
  309. public function exists($id)
  310. {
  311. return isset($this->rows[$id]);
  312. }
  313. /**
  314. * check if the collection is empty or not
  315. * @return boolean
  316. */
  317. public function isEmpty()
  318. {
  319. if( $this->totalRecords == 0 )
  320. {
  321. return true;
  322. }
  323. return false;
  324. }
  325. /**
  326. * check if given object exists in collection
  327. * @param mysqlClass_CollectionItem $item
  328. * @return bool
  329. */
  330. public function contains($item)
  331. {
  332. if( $item instanceof mysqlClass_CollectionItem )
  333. {
  334. return isset($this->rows[$item->getData("id")]);
  335. }
  336. return false;
  337. }
  338. /**
  339. * get collection item count
  340. * @return integer
  341. */
  342. public function count()
  343. {
  344. return count($this->rows);
  345. }
  346. /**
  347. * alias of count
  348. * @return integer
  349. */
  350. public function length()
  351. {
  352. return $this->count();
  353. }
  354. /**
  355. * serializes collection items
  356. * @return string
  357. */
  358. public function serialize()
  359. {
  360. return serialize($this->rows);
  361. }
  362. /**
  363. * unserialize data and store into collection
  364. * @param string $data
  365. */
  366. public function unserialize($data)
  367. {
  368. $this->rows = unserialize($data);
  369. }
  370. /**
  371. * remove item from collection by item id
  372. * @param string|integer $id
  373. * @return mysqlClass_Collection
  374. */
  375. public function removeItemById($id)
  376. {
  377. if(isset($this->rows[$id]))
  378. {
  379. unset($this->rows[$id]);
  380. $this->totalRecords--;
  381. }
  382. return $this;
  383. }
  384. /**
  385. * clear collection items
  386. * @return mysqlClass_Collection
  387. */
  388. public function clear()
  389. {
  390. $this->rows = array();
  391. return $this;
  392. }
  393. /**
  394. * reset collection
  395. * @return mysqlClass_Collection
  396. */
  397. public function reset()
  398. {
  399. return $this->clear();
  400. }
  401. /*
  402. ** filter
  403. */
  404. /**
  405. * adds an column to filter
  406. * @param string $column
  407. * @param string $value
  408. * @param string $logic
  409. * @return mysqlClass_Collection
  410. */
  411. public function addColumnToFilter($column, $value, $logic = self::LOGIC_EQ)
  412. {
  413. $filter = array();
  414. $filter["field"] = $column;
  415. $filter["value"] = $value;
  416. $filter["logic"] = strtolower($logic);
  417. $this->filters[] = $filter;
  418. $this->filterCollection($column, $value, $logic);
  419. return $this;
  420. }
  421. /**
  422. * alias of addColumnToFilter
  423. * @param string $field
  424. * @param string $value
  425. * @param string $logic
  426. * @return mysqlClass_Collection
  427. */
  428. public function addFieldToFilter($field, $value, $logic = self::LOGIC_EQ)
  429. {
  430. return $this->addColumnToFilter($field, $value, $logic);
  431. }
  432. /**
  433. * gets an collection of filtered items
  434. * @param string $field
  435. * @param string $value
  436. * @param string $logic
  437. * @return mysqlClass_Collection
  438. */
  439. public function filterCollection($field, $value, $logic = self::LOGIC_EQ)
  440. {
  441. $filteredCollection = new self();
  442. // only convert value once
  443. if( $logic == self::LOGIC_IN )
  444. $value = is_array($value) ? $value : explode(",", $value);
  445. foreach( $this->rows as $item )
  446. {
  447. if( !($item instanceof mysqlClass_CollectionItem) )
  448. continue;
  449. switch( $logic )
  450. {
  451. case self::LOGIC_IN:
  452. if( in_array($item->getData($field), $value) ) $filteredCollection->addItem($item);
  453. break;
  454. case self::LOGIC_LIKE:
  455. if( strpos(strtolower($item->getData($field)), strtolower($value)) !== false ) $filteredCollection->addItem($item);
  456. break;
  457. case self::LOGIC_GT:
  458. if( intval($item->getData($field)) > intval($value) ) $filteredCollection->addItem($item);
  459. break;
  460. case self::LOGIC_LT:
  461. if( intval($item->getData($field)) < intval($value) ) $filteredCollection->addItem($item);
  462. break;
  463. case self::LOGIC_GTE:
  464. if( intval($item->getData($field)) >= intval($value) ) $filteredCollection->addItem($item);
  465. break;
  466. case self::LOGIC_LTE:
  467. if( intval($item->getData($field)) <= intval($value) ) $filteredCollection->addItem($item);
  468. break;
  469. case self::LOGIC_NEQ:
  470. if( $item->getData($field) != $value ) $filteredCollection->addItem($item);
  471. break;
  472. case self::LOGIC_SNEQ:
  473. if( $item->getData($field) !== $value ) $filteredCollection->addItem($item);
  474. break;
  475. case self::LOGIC_SEQ:
  476. if( $item->getData($field) === $value ) $filteredCollection->addItem($item);
  477. break;
  478. case self::LOGIC_EQ:
  479. default:
  480. if( $item->getData($field) == $value ) $filteredCollection->addItem($item);
  481. break;
  482. }
  483. }
  484. $this->isFiltersLoaded = true;
  485. $this->rows = $filteredCollection->getItems();
  486. unset($filteredCollection);
  487. return $this;
  488. }
  489. /*
  490. ** callbacks
  491. */
  492. /**
  493. * walk through the collection and returns array with results
  494. * @param string $callback
  495. * @param array $arguments
  496. * @return array
  497. */
  498. public function walk($callback, $arguments = array())
  499. {
  500. $results = array();
  501. foreach( $this->rows as $id => $item )
  502. {
  503. array_unshift($arguments, $item);
  504. $results[$id] = call_user_func_array($callback, $arguments);
  505. }
  506. return $results;
  507. }
  508. /**
  509. *
  510. * @param $callback
  511. * @param array $arguments
  512. * @return mysqlClass_Collection
  513. */
  514. public function each($callback, $arguments = array())
  515. {
  516. foreach( $this->rows as $id => $item )
  517. {
  518. array_unshift($arguments, $item);
  519. $this->rows[$id] = call_user_func_array($callback, $arguments);
  520. }
  521. return $this;
  522. }
  523. /*
  524. ** output
  525. */
  526. /**
  527. * return collection as xml
  528. * @return string
  529. */
  530. public function toXml()
  531. {
  532. $xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
  533. $xml .= "<collection>\n";
  534. $xml .= " <totalRecords>" . $this->totalRecords . "</totalRecords>\n";
  535. $xml .= " <items>\n";
  536. foreach( $this->rows as $item )
  537. {
  538. if( $item instanceof mysqlClass_CollectionItem )
  539. $xml .= $item->toXml(true);
  540. }
  541. $xml .= " <items>\n";
  542. $xml .= "<collection>\n";
  543. return $xml;
  544. }
  545. /**
  546. * return collection as array
  547. * @param array $requiredFields
  548. * @return array
  549. */
  550. public function toArray($requiredFields = array())
  551. {
  552. $array = array();
  553. $array["totalRecords"] = $this->totalRecords;
  554. $array["items"] = array();
  555. foreach( $this->rows as $id => $item )
  556. {
  557. if( $item instanceof mysqlClass_CollectionItem )
  558. $array["items"][$id] = $item->toArray($requiredFields);
  559. }
  560. return $array;
  561. }
  562. /**
  563. * return collection as string
  564. * @return string
  565. */
  566. public function toString()
  567. {
  568. return $this->serialize();
  569. }
  570. /*
  571. ** array access
  572. */
  573. /**
  574. * implementation of ArrayAccess
  575. * @param string $id
  576. * @param mixed $value
  577. */
  578. public function offsetSet($id, $value)
  579. {
  580. $this->rows[$id] = $value;
  581. }
  582. /**
  583. * implementation of ArrayAccess
  584. * @param string $id
  585. * @return boolean
  586. */
  587. public function offsetExists($id)
  588. {
  589. return isset($this->rows[$id]);
  590. }
  591. /**
  592. * implementation of ArrayAccess
  593. * @param string $id
  594. */
  595. public function offsetUnset($id)
  596. {
  597. unset($this->rows[$id]);
  598. }
  599. /**
  600. * implementation of ArrayAccess
  601. * @param string $id
  602. * @return mysqlClass_CollectionItem
  603. */
  604. public function offsetGet($id)
  605. {
  606. return isset($this->rows[$id]) ? $this->rows[$id] : false;
  607. }
  608. }