Merge branches 'catalog' and 'upload_management' of https://github.com/thelia/thelia into catalog

# By franck
# Via franck
* 'catalog' of https://github.com/thelia/thelia:
  Impemented combination creation

# By Manuel Raynaud (29) and others
# Via gmorel (6) and others
* 'upload_management' of https://github.com/thelia/thelia: (52 commits)
  Working : Upload image : Fix upload validation
  - Image format allowed - manual-reverse order on image loop
  Upload allow only for images
  Hide upload zone during upload
  Working : Upload image : Fix unit tests
  Working : Upload image : set product image form loaded via ajax, fix category, folder, content
  WIP : Upload image : set product image form loaded via ajax
  Setting tinymce
  Update uploader view Update image edit view
  Working : Upload management : on content
  Working : Upload management : on folder, category, product
  cache dataccessfunctions
  Working : Upload management : fix e.preventDefault in chrome and safari
  Working : Image management set on Category
  fire event on insert content in createmethod
  fix issue, default foler is set on content creation
  allow to create new content
  update default param of content model
  create content listener for crud management
  dispatch event in pre/post crud method for content model
  ...

Conflicts:
	templates/admin/default/product-edit.html
This commit is contained in:
gmorel
2013-09-23 17:10:03 +02:00
98 changed files with 8688 additions and 277 deletions

View File

@@ -2,6 +2,8 @@
namespace Thelia\Model;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Thelia\Model\Base\CategoryImage as BaseCategoryImage;
use Propel\Runtime\Connection\ConnectionInterface;
@@ -25,4 +27,29 @@ class CategoryImage extends BaseCategoryImage
return true;
}
/**
* Set Image parent id
*
* @param int $parentId parent id
*
* @return $this
*/
public function setParentId($parentId)
{
$this->setCategoryId($parentId);
return $this;
}
/**
* Get Image parent id
*
* @return int parent id
*/
public function getParentId()
{
return $this->getCategoryId();
}
}

View File

@@ -2,7 +2,12 @@
namespace Thelia\Model;
use Propel\Runtime\Propel;
use Thelia\Core\Event\Content\ContentEvent;
use Thelia\Core\Event\TheliaEvents;
use Thelia\Model\Base\Content as BaseContent;
use Thelia\Model\ContentFolderQuery;
use Thelia\Model\Map\ContentTableMap;
use Thelia\Tools\URL;
use Propel\Runtime\Connection\ConnectionInterface;
@@ -30,13 +35,78 @@ class Content extends BaseContent
// and generate the position relative to this folder
}
/**
* {@inheritDoc}
*/
public function preInsert(ConnectionInterface $con = null)
public function getDefaultFolderId()
{
$this->setPosition($this->getNextPosition());
// Find default folder
$default_folder = ContentFolderQuery::create()
->filterByContentId($this->getId())
->filterByDefaultFolder(true)
->findOne();
return $default_folder == null ? 0 : $default_folder->getFolderId();
}
public function setDefaultFolder($folderId)
{
/* ContentFolderQuery::create()
->filterByContentId($this->getId)
->update(array("DefaultFolder" => 0));*/
return $this;
}
public function create($defaultFolderId)
{
$con = Propel::getWriteConnection(ContentTableMap::DATABASE_NAME);
$con->beginTransaction();
$this->dispatchEvent(TheliaEvents::BEFORE_CREATECONTENT, new ContentEvent($this));
try {
$this->save($con);
$cf = new ContentFolder();
$cf->setContentId($this->getId())
->setFolderId($defaultFolderId)
->setDefaultFolder(1)
->save($con);
$this->setPosition($this->getNextPosition())->save($con);
$con->commit();
$this->dispatchEvent(TheliaEvents::AFTER_CREATECONTENT,new ContentEvent($this));
} catch(\Exception $ex) {
$con->rollback();
throw $ex;
}
}
public function preUpdate(ConnectionInterface $con = null)
{
$this->dispatchEvent(TheliaEvents::BEFORE_UPDATECONTENT, new ContentEvent($this));
return true;
}
public function postUpdate(ConnectionInterface $con = null)
{
$this->dispatchEvent(TheliaEvents::AFTER_UPDATECONTENT, new ContentEvent($this));
}
public function preDelete(ConnectionInterface $con = null)
{
$this->dispatchEvent(TheliaEvents::BEFORE_DELETECONTENT, new ContentEvent($this));
return true;
}
public function postDelete(ConnectionInterface $con = null)
{
$this->dispatchEvent(TheliaEvents::AFTER_DELETECONTENT, new ContentEvent($this));
}
}

