Short-circuit. if (empty($data) || empty($fields)) { return $data; } #-> Find the data we have an interest in. $result = array(); foreach ($data as $row) { if (isset($row[0])) { if (!isset($mergeMap)) { $mergeMap = array(); foreach ($row as $id => $nest) { is_numeric($id) && $mergeMap[] = $id; } } foreach ($mergeMap as $id) { $row = array_merge($row, $row[$id]); unset($row[$id]); } } $result[] = self::extractDataFromRow($fields, $row); } #-> Fin. return $result; } /** * Extract specified fields from a [nested] data row. * @param array $fields * @param array $row * @return array */ static public function extractDataFromRow(array $fields, array $row) { $result = array(); foreach ($fields as $key => $field) { if (is_array($field)) { if (is_numeric($key)) { $result[$key] = isset($row[$key]) ? self::extractData($field, $row) : array(); } else { $result[$key] = isset($row[$key]) ? self::extractDataFromRow($field, $row[$key]) : array(); } } else { if (is_numeric($key)) { $result[$field] = isset($row[$field]) ? $row[$field] : null; } else { if (!is_object($field)) { switch ($field) { case 'DateTime': isset($dateTimeFormat) || $dateTimeFormat = \Utility\Registry::getConfigParam('DateTimeFormat'); $result[$key] = isset($row[$key]) && is_object($row[$key]) ? $row[$key]->format($dateTimeFormat) : null; break; case 'Date': isset($dateTimeFormat) || $dateFormat = \Utility\Registry::getConfigParam('DateFormat'); $result[$key] = isset($row[$key]) && is_object($row[$key]) ? $row[$key]->format($dateFormat) : null; break; case 'Array': $result[$key] = isset($row[$key]) && !empty($row[$key]) ? unserialize($row[$key]) : array(); break; } } elseif (is_callable($field)) { $result[$key] = $field(isset($row[$key]) ? $row[$key] : null); } } } } return $result; } /** * Build DQL order by string from array input. * @param array $input * @param boolean $final * @return string */ static public function dqlOrder(array $input, $final = true) { $orderBy = array(); foreach ($input as $field => $direction) { $direction = 'DESC' == strtoupper($direction) ? 'DESC' : 'ASC'; $orderBy[] = "$field $direction"; } return ($final && !empty($orderBy)) ? 'ORDER BY ' . implode(', ', $orderBy) : implode(', ', $orderBy); } /** * Build DQL where statement from array input. * @param array $input * @param string $baseTable * @param boolean $final * @param number $prepend * @return array */ static public function dqlFilter(array $input, $baseTable, $final = true, $prepend = 0, $op = ' AND ') { $prepend++; $subPrepend = $prepend; $i = 0; $filter = array(); $params = array(); foreach ($input as $field => $value) { $i++; $param = 'p' . $prepend . 'd' . $i; !is_array($value) && !strpos($field, '.') && $field = "$baseTable.$field"; if (is_array($value)) { $subPrepend++; $subOp = (' AND ' == $op) ? ' OR ' : ' AND '; $parts = array(); $subFilter = self::dqlFilter($value, $baseTable, false, $subPrepend, $subOp); $filter[] = '(' . $subFilter['Where'] . ')'; $params = array_merge($params, $subFilter['Params']); } elseif (false !== strpos($value, '%')) { $filter[] = "$field LIKE :$param"; $params[$param] = $value; } elseif ('BETWEEN' == substr(strtoupper($value), 0, 7)) { $i++; $param2 = 'p' . $prepend . 'd' . $i; list($x, $y) = explode(',', trim(substr($value, 7, strlen($value) - 2))); $filter[] = "$field BETWEEN :$param AND :$param2"; $params[$param] = $x; $params[$param2] = $y; } elseif ('NOT IN' == substr(strtoupper($value), 0, 6)) { $filter[] = "$field NOT IN (:$param)"; $params[$param] = explode(',', trim(substr($value, 6, strlen($value) - 6))); } elseif ('=NULL' == strtoupper($value)) { $filter[] = "$field IS NULL"; } elseif ('!NULL' == strtoupper($value)) { $filter[] = "$field IS NOT NULL"; } elseif ('IN ' == substr(strtoupper($value), 0, 3)) { $filter[] = "$field IN (:$param)"; $params[$param] = explode(',', trim(substr($value, 3, strlen($value) - 3))); } elseif ('!=' == substr($value, 0, 2)) { $filter[] = "$field != :$param"; $params[$param] = trim(substr($value, 2, strlen($value) - 2)); } elseif ('<>' == substr($value, 0, 2)) { $filter[] = "$field <> :$param"; $params[$param] = trim(substr($value, 2, strlen($value) - 2)); } elseif ('<=' == substr($value, 0, 2)) { $filter[] = "$field <= :$param"; $params[$param] = trim(substr($value, 2, strlen($value) - 2)); } elseif ('>=' == substr($value, 0, 2)) { $filter[] = "$field >= :$param"; $params[$param] = trim(substr($value, 2, strlen($value) - 2)); } elseif ('>' == substr($value, 0, 1)) { $filter[] = "$field > :$param"; $params[$param] = trim(substr($value, 2, strlen($value) - 1)); } elseif ('<' == substr($value, 0, 1)) { $filter[] = "$field < :$param"; $params[$param] = trim(substr($value, 2, strlen($value) - 1)); } elseif ('=' == substr($value, 0, 1)) { $filter[] = "$field = :$param"; $params[$param] = trim(substr($value, 2, strlen($value) - 1)); } elseif ('!' == substr($value, 0, 1)) { $filter[] = "$field != :$param"; $params[$param] = trim(substr($value, 2, strlen($value) - 1)); } else { $filter[] = "$field = :$param"; $params[$param] = $value; } } return array( 'Where' => ($final && !empty($filter)) ? 'WHERE ' . implode($op, $filter) : implode($op, $filter), 'Params' => $params ); } static public function lockTables(array $write = array(), array $read = array()) { $locks = array(); if (empty($write) && empty($read)) { return; } foreach ($write as $table) { $locks[] = "$table WRITE"; } foreach ($read as $table) { $locks[] = "$table READ"; } \Utility\Registry::getEntityManager() ->getConnection() ->exec('LOCK TABLES ' . implode(', ', $locks)); } static public function unlockTables() { \Utility\Registry::getEntityManager() ->getConnection() ->exec('UNLOCK TABLES'); } static public function setReadCommittedIsolation() { \Utility\Registry::getEntityManager() ->getConnection() ->exec("SET SESSION tx_isolation='READ-COMMITTED'"); } static public function beginTransaction() { \Utility\Registry::getEntityManager() ->getConnection() ->exec('START TRANSACTION'); } static public function commitTransaction() { \Utility\Registry::getEntityManager() ->getConnection() ->exec('COMMIT'); } static public function rollbackTransaction() { \Utility\Registry::getEntityManager() ->getConnection() ->exec('ROLLBACK'); } }