shopProductsCollection: проблемы с при`join`неными таблицами На рассмотрении
Используя shopProductsCollection::addJoin() добавил таблицы, но не получается вывести значения из них используя shopProductsCollection::getProducts($fields). Из $fields удаляются все поля не относящиеся к товару (p.*). Из-за этого также невозможно отсортировать данные по полям доп.таблиц.
Из описания shopProductsCollection::getSQL() следует что можно задать тип объединения используя поле 'type', но shopProductsCollection::addJoin() не позволяет задать его. Метод нужно дополнить:
/**
* Adds a simple JOIN clause to product selection query.
*
* @param string|array $table Table name to be used in JOIN clause.
* Alternatively an associative array may be specified containing values for all method parameters.
* In this case $on and $where parameters are ignored.
* @param string $on ON condition FOR JOIN, must not include 'ON' keyword
* @param string $where WHERE condition for SELECT, must not include 'WHERE' keyword
* @param string $type Type of join (LEFT, RIGHT, INNER)
* @return string Specified table's alias to be used in SQL query
*/
public function addJoin($table, $on = null, $where = null, $type = null)
{
if (is_array($table)) {
if (isset($table['on'])) {
$on = $table['on'];
}
if (isset($table['where'])) {
$where = $table['where'];
}
if (isset($table['type'])) {
$type = $table['type'];
}
$table = $table['table'];
}
$t = explode('_', $table);
$alias = '';
foreach ($t as $tp) {
if ($tp == 'shop') {
continue;
}
$alias .= substr($tp, 0, 1);
}
if (!$alias) {
$alias = $table;
}
if (!isset($this->join_index[$alias])) {
$this->join_index[$alias] = 1;
} else {
$this->join_index[$alias]++;
}
$alias .= $this->join_index[$alias];
$join = array(
'table' => $table,
'alias' => $alias,
);
if ($on) {
$join['on'] = str_replace(':table', $alias, $on);
}
if ($type) {
$join['type'] = $type;
}
$this->joins[] = $join;
if ($where) {
$this->where[] = str_replace(':table', $alias, $where);
}
return $alias;
}
/**
* Adds a LEFT JOIN clause to product selection query.
*
* @param string|array $table Table name to be used in JOIN clause.
* Alternatively an associative array may be specified containing values for all method parameters.
* In this case $on and $where parameters are ignored.
* @param string $on ON condition FOR JOIN, must not include 'ON' keyword
* @param string $where WHERE condition for SELECT, must not include 'WHERE' keyword
* @return string Specified table's alias to be used in SQL query
*/
public function addLeftJoin($table, $on = null, $where = null)
{
return $this->addJoin($table, $on, $where, 'LEFT');
}Добавление новых комментариев к этой теме отключено.










3 комментария
Попутно всплыл баг в методе orderBy:
if ($this->getModel()->fieldExists($field)) { $this->getSQL(); if ($field == 'count') { $this->fields[] = 'IF(p.count IS NULL, 1, 0) count_null'; return $this->order_by = 'count_null '.$order.', p.count '.$order; } elseif ($field == 'stock_worth') { $this->fields[] = 'IFNULL(p.count, 0)*p.price AS stock_worth'; $this->order_by = 'stock_worth '.$order; } else { return $this->order_by = 'p.'.$field." ".$order; }Мне не понятно при каких обстоятельствах сработает stock_worth.
Использование в методе $this->getSQL(); тоже не понятно чем обусловлено, почему не использовать $this->prepare()?
В итоге у меня получился вот такой код:
/** * Add special field to product selection query. * * @param string $field * @return void */ public function addField($field) { if (!in_array($field, $this->fields)) { $this->fields[] = $field; } } /** * Changes ORDER BY clause of product selection query. * * @param string|array $field Name of field. Alternative value options: * 'sort' (ignored) * 'rand()' or 'RAND()' — sets 'RAND()' condition for ORDER BY clause * 'count' * 'stock_worth' * array($field, $order) — in this case $order parameter is ignored * @param string $order 'ASC' or 'DESC' modifier * @return string New ORDER BY clause or empty string (for 'rand()' $field value) */ public function orderBy($field, $order = 'ASC') { if (is_array($field)) { if (count($field) > 1) { list($field, $order) = $field; } else { $field = array_shift($field); } } $field = trim($field); if (!$field || $field == 'sort') { return ''; } $order = strtoupper(trim($order)); if ($order != 'DESC') { $order = 'ASC'; } if (strpos($field, '.') === false) { if ($field == 'stock_worth') { $this->addField('IFNULL(p.count, 0)*p.price AS stock_worth'); } elseif ($field == 'count') { $this->addField('IF(p.count IS NULL, 1, 0) count_null'); $result = $this->order_by = 'count_null ' . $order . ', p.count ' . $order; } elseif (strtolower($field) == 'rand()') { $this->order_by = 'RAND()'; $result = ''; } elseif ($this->getModel()->fieldExists($field)) { $field = 'p.' . $field; } } if (!isset($result)) { $result = $this->order_by = $field . ' ' . $order; } $this->prepare(); return $result; }попутно добавил метод для добавления полей.