View File

@@ -25,4 +25,28 @@ class ContentImage extends BaseContentImage
return true;
}
/**
* Set Image parent id
*
* @param int $parentId parent id
*
* @return $this
*/
public function setParentId($parentId)
{
$this->setContentId($parentId);
return $this;
}
/**
* Get Image parent id
*
* @return int parent id
*/
public function getParentId()
{
return $this->getContentId();
}
}

View File

@@ -2,6 +2,8 @@
namespace Thelia\Model;
use Thelia\Core\Event\FolderEvent;
use Thelia\Core\Event\TheliaEvents;
use Thelia\Model\Base\Folder as BaseFolder;
use Thelia\Tools\URL;
use Propel\Runtime\Connection\ConnectionInterface;
@@ -67,6 +69,37 @@ class Folder extends BaseFolder
{
$this->setPosition($this->getNextPosition());
$this->dispatchEvent(TheliaEvents::BEFORE_CREATEFOLDER, new FolderEvent($this));
return true;
}
public function postInsert(ConnectionInterface $con = null)
{
$this->dispatchEvent(TheliaEvents::AFTER_CREATEFOLDER, new FolderEvent($this));
}
public function preUpdate(ConnectionInterface $con = null)
{
$this->dispatchEvent(TheliaEvents::BEFORE_UPDATEFOLDER, new FolderEvent($this));
return true;
}
public function postUpdate(ConnectionInterface $con = null)
{
$this->dispatchEvent(TheliaEvents::AFTER_UPDATEFOLDER, new FolderEvent($this));
}
public function preDelete(ConnectionInterface $con = null)
{
$this->dispatchEvent(TheliaEvents::BEFORE_DELETEFOLDER, new FolderEvent($this));
return true;
}
public function postDelete(ConnectionInterface $con = null)
{
$this->dispatchEvent(TheliaEvents::AFTER_DELETEFOLDER, new FolderEvent($this));
}
}

View File

@@ -25,4 +25,28 @@ class FolderImage extends BaseFolderImage
return true;
}
/**
* Set Image parent id
*
* @param int $parentId parent id
*
* @return $this
*/
public function setParentId($parentId)
{
$this->setFolderId($parentId);
return $this;
}
/**
* Get Image parent id
*
* @return int parent id
*/
public function getParentId()
{
return $this->getFolderId();
}
}

View File

