initial commit
[namibia] / module / Utility / src / Utility / Doctrine.php
1 <?php
2 namespace Utility;
3
4
5
6 /**
7  * Some doctrine helper functionality.
8  * @author andre.fourie
9  */
10 class Doctrine
11 {
12
13         /**
14          * Extract specified fields from a dataset.
15          * @param array $fields
16          * @param array $data
17          * @return array
18          */
19         static public function extractData(array $fields, array $data)
20         {
21                 #-> Short-circuit.
22                 if (empty($data) || empty($fields))
23                 {
24                         return $data;
25                 }
26
27                 #-> Find the data we have an interest in.
28                 $result = array();
29                 foreach ($data as $row)
30                 {
31                         if (isset($row[0]))
32                         {
33                                 if (!isset($mergeMap))
34                                 {
35                                         $mergeMap = array();
36                                         foreach ($row as $id => $nest)
37                                         {
38                                                 is_numeric($id)
39                                                         && $mergeMap[] = $id;
40                                         }
41                                 }
42                                 foreach ($mergeMap as $id)
43                                 {
44                                         $row = array_merge($row, $row[$id]);
45                                         unset($row[$id]);
46                                 }
47                         }
48                         $result[] = self::extractDataFromRow($fields, $row);
49                 }
50
51                 #-> Fin.
52                 return $result;
53         }
54
55         /**
56          * Extract specified fields from a [nested] data row.
57          * @param array $fields
58          * @param array $row
59          * @return array
60          */
61         static public function extractDataFromRow(array $fields, array $row)
62         {
63                 $result = array();
64                 foreach ($fields as $key => $field)
65                 {
66                         if (is_array($field))
67                         {
68                                 if (is_numeric($key))
69                                 {
70                                         $result[$key] = isset($row[$key])
71                                                 ? self::extractData($field, $row)
72                                                 : array();
73                                 }
74                                 else
75                                 {
76                                         $result[$key] = isset($row[$key])
77                                                 ? self::extractDataFromRow($field, $row[$key])
78                                                 : array();
79                                 }
80                         }
81                         else
82                         {
83                                 if (is_numeric($key))
84                                 {
85                                         $result[$field] = isset($row[$field])
86                                                 ? $row[$field]
87                                                 : null;
88                                 }
89                                 else
90                                 {
91                                         if (!is_object($field))
92                                         {
93                                                 switch ($field)
94                                                 {
95                                                         case 'DateTime':
96                                                                 isset($dateTimeFormat)
97                                                                         || $dateTimeFormat = \Utility\Registry::getConfigParam('DateTimeFormat');
98                                                                 $result[$key] = isset($row[$key]) && is_object($row[$key])
99                                                                         ? $row[$key]->format($dateTimeFormat)
100                                                                         : null;
101                                                                 break;
102                                                         case 'Date':
103                                                                 isset($dateTimeFormat)
104                                                                         || $dateFormat = \Utility\Registry::getConfigParam('DateFormat');
105                                                                 $result[$key] = isset($row[$key]) && is_object($row[$key])
106                                                                         ? $row[$key]->format($dateFormat)
107                                                                         : null;
108                                                                 break;
109                                                         case 'Array':
110                                                                 $result[$key] = isset($row[$key]) && !empty($row[$key])
111                                                                         ? unserialize($row[$key])
112                                                                         : array();
113                                                                 break;
114                                                 }
115                                         }
116                                         elseif (is_callable($field))
117                                         {
118                                                 $result[$key] = $field(isset($row[$key]) ? $row[$key] : null);
119                                         }
120                                 }
121                         }
122                 }
123                 return $result;
124         }
125
126         /**
127          * Build DQL order by string from array input.
128          * @param array $input
129          * @param boolean $final
130          * @return string
131          */
132         static public function dqlOrder(array $input, $final = true)
133         {
134                 $orderBy = array();
135                 foreach ($input as $field => $direction)
136                 {
137                         $direction = 'DESC' == strtoupper($direction)
138                                 ? 'DESC'
139                                 : 'ASC';
140                         $orderBy[] = "$field $direction";
141                 }
142                 return ($final && !empty($orderBy))
143                         ? 'ORDER BY ' . implode(', ', $orderBy)
144                         : implode(', ', $orderBy);
145         }
146
147         /**
148          * Build DQL where statement from array input.
149          * @param array $input
150          * @param string $baseTable
151          * @param boolean $final
152          * @param number $prepend
153          * @return array
154          */
155         static public function dqlFilter(array $input, $baseTable, $final = true, $prepend = 0, $op = ' AND ')
156         {
157                 $prepend++;
158                 $subPrepend = $prepend;
159                 $i = 0;
160                 $filter = array();
161                 $params = array();
162                 foreach ($input as $field => $value)
163                 {
164                         $i++;
165                         $param = 'p' . $prepend . 'd' . $i;
166                         !is_array($value)
167                                 && !strpos($field, '.')
168                                 && $field = "$baseTable.$field";
169                         if (is_array($value))
170                         {
171                                 $subPrepend++;
172                                 $subOp = (' AND ' == $op)
173                                         ? ' OR '
174                                         : ' AND ';
175                                 $parts = array();
176                                 $subFilter = self::dqlFilter($value, $baseTable, false, $subPrepend, $subOp);
177                                 $filter[] = '(' . $subFilter['Where'] . ')';
178                                 $params = array_merge($params, $subFilter['Params']);
179                         }
180                         elseif (false !== strpos($value, '%'))
181                         {
182                                 $filter[] = "$field LIKE :$param";
183                                 $params[$param] = $value;
184                         }
185                         elseif ('BETWEEN' == substr(strtoupper($value), 0, 7))
186                         {
187                                 $i++;
188                                 $param2 = 'p' . $prepend . 'd' . $i;
189                                 list($x, $y) = explode(',', trim(substr($value, 7, strlen($value) - 2)));
190                                 $filter[] = "$field BETWEEN :$param AND :$param2";
191                                 $params[$param] = $x;
192                                 $params[$param2] = $y;
193                         }
194                         elseif ('NOT IN' == substr(strtoupper($value), 0, 6))
195                         {
196                                 $filter[] = "$field NOT IN (:$param)";
197                                 $params[$param] = explode(',', trim(substr($value, 6, strlen($value) - 6)));
198                         }
199                         elseif ('=NULL' == strtoupper($value))
200                         {
201                                 $filter[] = "$field IS NULL";
202                         }
203                         elseif ('!NULL' == strtoupper($value))
204                         {
205                                 $filter[] = "$field IS NOT NULL";
206                         }
207                         elseif ('IN ' == substr(strtoupper($value), 0, 3))
208                         {
209                                 $filter[] = "$field IN (:$param)";
210                                 $params[$param] = explode(',', trim(substr($value, 3, strlen($value) - 3)));
211                         }
212                         elseif ('!=' == substr($value, 0, 2))
213                         {
214                                 $filter[] = "$field != :$param";
215                                 $params[$param] = trim(substr($value, 2, strlen($value) - 2));
216                         }
217                         elseif ('<>' == substr($value, 0, 2))
218                         {
219                                 $filter[] = "$field <> :$param";
220                                 $params[$param] = trim(substr($value, 2, strlen($value) - 2));
221                         }
222                         elseif ('<=' == substr($value, 0, 2))
223                         {
224                                 $filter[] = "$field <= :$param";
225                                 $params[$param] = trim(substr($value, 2, strlen($value) - 2));
226                         }
227                         elseif ('>=' == substr($value, 0, 2))
228                         {
229                                 $filter[] = "$field >= :$param";
230                                 $params[$param] = trim(substr($value, 2, strlen($value) - 2));
231                         }
232                         elseif ('>' == substr($value, 0, 1))
233                         {
234                                 $filter[] = "$field > :$param";
235                                 $params[$param] = trim(substr($value, 2, strlen($value) - 1));
236                         }
237                         elseif ('<' == substr($value, 0, 1))
238                         {
239                                 $filter[] = "$field < :$param";
240                                 $params[$param] = trim(substr($value, 2, strlen($value) - 1));
241                         }
242                         elseif ('=' == substr($value, 0, 1))
243                         {
244                                 $filter[] = "$field = :$param";
245                                 $params[$param] = trim(substr($value, 2, strlen($value) - 1));
246                         }
247                         elseif ('!' == substr($value, 0, 1))
248                         {
249                                 $filter[] = "$field != :$param";
250                                 $params[$param] = trim(substr($value, 2, strlen($value) - 1));
251                         }
252                         else
253                         {
254                                 $filter[] = "$field = :$param";
255                                 $params[$param] = $value;
256                         }
257                 }
258                 return array(
259                                 'Where'  => ($final && !empty($filter))
260                                                                 ? 'WHERE ' . implode($op, $filter)
261                                                                 : implode($op, $filter),
262                                 'Params' => $params
263                 );
264         }
265
266         static public function lockTables(array $write = array(), array $read = array())
267         {
268                 $locks = array();
269                 if (empty($write) && empty($read))
270                 {
271                         return;
272                 }
273                 foreach ($write as $table)
274                 {
275                         $locks[] = "$table WRITE";
276                 }
277                 foreach ($read as $table)
278                 {
279                         $locks[] = "$table READ";
280                 }
281                 \Utility\Registry::getEntityManager()
282                         ->getConnection()
283                         ->exec('LOCK TABLES ' . implode(', ', $locks));
284         }
285
286         static public function unlockTables()
287         {
288                 \Utility\Registry::getEntityManager()
289                         ->getConnection()
290                         ->exec('UNLOCK TABLES');
291         }
292
293         static public function setReadCommittedIsolation()
294         {
295                 \Utility\Registry::getEntityManager()
296                         ->getConnection()
297                         ->exec("SET SESSION tx_isolation='READ-COMMITTED'");
298         }
299
300         static public function beginTransaction()
301         {
302                 \Utility\Registry::getEntityManager()
303                         ->getConnection()
304                         ->exec('START TRANSACTION');
305         }
306         static public function commitTransaction()
307         {
308                 \Utility\Registry::getEntityManager()
309                         ->getConnection()
310                         ->exec('COMMIT');
311         }
312
313         static public function rollbackTransaction()
314         {
315                 \Utility\Registry::getEntityManager()
316                         ->getConnection()
317                         ->exec('ROLLBACK');
318         }
319
320 }