PluginProbe ʕ •ᴥ•ʔ
WP All Import – Drag & Drop Import for CSV, XML, Excel & Google Sheets / trunk
WP All Import – Drag & Drop Import for CSV, XML, Excel & Google Sheets vtrunk
3.9.5 3.9.6 4.0.0 4.0.1 4.1.0 trunk 2.12 2.13 2.14 3.0 3.0.1 3.0.2 3.0.3 3.0.4 3.1.0 3.1.1 3.1.2 3.1.3 3.1.4 3.1.5 3.2.0 3.2.1 3.2.2 3.2.3 3.2.4 3.2.5 3.2.6 3.2.7 3.2.8 3.2.9 3.3.0 3.3.1 3.3.2 3.3.3 3.3.4 3.3.5 3.3.6 3.3.7 3.3.8 3.3.9 3.4.0 3.4.1 3.4.2 3.4.3 3.4.4 3.4.5 3.4.6 3.4.7 3.4.8 3.4.9 3.5.0 3.5.1 3.5.2 3.5.3 3.5.4 3.5.5 3.5.6 3.5.7 3.5.8 3.5.9 3.6.0 3.6.1 3.6.2 3.6.3 3.6.4 3.6.5 3.6.6 3.6.7 3.6.8 3.6.9 3.7.0 3.7.1 3.7.2 3.7.3 3.7.3-beta-1.0 3.7.4 3.7.4-beta-1.0 3.7.5 3.7.6 3.7.7 3.7.8 3.7.9 3.8.0 3.9.0 3.9.1 3.9.2 3.9.3 3.9.4
wp-all-import / models / model.php
wp-all-import / models Last commit date
file 10 years ago history 9 years ago image 3 weeks ago import 3 weeks ago model 3 weeks ago post 12 years ago template 12 years ago model.php 3 weeks ago
model.php
201 lines
1 <?php
2 /**
3 * Base class for models
4 *
5 * @author Maksym Tsypliakov <maksym.tsypliakov@gmail.com>
6 */
7 abstract class PMXI_Model extends ArrayObject {
8 /**
9 * WPDB instance
10 * @var wpdb
11 */
12 protected $wpdb;
13 /**
14 * Table name the model is linked to
15 * @var string
16 */
17 protected $table;
18 /**
19 * Array of columns representing primary key
20 * @var array
21 */
22 protected $primary = array('id');
23 /**
24 * Wether key field is auto_increment (sure make scence only if key s
25 * @var bool
26 */
27 protected $auto_increment = FALSE;
28
29 /**
30 * Cached data retrieved from database
31 * @var array
32 */
33 private static $meta_cache = array();
34
35 /**
36 * Initialize model
37 * @param array[optional] $data Array of record data to initialize object with
38 */
39 public function __construct() {
40 $this->wpdb = $GLOBALS['wpdb'];
41 }
42
43 /**
44 * Read records from database by specified fields and values
45 * When 1st parameter is an array, it expected to be an associative array of field => value pairs to read data by
46 * If 2 parameters are set, first one is expected to be a field name and second - it's value
47 *
48 * @param string|array $field
49 * @param mixed[optional] $value
50 * @return PMXI_Model
51 */
52 abstract public function getBy($field = NULL, $value = NULL);
53
54 /**
55 * Magic function to automatically resolve calls like $obj->getBy%FIELD_NAME%
56 * @param string $method
57 * @param array $args
58 * @return PMXI_Model
59 */
60 public function __call($method, $args) {
61 if (preg_match('%^get_?by_?(.+)%i', $method, $mtch)) {
62 array_unshift($args, $mtch[1]);
63 return call_user_func_array(array($this, 'getBy'), $args);
64 } else {
65 throw new Exception(esc_html("Requested method " . get_class($this) . "::$method doesn't exist."));
66 }
67 }
68
69 /**
70 * Bind model to database table
71 * @param string $tableName
72 * @return PMXI_Model
73 */
74 public function setTable($tableName) {
75 if ( ! is_null($this->table)) {
76 throw new Exception(esc_html('Table name cannot be changed once being set.'));
77 }
78 $this->table = $tableName;
79 if ( ! isset(self::$meta_cache[$this->table])) {
80 // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
81 $tableMeta = $this->wpdb->get_results("SHOW COLUMNS FROM $this->table", ARRAY_A);
82 $primary = array();
83 $auto_increment = false;
84 foreach ($tableMeta as $colMeta) {
85 if ('PRI' == $colMeta['Key']) {
86 $primary[] = $colMeta['Field'];
87 }
88 if ('auto_increment' == $colMeta['Extra']) {
89 $auto_increment = true;
90 break; // no point to iterate futher since auto_increment means corresponding primary key is simple
91 }
92 }
93 self::$meta_cache[$this->table] = array('primary' => $primary, 'auto_increment' => $auto_increment);
94 }
95 $this->primary = self::$meta_cache[$this->table]['primary'];
96 $this->auto_increment = self::$meta_cache[$this->table]['auto_increment'];
97
98 return $this;
99 }
100
101 /**
102 * Return database table name this object is bound to
103 * @return string
104 */
105 public function getTable() {
106 return $this->table;
107 }
108 /**
109 * Return column name with table name
110 * @param string $col
111 * @return string
112 */
113 public function getFieldName($col) {
114 return $this->table . '.' . $col;
115 }
116
117 /**
118 * Compose WHERE clause based on parameters provided
119 * @param string|array $field
120 * @param mixed[optional] $value
121 * @param string[optional] $operator AND or OR string, 'AND' by default
122 * @return string
123 */
124 protected function buildWhere($field, $value = NULL, $operator = NULL) {
125 if ( ! is_array($field)) {
126 $field = array($field => $value);
127 } else { // shift arguments
128 $operator = $value;
129 }
130 ! is_null($operator) or $operator = 'AND'; // apply default operator value
131
132 $where = array();
133 foreach ($field as $key => $val) {
134 if (is_int($key)) {
135 $where[] = '(' . call_user_func_array(array($this, 'buildWhere'), $val) . ')';
136 } else {
137 if ( ! preg_match('%^(.+?) *(=|<>|!=|<|>|<=|>=| (NOT +)?(IN|(LIKE|REGEXP|RLIKE)( BINARY)?))?$%i', trim($key), $mtch)) {
138 throw new Exception(esc_html('Wrong field name format.'));
139 }
140 $key = $mtch[1];
141 if (is_array($val) and (empty($mtch[2]) or 'IN' == strtoupper($mtch[4]))) {
142 $op = empty($mtch[2]) ? 'IN' : strtoupper(trim($mtch[2]));
143 // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
144 if (count($val)) $where[] = $this->wpdb->prepare("$key $op (" . implode(', ', array_fill(0, count($val), "%s")) . ")", $val);
145 } else {
146 $op = empty($mtch[2]) ? '=' : strtoupper(trim($mtch[2]));
147 // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
148 $where[] = $this->wpdb->prepare("$key $op %s", $val);
149 }
150 }
151 }
152 return implode(" $operator ", $where);
153 }
154
155 /**
156 * Return associative array with record data
157 * @param bool[optional] $serialize Whether returned fields should be serialized
158 * @return array
159 */
160 public function toArray($serialize = FALSE) {
161 $result = (array)$this;
162 if ($serialize) {
163 foreach ($result as $k => $v) {
164 if ( ! is_scalar($v)) {
165 $result[$k] = serialize($v);
166 }
167 }
168 }
169 return $result;
170 }
171
172 /**
173 * Check whether object data is empty
174 * @return bool
175 */
176 public function isEmpty() {
177 return $this->count() == 0;
178 }
179
180 /**
181 * Empty object data
182 * @return PMXI_Model
183 */
184 public function clear() {
185 $this->exchangeArray(array());
186 return $this;
187 }
188
189 /**
190 * Delete all content from model's table
191 * @return PMXI_Model
192 */
193 public function truncateTable() {
194 // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
195 if (FALSE !== $this->wpdb->query("TRUNCATE $this->table")) {
196 return $this;
197 } else {
198 throw new Exception(esc_html($this->wpdb->last_error));
199 }
200 }
201 }