@@ -2,10 +2,17 @@
namespace Thelia\Model;
use Propel\Runtime\ActiveQuery\Criteria;
use Propel\Runtime\Connection\ConnectionInterface;
use Propel\Runtime\Propel;
use Thelia\Core\Event\OrderEvent;
use Thelia\Core\Event\TheliaEvents;
use Thelia\Model\Base\Order as BaseOrder;
use Thelia\Model\Base\OrderProductTaxQuery;
use Thelia\Model\Map\OrderProductTaxTableMap;
use Thelia\Model\OrderProductQuery;
use Thelia\Model\Map\OrderTableMap;
use \PDO;
class Order extends BaseOrder
{
@@ -19,20 +26,209 @@ class Order extends BaseOrder
*/
public function preInsert(ConnectionInterface $con = null)
{
$this->dispatchEvent(TheliaEvents::ORDER_SET_REFERENCE, new OrderEvent($this));
$this->dispatchEvent(TheliaEvents::ORDER_BEFORE_CREATE, new OrderEvent($this));
return true;
}
/**
* {@inheritDoc}
*/
public function postInsert(ConnectionInterface $con = null)
{
$this->dispatchEvent(TheliaEvents::ORDER_AFTER_CREATE, new OrderEvent($this));
}
/**
* calculate the total amount
*
* @TODO create body method
* @param int $tax
*
* @return int
* @return int|string|Base\double
*/
public function getTotalAmount()
public function getTotalAmount(&$tax = 0)
{
return 2;
$amount = 0;
$tax = 0;
/* browse all products */
$orderProductIds = array();
foreach($this->getOrderProducts() as $orderProduct) {
$taxAmount = OrderProductTaxQuery::create()
->withColumn('SUM(' . OrderProductTaxTableMap::AMOUNT . ')', 'total_tax')
->filterByOrderProductId($orderProduct->getId(), Criteria::EQUAL)
->findOne();
$amount += ($orderProduct->getWasInPromo() == 1 ? $orderProduct->getPromoPrice() : $orderProduct->getPrice()) * $orderProduct->getQuantity();
$tax += round($taxAmount->getVirtualColumn('total_tax'), 2) * $orderProduct->getQuantity();
}
return $amount + $tax + $this->getPostage(); // @todo : manage discount
}
/**
* PROPEL SHOULD FIX IT
*
* Insert the row in the database.
*
* @param ConnectionInterface $con
*
* @throws PropelException
* @see doSave()
*/
protected function doInsert(ConnectionInterface $con)
{
$modifiedColumns = array();
$index = 0;
$this->modifiedColumns[] = OrderTableMap::ID;
if (null !== $this->id) {
throw new PropelException('Cannot insert a value for auto-increment primary key (' . OrderTableMap::ID . ')');
}
// check the columns in natural order for more readable SQL queries
if ($this->isColumnModified(OrderTableMap::ID)) {
$modifiedColumns[':p' . $index++] = 'ID';
}
if ($this->isColumnModified(OrderTableMap::REF)) {
$modifiedColumns[':p' . $index++] = 'REF';
}
if ($this->isColumnModified(OrderTableMap::CUSTOMER_ID)) {
$modifiedColumns[':p' . $index++] = 'CUSTOMER_ID';
}
if ($this->isColumnModified(OrderTableMap::INVOICE_ORDER_ADDRESS_ID)) {
$modifiedColumns[':p' . $index++] = 'INVOICE_ORDER_ADDRESS_ID';
}
if ($this->isColumnModified(OrderTableMap::DELIVERY_ORDER_ADDRESS_ID)) {
$modifiedColumns[':p' . $index++] = 'DELIVERY_ORDER_ADDRESS_ID';
}
if ($this->isColumnModified(OrderTableMap::INVOICE_DATE)) {
$modifiedColumns[':p' . $index++] = 'INVOICE_DATE';
}
if ($this->isColumnModified(OrderTableMap::CURRENCY_ID)) {
$modifiedColumns[':p' . $index++] = 'CURRENCY_ID';
}
if ($this->isColumnModified(OrderTableMap::CURRENCY_RATE)) {
$modifiedColumns[':p' . $index++] = 'CURRENCY_RATE';
}
if ($this->isColumnModified(OrderTableMap::TRANSACTION_REF)) {
$modifiedColumns[':p' . $index++] = 'TRANSACTION_REF';
}
if ($this->isColumnModified(OrderTableMap::DELIVERY_REF)) {
$modifiedColumns[':p' . $index++] = 'DELIVERY_REF';
}
if ($this->isColumnModified(OrderTableMap::INVOICE_REF)) {
$modifiedColumns[':p' . $index++] = 'INVOICE_REF';
}
if ($this->isColumnModified(OrderTableMap::POSTAGE)) {
$modifiedColumns[':p' . $index++] = 'POSTAGE';
}
if ($this->isColumnModified(OrderTableMap::PAYMENT_MODULE_ID)) {
$modifiedColumns[':p' . $index++] = 'PAYMENT_MODULE_ID';
}
if ($this->isColumnModified(OrderTableMap::DELIVERY_MODULE_ID)) {
$modifiedColumns[':p' . $index++] = 'DELIVERY_MODULE_ID';
}
if ($this->isColumnModified(OrderTableMap::STATUS_ID)) {
$modifiedColumns[':p' . $index++] = 'STATUS_ID';
}
if ($this->isColumnModified(OrderTableMap::LANG_ID)) {
$modifiedColumns[':p' . $index++] = 'LANG_ID';
}
if ($this->isColumnModified(OrderTableMap::CREATED_AT)) {
$modifiedColumns[':p' . $index++] = 'CREATED_AT';
}
if ($this->isColumnModified(OrderTableMap::UPDATED_AT)) {
$modifiedColumns[':p' . $index++] = 'UPDATED_AT';
}
$db = Propel::getServiceContainer()->getAdapter(OrderTableMap::DATABASE_NAME);
if ($db->useQuoteIdentifier()) {
$tableName = $db->quoteIdentifierTable(OrderTableMap::TABLE_NAME);
} else {
$tableName = OrderTableMap::TABLE_NAME;
}
$sql = sprintf(
'INSERT INTO %s (%s) VALUES (%s)',
$tableName,
implode(', ', $modifiedColumns),
implode(', ', array_keys($modifiedColumns))
);
try {
$stmt = $con->prepare($sql);
foreach ($modifiedColumns as $identifier => $columnName) {
switch ($columnName) {
case 'ID':
$stmt->bindValue($identifier, $this->id, PDO::PARAM_INT);
break;
case 'REF':
$stmt->bindValue($identifier, $this->ref, PDO::PARAM_STR);
break;
case 'CUSTOMER_ID':
$stmt->bindValue($identifier, $this->customer_id, PDO::PARAM_INT);
break;
case 'INVOICE_ORDER_ADDRESS_ID':
$stmt->bindValue($identifier, $this->invoice_order_address_id, PDO::PARAM_INT);
break;
case 'DELIVERY_ORDER_ADDRESS_ID':
$stmt->bindValue($identifier, $this->delivery_order_address_id, PDO::PARAM_INT);
break;
case 'INVOICE_DATE':
$stmt->bindValue($identifier, $this->invoice_date ? $this->invoice_date->format("Y-m-d H:i:s") : null, PDO::PARAM_STR);
break;
case 'CURRENCY_ID':
$stmt->bindValue($identifier, $this->currency_id, PDO::PARAM_INT);
break;
case 'CURRENCY_RATE':
$stmt->bindValue($identifier, $this->currency_rate, PDO::PARAM_STR);
break;
case 'TRANSACTION_REF':
$stmt->bindValue($identifier, $this->transaction_ref, PDO::PARAM_STR);
break;
case 'DELIVERY_REF':
$stmt->bindValue($identifier, $this->delivery_ref, PDO::PARAM_STR);
break;
case 'INVOICE_REF':
$stmt->bindValue($identifier, $this->invoice_ref, PDO::PARAM_STR);
break;
case 'POSTAGE':
$stmt->bindValue($identifier, $this->postage, PDO::PARAM_STR);
break;
case 'PAYMENT_MODULE_ID':
$stmt->bindValue($identifier, $this->payment_module_id, PDO::PARAM_INT);
break;
case 'DELIVERY_MODULE_ID':
$stmt->bindValue($identifier, $this->delivery_module_id, PDO::PARAM_INT);
break;
case 'STATUS_ID':
$stmt->bindValue($identifier, $this->status_id, PDO::PARAM_INT);
break;
case 'LANG_ID':
$stmt->bindValue($identifier, $this->lang_id, PDO::PARAM_INT);
break;
case 'CREATED_AT':
$stmt->bindValue($identifier, $this->created_at ? $this->created_at->format("Y-m-d H:i:s") : null, PDO::PARAM_STR);
break;
case 'UPDATED_AT':
$stmt->bindValue($identifier, $this->updated_at ? $this->updated_at->format("Y-m-d H:i:s") : null, PDO::PARAM_STR);
break;
}
}
$stmt->execute();
} catch (Exception $e) {
Propel::log($e->getMessage(), Propel::LOG_ERR);
throw new PropelException(sprintf('Unable to execute INSERT statement [%s]', $sql), 0, $e);
}
try {
$pk = $con->lastInsertId();
} catch (Exception $e) {
throw new PropelException('Unable to get autoincrement id.', 0, $e);
}
$this->setId($pk);
$this->setNew(false);
}
}

