<?php
/**
* СодеÑÐ¶Ð¸Ñ ÐºÐ»Ð°ÑÑ DBDataSet
*
* @package energine
* @author dr.Pavka
* @copyright ColoCall 2006
* @version $Id: DBDataSet.class.php,v 1.11 2008/01/12 14:29:12 pavka Exp $
*/
//require_once('core/modules/share/components/DataSet.class.php');
//require_once('core/framework/MultiLanguageBuilder.class.php');
/**
* ÐлаÑÑ Ð¿Ð¾Ð·Ð²Ð¾Ð»ÑÑÑий вÑводиÑÑ Ð´Ð°Ð½Ð½Ñе из ÐÐ
*
* @package energine
* @subpackage share
*/
class DBDataSet extends DataSet {
/**
* ÐÐ¼Ñ ÑаблиÑÑ ÑодеÑжаÑей пеÑеводÑ
*
* @var string
* @access private
*/
private $translationTableName = false;
/**
* ÐÐ¼Ñ Ð¿Ð¾Ð»Ñ Ð¿ÐµÑвиÑного клÑÑа
*
* @var string
* @access private
*/
private $pk = false;
/**
* УÑÐ»Ð¾Ð²Ð¸Ñ Ð²ÑбоÑки
*
* @var array
* @access private
*/
private $filter = array();
/**
* УÑловие ÑоÑÑиÑовки
*
* @var array
* @access protected
*/
private $order = null;
/**
* ÐгÑаниÑение колиÑеÑÑва запиÑей
*
* @var array
* @access private
*/
private $limit = null;
/**
* ÐейÑÑвие коÑоÑое иÑполнÑлоÑÑ Ð½Ð° пÑедÑдÑÑем Ñаге
* иÑполÑзÑеÑÑÑ Ð² меÑоде ÑоÑ
ÑанениÑ
*
* @var string
* @access private
*/
private $previousAction = false;
/**
* ÐонÑÑÑÑкÑÐ¾Ñ ÐºÐ»Ð°ÑÑа
*
* @return void
*/
public function __construct($name, $module, Document $document, array $params = null) {
parent::__construct($name, $module, $document, $params);
$this->setType(self::COMPONENT_TYPE_LIST);
}
/**
* Ðобавлен паÑамеÑÑ tableName
*
* @return type
* @access protected
*/
protected function defineParams() {
return array_merge(
parent::defineParams(),
array(
'tableName' => false,
'onlyCurrentLang' => false
)
);
}
/**
* ÐеÑеопÑеделеннÑй меÑод загÑÑзки опиÑÐ°Ð½Ð¸Ñ Ð´Ð°Ð½Ð½ÑÑ
* ÐозвÑаÑÐ°ÐµÑ Ð¸Ð½ÑоÑмаÑÐ¸Ñ Ð¾ колонкаÑ
в оÑновной ÑаблиÑе и ÑаблиÑе пеÑеводов
*
* @return array
* @access protected
*/
protected function loadDataDescription() {
$result = $this->dbh->getColumnsInfo($this->getTableName());
if ($this->getTranslationTableName()) {
$transColumnsDescription = $this->dbh->getColumnsInfo($this->getTranslationTableName());
foreach (array_keys($transColumnsDescription) as $fieldName) {
//Ð´Ð»Ñ Ð²ÑеÑ
полей кÑоме иденÑиÑикаÑоÑа ÑзÑка и пеÑвиÑного клÑÑа вÑÑÑавлÑем дополниÑелÑное ÑвойÑÑво isMultiLanguage
if (!in_array($fieldName, array($this->getPK(), 'lang_id'))) {
$transColumnsDescription[$fieldName]['isMultilanguage'] = true;
}
elseif ($fieldName === 'lang_id' && $this->getPK() !== 'lang_id') {
$transColumnsDescription[$fieldName]['languageID'] = true;
}
}
$result += $transColumnsDescription;
if (isset($result['lang_id'])) {
$result['lang_id']['key'] = false;
}
else {
throw new SystemException('ERR_DEV_NO_LANG_ID', SystemException::ERR_DEVELOPER);
}
}
return $result;
}
/**
* ÐеÑеопÑеделеннÑй меÑод загÑÑзки даннÑÑ
*
* @return array
* @access protected
*/
protected function loadData() {
$data = false;
if ($this->pager) {
// pager ÑÑÑеÑÑвÑÐµÑ -- загÑÑжаем ÑолÑко ÑаÑÑÑ Ð´Ð°Ð½Ð½ÑÑ
, ÑекÑÑÑÑ ÑÑÑаниÑÑ
$this->setLimit($this->pager->getLimit());
}
//ÐÑли не ÑÑÑеÑÑвÑÐµÑ ÑаблиÑÑ Ñ Ð¿ÐµÑеводами, Ñо вÑбиÑаем даннÑе из оÑновной ÑаблиÑÑ
if (!$this->getTranslationTableName()) {
$dbFields = array();
foreach ($this->getDataDescription()->getFieldDescriptions() as $fieldName => $field) {
if (is_null($field->getPropertyValue('customField'))) {
array_push($dbFields, $fieldName);
}
}
//ÐÑли не пÑÑÑой маÑÑив полей Ð´Ð»Ñ Ð¾ÑбоÑа
if (!empty($dbFields)) {
if ($this->pager) {
$recordCount = simplifyDBResult($this->dbh->select($this->getTableName(), 'count(*) as recordsCount', $this->getFilter()), 'recordsCount', true);
$this->pager->setRecordsCount($recordCount);
}
if ($this->getType() == self::COMPONENT_TYPE_FORM_ADD ) {
$dbFields = array_flip($dbFields);
foreach ($dbFields as $key => $value) {
$dbFields[$key] = '';
}
$res = array($dbFields);
}
else {
$res = $this->dbh->select($this->getTableName(), $dbFields, $this->getFilter(), $this->getOrder(), $this->getLimit());
}
if (is_array($res)) {
$data = $res;
}
}
}
else {
//ÐÐ»Ñ Ð¼ÑлÑÑиÑзÑÑной ÑаблиÑÑ - деÑгаем меÑод загÑÑзки даннÑÑ
$data = $this->multiLoadData();
}
return $data;
}
/**
* ÐозвÑаÑÐ°ÐµÑ ÑзÑк на коÑоÑм беÑÑÑÑÑ Ð´Ð°Ð½Ð½Ñе
*
* @return int
* @access protected
*/
protected function getDataLanguage() {
$result = false;
if ($this->getParam('onlyCurrentLang')) {
$result = $this->document->getLang();
}
return $result;
}
/**
* ÐагÑÑзка мÑлÑÑиÑзÑÑнÑÑ
даннÑÑ
*
* @return array
* @access private
*/
private function multiLoadData() {
$data = false;
$lang = Language::getInstance();
$lang = $lang->getLanguages();
$dbFields = array();
$filter = $order = $limit = '';
//Создаем пеÑеÑÐµÐ½Ñ Ð¿Ð¾Ð»ÐµÐ¹ в ÑоÑмаÑе array('Ð¸Ð¼Ñ Ð¾Ñновной ÑаблиÑÑ' => array('Ð¸Ð¼Ñ Ð¿Ð¾Ð»Ñ'=>'Ð¸Ð¼Ñ ÑаблиÑÑ.Ð¸Ð¼Ñ Ð¿Ð¾Ð»Ñ'), 'Ð¸Ð¼Ñ ÑаблиÑÑпеÑеводов' => array('Ð¸Ð¼Ñ Ð¿Ð¾Ð»Ñ'=>'Ð¸Ð¼Ñ ÑаблиÑÑ.Ð¸Ð¼Ñ Ð¿Ð¾Ð»Ñ'))
foreach ($this->getDataDescription()->getFieldDescriptions() as $fieldName => $field) {
//Ðе вклÑÑаем в Ð½Ð°Ð±Ð¾Ñ Ð¸Ð´ÐµÐ½ÑиÑикаÑÐ¾Ñ ÑзÑка
if (!$field->getPropertyValue('languageID') && $field->getPropertyValue('key') !== true) {
//не вклÑÑаем в Ð½Ð°Ð±Ð¾Ñ Ð¿Ð¾Ð»Ñ Ð¿Ð¾Ð»ÑÑеннÑе из конÑигÑÑаÑии
if (is_null($field->getPropertyValue('customField'))) {
$dbFields[$field->getPropertyValue('tableName')][$fieldName] = $field->getPropertyValue('tableName').'.'.$fieldName;
}
}
}
if (!is_null($this->getOrder())){
$order = $this->dbh->buildOrderCondition($this->getOrder());
}
$filterCondition = $this->getFilter();
if (!empty($filterCondition)) {
$filter = $this->dbh->buildWhereCondition($filterCondition).($this->getParam('onlyCurrentLang')?' AND lang_id = '.$this->getDataLanguage():'');
}
elseif($this->getDataLanguage() && $this->getParam('onlyCurrentLang')) {
$filter = ' WHERE lang_id = '.$this->getDataLanguage();
}
if (!is_null($this->getLimit())) {
$limit = $this->getLimit();
$limit = $this->dbh->buildLimitStatement($limit);
}
//ÐÑли ÑÑÑеÑÑвÑÐµÑ Ð»Ð¸ÑÑалка ÑказÑваем ей колиÑеÑÑво запиÑей
if ($this->pager) {
//ÐпÑеделÑем обÑее колиÑеÑÑво запиÑей
$request = sprintf(
"SELECT COUNT(*) as records_count
FROM %s
LEFT JOIN %s ON %s.%s = %s.%s
%s
",
$this->getTableName(),
$this->getTranslationTableName(), $this->getTranslationTableName(), $this->getPK(), $this->getTableName(), $this->getPK(),
$filter
);
$recordsCount = $this->dbh->selectRequest($request);
$recordsCount = simplifyDBResult($recordsCount, 'records_count', true);
$this->pager->setRecordsCount($recordsCount);
}
if ($this->getType() != self::COMPONENT_TYPE_FORM_ADD) {
$request=sprintf(
"SELECT
%s.%s, %s.lang_id,
%s
%s
FROM %s
LEFT JOIN %s ON %s.%s = %s.%s
%s
%s
%s
",
$this->getTableName(), $this->getPK(), $this->getTranslationTableName(),
(isset($dbFields[$this->getTableName()]))?implode(',', $dbFields[$this->getTableName()]):'',
isset($dbFields[$this->getTranslationTableName()])?((isset($dbFields[$this->getTableName()]))?',':'').implode(',', $dbFields[$this->getTranslationTableName()]):'',
$this->getTableName(),
$this->getTranslationTableName(), $this->getTranslationTableName(), $this->getPK(), $this->getTableName(), $this->getPK(),
$filter,
$order,
$limit
);
$data = $this->dbh->selectRequest($request);
//ÐÑли даннÑе не ÑолÑко Ð´Ð»Ñ ÑекÑÑего ÑзÑка
if (is_array($data) &&(!$this->getDataLanguage() || $this->getDataLanguage()&&!$this->getParam('onlyCurrentLang') && isset($dbFields[$this->getTranslationTableName()]))) {
//ÑоÑмиÑÑем маÑÑиÑÑ
foreach ($data as $row) {
$matrix[$row[$this->getPK()]][$row['lang_id']] = $row;
}
//ÑоÑмиÑÑем обÑазеÑ
//в нем вÑе ÑзÑкозавиÑимÑе Ð¿Ð¾Ð»Ñ Ð·Ð°Ð¿Ð¾Ð»Ð½ÐµÐ½Ñ nullами
foreach (array_keys($dbFields[$this->getTranslationTableName()]) as $fieldName) {
$translationColumns[] = 'NULL as '.$fieldName;
}
$request = sprintf('
SELECT %s, %s %s
FROM %s
WHERE %s IN(%s)
',
$this->getPK(), (isset($dbFields[$this->getTableName()]))?implode(',', $dbFields[$this->getTableName()]).',':'', implode(',', $translationColumns),
$this->getTableName(),
$this->getPK(), implode(',', array_keys($matrix)));
$res = $this->dbh->selectRequest($request);
foreach ($res as $row) {
$template[$row[$this->getPK()]] = $row;
}
$data = array();
if ($this->getDataLanguage()&&!$this->getParam('onlyCurrentLang')) {
$lang = array($this->getDataLanguage() => $lang[$this->getDataLanguage()]);
}
foreach ($matrix as $ltagID => $langVersions) {
foreach (array_keys($lang) as $langID) {
if (isset($langVersions[$langID])) {
$data[] = $langVersions[$langID];
}
else {
$data[arrayPush($data, $template[$ltagID])]['lang_id'] = $langID;
}
}
}
}
}
else {
$i=0;
$dbFields = array_merge(
(isset($dbFields[$this->getTableName()]))?array_keys($dbFields[$this->getTableName()]):array(),
array_keys($dbFields[$this->getTranslationTableName()])
);
$dbFields = array_flip($dbFields);
foreach ($dbFields as $key => $value) {
$dbFields[$key] = '';
}
foreach (array_keys($lang) as $langID) {
$data[$i][$this->getPK()] = null;
$data[$i]['lang_id'] = $langID;
$data[$i] = array_merge($data[$i], $dbFields);
$i++;
}
}
return $data;
}
/**
* УÑÑÐ°Ð½Ð°Ð²Ð»Ð¸Ð²Ð°ÐµÑ Ð¸Ð¼Ñ ÑаблиÑÑ
*
* @param string
* @return type
* @access protected
*/
protected function setTableName($tableName) {
$this->setParam('tableName', $tableName);
}
/**
* ÐÐ»Ñ Ð¿Ð°ÑамеÑÑа tableName ÑÑÑанавливаем еÑе и Ð¸Ð¼Ñ ÑаблиÑÑ Ð¿ÐµÑеводов
*
* @param string $name
* @param mixed $value
* @return void
* @access protected
*/
protected function setParam($name, $value) {
if ($name == 'tableName') {
$this->translationTableName = $this->dbh->getTranslationTablename($value);
}
parent::setParam($name, $value);
}
/**
* ÐозвÑаÑÐ°ÐµÑ Ð¸Ð¼Ñ ÑаблиÑÑ
*
* @return string
* @access protected
* @final
*/
final protected function getTableName() {
if (!$this->getParam('tableName')) {
throw new SystemException('ERR_DEV_NO_TABLENAME', SystemException::ERR_DEVELOPER);
}
return $this->getParam('tableName');
}
/**
* ÐозвÑаÑÐ°ÐµÑ Ð·Ð½Ð°Ñение ÑилÑÑÑа
*
* @return mixed
* @access protected
* @final
*/
final protected function getFilter() {
return $this->filter;
}
/**
* УÑÑÐ°Ð½Ð°Ð²Ð»Ð¸Ð²Ð°ÐµÑ Ð·Ð½Ð°Ñение ÑилÑÑÑа
*
* @param mixed
* @return void
* @access protected
* @final
* @see QAL::select()
*/
final protected function setFilter($filter) {
$this->clearFilter();
if (!empty($filter)) {
$this->addFilterCondition($filter);
}
}
/**
* ÐобавлÑÐµÑ ÑÑловие к ÑилÑÑÑÑ
*
* @return void
* @access protected
*/
protected function addFilterCondition($filter) {
if (is_numeric($filter)) {
$filter = array($this->getTableName().'.'.$this->getPK()=>$filter);
}
elseif (is_string($filter)) {
$filter = array($filter);
}
$this->filter = array_merge($this->filter, $filter);
}
/**
* СбÑÐ¾Ñ ÑилÑÑÑа
*
* @return void
* @access protected
* @final
*/
final protected function clearFilter() {
$this->filter = array();
}
/**
* ÐозвÑаÑÐ°ÐµÑ ÑÑÐ»Ð¾Ð²Ð¸Ñ ÑоÑÑÑовки
*
* @return array
* @access protected
* @final
*/
final protected function getOrder() {
return $this->order;
}
/**
* УÑÑÐ°Ð½Ð°Ð²Ð»Ð¸Ð²Ð°ÐµÑ ÑÑловие ÑоÑÑÑовки
*
* @param mixed
* @return void
* @access protected
* @final
*/
final protected function setOrder($order) {
if (is_array($order)) {
if (!in_array(current($order), array(QAL::ASC, QAL::DESC))) {
throw new SystemException('ERR_DEV_BAD_ORDER_FORMAT', SystemException::ERR_DEVELOPER);
}
$this->order = $order;
}
else {
$this->order = array($order=>QAL::ASC);
}
}
/**
* ÐозвÑаÑÐ°ÐµÑ Ð¾Ð³ÑаниÑÐµÐ½Ð¸Ñ Ð¿Ð¾ колиÑеÑÑÐ²Ñ Ð·Ð°Ð¿Ð¸Ñей
*
* @return array
* @access protected
* @final
*/
final protected function getLimit() {
return $this->limit;
}
/**
* УÑÑÐ°Ð½Ð°Ð²Ð»Ð¸Ð²Ð°ÐµÑ Ð¾Ð³ÑаниÑÐµÐ½Ð¸Ñ Ð¿Ð¾ колиÑеÑÑÐ²Ñ Ð·Ð°Ð¿Ð¸Ñей
*
* @param array
* @return void
* @access protected
* @final
*/
final protected function setLimit(array $limit) {
$this->limit = $limit;
}
/**
* ÐозвÑаÑÐ°ÐµÑ Ð¸Ð¼Ñ Ð¿Ð¾Ð»Ñ - пеÑвиÑного клÑÑа
*
* @return string
* @access protected
* @final
*/
final protected function getPK() {
if (!$this->pk) {
$res = $this->dbh->getColumnsInfo($this->getTableName());
if (is_array($res)) {
foreach ($res as $fieldName => $fieldInfo) {
if ($fieldInfo['key'] === true) {
$this->pk = $fieldName;
}
}
if (!isset($this->pk)) {
throw new SystemException('ERR_DEV_NO_PK', SystemException::ERR_DEVELOPER);
}
}
else {
throw new SystemException('ERR_DEV_NO_PK', SystemException::ERR_DEVELOPER);
}
}
return $this->pk;
}
/**
* ÐÐ»Ñ Ð¼ÑлÑÑиÑзÑÑного гÑида
* подменÑем поÑÑÑоиÑелÑ
*
* @return Builder
* @access protected
*/
protected function createBuilder() {
if (!$this->getTranslationTableName()) {
$result = parent::createBuilder();
}
else {
$result = new MultiLanguageBuilder();
}
return $result;
}
/**
* добавлена обÑабоÑка клÑÑей
*
* @return DataDescription
* @access protected
*/
protected function createDataDescription() {
$result = parent::createDataDescription();
foreach ($result->getFieldDescriptions() as $fieldName => $fieldMetaData) {
$keyInfo = $fieldMetaData->getPropertyValue('key');
//ÐÑли ÑÑо внеÑний клÑÑ
if (is_array($keyInfo) && in_array($fieldMetaData->getType(), array(FieldDescription::FIELD_TYPE_SELECT, FieldDescription::FIELD_TYPE_MULTI))) {
$fkTableName = $keyInfo['tableName'];
$fkKeyName = $keyInfo['fieldName'];
//загÑÑжаем инÑоÑмаÑÐ¸Ñ Ð¾ возможнÑÑ
знаÑениÑÑ
call_user_func_array(array($fieldMetaData, 'loadAvailableValues'), $this->getFKData($fkTableName, $fkKeyName));
}
}
return $result;
}
/**
* ÐозвÑаÑÐ°ÐµÑ Ð´Ð°Ð½Ð½Ñе о знаÑÐµÐ½Ð¸Ñ Ð² ÑвÑзанной ÑаблиÑÑ
*
* @return array
* @access protected
*/
protected function getFKData($fkTableName, $fkKeyName) {
$fkValueName = substr($fkKeyName, 0, strpos($fkKeyName, '_')).'_name';
//еÑли ÑÑÑеÑÑвÑÐµÑ ÑаблиÑа Ñ Ð¿ÐµÑеводами Ð´Ð»Ñ ÑвÑзанной ÑаблиÑÑ
//нÑжно бÑаÑÑ Ð·Ð½Ð°ÑÐµÐ½Ð¸Ñ Ð¾ÑÑÑда
$transTableName = $this->dbh->getTranslationTablename($fkTableName);
if ($transTableName) {
$request = sprintf('SELECT main.*,trans.%s FROM %s main LEFT JOIN %s trans on trans.%s = main.%s WHERE lang_id =%s', $fkValueName, $fkTableName, $transTableName, $fkKeyName, $fkKeyName, $this->document->getLang());
$res = $this->dbh->selectRequest($request);
}
else {
$res = $this->dbh->select($fkTableName);
}
return array($res, $fkKeyName, $fkValueName);
}
/**
* ÐозвÑаÑÐ°ÐµÑ Ð¸Ð¼Ñ ÑаблиÑÑ Ð¿ÐµÑеводов
*
* @return string
* @access protected
* @final
*/
final protected function getTranslationTableName() {
return $this->translationTableName;
}
/**
* ÐеÑод вÑÐ²Ð¾Ð´Ð¸Ñ ÑоÑÐ¼Ñ Ð¿ÑоÑмоÑÑа
*
* @return void
* @access protected
*/
protected function view() {
$this->setType(self::COMPONENT_TYPE_FORM);
//$this->addCrumb('TXT_VIEW_ITEM');
$id = $this->getActionParams();
list($id) = $id;
if (!$this->recordExists($id)) {
throw new SystemException('ERR_404', SystemException::ERR_404);
}
$this->setFilter($id);
$this->prepare();
foreach ($this->getDataDescription()->getFieldDescriptions() as $fieldDescription) {
$fieldDescription->setMode(FieldDescription::FIELD_MODE_READ);
}
}
/**
* ÐпÑеделÑÐµÑ ÑÑÑеÑÑвÑÐµÑ Ð»Ð¸ запиÑÑ Ñ Ð¸Ð´ÐµÐ½ÑиÑикаÑоÑом пеÑеданнÑм в паÑамеÑÑе
* ÐÑзÑваеÑÑÑ Ð¸Ð· меÑодов где нÑжно бÑÑÑ ÑвеÑеннÑм в налиÑии запиÑи(view, edit,delete)
*
* @param string
* @param mixed
* @return void
* @access protected
* @final
*/
final protected function recordExists($id, $fieldName = false) {
if (!$fieldName) {
$fieldName = $this->getPK();
}
$res = $this->dbh->select($this->getTableName(), array($fieldName), array($fieldName=>$id));
return is_array($res);
}
/**
* ÐозвÑаÑÐ°ÐµÑ Ð¿ÑедÑдÑÑее дейÑÑвие
*
* @return string
* @access protected
* @final
*/
final protected function getPreviousAction() {
if (!$this->previousAction) {
if (!isset($_POST['componentAction'])) {
throw new SystemException('ERR_NO_COMPONENT_ACTION', SystemException::ERR_CRITICAL);
}
else {
$this->previousAction = $_POST['componentAction'];
}
}
return $this->previousAction;
}
}