database->adapter, $config->database->params->toArray()); Qs_Db::$_instance->query( 'SET NAMES utf8; SET LOCAL TIME_ZONE = ' .Qs_Db::$_instance->quote(sprintf('%+d:00', idate('Z') / 3600)) ); Zend_Db_Table::setDefaultAdapter(Qs_Db::$_instance); } return Qs_Db::$_instance; } public static function getSelect() { return static::getInstance()->select(); } /** * @static * @return Zend_Config | mixed * @throws Qs_Db_Exception */ public static function getConfig() { if (null === Qs_Db::$_config) { if (!Zend_Registry::isRegistered('config')) { throw new Qs_Db_Exception('config is not registered in Zend_Registry'); } Qs_Db::$_config = Zend_Registry::get('config'); } return Qs_Db::$_config; } public static function getTableName($shortName) { if (!isset(Qs_Db::$_tableNames[$shortName])) { $dbPrefix = explode('_', $shortName); $dbPrefix = reset($dbPrefix); $config = Qs_Db::getConfig(); /** @var Zend_Config $additionalDatabases */ if (null !== ($additionalDatabases = $config->database->get('additionalDatabases'))) { if (null !== ($database = $additionalDatabases->get($dbPrefix))) { $name = substr($shortName, strlen($dbPrefix) + 1); Qs_Db::$_tableNames[$shortName] = $database->name . '.' . $database->tablePrefix . $name; } else { Qs_Db::$_tableNames[$shortName] = $config->database->params->dbname . '.' . $config->database->tablePrefix . $shortName; } } else { Qs_Db::$_tableNames[$shortName] = $config->database->tablePrefix . $shortName; } } return Qs_Db::$_tableNames[$shortName]; } public static function getTableAlias($fullName) { if (($alias = array_search($fullName, Qs_Db::$_tableNames, true))) { return $alias; } $config = Qs_Db::getConfig(); $tablePrefix = $config->database->tablePrefix; /** @var Zend_Config $additionalDatabases */ if (null !== ($additionalDatabases = $config->database->get('additionalDatabases'))) { throw new Exception('Method does not support additional databases'); } else { $shortName = $fullName; if ($tablePrefix === substr($fullName, 0, strlen($tablePrefix))) { $shortName = substr($fullName, strlen($tablePrefix)); } Qs_Db::$_tableNames[$shortName] = $fullName; } return $shortName; } public static function filter(Zend_Db_Select $select, array $filter, $alias) { if (empty($filter)) { return false; } $tableInfo = Qs_Array::get($select->getPart(Zend_Db_Select::FROM), $alias); if (null === $tableInfo) { throw new Qs_Db_Exception( 'Alias "' . $alias . '" not found in select "FROM" part' . print_r($select->getPart(Zend_Db_Select::FROM), true) ); } $table = new Qs_Db_Table(array('name' => $tableInfo['tableName'], 'schema' => $tableInfo['schema'])); $metaData = $table->getMetaData(); foreach ($filter as $field => $value) { if (!array_key_exists($field, $metaData)) { continue; } $_field = $select->getAdapter()->quoteIdentifier($alias . '.' . $field); if (is_null($value)) { $_conditionAndValue = 'IS NULL'; } else { $type = Qs_Db::_getMetaTypeToType(Qs_Array::get($metaData, $field . '[DATA_TYPE]')); $_condition = is_array($value) ? ' IN (?)' : '= ?'; $_conditionAndValue = $select->getAdapter()->quoteInto($_condition, $value, $type); } $select->where($_field . ' ' . $_conditionAndValue); } return true; } /** * Modified version of function Zend_Db_Adapter_Abstract->_whereExpr * * Convert an array, string, or Zend_Db_Expr object * into a string to put in a WHERE clause. * * @param array|string|Zend_Db_Expr $where * @return string */ public static function getWhereSql($where) { if (empty($where)) { return 1; } $db = Qs_Db::getInstance(); $where = (array) $where; foreach ($where as $condition => &$term) { if (is_int($condition)) { if ($term instanceof Zend_Db_Expr) { $term = $term->__toString(); } } else { $condition = (false !== strpos($condition, '?')) ? $condition : $condition . ' = ?'; $term = $db->quoteInto($condition, $term); } $term = '(' . $term . ')'; } $where = implode(' AND ', $where); return $where; } protected static function _getMetaTypeToType($type) { switch (strtolower($type)) { case 'mediumint': // break was intentionally omitted case 'smallint': // break was intentionally omitted case 'tinyint': // break was intentionally omitted case 'bit': // break was intentionally omitted case 'bool': // break was intentionally omitted case 'boolean': // break was intentionally omitted case 'int': $type = Qs_Db::INT_TYPE; break; case 'serial': // break was intentionally omitted case 'bingint': $type = Qs_Db::BIGINT_TYPE; break; case 'decimal': // break was intentionally omitted case 'double': // break was intentionally omitted case 'float': // break was intentionally omitted case 'real': $type = Qs_Db::FLOAT_TYPE; break; default: $type = null; break; } return $type; } public static function getPairExpr($tableAlias, $alias = null) { $pair = static::getPair($tableAlias, $alias); $db = static::getInstance(); return new Zend_Db_Expr($db->quoteIdentifier(current($pair)) . ' AS ' . $db->quoteIdentifier(key($pair))); } public static function getPair($tableAlias, $alias = null) { if (null === $alias) { $alias = $tableAlias; } return array($alias => static::getTableName($tableAlias)); } public static function getField($field, $alias = null) { return ((null === $alias) ? '' : $alias . '.') . $field; } public static function quoteField($field, $alias = null) { return Qs_Db::getInstance()->quoteIdentifier(static::getField($field, $alias)); } public static function getLastQuery() { return Qs_Db::getInstance()->getProfiler()->getLastQueryProfile()->getQuery(); } /** * Method quotes values according to meta data, unknown fields will be removed * @static * @param array $row * @param string|Zend_Db_Table $table Table alias or instance * @return array * @throws Qs_Db_Exception */ public static function quoteRow(array $row, $table) { static $metaDataCache = array(); /** @var Qs_Db_Table $table */ $table = (is_string($table)) ? new Qs_Db_Table($table) : $table; if (!$table instanceof Zend_Db_Table) { throw new Qs_Db_Exception('Wrong param "$table"'); } $tableName = $table->getName(); if (!array_key_exists($tableName, $metaDataCache)) { $metaDataCache[$tableName] = $table->info(Zend_Db_Table::METADATA); } $metaData = $metaDataCache[$tableName]; $db = static::getInstance(); $quotedRow = array(); foreach ($row as $name => $value) { if (array_key_exists($name, $metaData)) { $colMeta = $metaData[$name]; $quotedRow[$name] = (null === $value && $colMeta['NULLABLE']) ? 'NULL' : $db->quote($value, static::_getMetaTypeToType($colMeta['DATA_TYPE'])); } } return $quotedRow; } /** * Returns quoted list * @static * @param array $list * @param string|Zend_Db_Table $table Table alias or instance * @return array */ public static function quoteList(array $list, $table) { $quotedList = array(); foreach ($list as $key => $row) { $quotedList[$key] = static::quoteRow($row, $table); } return $quotedList; } /** * @param int|string $id int - id value, string - id field name * @return int|string */ public static function quoteIdField($id) { return (is_int($id) || ctype_digit($id)) ? (int)$id : static::getInstance()->quoteIdentifier((string)$id); } /** * @param array|string $alias alias | [alias, shortAlias] * @param array|string $where * @return Zend_Db_Expr */ public static function getCountExpr($alias, $where) { $pair = (is_array($alias)) ? Qs_Db::getPair(array_shift($alias), array_shift($alias)) : Qs_Db::getPair($alias); $select = Qs_Db::getSelect(); $select->from($pair, array('COUNT(*)')); $select->where(Qs_Db::getWhereSql($where)); return new \Zend_Db_Expr('(' . $select . ')'); } public static function joinTranslation(Zend_Db_Select $select, $table, $lang = null, $contentTable = null, array $contentFields = null, $primaryKey = 'id') { $lang = ($lang) ? $lang : Qs_Constant::get('CURRENT_LANGUAGE'); $contentTable = isset($contentTable) ? $contentTable : "{$table}Content"; $contentFields = isset($contentFields) ? $contentFields : self::getContentFields($contentTable, $primaryKey); $defaultLang = Qs_Constant::get('DEFAULT_LANGUAGE'); if ($lang !== $defaultLang) { $contentDefault = $contentTable . 'Default'; $fields = []; foreach ($contentFields as $alias => $name) { $alias = (is_numeric($alias)) ? $name : $alias; $fields[$alias] = new Zend_Db_Expr("IF(`$contentTable`.`{$name}` > '', `$contentTable`.`{$name}`, `$contentDefault`.`{$name}`)"); } $contentFields = $fields; $select->joinLeft( static::getPair($contentTable, $contentDefault), static::getInstance()->quoteInto( "`{$contentDefault}`.`{$primaryKey}` = `{$table}`.`{$primaryKey}` AND `{$contentDefault}`.`lang` = ?", $defaultLang ), [] ); } $select->joinLeft( static::getPair($contentTable, $contentTable), static::getInstance()->quoteInto( "`{$contentTable}`.`{$primaryKey}` = `{$table}`.`{$primaryKey}` AND `{$contentTable}`.`lang` = ?", $lang ), $contentFields ); return null; } public static function getContentFields($contentTable, $primaryKey = 'id') { $table = new Qs_Db_Table($contentTable); $fields = $table->getMetaData(); unset($fields['lang'], $fields[$primaryKey]); return array_keys($fields); } }