24
core/lib/Thelia/Model/OrderProduct.php Executable file → Normal file
View File

@@ -2,8 +2,30 @@
namespace Thelia\Model;
use Propel\Runtime\Connection\ConnectionInterface;
use Thelia\Core\Event\OrderEvent;
use Thelia\Core\Event\TheliaEvents;
use Thelia\Model\Base\OrderProduct as BaseOrderProduct;
class OrderProduct extends BaseOrderProduct {
class OrderProduct extends BaseOrderProduct
{
use \Thelia\Model\Tools\ModelEventDispatcherTrait;
/**
* {@inheritDoc}
*/
public function preInsert(ConnectionInterface $con = null)
{
$this->dispatchEvent(TheliaEvents::ORDER_PRODUCT_BEFORE_CREATE, new OrderEvent($this->getOrder()));
return true;
}
/**
* {@inheritDoc}
*/
public function postInsert(ConnectionInterface $con = null)
{
$this->dispatchEvent(TheliaEvents::ORDER_PRODUCT_AFTER_CREATE, new OrderEvent($this->getOrder()));
}
}

3
core/lib/Thelia/Model/OrderProductQuery.php Executable file → Normal file
View File

@@ -15,6 +15,7 @@ use Thelia\Model\Base\OrderProductQuery as BaseOrderProductQuery;
* long as it does not already exist in the output directory.
*
*/
class OrderProductQuery extends BaseOrderProductQuery {
class OrderProductQuery extends BaseOrderProductQuery
{
} // OrderProductQuery

View File

@@ -2,8 +2,11 @@
namespace Thelia\Model;
use Propel\Runtime\Exception\PropelException;
use Propel\Runtime\Propel;
use Thelia\Model\Base\OrderQuery as BaseOrderQuery;
use \PDO;
use Thelia\Model\Map\OrderTableMap;
/**
* Skeleton subclass for performing query and update operations on the 'order' table.
@@ -15,6 +18,38 @@ use Thelia\Model\Base\OrderQuery as BaseOrderQuery;
* long as it does not already exist in the output directory.
*
*/
class OrderQuery extends BaseOrderQuery {
class OrderQuery extends BaseOrderQuery
{
/**
* PROPEL SHOULD FIX IT
*
* Find object by primary key using raw SQL to go fast.
* Bypass doSelect() and the object formatter by using generated code.
*
* @param mixed $key Primary key to use for the query
* @param ConnectionInterface $con A connection object
*
* @return Order A model object, or null if the key is not found
*/
protected function findPkSimple($key, $con)
{
$sql = 'SELECT ID, REF, CUSTOMER_ID, INVOICE_ORDER_ADDRESS_ID, DELIVERY_ORDER_ADDRESS_ID, INVOICE_DATE, CURRENCY_ID, CURRENCY_RATE, TRANSACTION_REF, DELIVERY_REF, INVOICE_REF, POSTAGE, PAYMENT_MODULE_ID, DELIVERY_MODULE_ID, STATUS_ID, LANG_ID, CREATED_AT, UPDATED_AT FROM `order` WHERE ID = :p0';
try {
$stmt = $con->prepare($sql);
$stmt->bindValue(':p0', $key, PDO::PARAM_INT);
$stmt->execute();
} catch (\Exception $e) {
Propel::log($e->getMessage(), Propel::LOG_ERR);
throw new PropelException(sprintf('Unable to execute SELECT statement [%s]', $sql), 0, $e);
}
$obj = null;
if ($row = $stmt->fetch(\PDO::FETCH_NUM)) {
$obj = new Order();
$obj->hydrate($row);
OrderTableMap::addInstanceToPool($obj, (string) $key);
}
$stmt->closeCursor();
return $obj;
}
} // OrderQuery

View File

@@ -98,8 +98,6 @@ class Product extends BaseProduct
->filterByDefaultCategory(true)
->findOne()
;
echo "newcat= $defaultCategoryId ";
var_dump($productCategory);
if ($productCategory == null || $productCategory->getCategoryId() != $defaultCategoryId) {
exit;

View File

@@ -25,4 +25,28 @@ class ProductImage extends BaseProductImage
return true;
}
/**
* Set Image parent id
*
* @param int $parentId parent id
*
* @return $this
*/
public function setParentId($parentId)
{
$this->setProductId($parentId);
return $this;
}
/**
* Get Image parent id
*
* @return int parent id
*/
public function getParentId()
{
return $this->getProductId();
}
}

View File

@@ -3,7 +3,25 @@
namespace Thelia\Model;
use Thelia\Model\Base\TaxRule as BaseTaxRule;
use Thelia\TaxEngine\Calculator;
use Thelia\TaxEngine\OrderProductTaxCollection;
class TaxRule extends BaseTaxRule {
class TaxRule extends BaseTaxRule
{
/**
* @param Country $country
* @param $untaxedAmount
* @param null $askedLocale
*
* @return OrderProductTaxCollection
*/
public function getTaxDetail(Country $country, $untaxedAmount, $askedLocale = null)
{
$taxCalculator = new Calculator();
$taxCollection = new OrderProductTaxCollection();
$taxCalculator->loadTaxRule($this, $country)->getTaxedPrice($untaxedAmount, $taxCollection, $askedLocale);
return $taxCollection;
}
}

View File

@@ -21,13 +21,19 @@ class TaxRuleQuery extends BaseTaxRuleQuery
{
const ALIAS_FOR_TAX_RULE_COUNTRY_POSITION = 'taxRuleCountryPosition';
public function getTaxCalculatorCollection(Product $product, Country $country)
/**
* @param TaxRule $taxRule
* @param Country $country
*
* @return array|mixed|\Propel\Runtime\Collection\ObjectCollection
*/
public function getTaxCalculatorCollection(TaxRule $taxRule, Country $country)
{
$search = TaxQuery::create()
->filterByTaxRuleCountry(
TaxRuleCountryQuery::create()
->filterByCountry($country, Criteria::EQUAL)
->filterByTaxRuleId($product->getTaxRuleId())
->filterByTaxRuleId($taxRule->getId())
->orderByPosition()
->find()
)