// Improve collections : where() method reworked (prototype changed) + validation of fields

This commit is contained in:
rMalie
2011-12-19 16:57:28 +00:00
parent 219f3ac870
commit b2b678ab3d
15 changed files with 240 additions and 67 deletions
+1 -1
View File
@@ -208,7 +208,7 @@ class CartRuleCore extends ObjectModel
{
$return = true;
$cart_rules = new Collection('CartRule');
$cart_rules->where('a.id_customer = '.(int)$id_customer);
$cart_rules->where('id_customer', '=', $id_customer);
foreach ($cart_rules as $cart_rule)
$return &= $cart_rule->delete();
return $return;
+2 -1
View File
@@ -681,7 +681,8 @@ class CategoryCore extends ObjectModel
$id_lang = Context::getContext()->language->id;
$categories = new Collection('Category', $id_lang);
$categories->where((int)$this->nleft.' < nleft AND nright < '.(int)$this->nright);
$categories->where('nleft', '>', $this->nleft);
$categories->where('nright', '<', $this->nright);
return $categories;
}
+177 -14
View File
@@ -72,6 +72,10 @@ class CollectionCore implements Iterator, ArrayAccess, Countable
*/
protected $total;
protected $fields = array();
protected $alias = array();
protected $alias_iterator = 0;
/**
* @param string $classname
* @param int $id_lang
@@ -87,53 +91,122 @@ class CollectionCore implements Iterator, ArrayAccess, Countable
else if (!isset($this->definition['primary']))
throw new PrestashopException('Miss primary in definition for class '.$this->classname);
$alias = $this->generateAlias();
$this->query = new DbQuery();
$this->query->select('a.*');
$this->query->from($this->definition['table'], 'a');
$this->query->select($alias.'.*');
$this->query->from($this->definition['table'], $alias);
// If multilang, create association to lang table
// @todo create virtual association with lang in ObjectModel::getDefinition()
if (isset($this->definition['multilang']) && $this->definition['multilang'])
{
$this->query->select('b.*');
$this->query->leftJoin($this->definition['table'].'_lang', 'b', 'a.'.$this->definition['primary'].' = b.'.$this->definition['primary']);
$lang_alias = $this->generateAlias('@lang');
$this->query->select($lang_alias.'.*');
$this->query->leftJoin($this->definition['table'].'_lang', $lang_alias, $alias.'.'.$this->definition['primary'].' = '.$lang_alias.'.'. $this->definition['primary']);
if ($this->id_lang)
$this->query->where('b.id_lang = '.(int)$this->id_lang);
$this->query->where($lang_alias.'.id_lang = '.(int)$this->id_lang);
}
}
/**
* Add WHERE restriction on query
*
* @param string $str
* @param string $field Field name
* @param string $operator List of operators : =, !=, <>, <, <=, >, >=, like, notlike, regexp, notregexp
* @param mixed $value
* @return Collection
*/
public function where($str)
public function where($field, $operator, $value)
{
$this->query->where($str);
// Create WHERE clause with an array value (IN, NOT IN)
if (is_array($value))
{
switch (strtolower($operator))
{
case '=' :
case 'in' :
$this->query->where($this->parseField($field).' IN('.implode(', ', $this->formatValue($value, $field)));
break;
case '!=' :
case '<>' :
case 'notin' :
$this->query->where($this->parseField($field).' NOT IN('.implode(', ', $this->formatValue($value, $field)));
break;
default :
throw new PrestashopException('Operator not supported for array value');
}
}
// Create WHERE clause
else
{
switch (strtolower($operator))
{
case '=' :
case '!=' :
case '<>' :
case '>' :
case '>=' :
case '<' :
case '<=' :
case 'like' :
case 'regexp' :
$this->query->where($this->parseField($field).' '.$operator.' '.$this->formatValue($value, $field));
break;
case 'notlike' :
$this->query->where($this->parseField($field).' NOT LIKE '.$this->formatValue($value, $field));
break;
case 'notregexp' :
$this->query->where($this->parseField($field).' NOT REGEXP '.$this->formatValue($value, $field));
break;
default :
throw new PrestashopException('Operator not supported');
}
}
return $this;
}
/**
* Add WHERE restriction on query using real SQL syntax
*
* @param string $sql
*/
public function sqlWhere($sql)
{
$this->query->where($this->parseFields($sql));
return $this;
}
/**
* Add ORDER BY restriction on query
*
* @param string $str
* @param string $field Field name
* @param string $order asc|desc
* @return Collection
*/
public function orderBy($str)
public function orderBy($field, $order = 'asc')
{
$this->query->orderBy($str);
$order = strtolower($order);
if ($order != 'asc' && $order != 'desc')
throw new PrestashopException('Order must be asc or desc');
$this->query->orderBy($this->parseField($field).' '.$order);
return $this;
}
/**
* Add GROUP BY restriction on query
*
* @param string $str
* @param string $field Field name
* @return Collection
*/
public function groupBy($str)
public function groupBy($field)
{
$this->query->groupBy($str);
$this->query->groupBy($this->parseField($field));
return $this;
}
@@ -284,4 +357,94 @@ class CollectionCore implements Iterator, ArrayAccess, Countable
$this->getAll();
unset($this->results[$offset]);
}
/**
* Parse all fields with {field} syntax in a string
*
* @param string $str
* @return string
*/
protected function parseFields($str)
{
preg_match_all('#\{(([a-z0-9_]+\.)*[a-z0-9_]+)\}#i', $str, $m);
for ($i = 0, $total = count($m[0]); $i < $total; $i++)
$str = str_replace($m[0][$i], $this->parseField($m[1][$i]), $str);
return $str;
}
/**
* Replace a field with its SQL version (E.g. manufacturer.name with a2.name)
*
* @param string $field Field name
* @return string
*/
protected function parseField($field)
{
$info = $this->getFieldInfo($field);
return $info['alias'].'.`'.$info['name'].'`';
}
/**
* Format a value with the type of the given field
*
* @param mixed $value
* @param string $field Field name
*/
protected function formatValue($value, $field)
{
$info = $this->getFieldInfo($field);
if (is_array($value))
{
$results = array();
foreach ($value as $item)
$results[] = ObjectModel::formatValue($item, $info['type'], true);
return $results;
}
return ObjectModel::formatValue($value, $info['type'], true);
}
/**
* Obtain some informations on a field (alias, name, type, etc.)
*
* @param string $field Field name
* @return array
*/
protected function getFieldInfo($field)
{
if (!isset($this->fields[$field]))
{
$split = explode('.', $field);
$association = '';
$definition = ObjectModel::getDefinition($this->classname);
for ($i = 0, $total_association = count($split) - 1; $i < $total_association; $i++)
{
// @todo association
}
$fieldname = $split[$i];
if (!isset($definition['fields'][$fieldname]))
throw new PrestashopException('Field '.$fieldname.' not found in class '.$this->classname);
$this->fields[$field] = array(
'name' => $fieldname,
'association' => $association,
'alias' => $this->generateAlias($association),
'type' => $definition['fields'][$fieldname]['type'],
);
}
return $this->fields[$field];
}
/**
* Generate uniq alias from association name
*
* @param string $association Use empty association for alias on current table
* @return string
*/
protected function generateAlias($association = '')
{
if (!isset($this->alias[$association]))
$this->alias[$association] = 'a'.$this->alias_iterator++;
return $this->alias[$association];
}
}
+1 -1
View File
@@ -183,7 +183,7 @@ class LocalizationPackCore
if (!$trg->save())
{
$this->_errors = Tools::displayError('This tax rule can\'t be saved.');
$this->_errors[] = Tools::displayError('This tax rule can\'t be saved.');
return false;
}
+39 -32
View File
@@ -300,42 +300,49 @@ abstract class ObjectModelCore
}
// Format field value
switch ($data['type'])
{
case self::TYPE_INT :
$fields[$field] = (int)$value;
break;
case self::TYPE_BOOL :
$fields[$field] = (int)$value;
break;
case self::TYPE_FLOAT :
$fields[$field] = (float)$value;
break;
case self::TYPE_DATE :
$fields[$field] = pSQL($value);
break;
case self::TYPE_STRING :
$fields[$field] = pSQL($value);
break;
case self::TYPE_HTML :
$fields[$field] = pSQL($value, true);
break;
default :
if (method_exists($this, 'formatType'.$data['type']))
$fields[$field] = $this->{'formatType'.$data['type']}($value);
break;
}
$fields[$field] = ObjectModel::formatValue($value, $data['type']);
}
return $fields;
}
/**
* Format a data
*
* @param mixed $value
* @param int $type
*/
public static function formatValue($value, $type, $with_quotes = false)
{
switch ($type)
{
case self::TYPE_INT :
return (int)$value;
case self::TYPE_BOOL :
return (int)$value;
case self::TYPE_FLOAT :
return (float)$value;
case self::TYPE_DATE :
if ($with_quotes)
return '\''.pSQL($value).'\'';
return pSQL($value);
case self::TYPE_HTML :
if ($with_quotes)
return '\''.pSQL($value).'\'';
return pSQL($value);
case self::TYPE_STRING :
default :
if ($with_quotes)
return '\''.pSQL($value).'\'';
return pSQL($value);
}
}
/**
* Save current object to database (add or update)
*
@@ -1198,7 +1205,7 @@ abstract class ObjectModelCore
$reflection = new ReflectionClass($class);
$definition = $reflection->getStaticPropertyValue('definition');
if ($field)
return isset($definition[$field]) ? $definition[$field] : null;
return isset($definition['fields'][$field]) ? $definition['fields'][$field] : null;
return $definition;
}
+2 -2
View File
@@ -151,10 +151,10 @@ class ProductSupplierCore extends ObjectModel
public static function getSupplierCollection($id_product, $group_by_supplier = true)
{
$suppliers = new Collection('ProductSupplier');
$suppliers->where('a.id_product = '.(int)$id_product);
$suppliers->where('id_product', '=', $id_product);
if ($group_by_supplier)
$suppliers->groupBy('a.id_supplier');
$suppliers->groupBy('id_supplier');
return $suppliers;
}
+2 -2
View File
@@ -1337,7 +1337,7 @@ class OrderCore extends ObjectModel
public function getOrderPaymentCollection()
{
$order_payments = new Collection('OrderPayment');
$order_payments->where('id_order = '.(int)$this->id);
$order_payments->where('id_order', '=', $this->id);
return $order_payments;
}
@@ -1426,7 +1426,7 @@ class OrderCore extends ObjectModel
public function getInvoicesCollection()
{
$order_invoices = new Collection('OrderInvoice');
$order_invoices->where('id_order = '.(int)$this->id);
$order_invoices->where('id_order', '=', $this->id);
return $order_invoices;
}
+1 -1
View File
@@ -503,7 +503,7 @@ class OrderInvoiceCore extends ObjectModel
public function getOrderPaymentCollection()
{
$order_payments = new Collection('OrderPayment');
$order_payments->where('id_order_invoice = '.(int)$this->id);
$order_payments->where('id_order_invoice', '=', $this->id);
return $order_payments;
}
}
+1 -1
View File
@@ -94,7 +94,7 @@ class OrderPaymentCore extends ObjectModel
public static function getByInvoiceId($id_invoice)
{
$payments = new Collection('OrderPayment');
$payments->where('a.id_order_invoice = '.(int)$id_invoice);
$payments->where('id_order_invoice', '=', $id_invoice);
return $payments;
}
}
+2 -2
View File
@@ -79,9 +79,9 @@ class GroupShopCore extends ObjectModel
public static function getGroupShops($active = true)
{
$groups = new Collection('GroupShop');
$groups->where('deleted = 0');
$groups->where('deleted', '=', false);
if ($active)
$groups->where('active = 1');
$groups->where('active', '=', true);
return $groups;
}
+1 -1
View File
@@ -93,7 +93,7 @@ class ShopUrlCore extends ObjectModel
{
$urls = new Collection('ShopUrl');
if ($id_shop)
$urls->where('id_shop = '.(int)$id_shop);
$urls->where('id_shop', '=', $id_shop);
return $urls;
}
+4 -3
View File
@@ -620,11 +620,12 @@ class StockManagerCore implements StockManagerInterface
protected function getStockCollection($id_product, $id_product_attribute, $id_warehouse = null, $price_te = null)
{
$stocks = new Collection('Stock');
$stocks->where('a.id_product = '.(int)$id_product.' AND a.id_product_attribute = '.(int)$id_product_attribute);
$stocks->where('id_product', '=', $id_product);
$stocks->where('id_product_attribute', '=', $id_product_attribute);
if ($id_warehouse)
$stocks->where('a.id_warehouse = '.(int)$id_warehouse);
$stocks->where('id_warehouse', '=', $id_warehouse);
if ($price_te)
$stocks->where('a.price_te = '.(float)$price_te);
$stocks->where('price_te', '=', $price_te);
return $stocks;
}
+1 -1
View File
@@ -264,7 +264,7 @@ class SupplyOrderCore extends ObjectModel
public function getEntriesCollection()
{
$details = new Collection('SupplyOrderDetail');
$details->where('a.id_supply_order = '.(int)$this->id);
$details->where('id_supply_order', '=', $this->id);
return $details;
}
+1 -1
View File
@@ -117,7 +117,7 @@ class WarehouseProductLocationCore extends ObjectModel
public static function getCollection($id_product)
{
$collection = new Collection('WarehouseProductLocation');
$collection->where('a.id_product = '.(int)$id_product);
$collection->where('id_product', '=', $id_product);
return $collection;
}
}
@@ -1089,12 +1089,13 @@ class AdminSupplyOrdersControllerCore extends AdminController
if (count($ids) <= 0)
return;
$orders = new Collection('SupplyOrder', $id_lang = (int)Context::getContext()->language->id);
$orders->where('is_template = 0');
$orders->where('id_supply_order IN('.implode(', ', $ids).')');
$id_lang = Context::getContext()->language->id;
$orders = new Collection('SupplyOrder', $id_lang);
$orders->where('is_template', '=', false);
$orders->where('id_supply_order', 'in', $ids);
$id_warehouse = $this->getCurrentWarehouse();
if ($id_warehouse != -1)
$orders->where('id_warehouse = '.(int)$id_warehouse);
$orders->where('id_warehouse', '=', $id_warehouse);
$orders->getAll();
$csv = new CSV($orders, $this->l('supply_orders'));
$csv->export();