diff --git a/core/lib/Thelia/Action/Customer.php b/core/lib/Thelia/Action/Customer.php index 9fee8b69e..34f0b418c 100755 --- a/core/lib/Thelia/Action/Customer.php +++ b/core/lib/Thelia/Action/Customer.php @@ -83,9 +83,10 @@ class Customer extends BaseAction implements EventSubscriberInterface public function delete(CustomerEvent $event) { - $customer = $event->getCustomer(); + if (null !== $customer = $event->getCustomer()) { - $customer->delete(); + $customer->delete(); + } } private function createOrUpdateCustomer(CustomerModel $customer, CustomerCreateOrUpdateEvent $event) diff --git a/core/lib/Thelia/Config/Resources/routing/admin.xml b/core/lib/Thelia/Config/Resources/routing/admin.xml index a966b2608..823e037b5 100755 --- a/core/lib/Thelia/Config/Resources/routing/admin.xml +++ b/core/lib/Thelia/Config/Resources/routing/admin.xml @@ -109,19 +109,17 @@ - Thelia\Controller\Admin\CustomerController::indexAction + Thelia\Controller\Admin\CustomerController::defaultAction - - Thelia\Controller\Admin\CustomerController::viewAction - \d+ - - - + Thelia\Controller\Admin\CustomerController::updateAction - \d+ + + Thelia\Controller\Admin\CustomerController::processUpdateAction + + Thelia\Controller\Admin\CustomerController::deleteAction @@ -146,14 +144,12 @@ Thelia\Controller\Admin\AddressController::createAction - + Thelia\Controller\Admin\AddressController::updateAction - \d+ - + Thelia\Controller\Admin\AddressController::processUpdateAction - \d+ diff --git a/core/lib/Thelia/Controller/Admin/AddressController.php b/core/lib/Thelia/Controller/Admin/AddressController.php index 26f97c9b3..a89366583 100644 --- a/core/lib/Thelia/Controller/Admin/AddressController.php +++ b/core/lib/Thelia/Controller/Admin/AddressController.php @@ -42,7 +42,7 @@ class AddressController extends AbstractCrudController public function __construct() { parent::__construct( - 'address', + 'registration_date', null, null, @@ -50,10 +50,7 @@ class AddressController extends AbstractCrudController TheliaEvents::ADDRESS_CREATE, TheliaEvents::ADDRESS_UPDATE, - TheliaEvents::ADDRESS_DELETE, - null, - null - + TheliaEvents::ADDRESS_DELETE ); } @@ -79,7 +76,7 @@ class AddressController extends AbstractCrudController \Thelia\Log\Tlog::getInstance()->error(sprintf("error during address setting as default with message %s", $e->getMessage())); } - $this->redirectToRoute('admin.customer.update.view', array(), array('customer_id' => $address->getCustomerId())); + $this->redirectToEditionTemplate(); } /** @@ -99,13 +96,14 @@ class AddressController extends AbstractCrudController } /** - * Hydrate the update form for this object, before passing it to the update template + * Fills in the form data array * - * @param \Thelia\Model\Address $object + * @param unknown $object + * @return multitype:NULL */ - protected function hydrateObjectForm($object) + protected function createFormDataArray($object) { - $data = array( + return array( "label" => $object->getLabel(), "title" => $object->getTitleId(), "firstname" => $object->getFirstname(), @@ -120,8 +118,16 @@ class AddressController extends AbstractCrudController "phone" => $object->getPhone(), "company" => $object->getCompany() ); + } - return new AddressUpdateForm($this->getRequest(), "form", $data); + /** + * Hydrate the update form for this object, before passing it to the update template + * + * @param \Thelia\Model\Address $object + */ + protected function hydrateObjectForm($object) + { + return new AddressUpdateForm($this->getRequest(), "form", $this->createFormDataArray($object)); } /** @@ -240,7 +246,8 @@ class AddressController extends AbstractCrudController */ protected function renderListTemplate($currentOrder) { - // TODO: Implement renderListTemplate() method. + // We render here the customer edit template. + return $this->renderEditionTemplate(); } /** @@ -248,9 +255,10 @@ class AddressController extends AbstractCrudController */ protected function renderEditionTemplate() { - return $this->render('ajax/address-update-modal', array( - "address_id" => $this->getRequest()->get('address_id'), - "customer_id" => $this->getExistingObject()->getCustomerId() + return $this->render('customer-edit', array( + "address_id" => $this->getRequest()->get('address_id'), + "page" => $this->getRequest()->get('page'), + "customer_id" => $this->getCustomerId() )); } @@ -259,8 +267,11 @@ class AddressController extends AbstractCrudController */ protected function redirectToEditionTemplate() { - $address = $this->getExistingObject(); - $this->redirectToRoute('admin.customer.update.view', array(), array('customer_id' => $address->getCustomerId())); + // We display here the custromer edition template + $this->redirectToRoute('admin.customer.update.view', array( + "page" => $this->getRequest()->get('page'), + "customer_id" => $this->getCustomerId() + )); } /** @@ -279,8 +290,7 @@ class AddressController extends AbstractCrudController */ protected function performAdditionalDeleteAction($deleteEvent) { - $address = $deleteEvent->getAddress(); - $this->redirectToRoute('admin.customer.update.view', array(), array('customer_id' => $address->getCustomerId())); + $this->redirectToEditionTemplate(); } /** @@ -298,4 +308,11 @@ class AddressController extends AbstractCrudController { $this->redirectToEditionTemplate(); } + + protected function getCustomerId() { + if (null !== $address = $this->getExistingObject()) + return $address->getCustomerId(); + else + return $this->getRequest()->get('customer_id', 0); + } } diff --git a/core/lib/Thelia/Controller/Admin/CustomerController.php b/core/lib/Thelia/Controller/Admin/CustomerController.php index 9719748fc..ec55b3e43 100644 --- a/core/lib/Thelia/Controller/Admin/CustomerController.php +++ b/core/lib/Thelia/Controller/Admin/CustomerController.php @@ -35,171 +35,96 @@ use Thelia\Form\Exception\FormValidationException; use Thelia\Model\CustomerQuery; use Thelia\Core\Translation\Translator; use Thelia\Tools\Password; +use Thelia\Model\AddressQuery; +use Thelia\Model\Address; /** * Class CustomerController * @package Thelia\Controller\Admin * @author Manuel Raynaud */ -class CustomerController extends BaseAdminController +class CustomerController extends AbstractCrudController { - public function indexAction() + public function __construct() { - if (null !== $response = $this->checkAuth(AdminResources::CUSTOMER, AccessManager::VIEW)) return $response; - return $this->render("customers", array("display_customer" => 20)); + parent::__construct( + 'customer', + 'lastname', + 'customer_order', + + AdminResources::CUSTOMER, + + TheliaEvents::CUSTOMER_CREATEACCOUNT, + TheliaEvents::CUSTOMER_UPDATEACCOUNT, + TheliaEvents::CUSTOMER_DELETEACCOUNT + ); } - public function viewAction($customer_id) + protected function getCreationForm() { - if (null !== $response = $this->checkAuth(AdminResources::CUSTOMER, AccessManager::VIEW)) return $response; - return $this->render("customer-edit", array( - "customer_id" => $customer_id - )); + return new CustomerCreateForm($this->getRequest()); } - /** - * update customer action - * - * @param $customer_id - * @return mixed|\Thelia\Core\HttpFoundation\Response - */ - public function updateAction($customer_id) + protected function getUpdateForm() { - if (null !== $response = $this->checkAuth(AdminResources::CUSTOMER, AccessManager::UPDATE)) return $response; - - $message = false; - - $customerUpdateForm = new CustomerUpdateForm($this->getRequest()); - - try { - $customer = CustomerQuery::create()->findPk($customer_id); - - if (null === $customer) { - throw new \InvalidArgumentException(sprintf("%d customer id does not exist", $customer_id)); - } - - $form = $this->validateForm($customerUpdateForm); - - $event = $this->createEventInstance($form->getData()); - $event->setCustomer($customer); - - $this->dispatch(TheliaEvents::CUSTOMER_UPDATEACCOUNT, $event); - - $customerUpdated = $event->getCustomer(); - - $this->adminLogAppend(AdminResources::CUSTOMER, AccessManager::UPDATE, sprintf("Customer with Ref %s (ID %d) modified", $customerUpdated->getRef() , $customerUpdated->getId())); - - if ($this->getRequest()->get("save_mode") == "close") { - $this->redirectToRoute("admin.customers"); - } else { - $this->redirectSuccess($customerUpdateForm); - } - - } catch (FormValidationException $e) { - $message = sprintf("Please check your input: %s", $e->getMessage()); - } catch (PropelException $e) { - $message = $e->getMessage(); - } catch (\Exception $e) { - $message = sprintf("Sorry, an error occured: %s", $e->getMessage()." ".$e->getFile()); - } - - if ($message !== false) { - \Thelia\Log\Tlog::getInstance()->error(sprintf("Error during customer update process : %s.", $message)); - - $customerUpdateForm->setErrorMessage($message); - - $this->getParserContext() - ->addForm($customerUpdateForm) - ->setGeneralError($message) - ; - } - - return $this->render("customer-edit", array( - "customer_id" => $customer_id - )); + return new CustomerUpdateForm($this->getRequest()); } - public function createAction() + protected function getCreationEvent($formData) { - if (null !== $response = $this->checkAuth(AdminResources::CUSTOMER, AccessManager::CREATE)) return $response; - - $message = null; - - $customerCreateForm = new CustomerCreateForm($this->getRequest()); - - try { - - $form = $this->validateForm($customerCreateForm); - - $data = $form->getData(); - $data["password"] = Password::generateRandom(); - - $event = $this->createEventInstance($form->getData()); - - - - $this->dispatch(TheliaEvents::CUSTOMER_CREATEACCOUNT, $event); - - $successUrl = $customerCreateForm->getSuccessUrl(); - - $successUrl = str_replace('_ID_', $event->getCustomer()->getId(), $successUrl); - - $this->redirect($successUrl); - - - }catch (FormValidationException $e) { - $message = sprintf("Please check your input: %s", $e->getMessage()); - } catch (PropelException $e) { - $message = $e->getMessage(); - } catch (\Exception $e) { - $message = sprintf("Sorry, an error occured: %s", $e->getMessage()." ".$e->getFile()); - } - - if ($message !== false) { - \Thelia\Log\Tlog::getInstance()->error(sprintf("Error during customer creation process : %s.", $message)); - - $customerCreateForm->setErrorMessage($message); - - $this->getParserContext() - ->addForm($customerCreateForm) - ->setGeneralError($message) - ; - } - - return $this->render("customers", array("display_customer" => 20)); + return $this->createEventInstance($formData); } - public function deleteAction() + protected function getUpdateEvent($formData) { - if (null !== $response = $this->checkAuth(AdminResources::CUSTOMER, AccessManager::DELETE)) return $response; + $event = $this->createEventInstance($formData); - $message = null; + $event->setCustomer($this->getExistingObject()); - try { - $customer_id = $this->getRequest()->get("customer_id"); - $customer = CustomerQuery::create()->findPk($customer_id); + return $event; + } - if (null === $customer) { - throw new \InvalidArgumentException(Translator::getInstance("The customer you want to delete does not exist")); - } + protected function getDeleteEvent() + { + return new CustomerEvent($this->getExistingObject()); + } - $event = new CustomerEvent($customer); + protected function eventContainsObject($event) + { + return $event->hasCustomer(); + } - $this->dispatch(TheliaEvents::CUSTOMER_DELETEACCOUNT, $event); - } catch (\Exception $e) { - $message = $e->getMessage(); - } + protected function hydrateObjectForm($object) + { + // Get default adress of the customer + $address = $object->getDefaultAddress(); - $params = array( - "customer_page" => $this->getRequest()->get("customer_page", 1) + // Prepare the data that will hydrate the form + $data = array( + 'id' => $object->getId(), + 'firstname' => $object->getFirstname(), + 'lastname' => $object->getLastname(), + 'email' => $object->getEmail(), + 'title' => $object->getTitleId(), + + 'company' => $address->getCompany(), + 'address1' => $address->getAddress1(), + 'address2' => $address->getAddress2(), + 'address3' => $address->getAddress3(), + 'phone' => $address->getPhone(), + 'cellphone' => $address->getCellphone(), + 'zipcode' => $address->getZipcode(), + 'city' => $address->getCity(), + 'country' => $address->getCountryId(), ); - if ($message) { - $params["delete_error_message"] = $message; - } - - $this->redirectToRoute("admin.customers", $params); + // A loop is used in the template + return new CustomerUpdateForm($this->getRequest(), 'form', $data); + } + protected function getObjectFromEvent($event) + { + return $event->hasCustomer() ? $event->getCustomer() : null; } /** @@ -209,26 +134,75 @@ class CustomerController extends BaseAdminController private function createEventInstance($data) { $customerCreateEvent = new CustomerCreateOrUpdateEvent( - $data["title"], - $data["firstname"], - $data["lastname"], - $data["address1"], - $data["address2"], - $data["address3"], - $data["phone"], - $data["cellphone"], - $data["zipcode"], - $data["city"], - $data["country"], - isset($data["email"])?$data["email"]:null, - isset($data["password"]) ? $data["password"]:null, - $this->getRequest()->getSession()->getLang()->getId(), - isset($data["reseller"])?$data["reseller"]:null, - isset($data["sponsor"])?$data["sponsor"]:null, - isset($data["discount"])?$data["discount"]:null, - isset($data["company"])?$data["company"]:null + $data["title"], + $data["firstname"], + $data["lastname"], + $data["address1"], + $data["address2"], + $data["address3"], + $data["phone"], + $data["cellphone"], + $data["zipcode"], + $data["city"], + $data["country"], + isset($data["email"])?$data["email"]:null, + isset($data["password"]) && ! empty($data["password"]) ? $data["password"]:null, + $this->getRequest()->getSession()->getLang()->getId(), + isset($data["reseller"])?$data["reseller"]:null, + isset($data["sponsor"])?$data["sponsor"]:null, + isset($data["discount"])?$data["discount"]:null, + isset($data["company"])?$data["company"]:null ); return $customerCreateEvent; } -} + + protected function getExistingObject() + { + return CustomerQuery::create()->findPk($this->getRequest()->get('customer_id', 0)); + } + + protected function getObjectLabel($object) + { + return $object->getRef() . "(".$object->getLastname()." ".$object->getFirstname().")"; + } + + protected function getObjectId($object) + { + return $object->getId(); + } + + protected function getEditionArguments() + { + return array( + 'customer_id' => $this->getRequest()->get('customer_id', 0), + 'page' => $this->getRequest()->get('page', 1) + ); + } + + protected function renderListTemplate($currentOrder) + { + return $this->render('customers', array( + 'customer_order' => $currentOrder, + 'display_customer' => 20, + 'page' => $this->getRequest()->get('page', 1) + )); + } + + protected function redirectToListTemplate() + { + $this->redirectToRoute('admin.customers', array( + 'page' => $this->getRequest()->get('page', 1)) + ); + } + + protected function renderEditionTemplate() + { + return $this->render('customer-edit', $this->getEditionArguments()); + } + + protected function redirectToEditionTemplate() + { + $this->redirectToRoute("admin.customer.update.view", $this->getEditionArguments()); + } +} \ No newline at end of file diff --git a/core/lib/Thelia/Controller/NullControllerInterface.php b/core/lib/Thelia/Controller/NullControllerInterface.php deleted file mode 100755 index 6e832aff6..000000000 --- a/core/lib/Thelia/Controller/NullControllerInterface.php +++ /dev/null @@ -1,19 +0,0 @@ - - */ - -interface NullControllerInterface -{ - /** - * Nothing to do - */ - public function noAction(Request $request); - -} diff --git a/core/lib/Thelia/Core/Event/Customer/CustomerCreateOrUpdateEvent.php b/core/lib/Thelia/Core/Event/Customer/CustomerCreateOrUpdateEvent.php index 2c59c2899..2c45942f3 100755 --- a/core/lib/Thelia/Core/Event/Customer/CustomerCreateOrUpdateEvent.php +++ b/core/lib/Thelia/Core/Event/Customer/CustomerCreateOrUpdateEvent.php @@ -31,7 +31,7 @@ use Thelia\Model\Customer; * @package Thelia\Core\Event * @author Manuel Raynaud */ -class CustomerCreateOrUpdateEvent extends ActionEvent +class CustomerCreateOrUpdateEvent extends CustomerEvent { //base parameters for creating new customer protected $title; @@ -53,11 +53,6 @@ class CustomerCreateOrUpdateEvent extends ActionEvent protected $discount; protected $company; - /** - * @var \Thelia\Model\Customer - */ - protected $customer; - /** * @param int $title the title customer id * @param string $firstname @@ -242,21 +237,4 @@ class CustomerCreateOrUpdateEvent extends ActionEvent { return $this->sponsor; } - - /** - * @param Customer $customer - */ - public function setCustomer(Customer $customer) - { - $this->customer = $customer; - } - - /** - * @return Customer - */ - public function getCustomer() - { - return $this->customer; - } - } diff --git a/core/lib/Thelia/Core/Event/Customer/CustomerEvent.php b/core/lib/Thelia/Core/Event/Customer/CustomerEvent.php index f11bb7f2d..e76f23955 100755 --- a/core/lib/Thelia/Core/Event/Customer/CustomerEvent.php +++ b/core/lib/Thelia/Core/Event/Customer/CustomerEvent.php @@ -28,13 +28,23 @@ use Thelia\Core\Event\ActionEvent; class CustomerEvent extends ActionEvent { - public $customer; + public $customer = null; - public function __construct(Customer $customer) + public function __construct(Customer $customer = null) { $this->customer = $customer; } + /** + * @param Customer $customer + */ + public function setCustomer(Customer $customer) + { + $this->customer = $customer; + + return $this; + } + /** * @return \Thelia\Model\Customer */ @@ -43,4 +53,12 @@ class CustomerEvent extends ActionEvent return $this->customer; } + /** + * @return bool + */ + public function hasCustomer() + { + return $this->customer != null; + } + } diff --git a/core/lib/Thelia/Core/Event/Customer/CustomerLoginEvent.php b/core/lib/Thelia/Core/Event/Customer/CustomerLoginEvent.php index 56c29bf6c..0a046177e 100755 --- a/core/lib/Thelia/Core/Event/Customer/CustomerLoginEvent.php +++ b/core/lib/Thelia/Core/Event/Customer/CustomerLoginEvent.php @@ -26,17 +26,7 @@ namespace Thelia\Core\Event\Customer; use Thelia\Core\Event\ActionEvent; use Thelia\Model\Customer; -class CustomerLoginEvent extends ActionEvent +class CustomerLoginEvent extends CustomerEvent { - protected $customer; - - public function __construct(Customer $customer) - { - $this->customer = $customer; - } - - public function getCustomer() - { - return $this->customer; - } + // Nothing specific :) } diff --git a/core/lib/Thelia/Core/Template/Assets/AsseticHelper.php b/core/lib/Thelia/Core/Template/Assets/AsseticHelper.php index 12ed85ad2..6892d45a8 100755 --- a/core/lib/Thelia/Core/Template/Assets/AsseticHelper.php +++ b/core/lib/Thelia/Core/Template/Assets/AsseticHelper.php @@ -22,7 +22,6 @@ /*************************************************************************************/ namespace Thelia\Core\Template\Assets; - use Assetic\AssetManager; use Assetic\FilterManager; use Assetic\Filter; @@ -59,7 +58,7 @@ class AsseticHelper $am = new AssetManager(); $fm = new FilterManager(); - if (! empty($filters)) { + if (!empty($filters)) { $filter_list = explode(',', $filters); foreach ($filter_list as $filter_name) { @@ -67,36 +66,37 @@ class AsseticHelper $filter_name = trim($filter_name); switch ($filter_name) { - case 'less' : - $fm->set('less', new Filter\LessphpFilter()); - break; + case 'less': + $fm->set('less', new Filter\LessphpFilter()); + break; - case 'sass' : - $fm->set('sass', new Filter\Sass\SassFilter()); - break; + case 'sass': + $fm->set('sass', new Filter\Sass\SassFilter()); + break; - case 'cssembed' : - $fm->set('cssembed', new Filter\PhpCssEmbedFilter()); - break; + case 'cssembed': + $fm->set('cssembed', new Filter\PhpCssEmbedFilter()); + break; - case 'cssrewrite': - $fm->set('cssrewrite', new Filter\CssRewriteFilter()); - break; + case 'cssrewrite': + $fm->set('cssrewrite', new Filter\CssRewriteFilter()); + break; - case 'cssimport': - $fm->set('cssimport', new Filter\CssImportFilter()); - break; + case 'cssimport': + $fm->set('cssimport', new Filter\CssImportFilter()); + break; - case 'compass': - $fm->set('compass', new Filter\CompassFilter()); - break; + case 'compass': + $fm->set('compass', new Filter\CompassFilter()); + break; - default : - throw new \InvalidArgumentException("Unsupported Assetic filter: '$filter_name'"); - break; + default: + throw new \InvalidArgumentException("Unsupported Assetic filter: '$filter_name'"); + break; } } - } else { + } + else { $filter_list = array(); } @@ -106,7 +106,7 @@ class AsseticHelper $factory->setAssetManager($am); $factory->setFilterManager($fm); - $factory->setDefaultOutput('*'.(! empty($asset_type) ? '.' : '').$asset_type); + $factory->setDefaultOutput('*' . (!empty($asset_type) ? '.' : '') . $asset_type); $factory->setDebug($debug); @@ -129,7 +129,7 @@ class AsseticHelper // // before generating 3bc974a-ad3ef47.css, delete 3bc974a-* files. // - if ($dev_mode == true || ! file_exists($target_file)) { + if ($dev_mode == true || !file_exists($target_file)) { if (ConfigQuery::read('process_assets', true)) { @@ -144,7 +144,8 @@ class AsseticHelper foreach ($filter_list as $filter) { if ('?' != $filter[0]) { $asset->ensureFilter($fm->get($filter)); - } elseif (!$debug) { + } + elseif (!$debug) { $asset->ensureFilter($fm->get(substr($filter, 1))); } } @@ -155,6 +156,67 @@ class AsseticHelper } } - return rtrim($output_url, '/').'/'.$asset_target_path; + return rtrim($output_url, '/') . '/' . $asset_target_path; } -} + + // Create a hash of the current assets directory + public function getStamp($directory) + { + + $stamp = ''; + + foreach (new \DirectoryIterator($directory) as $fileInfo) { + + if ($fileInfo->isDot()) continue; + + if ($fileInfo->isDir()) { + $stamp .= $this->getStamp($fileInfo->getPathName()); + } + + if ($fileInfo->isFile()) { + $stamp .= $fileInfo->getMTime(); + } + } + + return $stamp; + } + + public function copyAssets($from_directory, $to_directory) + { + + echo "copy $from_directory to $to_directory\n"; + + $iterator = new \RecursiveIteratorIterator( + new \RecursiveDirectoryIterator($from_directory, \RecursiveDirectoryIterator::SKIP_DOTS), + \RecursiveIteratorIterator::SELF_FIRST); + + foreach ($iterator as $item) { + if ($item->isDir()) { + $dest_dir = $to_directory . DIRECTORY_SEPARATOR . $iterator->getSubPathName(); + + if (!is_dir($dest_dir)) { + if (file_exists($dest_dir)) { + @unlink($dest_dir); + } + + if (!mkdir($dest_dir, 0777, true)) { + throw new \RuntimeException( + "Failed to create directory $dest_dir. Please check that your web server has the proper access rights"); + } + } + } + else { + $dest_file = $to_directory . DIRECTORY_SEPARATOR . $iterator->getSubPathName(); + + if (file_exists($dest_file)) { + @unlink($dest_file); + } + + if (!copy($item, $dest_file)) { + throw new \RuntimeException( + "Failed to copy $source_file to $dest_file. Please check that your web server has the proper access rights"); + } + } + } + } +} \ No newline at end of file diff --git a/core/lib/Thelia/Core/Template/Loop/Customer.php b/core/lib/Thelia/Core/Template/Loop/Customer.php index 949103556..f955cd217 100755 --- a/core/lib/Thelia/Core/Template/Loop/Customer.php +++ b/core/lib/Thelia/Core/Template/Loop/Customer.php @@ -36,6 +36,9 @@ use Thelia\Core\Template\Loop\Argument\Argument; use Thelia\Model\CustomerQuery; use Thelia\Type\TypeCollection; use Thelia\Type; +use Thelia\Model\OrderQuery; +use Thelia\Model\Map\OrderAddressTableMap; +use Thelia\Model\Map\OrderTableMap; /** * @@ -65,7 +68,22 @@ class Customer extends BaseLoop implements SearchLoopInterface, PropelSearchLoop ) ), Argument::createBooleanTypeArgument('reseller'), - Argument::createIntTypeArgument('sponsor') + Argument::createIntTypeArgument('sponsor'), + new Argument( + 'order', + new TypeCollection( + new Type\EnumListType(array( + 'id', 'id_reverse', + 'reference', 'reference_reverse', + 'firstname', 'firstname_reverse', + 'lastname', 'lastname_reverse', + 'last_order', 'last_order_reverse', + 'order_amount', 'order_amount_reverse', + 'registration_date', 'registration_date_reverse' + )) + ), + 'lastname' + ) ); } @@ -151,6 +169,49 @@ class Customer extends BaseLoop implements SearchLoopInterface, PropelSearchLoop $search->filterBySponsor($sponsor, Criteria::EQUAL); } + $orders = $this->getOrder(); + + foreach ($orders as $order) { + switch ($order) { + case 'id': + $search->orderById(Criteria::ASC); + break; + case 'id_reverse': + $search->orderById(Criteria::DESC); + break; + + case 'reference': + $search->orderByRef(Criteria::ASC); + break; + case 'reference_reverse': + $search->orderByRef(Criteria::DESC); + break; + + case 'lastname': + $search->orderByLastname(Criteria::ASC); + break; + case 'lastname_reverse': + $search->orderByLastname(Criteria::DESC); + break; + + case 'firstname': + $search->orderByFirstname(Criteria::ASC); + break; + case 'firstname_reverse': + $search->orderByFirstname(Criteria::DESC); + break; + + case 'registration_date': + $search->orderByCreatedAt(Criteria::ASC); + break; + case 'registration_date_reverse': + $search->orderByCreatedAt(Criteria::DESC); + break; + + + } + } + return $search; } @@ -158,16 +219,24 @@ class Customer extends BaseLoop implements SearchLoopInterface, PropelSearchLoop public function parseResults(LoopResult $loopResult) { foreach ($loopResult->getResultDataCollection() as $customer) { + $loopResultRow = new LoopResultRow($customer); - $loopResultRow->set("ID", $customer->getId()); - $loopResultRow->set("REF", $customer->getRef()); - $loopResultRow->set("TITLE", $customer->getTitleId()); - $loopResultRow->set("FIRSTNAME", $customer->getFirstname()); - $loopResultRow->set("LASTNAME", $customer->getLastname()); - $loopResultRow->set("EMAIL", $customer->getEmail()); - $loopResultRow->set("RESELLER", $customer->getReseller()); - $loopResultRow->set("SPONSOR", $customer->getSponsor()); - $loopResultRow->set("DISCOUNT", $customer->getDiscount()); + + $loopResultRow + ->set("ID" , $customer->getId()) + ->set("REF" , $customer->getRef()) + ->set("TITLE" , $customer->getTitleId()) + ->set("FIRSTNAME" , $customer->getFirstname()) + ->set("LASTNAME" , $customer->getLastname()) + ->set("EMAIL" , $customer->getEmail()) + ->set("RESELLER" , $customer->getReseller()) + ->set("SPONSOR" , $customer->getSponsor()) + ->set("DISCOUNT" , $customer->getDiscount()) + + ->set("LAST_ORDER_DATE" , $lastOrder != null ? $lastOrder->getCreatedAt() : '') + ->set("LAST_ORDER_AMOUNT" , $lastOrder != null ? $lastOrder->getCreatedAt() : '') + ->set("LAST_ORDER_CURRENCY" , $lastOrder != null ? $lastOrder->getCreatedAt() : '') + ; $loopResult->addRow($loopResultRow); } diff --git a/core/lib/Thelia/Form/CustomerUpdateForm.php b/core/lib/Thelia/Form/CustomerUpdateForm.php index 06e094ec7..7442309be 100755 --- a/core/lib/Thelia/Form/CustomerUpdateForm.php +++ b/core/lib/Thelia/Form/CustomerUpdateForm.php @@ -82,6 +82,21 @@ class CustomerUpdateForm extends BaseForm "for" => "lastname" ) )) + ->add("email", "email", array( + "constraints" => array( + new Constraints\NotBlank() + ), + "label" => Translator::getInstance()->trans("Email address"), + "label_attr" => array( + "for" => "email" + ) + )) + ->add("password", "text", array( + "label" => Translator::getInstance()->trans("Password"), + "label_attr" => array( + "for" => "email" + ) + )) ->add("address1", "text", array( "constraints" => array( new Constraints\NotBlank() @@ -89,7 +104,7 @@ class CustomerUpdateForm extends BaseForm "label_attr" => array( "for" => "address" ), - "label" => Translator::getInstance()->trans("Street Address") + "label" => Translator::getInstance()->trans("Street Address ") )) ->add("address2", "text", array( "label" => Translator::getInstance()->trans("Address Line 2"), diff --git a/templates/admin/default/admin-layout.tpl b/templates/admin/default/admin-layout.tpl index 03a011866..5a8d564e2 100644 --- a/templates/admin/default/admin-layout.tpl +++ b/templates/admin/default/admin-layout.tpl @@ -22,7 +22,7 @@ {block name="before-bootstrap-css"}{/block} - {stylesheets file='assets/less/*' filters='less,cssembed'} + {stylesheets file='assets/less/main.less' filters='less,cssembed'} {/stylesheets} diff --git a/templates/admin/default/ajax/address-update-modal.html b/templates/admin/default/ajax/address-update-modal.html deleted file mode 100644 index 687c51b57..000000000 --- a/templates/admin/default/ajax/address-update-modal.html +++ /dev/null @@ -1,111 +0,0 @@ -{* Update an Address *} - -{form name="thelia.admin.address.update"} - -{* Capture the dialog body, to pass it to the generic dialog *} -{capture "edit_address_dialog"} - - {form_hidden_fields form=$form} - - {form_field form=$form field='label'} -
- - -
- {/form_field} - - {form_field form=$form field='company'} -
- - -
- {/form_field} - - {form_field form=$form field='title'} -
- - - -
- {/form_field} - - {form_field form=$form field='firstname'} -
- - -
- {/form_field} - - {form_field form=$form field='lastname'} -
- - -
- {/form_field} - - {form_field form=$form field='address1'} -
- - -
- -
- {form_field form=$form field='address2'} - - {/form_field} -
- -
- {form_field form=$form field='address3'} - - {/form_field} -
- {/form_field} - - {form_field form=$form field='zipcode'} -
- - -
- {/form_field} - - {form_field form=$form field='city'} -
- - -
- {/form_field} - - {form_field form=$form field='country'} -
- - -
- {/form_field} - -{/capture} - - {include - file = "includes/generic-create-dialog.html" - - dialog_id = "edit_address_dialog" - dialog_title = {intl l="Edit an address"} - dialog_body = {$smarty.capture.edit_address_dialog nofilter} - -dialog_ok_label = {intl l="Edit this address"} -dialog_cancel_label = {intl l="Cancel"} - -form_action = {url path="/admin/address/save/{$address_id}"} -form_enctype = {form_enctype form=$form} -form_error_message = $form_error_message -} - -{/form} \ No newline at end of file diff --git a/templates/admin/default/customer-edit.html b/templates/admin/default/customer-edit.html index 79aff3119..97f94deb2 100644 --- a/templates/admin/default/customer-edit.html +++ b/templates/admin/default/customer-edit.html @@ -30,18 +30,21 @@
{form name="thelia.admin.customer.update"} -
+ -
-
- - -
-
- {form_hidden_fields form=$form} + {include + file="includes/inner-form-toolbar.html" + hide_flags = true + close_url = {url path='/admin/customers'} + } + + {form_hidden_fields form=$form} + + + {form_field form=$form field='success_url'} - + {/form_field} {if $form_error}
{$form_error_message}
{/if} @@ -51,7 +54,7 @@ {form_field form=$form field='title'}
- + + +
{/form_field} {form_field form=$form field='lastname'}
- - + + +
+ {/form_field} + + {form_field form=$form field='email'} +
+ + +
+ {/form_field} + + {form_field form=$form field='password'} +
+ +
{/form_field} @@ -81,50 +98,50 @@ {form_field form=$form field='company'}
- - + +
{/form_field} {form_field form=$form field='address1'}
- - + +
{/form_field} {form_field form=$form field='address2'}
- +
{/form_field} {form_field form=$form field='address3'}
- +
{/form_field} {form_field form=$form field='zipcode'}
- - + +
{/form_field} {form_field form=$form field='city'}
- - + +
{/form_field} {form_field form=$form field='country'}
- +
@@ -149,13 +166,14 @@ {intl l="Address"} - {intl l="Actions"} + {intl l="Actions"} {loop name="address" type="address" customer="$customer_id" backend_context="1" default="0"} + {$LABEL}
{loop name="address.title" type="title" id=$TITLE}{$SHORT}{/loop} {$FIRSTNAME} {$LASTNAME}
{$ADDRESS1} @@ -166,21 +184,21 @@
{$TITLE} {/loop} {if $PHONE} -
P:{$PHONE} +
{intl l="Phone"}: {$PHONE} {/if} {if $CELLPHONE} -
P:{$CELLPHONE} +
{intl l="Cellular phone"}: {$CELLPHONE} {/if}
- +
- + - + @@ -262,168 +280,117 @@
-
- {* Add an Address *} +{* -- Add an Address -------------------------------------------------------- *} - {form name="thelia.admin.address.create"} +{form name="thelia.admin.address.create"} - {* Capture the dialog body, to pass it to the generic dialog *} - {capture "address_creation_dialog"} + {* Capture the dialog body, to pass it to the generic dialog *} + {capture "address_creation_dialog"} - {form_hidden_fields form=$form} - - {form_field form=$form field='success_url'} - - {/form_field} - {form_field form=$form field='label'} -
- - -
- {/form_field} + {include file='includes/customer_address_form_fields.html' customer_id=$customer_id page=$page} - {form_field form=$form field='company'} -
- - -
- {/form_field} - - {form_field form=$form field='title'} -
- - - -
- {/form_field} - - {form_field form=$form field='firstname'} -
- - -
- {/form_field} - - {form_field form=$form field='lastname'} -
- - -
- {/form_field} - - {form_field form=$form field='address1'} -
- - -
- -
- {form_field form=$form field='address2'} - - {/form_field} -
- -
- {form_field form=$form field='address3'} - - {/form_field} -
- {/form_field} - - {form_field form=$form field='zipcode'} -
- - -
- {/form_field} - - {form_field form=$form field='city'} -
- - -
- {/form_field} - - {form_field form=$form field='country'} -
- - -
- {/form_field} - - {/capture} - - {include - file = "includes/generic-create-dialog.html" - - dialog_id = "address_creation_dialog" - dialog_title = {intl l="Create an address"} - dialog_body = {$smarty.capture.address_creation_dialog nofilter} - - dialog_ok_label = {intl l="Create this address"} - dialog_cancel_label = {intl l="Cancel"} - - form_action = {url path='/admin/address/create'} - form_enctype = {form_enctype form=$form} - form_error_message = $form_error_message - } - - {/form} - - - - - {* Default confirmation dialog *} - - {capture "use_address_dialog"} - {/capture} {include - file = "includes/generic-confirm-dialog.html" + file = "includes/generic-create-dialog.html" - dialog_id = "use_address_dialog" - dialog_title = {intl l="Use address by default"} - dialog_message = {intl l="Do you really want to use this address by default ?"} + dialog_id = "address_creation_dialog" + dialog_title = {intl l="Create a customer address"} + dialog_body = {$smarty.capture.address_creation_dialog nofilter} - form_action = {url path='/admin/address/use'} - form_content = {$smarty.capture.use_address_dialog nofilter} + dialog_ok_label = {intl l="Create this address"} + dialog_cancel_label = {intl l="Cancel"} + + form_action = {url path='/admin/address/create'} + form_enctype = {form_enctype form=$form} + form_error_message = $form_error_message } - {* Delete confirmation dialog *} +{/form} - {capture "delete_address_dialog"} - - {/capture} +{* -- Update an Address ----------------------------------------------------- *} - {include - file = "includes/generic-confirm-dialog.html" +{if $address_id > 0} + {form name="thelia.admin.address.update"} - dialog_id = "delete_address_dialog" - dialog_title = {intl l="Delete address"} - dialog_message = {intl l="Do you really want to delete this address ?"} + {* Capture the dialog body, to pass it to the generic dialog *} - form_action = {url path='/admin/address/delete'} - form_content = {$smarty.capture.delete_address_dialog nofilter} - } + {capture "address_update_dialog"} + + + {include file='includes/customer_address_form_fields.html' customer_id=$customer_id page=$page} + + {/capture} + + {include + file = "includes/generic-create-dialog.html" + + dialog_id = "address_update_dialog" + dialog_title = {intl l="Edit a customer address"} + dialog_body = {$smarty.capture.address_update_dialog nofilter} + + dialog_ok_label = {intl l="Save this address"} + dialog_cancel_label = {intl l="Cancel"} + + form_action = {url path="/admin/address/save"} + form_enctype = {form_enctype form=$form} + form_error_message = $form_error_message + } + + {/form} +{/if} + +{* -- Confirm making an address the default --------------------------------- *} + +{capture "use_address_dialog"} + + + + +{/capture} + +{include + file = "includes/generic-confirm-dialog.html" + + dialog_id = "use_address_dialog" + dialog_title = {intl l="Use address by default"} + dialog_message = {intl l="Do you really want to use this address by default ?"} + + form_action = {url path='/admin/address/use'} + form_content = {$smarty.capture.use_address_dialog nofilter} +} + +{* -- Delete confirmation dialog -------------------------------------------- *} + +{capture "delete_address_dialog"} + + + + +{/capture} + +{include + file = "includes/generic-confirm-dialog.html" + + dialog_id = "delete_address_dialog" + dialog_title = {intl l="Delete address"} + dialog_message = {intl l="Do you really want to delete this address ?"} + + form_action = {url path='/admin/address/delete'} + form_content = {$smarty.capture.delete_address_dialog nofilter} +} {/block} + {block name="javascript-initialization"} + {javascripts file='assets/js/main.js'} {/javascripts} {/block} \ No newline at end of file diff --git a/templates/admin/default/customers.html b/templates/admin/default/customers.html index ba083b61c..9dff5e9c3 100644 --- a/templates/admin/default/customers.html +++ b/templates/admin/default/customers.html @@ -7,9 +7,6 @@ {block name="check-access"}view{/block} {block name="main-content"} - {assign var=customer_page value={$smarty.get.page|default:1}} - -
@@ -41,27 +38,83 @@ - {intl l="customer ref"} + {admin_sortable_header + current_order=$customer_order + order='reference' + reverse_order='reference_reverse' + path={url path='/admin/customers'} + request_parameter_name='customer_order' + label="{intl l='Reference'}" + } - {module_include location='category_list_header'} + {module_include location='customer_list_header'} - - {intl l="firstname & lastname"} + + {admin_sortable_header + current_order=$customer_order + order='lastname' + reverse_order='lastname_reverse' + path={url path='/admin/customers'} + request_parameter_name='customer_order' + label="{intl l='Last name'}" + } - - {intl l="last order"} + + {admin_sortable_header + current_order=$customer_order + order='firstname' + reverse_order='firstname_reverse' + path={url path='/admin/customers'} + request_parameter_name='customer_order' + label="{intl l='First name'}" + } - {intl l='order amount'} + + {admin_sortable_header + current_order=$customer_order + order='registration_date' + reverse_order='registration_date_reverse' + path={url path='/admin/customers'} + request_parameter_name='customer_order' + label="{intl l='Registration date'}" + } + + {intl l='Date of last order'} + {intl l='Last order amount'} + +{* TODO + + {admin_sortable_header + current_order=$customer_order + order='last_order' + reverse_order='last_order_reverse' + path={url path='/admin/customers'} + request_parameter_name='customer_order' + label="{intl l='Date of last order'}" + } + + + + {admin_sortable_header + current_order=$customer_order + order='order_amount' + reverse_order='order_amount_reverse' + path={url path='/admin/customers'} + request_parameter_name='customer_order' + label="{intl l='Last order amount'}" + } + +*} {intl l='Actions'} - {loop name="customer_list" type="customer" current="false" visible="*" backend_context="1" page={$customer_page} limit={$display_customer}} + {loop name="customer_list" type="customer" current="false" visible="*" order=$customer_order backend_context="1" page=$page limit=$display_customer} {assign "lastOrderDate" ''} {assign "lastOrderAmount" ''} {assign "lastOrderCurrency" ''} @@ -75,14 +128,23 @@ {/loop} - {$REF} + {$REF} - {$FIRSTNAME} {$LASTNAME} + {$LASTNAME} + + {$FIRSTNAME} + + + {module_include location='customer_list_row'} + + {format_date date=$CREATE_DATE} + + {$lastOrderDate} @@ -94,7 +156,7 @@
{loop type="auth" name="can_change" role="ADMIN" resource="admin.customer" access="UPDATE"} - + {/loop} {loop type="auth" name="can_send_mail" role="ADMIN" resource="admin.customer" access="VIEW"} @@ -111,10 +173,10 @@ - +
    - {if $customer_page != 1} + {if $page != 1}
  • «
  • {else}
  • «
  • @@ -137,7 +199,7 @@ {/if}
- + @@ -163,7 +225,7 @@ {form_field form=$form field='success_url'} {* on success, redirect to the edition page, _ID_ is replaced with the created object ID, see controller *} - + {/form_field} {form_field form=$form field="password"} @@ -283,7 +345,7 @@ {* Delete confirmation dialog *} {capture "delete_customer_dialog"} - + {/capture} diff --git a/templates/admin/default/includes/customer_address_form_fields.html b/templates/admin/default/includes/customer_address_form_fields.html new file mode 100644 index 000000000..d86b7921e --- /dev/null +++ b/templates/admin/default/includes/customer_address_form_fields.html @@ -0,0 +1,124 @@ +{* Customer address creation / modification fields, used in the customer-edit.html template *} + +{form_hidden_fields form=$form} + + + + +{form_field form=$form field='success_url'} + +{/form_field} + +{form_field form=$form field='label'} +
+ + +
+{/form_field} + +{form_field form=$form field='company'} +
+ + +
+{/form_field} + +{form_field form=$form field='title'} +
+ + + +
+{/form_field} + +
+
+ {form_field form=$form field='firstname'} +
+ + +
+ {/form_field} +
+
+ {form_field form=$form field='lastname'} +
+ + +
+ {/form_field} +
+
+ +{form_field form=$form field='address1'} +
+ + +
+ +
+ {form_field form=$form field='address2'} + + {/form_field} +
+ +
+ {form_field form=$form field='address3'} + + {/form_field} +
+{/form_field} + +
+
+ {form_field form=$form field='zipcode'} +
+ + +
+ {/form_field} +
+
+ {form_field form=$form field='city'} +
+ + +
+ {/form_field} +
+
+ +{form_field form=$form field='country'} +
+ + +
+{/form_field} + +
+
+ {form_field form=$form field='phone'} +
+ + +
+ {/form_field} +
+
+ {form_field form=$form field='cellphone'} +
+ + +
+ {/form_field} +
+
+ diff --git a/templates/default/assets/less/styles.less b/templates/default/assets/less/styles.less index f226cbd67..d1d9dbf56 100755 --- a/templates/default/assets/less/styles.less +++ b/templates/default/assets/less/styles.less @@ -1,4 +1,3 @@ - /* Bootstrap */ @import "bootstrap/bootstrap.less";