/wp-content/app/code/core/Xedin/Core/Model/Db/Adapter.php
PHP | 854 lines | 580 code | 135 blank | 139 comment | 97 complexity | 1a139c9473b9046796f3699f076bb59e MD5 | raw file
- <?php
- /**
- * This is an object-oriended wrapper for the native WordPress wpdb class
- * that provides an ActiveRecord-style database interface.
- *
- * Using andWhere/orWhere functions with two-dimensional arrays, it is possible
- * to execute queries with very complex conditions.
- *
- * To retreive all records from a table, just use the from(), where() and
- * execute() functions consecutively.
- *
- * Results are provided in a form of multidimensional arrays.
- * Automatic table prefixing.
- *
- * @version 0.1.2
- * + Added join() and group() functions
- *
- * @author Xedin Unknown <xedin.unknown@gmail.com>
- */
- class Xedin_Core_Model_Db_Adapter {
- protected $_connection;
- protected $_result;
- protected $_lastResult;
- protected $_lastQuery;
- protected $_insertId;
- protected $_affectedRows;
-
- protected $_parts = array();
- protected $_isDebugMode = false;
- protected $_isAutoPrefix = true;
- const MYSQL_FIELD_NAME_KEY = 'Field';
- protected $_joinTypes = array(
- 'join',
- 'left join',
- 'right join',
- 'left outer join',
- 'right outer join',
- 'natural left join',
- 'natural right join',
- 'natural left outer join',
- 'natural right outer join',
- 'inner join',
- 'cross join'
- );
- public function __construct() {
- global $wpdb;
- $this->_connection = $wpdb->dbh;
- }
- public function isDebug($isDebug = null) {
- if (is_null($isDebug)) {
- return $this->_isDebugMode;
- }
- $this->_isDebugMode = $isDebug;
- return $this;
- }
- protected function _debug($text) {
- if ($this->isDebug()) {
- echo $text . "\n";
- }
- }
-
- public function isAutoPrefix($autoPrefix = null) {
- if( is_null($autoPrefix) ) {
- return $this->_isAutoPrefix;
- }
-
- $this->_isAutoPrefix = $autoPrefix;
- return $this;
- }
- protected function _addPart($partName, $value, $section = null, $explicitArray = false) {
- if ( ($value instanceof Zend_Db_Expr) || (!is_array($value) || $explicitArray) ) {
- if (empty($section)) {
- if (strtolower($partName) == 'from' && in_array($value, $this->_parts[$partName])) {
- return $this;
- }
- $this->_debug('adding ' . $partName . ' part "' . $value . '"');
- $this->_parts[$partName][] = $value;
- } else {
- $this->_parts[$partName][$section][] = $value;
- }
- return $this;
- }
- foreach ($value as $idx => $_value) {
- $this->_addPart($partName, $_value, $section, false);
- }
- return $this;
- }
- protected function _getPart($partName) {
- if (!isset($this->_parts[$partName]) || empty($this->_parts[$partName])) {
- return null;
- }
- return $this->_parts[$partName];
- }
- /**
- * @param <type> $fieldNames
- * @return Xedin_Core_Model_Db_Adapter
- */
- public function select($fieldNames) {
- $this->_debug('selecting "' . implode(',', (array) $fieldNames) . '"');
- $this->_addPart('select', $fieldNames);
- return $this;
- }
- /**
- * @param <type> $tableName
- * @param <type> $fieldNames
- * @return Xedin_Core_Model_Db_Adapter
- */
- public function update($tableName, $fieldNames) {
- $this->_addPart('update', $tableName);
- $this->_parts['set'] = $fieldNames;
- return $this;
- }
- /**
- * @param <type> $tableName
- * @param <type> $values
- * @param <type> $fieldNames
- * @return Xedin_Core_Model_Db_Adapter
- */
- public function insert($tableName, $values, $fieldNames = null) {
- $this->_addPart('into', $tableName);
- $this->_addPart('values', $values);
- if (!is_null($fieldNames)) {
- $this->_addPart('_fields', $fieldNames);
- }
- return $this;
- }
- /**
- * @param <type> $tableName
- * @param <type> $tableAlias
- * @return Xedin_Core_Model_Db_Adapter
- */
- public function from($tableName, $tableAlias = null) {
- if (!is_array($tableName)) {
- $fromEntry = array('table_name' => $tableName);
- if (!is_null($tableAlias)) {
- $fromEntry['alias'] = $tableAlias;
- }
- $this->_parts['from'][] = $fromEntry;
- return $this;
- }
- foreach ($tableName as $idx => $value) {
- // If numeric index, add with no alias
- if (is_number($idx)) {
- $this->from($value);
- } else {
- $this->from($idx, $value);
- }
- }
- return $this;
- }
- /**
- * @param <type> $conditions
- * @param <type> $all
- * @return Xedin_Core_Model_Db_Adapter
- */
- public function where($conditions, $all = false) {
- $this->andWhere($conditions, $all);
- return $this;
- }
- /**
- * @param array $conditions
- * @param bool $all
- * @return Xedin_Core_Model_Db_Adapter
- */
- public function andWhere($conditions, $all = false) {
- if (isset($conditions['field']) || (isset($conditions[0]) && !is_array($conditions[0]))) {
- $conditions = array($conditions);
- }
- $this->_parts['where']['and'][] = array('conditions' => $conditions, 'all' => $all);
- return $this;
- }
- /**
- * @param <type> $conditions
- * @param <type> $all
- * @return Xedin_Core_Model_Db_Adapter
- */
- public function orWhere($conditions, $all = false) {
- if (isset($conditions['field']) || (isset($conditions[0]) && !is_array($conditions[0])) || $conditions instanceof Zend_Db_Expr ) {
- $conditions = array($conditions);
- }
- $this->_parts['where']['or'][] = array('conditions' => $conditions, 'all' => $all);
- return $this;
- }
- /**
- * @return Xedin_Core_Model_Db_Adapter
- */
- public function delete() {
- $this->_addPart('delete', true);
- return $this;
- }
- /**
- * @param string|Zend_Db_Expression $fieldName
- * @param bool $ascending
- * @return Xedin_Core_Model_Db_Adapter
- */
- public function orderBy($fieldName, $ascending = true) {
- if( $fieldName instanceof Zend_Db_Expr ) {
- /* @var $fieldName Zend_Db_Expr */
- $this->_parts['order'] = $fieldName;
- return $this;
- }
-
- $order = $ascending ? 'asc' : 'desc';
- foreach ($fieldName as $idx => $_fieldName) {
- $this->_parts['order'][$order][$field][] = $_fieldName;
- }
- return $this;
- }
- /**
- * @param <type> $limit
- * @param <type> $offset
- * @return Xedin_Core_Model_Db_Adapter
- */
- public function limit($limit, $offset = 0) {
- $this->_parts['limit'] = array('limit' => $limit, 'offset' => $offset);
- return $this;
- }
- public function quoteField($fieldName) {
- if (!is_array($fieldName)) {
- $fieldName = array($fieldName);
- }
- foreach ($fieldName as $idx => $_fieldName) {
- if (stripos($_fieldName, '.')) {
- $complexName = explode('.', $_fieldName);
- // if (!$this->hasFrom($complexName[0])) {
- // $this->from($complexName[0]);
- // }
- $tableName = $complexName[0];
- if( $this->isAutoPrefix() ) {
- $tableName = $this->getPrefix($tableName);
- }
- $complexName[0] = $this->_surround($tableName, '`', null);
- if (trim($complexName[1]) != '*') {
- $complexName[1] = $this->_surround($complexName[1], '`', null);
- }
- $fieldName[$idx] = implode('.', $complexName);
- } else {
- $fieldName[$idx] = $this->_surround($_fieldName, '`');
- }
- }
- return implode(', ', $fieldName);
- }
- public function hasFrom($tableName) {
- $fromPart = $this->_getPart('from');
- foreach ($fromPart as $idx => $_from) {
- if ($_from['table_name'] == $tableName) {
- return true;
- }
- }
- return false;
- }
- public function quoteValue($value) {
- return $this->_surround($value, '\'', null, ', ');
- }
- protected function _surround($string, $before, $after = null, $delimiter = null) {
- if (is_null($string)) {
- return 'NULL';
- }
- if (is_null($after)) {
- $after = $before;
- }
- if (!is_array($string)) {
- return $before . $string . $after;
- }
- $surroundedStrings = array();
- foreach ($string as $idx => $_string) {
- $surroundedStrings[] = $this->_surround($_string, $before, $after);
- }
- if (!is_null($delimiter)) {
- $surroundedStrings = implode($delimiter, $surroundedStrings);
- }
- return $surroundedStrings;
- }
- /**
- * @return string The complete query string from the current parts.
- */
- public function getQueryString() {
- $queryString = '';
- $hasPart = false;
- foreach (array('update', 'values', 'from', 'delete') as $idx => $_queryType) {
- if ($this->hasPart($_queryType)) {
- $hasPart = $_queryType;
- }
- }
- if (!$hasPart) {
- $this->_debug(print_r(debug_backtrace(), true));
- throw new Exception(get_class($this) . ': Query must be one of the following types: SELECT, INSERT, UPDATE, DELETE.');
- }
- switch ($hasPart) {
- case 'delete':
- $conditionString = $this->_getConditionString();
- $fromString = $this->_getFromString();
- $queryString .= $this->_getDeleteString() . $fromString . $conditionString;
- break;
- case 'from':
- $selectString = $this->_getSelectString();
- if (empty($selectString)) {
- $selectString = 'SELECT *' . "\n";
- }
- $conditionString = $this->_getConditionString();
- $joinString = $this->_getJoinString();
- $fromString = $this->_getFromString();
- $queryString .= $this->_getSelectString() . $fromString . $joinString . $conditionString . $this->_getGroupByString() . $this->_getOrderByString() . $this->_getLimitString();
- break;
- case 'values':
- $queryString .= $this->_getInsertString();
- break;
- case 'update':
- $queryString .= $this->_getUpdateString() . $this->_getConditionString();
- break;
- }
- return $queryString;
- }
- /**
- * @return string
- */
- protected function _getSelectString() {
- $selectString = '';
- $part = $this->_getPart('select');
- if (is_null($part)) {
- return 'SELECT *' . "\n";
- }
- $this->_debug('building select "' . implode(', ', (array) $part) . '"');
- $selectString = 'SELECT ' . $this->quoteField($part) . "\n";
- return $selectString;
- }
- /**
- * @return string
- */
- protected function _getInsertString() {
- $insertString = 'INSERT';
- $valuesPart = $this->_getPart('values');
- if (is_null($valuesPart)) {
- return '';
- }
- $intoPart = $this->_getPart('into');
- if (is_null($intoPart)) {
- return '';
- }
- $insertString .= ' INTO ' . $this->quoteField($this->getPrefix($intoPart)) . ' ';
- $fieldsPart = $this->_getPart('_fields');
- if (!is_null($fieldsPart)) {
- $insertString .= '(' . $this->quoteField($fieldsPart) . ')' . "\n";
- }
- $insertString .= 'VALUES (' . $this->quoteValue($valuesPart) . ')' . "\n";
- return $insertString;
- }
- /**
- * @return string
- */
- protected function _getFromString() {
- $fromString = 'FROM';
- $fromPart = $this->_getPart('from');
- if (is_null($fromPart)) {
- return '';
- }
- $fromEntries = array();
- foreach ($fromPart as $idx => $_from) {
- $fromEntry = '';
- if( $this->isAutoPrefix() ) {
- $_from['table_name'] = $this->getPrefix($_from['table_name']);
- }
- $fromEntry .= "\t" . $this->quoteField($_from['table_name']);
- if (isset($_from['alias']) && !empty($_form['alias'])) {
- $fromEntry .= '.' . $this->quoteField($_from['alias']);
- }
- $fromEntries[] = $fromEntry;
- }
- $fromString .= implode(', ', $fromEntries) . "\n";
- return $fromString;
- }
- /**
- * @return string
- */
- protected function _getUpdateString() {
- $updateString = '';
- $updatePart = $this->_getPart('update');
- $setPart = $this->_getPart('set');
- if (is_null($updatePart) || is_null($setPart)) {
- return '';
- }
- $updateString .= 'UPDATE ' . $this->quoteField($this->getPrefix($updatePart)) . "\n";
- $updateString .= 'SET ';
- $setEntries = array();
- foreach ($setPart as $field => $value) {
- $setEntries[] = $this->quoteField($field) . ' = ' . $this->quoteValue($value);
- }
- $updateString .= implode(', ', $setEntries) . "\n";
- return $updateString;
- }
- /**
- * @return string
- */
- protected function _getDeleteString() {
- $deleteString = '';
- $deletePart = $this->_getPart('delete');
- if (!$deletePart) {
- return '';
- }
- $deleteString = 'DELETE ';
- return $deleteString;
- }
- /**
- * @return string
- */
- protected function _getOrderByString() {
- $orderString = '';
- $orderPart = $this->_getPart('order');
- if (!$orderPart) {
- return '';
- }
- if( $orderPart instanceof Zend_Db_Expr ) {
- return 'ORDER BY ' . (string)$orderPart . "\n";
- }
-
- foreach ($orderPart as $idx => $_order) {
- $orderEntries = array();
- foreach ($_order as $idx2 => $_fieldName) {
- $orderEntries[] = $this->quoteField($_fieldName) . ' ' . ( (strtolower($_order) == 'asc') ? 'ASC' : 'DESC' );
- }
- $orderString .= implode(', ', $orderEntries);
- }
- return 'ORDER BY ' . $orderString . "\n";
- }
- /**
- * @return string
- */
- protected function _getLimitString() {
- $limitString = '';
- $limitPart = $this->_getPart('limit');
- if (!$limitPart) {
- return '';
- }
- if ($limitPart['offset']) {
- $limitString .= $limitPart['offset'] . ',';
- }
- $limitString .= $limitPart['limit'];
- return 'LIMIT ' . $limitString . "\n";
- }
- /**
- * @return string
- */
- protected function _getConditionString() {
- $conditionString = '';
- $wherePart = $this->_getPart('where');
- if (is_null($wherePart) || empty($wherePart)) {
- return 'WHERE 1 ';
- }
- $k = 0;
- foreach ($wherePart as $_typeKey => $_type) {
- /**
- * @var string $_typeKey either 'and' or 'or'
- * @var array $_type contains numbered sections
- */
- $i = 0;
- if( $k>0 ) {
- $conditionString .= ' AND ';
- }
- $whereEntry = '';
- foreach ($_type as $_sectionIndex => $_section) {
- /**
- * @var int $_sectionIndex Numeric index of section
- * @var array $_section Array
- */
- $conditionSections = array();
- // <editor-fold defaultstate="collapsed" desc="Inner conditions loop">
- foreach ($_section['conditions'] as $_conditionIndex => $_condition) {
- if (!is_array($_condition)) {
- $conditionSections[] = $_condition;
- continue;
- }
- $field = '';
- if (isset($_condition['field'])) {
- $field = $_condition['field'];
- } elseif (!isset($_condition['field']) && isset($_condition[0])) {
- $field = $_condition[0];
- } else {
- throw new Exception(get_class($this) . ': Field is not set in condition.');
- }
- $operator = '';
- $value = '';
- if (isset($_condition['operator'])) {
- $operator = $_condition['operator'];
- } elseif (!isset($_condition['operator']) && isset($_condition[1]) && isset($_condition[2])) {
- $operator = $_condition[1];
- } elseif (!isset($_codition['operator']) && isset($_condition[1]) && !isset($_condition[2])) {
- $operator = '=';
- $value = $_condition[1];
- } else {
- throw new Exception(get_class($this) . ': Operator not set in condition.');
- }
- if (isset($_condition['value'])) {
- $value = $_condition['value'];
- } elseif (!isset($_condition['value']) && isset($_condition[2])) {
- $value = $_condition[2];
- } else {
- if (!isset($_condition[1]))
- throw new Exception(get_class($this) . ': Value not set in condition.');
- }
- $field = $this->quoteField($field);
- $value = $this->quoteValue($value);
- if ($operator == 'IN' || $operator == 'NOT IN') {
- $value = '(' . $value . ')';
- }
- $conditionSections[] = $field . ' ' . $operator . ' ' . $value;
- }// </editor-fold>
- $logicalOperator = $_section['all'] ? ' AND ' : ' OR ';
- $whereEntry = implode($logicalOperator, $conditionSections);
- if (count($conditionSections) > 1) {
- $whereEntry = '(' . $whereEntry . ')';
- }
- if ($i > 0) {
- switch (strtolower($_typeKey)) {
- case 'and':
- $conditionString .= ' AND ';
- break;
- case 'or':
- $conditionString .= ' OR ';
- break;
- }
- }
- $conditionString .= $whereEntry;
- $i++;
- }
- $k++;
- }
- return 'WHERE ' . $conditionString . "\n";
- }
- /**
- * @return wpdb The wordpress database instance
- */
- public function getConnection() {
- return $this->_connection;
- }
- /**
- * @param string $part
- * @param bool $all
- * @return bool
- */
- public function hasPart($part, $all = false) {
- if (!is_array($part)) {
- $part = strtolower($part);
- return ( isset($this->_parts[$part]) && !empty($this->_parts[$part]) );
- }
- foreach ($part as $idx => $_part) {
- if ($all && !$this->hasPart($part)) {
- return false;
- } elseif (!$all && $this->hasPart($part)) {
- return true;
- }
- }
- return!$all;
- }
- public function execute() {
- $string = $this->getQueryString();
- $this->reset();
- $this->query($string);
- $result = $this->getResults();
- return $result;
- }
- public function reset() {
- $this->_parts = array();
- }
- public function flush() {
- @mysql_free_result($this->_result);
- $this->_result = null;
- $this->_lastResult = null;
- $this->_affectedRows = null;
- $this->_insertId = null;
- return $this;
- }
-
- /**
- * @param string $query
- * @return Xedin_Wordpress_Db
- */
- public function query($query) {
- $this->_debug($query);
-
- $this->flush();
-
- $this->_lastQuery = $query;
- $this->_result = mysql_query($query, $this->getConnection());if ( preg_match( '/^\s*(insert|delete|update|replace) /i', $query ) ) {
- $this->_affectedRows = mysql_affected_rows( $this->getConnection() );
- if ( preg_match( '/^\s*(insert|replace) /i', $query ) ) {
- $this->_insertId = mysql_insert_id($this->getConnection() );
- }
- }
-
- if ($this->getLastError()) {
- throw new Exception(get_class($this) . ': ' . $this->getLastError() . ' in query "' . $this->getLastQuery() . '".');
- }
- return $this;
- }
- /**
- * @param string $query
- * @return array Result array with rows.
- */
- public function getResults() {
- if( empty($this->_lastResult) ) {
- $this->_lastResult = array();
-
- while( $_row = mysql_fetch_assoc($this->_result) ) {
- $this->_lastResult[] = $_row;
- }
- }
-
- return $this->_lastResult;
- }
- public function getPrefix($tableName = '') {
- global $wpdb;
- if (empty($tableName)) {
- return $wpdb->prefix;
- }
- if (!is_array($tableName)) {
- return $wpdb->prefix . $tableName;
- }
- $prefixedTableNames = array();
- foreach ($tableName as $idx => $_tableName) {
- $prefixedTableNames[] = $wpdb->prefix . $_tableName;
- }
- return $prefixedTableNames;
- }
- public function getAffectedRows() {
- return $this->getConnection()->_affectedRows;
- }
- public function getInsertId() {
- return $this->_insertId;
- }
- public function getLastQuery() {
- return $this->_lastQuery;
- }
- public function getLastResult() {
- return $this->getConnection()->_lastResult;
- }
- public function getNumRows() {
- return mysql_num_rows($this->_result);
- }
-
- /**
- *
- * @return string|null Error text if error occured; null otherwise.
- */
- public function getLastError() {
- $lastError = mysql_error($this->getConnection());
- return empty($lastError) ? null : $lastError;
- }
- public function getQueries() {
- return $this->getConnection()->queries;
- }
- /**
- * Gets a list of table fields.
- * The table name will not be prefixed.
- * If the second parameter is false, returns an array containing arrays with field info.
- * Otherwise, returns an array containing field names.
- *
- * @see http://dev.mysql.com/doc/refman/5.0/en/show-columns.html
- * @param string $tableName Name of the table for which to list fields.
- * @param type $namesOnly Whether or not to exclude field info, leaving only field names. Default: false.
- * @return array Field information or list of field names.
- */
- public function getFieldList($tableName, $namesOnly = false) {
- $fields = $this->query('SHOW FIELDS FROM ' . $this->quoteField($tableName));
- if (!$namesOnly) {
- return $fields;
- }
- $fieldNames = array();
- foreach ($fields as $idx => $_fieldInfo) {
- $fieldNames[] = $_fieldInfo[self::MYSQL_FIELD_NAME_KEY];
- }
- return $fieldNames;
- }
- public function getOne($index = 0) {
- $result = $this->execute();
- // Temporary test
- if (!isset($result[$index])) {
- return array();
- }
- return $result[$index];
- }
- public function join($tables, $fields) {
- $tables = (array) $tables;
- $fields = (array) $fields;
- $this->_addPart('join', $tables, 'tables', true);
- $this->_addPart('join', $fields, 'fields', true);
- return $this;
- }
- protected function _getJoinString() {
- $string = '';
- foreach ($this->_joinTypes as $idx => $_joinType) {
- if (!$this->hasPart($_joinType)) {
- continue;
- }
- $_joinPart = $this->_getPart($_joinType);
- foreach ($_joinPart['tables'] as $i => $_tables) {
- if( $this->isAutoPrefix() ) {
- $_tables = $this->getPrefix($_tables);
- }
- $string .= strtoupper($_joinType) . ' ';
- $string .= '(' . $this->quoteField( $_tables ) . ')';
- $string .= ' ON ';
- $string .= '(';
- $fields = $_joinPart['fields'][$i];
- foreach ($fields as $k => $_conditions) {
- foreach ($_conditions as $_field1 => $_field2) {
- $string .= $this->quoteField($_field1) . ' = ' . $this->quoteField($_field2) . ' AND';
- }
- }
- $string = substr($string, 0, strlen($string) - 4); // Remove the " AND" from the end
- $string .= ')';
- $string .= "\n";
- }
- }
- return $string;
- }
-
- public function groupBy($fields) {
- $this->_addPart('group by', $fields);
- return $this;
- }
-
- public function group($fields) {
- $this->groupBy($fields);
- return $this;
- }
-
- protected function _getGroupByString() {
- if( !$this->hasPart('group by') ) {
- return '';
- }
-
- return 'GROUP BY ' . $this->quoteField($this->_getPart('group by')) . "\n";
- }
- }
- ?>