list.php 4.66 KB
Newer Older
imac's avatar
imac committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
<?php
/**
 * Incapsulates behavior for list of database records
 * 
 * @author Max Tsiplyakov <makstsiplyakov@gmail.com>
 */
class PMAI_Model_List extends PMAI_Model {
	
	/**
	 * Total number of records in database which correspond last getBy rule without paging
	 * @var int
	 */
	protected $total = 0;

	/**
	 * Joined tables
	 * @var array
	 */
	protected $joined = array();
	/**
	 * Columns to select from database
	 * @var string
	 */
	protected $what = '*';
	/**
	 * Sets table to use in conjuction with primary list table
	 * @param string $table Table to join
	 * @param string $on Condition to join
	 * @param string $type Join type (INNER, OUTER, etc)
	 * @return PMAI_Model_List
	 */
	public function join($table, $on, $type = 'INNER') {
		$this->joined[] = ( ! is_null($type) ? $type . ' ' : '') . 'JOIN ' . $table . ' ON ' . $on;
		return $this;
	}
	
	/**
	 * Set columns to be selected from database
	 * @param array $columns
	 * @return PMAI_Model_List
	 */
	public function setColumns($columns) {
		is_array($columns) or $columns = func_get_args();
		$this->what = implode(', ', $columns);
		return $this;
	}
	
	/**
	 * Read records from database by specified fields and values
	 * When 1st parameter is an array, it's expected to be an associative array of field => value pairs to read data by 
	 * When 2nd parameter is a scalar, it's expected to be a field name and second parameter - it's value
	 * 
	 * @param string|array[optional] $field
	 * @param mixed[optional] $value
	 * @param string[optional] $orderBy Ordering rule
	 * @param int[optional] $page Paging paramter used to limit number of records returned
	 * @param int[optional] $perPage Page size when paging parameter is used (20 by default) 
	 * @return PMAI_Model_List
	 */
	public function getBy($field = NULL, $value = NULL, $orderBy = NULL, $page = NULL, $perPage = NULL, $groupBy = NULL) {
		if (is_array($field) or is_null($field)) { // when associative array is submitted, do not expect second paramter to be $value, but act as if there is no $value parameter at all
			$groupBy = $perPage; $perPage = $page; $page = $orderBy; $orderBy = $value; $value = NULL;
		}
		! is_null($perPage) or $perPage = 20; // set default value for page length
		$page = intval($page);
		
		$sql = "FROM $this->table ";
		$sql .= implode(' ', $this->joined);
		if ( ! is_null($field)) {
			$sql .= " WHERE " . $this->buildWhere($field, $value);
		}
		if ( ! is_null($groupBy)) {
			$sql .= " GROUP BY $groupBy";
		}
		is_null($orderBy) and $orderBy = implode(', ', $this->primary); // default sort order is by primary key
		$sql .= " ORDER BY $orderBy";
		if ($page > 0) {
			$sql = "SELECT SQL_CALC_FOUND_ROWS $this->what $sql LIMIT " . intval(($page - 1) * $perPage) . ", " . intval($perPage);
		} else {
			$sql = "SELECT $this->what $sql";
		}
		$result = $this->wpdb->get_results($sql, ARRAY_A);
		if (is_array($result)) {
			foreach ($result as $i => $row) {
				foreach ($row as $k => $v) {
					if (is_serialized($v)) {
						$result[$i][$k] = unserialize($v);
					}
				}
			}
			if ($page > 0) {
				$this->total = intval($this->wpdb->get_var('SELECT FOUND_ROWS()'));
			} else {
				$this->total = count($result);
			}
			$this->exchangeArray($result);
		} else {
			$this->total = 0;
			$this->clear();
		}
		return $this;
	}
	
	/**
	 * Count records in table
	 * @param string|array $field
	 * @param mixed[optional] $value
	 * @return int
	 */
	public function countBy($field = NULL, $value = NULL) {
		$sql = "SELECT COUNT(*) FROM $this->table ";
		$sql .= implode(' ', $this->joined);
		if ( ! is_null($field)) {
			$sql .= " WHERE " . $this->buildWhere($field, $value);
		}
		return intval($this->wpdb->get_var($sql));
	}
	
	/**
	 * Method returns number of rows in database which correspond last getBy query
	 * @return int
	 */
	public function total() {
		return $this->total;
	} 
	
	/**
	 * Converts elements to instances of specifield class. If includeFields are provided only fields listed are included
	 * @param string[optoinal] $elementClass
	 * @param array[optional] $includeFields
	 * @return PMAI_Model_List
	 */
	public function convertRecords($elementClass = NULL, $includeFields = NULL) {
		! is_null($elementClass) or $elementClass = preg_replace('%List$%', 'Record', get_class($this));
		if ( ! is_subclass_of($elementClass, PMAI_Plugin::PREFIX . 'Model_Record')) {
			throw new Exception("Provideded class name $elementClass must be a subclass of " . PMAI_Plugin::PREFIX . 'Model_Record');
		}
		$records = $this->exchangeArray(array());
		foreach ($records as $r) {
			$data = (array)$r;
			if ( ! is_null($includeFields)) {
				$data = array_intersect_key($data, array_flip($includeFields));
			}
			$this[] = new $elementClass($data);
		}
		return $this;
	}
	
}