diff --git a/core/lib/Thelia/Action/Currency.php b/core/lib/Thelia/Action/Currency.php index 68cc5904a..7f9c3281f 100644 --- a/core/lib/Thelia/Action/Currency.php +++ b/core/lib/Thelia/Action/Currency.php @@ -107,6 +107,7 @@ class Currency extends BaseAction implements EventSubscriberInterface CurrencyQuery::create()->filterByByDefault(true)->update(array('ByDefault' => false)); $currency + ->setDispatcher($this->getDispatcher()) ->setByDefault($event->getIsDefault()) ->save() ; @@ -139,7 +140,7 @@ class Currency extends BaseAction implements EventSubscriberInterface $rates_url = ConfigQuery::read('currency_rate_update_url', 'http://www.ecb.int/stats/eurofxref/eurofxref-daily.xml'); - $rate_data = file_get_contents($rates_url); + $rate_data = @file_get_contents($rates_url); if ($rate_data && $sxe = new \SimpleXMLElement($rate_data)) { @@ -149,12 +150,16 @@ class Currency extends BaseAction implements EventSubscriberInterface $rate = floatval($last['rate']); if (null !== $currency = CurrencyQuery::create()->findOneByCode($code)) { - $currency->setRate($rate)->save(); + $currency + ->setDispatcher($this->getDispatcher()) + ->setRate($rate) + ->save() + ; } } } else { - throw new \RuntimeException(sprintf("Failed to get currency rates data from URL %s", $url)); + throw new \RuntimeException(sprintf("Failed to get currency rates data from URL %s", $rates_url)); } } @@ -165,12 +170,18 @@ class Currency extends BaseAction implements EventSubscriberInterface */ public function updatePosition(CurrencyUpdatePositionEvent $event) { - if (null !== $category = CurrencyQuery::create()->findOneById($event->getObjectId())) { + if (null !== $currency = CurrencyQuery::create()->findOneById($event->getObjectId())) { - if ($event->getMode() == BaseChangePositionEvent::POSITION_ABSOLUTE) - return $category->changeAbsolutePosition($event->getPosition()); - else - return $this->exchangePosition($event->getMode()); + $currency->setDispatcher($this->getDispatcher()); + + $mode = $event->getMode(); + + if ($mode == CurrencyUpdatePositionEvent::POSITION_ABSOLUTE) + return $currency->changeAbsolutePosition($event->getPosition()); + else if ($mode == CurrencyUpdatePositionEvent::POSITION_UP) + return $currency->movePositionUp(); + else if ($mode == CurrencyUpdatePositionEvent::POSITION_DOWN) + return $currency->movePositionDown(); } } diff --git a/core/lib/Thelia/Command/CacheClear.php b/core/lib/Thelia/Command/CacheClear.php index 82a7cbd7f..37e853f05 100755 --- a/core/lib/Thelia/Command/CacheClear.php +++ b/core/lib/Thelia/Command/CacheClear.php @@ -24,6 +24,7 @@ namespace Thelia\Command; use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Filesystem\Filesystem; use Symfony\Component\Filesystem\Exception\IOException; @@ -44,7 +45,14 @@ class CacheClear extends ContainerAwareCommand { $this ->setName("cache:clear") - ->setDescription("Invalidate all caches"); + ->setDescription("Invalidate all caches") + ->addOption( + "without-assets", + null, + InputOption::VALUE_NONE, + "remove cache assets" + ) + ; } protected function execute(InputInterface $input, OutputInterface $output) @@ -52,20 +60,28 @@ class CacheClear extends ContainerAwareCommand $cacheDir = $this->getContainer()->getParameter("kernel.cache_dir"); - if (!is_writable($cacheDir)) { - throw new \RuntimeException(sprintf('Unable to write in the "%s" directory', $cacheDir)); - } - - $output->writeln(sprintf("Clearing cache in %s directory", $cacheDir)); - - $fs = new Filesystem(); - try { - $fs->remove($cacheDir); - - $output->writeln("cache cleared successfully"); - } catch (IOException $e) { - $output->writeln(sprintf("error during clearing cache : %s", $e->getMessage())); + $this->clearCache($cacheDir, $output); + if(!$input->getOption("without-assets")) { + $this->clearCache(THELIA_WEB_DIR . "/assets", $output); } } + + protected function clearCache($dir, OutputInterface $output) + { + if (!is_writable($dir)) { + throw new \RuntimeException(sprintf('Unable to write in the "%s" directory', $dir)); + } + + $output->writeln(sprintf("Clearing cache in %s directory", $dir)); + + $fs = new Filesystem(); + try { + $fs->remove($dir); + + $output->writeln(sprintf("%s cache dir cleared successfully", $dir)); + } catch (IOException $e) { + $output->writeln(sprintf("error during clearing cache : %s", $e->getMessage())); + } + } } diff --git a/core/lib/Thelia/Config/Resources/config.xml b/core/lib/Thelia/Config/Resources/config.xml index 96e5941cd..974de091c 100755 --- a/core/lib/Thelia/Config/Resources/config.xml +++ b/core/lib/Thelia/Config/Resources/config.xml @@ -129,6 +129,7 @@ + %kernel.environment% @@ -184,6 +185,7 @@ + diff --git a/core/lib/Thelia/Config/Resources/routing.xml b/core/lib/Thelia/Config/Resources/routing.xml index 5200aefc1..a8ad18abf 100755 --- a/core/lib/Thelia/Config/Resources/routing.xml +++ b/core/lib/Thelia/Config/Resources/routing.xml @@ -75,6 +75,10 @@ %kernel.debug% + + + + diff --git a/core/lib/Thelia/Config/Resources/routing/admin.xml b/core/lib/Thelia/Config/Resources/routing/admin.xml index ac652017c..2257a9459 100755 --- a/core/lib/Thelia/Config/Resources/routing/admin.xml +++ b/core/lib/Thelia/Config/Resources/routing/admin.xml @@ -113,10 +113,19 @@ Thelia\Controller\Admin\CurrencyController::deleteAction - + + Thelia\Controller\Admin\AttributeController::defaultAction + + + + + Thelia\Controller\Admin\CurrencyController::updatePositionAction + + + diff --git a/core/lib/Thelia/Config/Resources/routing/front.xml b/core/lib/Thelia/Config/Resources/routing/front.xml index a9857b837..f8b156946 100755 --- a/core/lib/Thelia/Config/Resources/routing/front.xml +++ b/core/lib/Thelia/Config/Resources/routing/front.xml @@ -60,13 +60,4 @@ cart - - diff --git a/core/lib/Thelia/Controller/Admin/AttributeController.php b/core/lib/Thelia/Controller/Admin/AttributeController.php new file mode 100644 index 000000000..d2c1ea351 --- /dev/null +++ b/core/lib/Thelia/Controller/Admin/AttributeController.php @@ -0,0 +1,57 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Controller\Admin; + +use Thelia\Core\Event\MessageDeleteEvent; +use Thelia\Core\Event\TheliaEvents; +use Thelia\Tools\URL; +use Thelia\Core\Event\MessageUpdateEvent; +use Thelia\Core\Event\MessageCreateEvent; +use Thelia\Log\Tlog; +use Thelia\Form\Exception\FormValidationException; +use Thelia\Core\Security\Exception\AuthorizationException; +use Thelia\Model\MessageQuery; +use Thelia\Form\MessageModificationForm; +use Thelia\Form\MessageCreationForm; + +/** + * Manages messages sent by mail + * + * @author Franck Allimant + */ +class AttributeController extends BaseAdminController +{ + /** + * The default action is displaying the messages list. + * + * @return Symfony\Component\HttpFoundation\Response the response + */ + public function defaultAction() { + + if (null !== $response = $this->checkAuth("admin.configuration.attributes.view")) return $response; + + return $this->render('product_attributes'); + } + +} \ No newline at end of file diff --git a/core/lib/Thelia/Controller/Admin/ConfigController.php b/core/lib/Thelia/Controller/Admin/ConfigController.php index a67ecbaaa..b84368c2f 100644 --- a/core/lib/Thelia/Controller/Admin/ConfigController.php +++ b/core/lib/Thelia/Controller/Admin/ConfigController.php @@ -241,7 +241,7 @@ class ConfigController extends BaseAdminController if ($this->getRequest()->get('save_mode') == 'stay') { $this->redirectToRoute( - "admin.configuration.variables.change", + "admin.configuration.variables.update", array('variable_id' => $variable_id) ); } diff --git a/core/lib/Thelia/Controller/Admin/CurrencyController.php b/core/lib/Thelia/Controller/Admin/CurrencyController.php index caa3d1bed..56acfb89d 100644 --- a/core/lib/Thelia/Controller/Admin/CurrencyController.php +++ b/core/lib/Thelia/Controller/Admin/CurrencyController.php @@ -316,17 +316,22 @@ class CurrencyController extends BaseAdminController if (null !== $response = $this->checkAuth("admin.configuration.currencies.update")) return $response; try { - $id = $this->getRequest()->get('currency_id', 0); $mode = $this->getRequest()->get('mode', null); + + if ($mode == 'up') + $mode = CurrencyUpdatePositionEvent::POSITION_UP; + else if ($mode == 'down') + $mode = CurrencyUpdatePositionEvent::POSITION_DOWN; + else + $mode = CurrencyUpdatePositionEvent::POSITION_ABSOLUTE; + $position = $this->getRequest()->get('position', null); - $event = new CurrencyUpdatePositionEvent(); - - $event - ->setObjectId($this->getRequest()->get('currency_id', 0)) - ->setPosition($this->getRequest()->get('position', 0)) - ->setMode($mode) - ; + $event = new CurrencyUpdatePositionEvent( + $this->getRequest()->get('currency_id', null), + $mode, + $this->getRequest()->get('position', null) + ); $this->dispatch(TheliaEvents::CURRENCY_UPDATE_POSITION, $event); } diff --git a/core/lib/Thelia/Controller/BaseController.php b/core/lib/Thelia/Controller/BaseController.php index 853776214..e5b098f02 100755 --- a/core/lib/Thelia/Controller/BaseController.php +++ b/core/lib/Thelia/Controller/BaseController.php @@ -81,6 +81,17 @@ class BaseController extends ContainerAware return $this->container->get('event_dispatcher'); } + /** + * + * return the Translator + * + * @return mixed \Thelia\Core\Translation\Translator + */ + public function getTranslator() + { + return $this->container->get('thelia.translator'); + } + /** * Return the parser context, * @@ -215,7 +226,7 @@ class BaseController extends ContainerAware $route = $this->container->get($routerName)->getRouteCollection()->get($routeId); if ($route == null) { - throw new InvalidArgumentException(sprintf("Route ID '%s' does not exists.", $routeId)); + throw new \InvalidArgumentException(sprintf("Route ID '%s' does not exists.", $routeId)); } return $route->getPath(); diff --git a/core/lib/Thelia/Controller/Front/DefaultController.php b/core/lib/Thelia/Controller/Front/DefaultController.php index 58501ebb0..fe7e1aede 100755 --- a/core/lib/Thelia/Controller/Front/DefaultController.php +++ b/core/lib/Thelia/Controller/Front/DefaultController.php @@ -46,16 +46,6 @@ class DefaultController extends BaseFrontController */ public function noAction(Request $request) { - if(ConfigQuery::isRewritingEnable()) { - - /* Does the query GET parameters match a rewritten URL ? */ - $rewrittenUrl = URL::getInstance()->retrieveCurrent($request); - if($rewrittenUrl->rewrittenUrl !== null) { - /* 301 redirection to rewritten URL */ - $this->redirect($rewrittenUrl->rewrittenUrl, 301); - } - } - $view = null; if (! $view = $request->query->get('view')) { @@ -71,5 +61,15 @@ class DefaultController extends BaseFrontController $request->attributes->set("_view", "index"); } + if(ConfigQuery::isRewritingEnable()) { + if($request->attributes->get('_rewritten', false) === false) { + /* Does the query GET parameters match a rewritten URL ? */ + $rewrittenUrl = URL::getInstance()->retrieveCurrent($request); + if($rewrittenUrl->rewrittenUrl !== null) { + /* 301 redirection to rewritten URL */ + $this->redirect($rewrittenUrl->rewrittenUrl, 301); + } + } + } } } diff --git a/core/lib/Thelia/Core/Event/BaseUpdatePositionEvent.php b/core/lib/Thelia/Core/Event/BaseUpdatePositionEvent.php index 3587a0757..41907c29c 100644 --- a/core/lib/Thelia/Core/Event/BaseUpdatePositionEvent.php +++ b/core/lib/Thelia/Core/Event/BaseUpdatePositionEvent.php @@ -74,14 +74,4 @@ class BaseUpdatePositionEvent extends ActionEvent $this->object_id = $object_id; return $this; } - - public function getObjectId() - { - return $this->object_id; - } - - public function setObjectId($object_id) - { - $this->object_id = $object_id; - } } diff --git a/core/lib/Thelia/Core/Event/CurrencyUpdatePositionEvent.php b/core/lib/Thelia/Core/Event/CurrencyUpdatePositionEvent.php index 655e24c9a..3a3dbb18f 100644 --- a/core/lib/Thelia/Core/Event/CurrencyUpdatePositionEvent.php +++ b/core/lib/Thelia/Core/Event/CurrencyUpdatePositionEvent.php @@ -23,6 +23,6 @@ namespace Thelia\Core\Event; -class CategoryChangePositionEvent extends BaseChangePositionEvent +class CurrencyUpdatePositionEvent extends BaseUpdatePositionEvent { } \ No newline at end of file diff --git a/core/lib/Thelia/Core/Routing/RewritingRouter.php b/core/lib/Thelia/Core/Routing/RewritingRouter.php new file mode 100644 index 000000000..79d5dc80b --- /dev/null +++ b/core/lib/Thelia/Core/Routing/RewritingRouter.php @@ -0,0 +1,219 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Core\Routing; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\Routing\Exception\InvalidParameterException; +use Symfony\Component\Routing\Exception\MethodNotAllowedException; +use Symfony\Component\Routing\Exception\MissingMandatoryParametersException; +use Symfony\Component\Routing\Exception\ResourceNotFoundException; +use Symfony\Component\Routing\Exception\RouteNotFoundException; +use Symfony\Component\Routing\Matcher\RequestMatcherInterface; +use Symfony\Component\Routing\RequestContext; +use Symfony\Component\Routing\RouteCollection; +use Symfony\Component\Routing\RouterInterface; +use Thelia\Exception\RedirectException; +use Thelia\Exception\UrlRewritingException; +use Thelia\Model\ConfigQuery; +use Thelia\Tools\Redirect; +use Thelia\Tools\URL; + + +/** + * Class RewritingRouter + * @package Thelia\Core\Routing + * @author Manuel Raynaud + * @author Etienne Roudeix + */ +class RewritingRouter implements RouterInterface, RequestMatcherInterface +{ + + /** + * @var RequestContext The context + */ + protected $context; + + /** + * @var options, don't use for now but mandatory + */ + protected $options; + + /** + * Sets the request context. + * + * @param RequestContext $context The context + * + * @api + */ + public function setContext(RequestContext $context) + { + // TODO: Implement setContext() method. + $this->context = $context; + } + + /** + * Gets the request context. + * + * @return RequestContext The context + * + * @api + */ + public function getContext() + { + // TODO: Implement getContext() method. + return $this->context; + } + + public function setOption($key, $value) + { + //NOTHING TO DO FOR NOW + } + + /** + * Gets the RouteCollection instance associated with this Router. + * + * @return RouteCollection A RouteCollection instance + */ + public function getRouteCollection() + { + return new RouteCollection(); + } + + /** + * Generates a URL or path for a specific route based on the given parameters. + * + * Parameters that reference placeholders in the route pattern will substitute them in the + * path or host. Extra params are added as query string to the URL. + * + * When the passed reference type cannot be generated for the route because it requires a different + * host or scheme than the current one, the method will return a more comprehensive reference + * that includes the required params. For example, when you call this method with $referenceType = ABSOLUTE_PATH + * but the route requires the https scheme whereas the current scheme is http, it will instead return an + * ABSOLUTE_URL with the https scheme and the current host. This makes sure the generated URL matches + * the route in any case. + * + * If there is no route with the given name, the generator must throw the RouteNotFoundException. + * + * @param string $name The name of the route + * @param mixed $parameters An array of parameters + * @param Boolean|string $referenceType The type of reference to be generated (one of the constants) + * + * @return string The generated URL + * + * @throws RouteNotFoundException If the named route doesn't exist + * @throws MissingMandatoryParametersException When some parameters are missing that are mandatory for the route + * @throws InvalidParameterException When a parameter value for a placeholder is not correct because + * it does not match the requirement + * + * @api + */ + public function generate($name, $parameters = array(), $referenceType = self::ABSOLUTE_PATH) + { + // TODO: Implement generate() method. + } + + /** + * Tries to match a URL path with a set of routes. + * + * If the matcher can not find information, it must throw one of the exceptions documented + * below. + * + * @param string $pathinfo The path info to be parsed (raw format, i.e. not urldecoded) + * + * @return array An array of parameters + * + * @throws ResourceNotFoundException If the resource could not be found + * @throws MethodNotAllowedException If the resource was found but the request method is not allowed + * + * @api + */ + public function match($pathinfo) + { + throw new ResourceNotFoundException("impossible to find route with this method, please use matchRequest method"); + } + + /** + * Tries to match a request with a set of routes. + * + * If the matcher can not find information, it must throw one of the exceptions documented + * below. + * + * @param Request $request The request to match + * + * @throws \Exception|\Thelia\Exception\UrlRewritingException + * @throws \Symfony\Component\Routing\Exception\ResourceNotFoundException + * @throws \Thelia\Exception\RedirectException + * @return array An array of parameters + * + */ + public function matchRequest(Request $request) + { + if(ConfigQuery::isRewritingEnable()) { + try { + $rewrittenUrlData = URL::getInstance()->resolve($request->getPathInfo()); + } catch(UrlRewritingException $e) { + switch($e->getCode()) { + case UrlRewritingException::URL_NOT_FOUND : + throw new ResourceNotFoundException(); + break; + default: + throw $e; + } + } + + /* is the URL redirected ? */ + + if(null !== $rewrittenUrlData->redirectedToUrl) { + $this->redirect($rewrittenUrlData->redirectedToUrl, 301); + } + + /* define GET arguments in request */ + + if(null !== $rewrittenUrlData->view) { + $request->attributes->set('_view', $rewrittenUrlData->view); + if(null !== $rewrittenUrlData->viewId) { + $request->query->set($rewrittenUrlData->view . '_id', $rewrittenUrlData->viewId); + } + } + if(null !== $rewrittenUrlData->locale) { + $request->query->set('locale', $rewrittenUrlData->locale); + } + + foreach($rewrittenUrlData->otherParameters as $parameter => $value) { + $request->query->set($parameter, $value); + } + + return array ( + '_controller' => 'Thelia\\Controller\\Front\\DefaultController::noAction', + '_route' => 'rewrite', + '_rewritten' => true, + ); + } + throw new ResourceNotFoundException(); + } + + protected function redirect($url, $status = 302) + { + Redirect::exec($url, $status); + } +} \ No newline at end of file diff --git a/core/lib/Thelia/Core/Template/Assets/AsseticHelper.php b/core/lib/Thelia/Core/Template/Assets/AsseticHelper.php index c5995e3de..cd7f06ac8 100755 --- a/core/lib/Thelia/Core/Template/Assets/AsseticHelper.php +++ b/core/lib/Thelia/Core/Template/Assets/AsseticHelper.php @@ -43,15 +43,16 @@ class AsseticHelper * Generates assets from $asset_path in $output_path, using $filters. * * @param string $asset_path the full path to the asset file (or file collection) - * @param unknown $output_path the full disk path to the output directory (shoud be visible to web server) - * @param unknown $output_url the URL to the generated asset directory - * @param unknown $asset_type the asset type: css, js, ... The generated files will have this extension. Pass an empty string to use the asset source extension. - * @param unknown $filters a list of filters, as defined below (see switch($filter_name) ...) - * @param unknown $debug true / false + * @param string $output_path the full disk path to the output directory (shoud be visible to web server) + * @param string $output_url the URL to the generated asset directory + * @param string $asset_type the asset type: css, js, ... The generated files will have this extension. Pass an empty string to use the asset source extension. + * @param array $filters a list of filters, as defined below (see switch($filter_name) ...) + * @param boolean $debug true / false + * @param boolean $dev_mode true / false. If true, assets are not cached and always compiled. * @throws \InvalidArgumentException if an invalid filter name is found * @return string The URL to the generated asset file. */ - public function asseticize($asset_path, $output_path, $output_url, $asset_type, $filters, $debug) + public function asseticize($asset_path, $output_path, $output_url, $asset_type, $filters, $debug, $dev_mode = false) { $asset_name = basename($asset_path); $asset_dir = dirname($asset_path); @@ -106,17 +107,49 @@ class AsseticHelper $factory->setDebug($debug); - $factory->addWorker(new CacheBustingWorker()); + $factory->addWorker(new CacheBustingWorker('-')); - // Prepare the assets writer - $writer = new AssetWriter($output_path); + // We do not pass the filter list here, juste to get the asset file name + $asset = $factory->createAsset($asset_name); - $asset = $factory->createAsset($asset_name, $filter_list); + $asset_target_path = $asset->getTargetPath(); - $cache = new AssetCache($asset, new FilesystemCache($output_path)); + $target_file = sprintf("%s/%s", $output_path, $asset_target_path); - $writer->writeAsset($cache); + // As it seems that assetic cannot handle a real file cache, let's do the job ourselves. + // It works only if the CacheBustingWorker is used, as a new file name is generated for each version. + // + // the previous version of the file is deleted, by getting the first part of the ouput file name + // (the one before '-'), and delete aby file beginning with the same string. Example: + // old name: 3bc974a-dfacc1f.css + // new name: 3bc974a-ad3ef47.css + // + // before generating 3bc974a-ad3ef47.css, delete 3bc974a-* files. + // + if ($dev_mode == true || ! file_exists($target_file)) { - return rtrim($output_url, '/').'/'.$asset->getTargetPath(); + // Delete previous version of the file + list($commonPart, $dummy) = explode('-', $asset_target_path); + + foreach (glob("$output_path/$commonPart-*") as $filename) { + @unlink($filename); + } + + // Apply filters now + foreach ($filter_list as $filter) { + if ('?' != $filter[0]) { + $asset->ensureFilter($fm->get($filter)); + } + elseif (!$debug) { + $asset->ensureFilter($fm->get(substr($filter, 1))); + } + } + + $writer = new AssetWriter($output_path); + + $writer->writeAsset($asset); + } + + return rtrim($output_url, '/').'/'.$asset_target_path; } } diff --git a/core/lib/Thelia/Core/Template/Loop/Attribute.php b/core/lib/Thelia/Core/Template/Loop/Attribute.php index e967709f3..ecdc551d2 100755 --- a/core/lib/Thelia/Core/Template/Loop/Attribute.php +++ b/core/lib/Thelia/Core/Template/Loop/Attribute.php @@ -162,7 +162,8 @@ class Attribute extends BaseI18nLoop ->set("TITLE",$attribute->getVirtualColumn('i18n_TITLE')) ->set("CHAPO", $attribute->getVirtualColumn('i18n_CHAPO')) ->set("DESCRIPTION", $attribute->getVirtualColumn('i18n_DESCRIPTION')) - ->set("POSTSCRIPTUM", $attribute->getVirtualColumn('i18n_POSTSCRIPTUM')); + ->set("POSTSCRIPTUM", $attribute->getVirtualColumn('i18n_POSTSCRIPTUM')) + ->set("POSITION", $attribute->getPosition()); $loopResult->addRow($loopResultRow); } diff --git a/core/lib/Thelia/Core/Template/Loop/AttributeAvailability.php b/core/lib/Thelia/Core/Template/Loop/AttributeAvailability.php index cd5ad6564..ca4618f53 100755 --- a/core/lib/Thelia/Core/Template/Loop/AttributeAvailability.php +++ b/core/lib/Thelia/Core/Template/Loop/AttributeAvailability.php @@ -131,7 +131,8 @@ class AttributeAvailability extends BaseI18nLoop ->set("TITLE",$attributeAv->getVirtualColumn('i18n_TITLE')) ->set("CHAPO", $attributeAv->getVirtualColumn('i18n_CHAPO')) ->set("DESCRIPTION", $attributeAv->getVirtualColumn('i18n_DESCRIPTION')) - ->set("POSTSCRIPTUM", $attributeAv->getVirtualColumn('i18n_POSTSCRIPTUM')); + ->set("POSTSCRIPTUM", $attributeAv->getVirtualColumn('i18n_POSTSCRIPTUM')) + ->set("POSITION", $attributeAv->getPosition()); $loopResult->addRow($loopResultRow); } diff --git a/core/lib/Thelia/Core/Template/Loop/Country.php b/core/lib/Thelia/Core/Template/Loop/Country.php index aee6492f7..0aeb62b15 100755 --- a/core/lib/Thelia/Core/Template/Loop/Country.php +++ b/core/lib/Thelia/Core/Template/Loop/Country.php @@ -113,10 +113,10 @@ class Country extends BaseI18nLoop ->set("TITLE",$country->getVirtualColumn('i18n_TITLE')) ->set("CHAPO", $country->getVirtualColumn('i18n_CHAPO')) ->set("DESCRIPTION", $country->getVirtualColumn('i18n_DESCRIPTION')) - ->set("POSTSCRIPTUM", $country->getVirtualColumn('i18n_POSTSCRIPTUM')); - $loopResultRow->set("ISOCODE", $country->getIsocode()); - $loopResultRow->set("ISOALPHA2", $country->getIsoalpha2()); - $loopResultRow->set("ISOALPHA3", $country->getIsoalpha3()); + ->set("POSTSCRIPTUM", $country->getVirtualColumn('i18n_POSTSCRIPTUM')) + ->set("ISOCODE", $country->getIsocode()) + ->set("ISOALPHA2", $country->getIsoalpha2()) + ->set("ISOALPHA3", $country->getIsoalpha3()); $loopResult->addRow($loopResultRow); } diff --git a/core/lib/Thelia/Core/Template/Loop/Feature.php b/core/lib/Thelia/Core/Template/Loop/Feature.php index 6c2401f42..14b7afaf5 100755 --- a/core/lib/Thelia/Core/Template/Loop/Feature.php +++ b/core/lib/Thelia/Core/Template/Loop/Feature.php @@ -154,7 +154,8 @@ class Feature extends BaseI18nLoop ->set("TITLE",$feature->getVirtualColumn('i18n_TITLE')) ->set("CHAPO", $feature->getVirtualColumn('i18n_CHAPO')) ->set("DESCRIPTION", $feature->getVirtualColumn('i18n_DESCRIPTION')) - ->set("POSTSCRIPTUM", $feature->getVirtualColumn('i18n_POSTSCRIPTUM')); + ->set("POSTSCRIPTUM", $feature->getVirtualColumn('i18n_POSTSCRIPTUM')) + ->set("POSITION", $feature->getPosition()); $loopResult->addRow($loopResultRow); } diff --git a/core/lib/Thelia/Core/Template/Loop/FeatureAvailability.php b/core/lib/Thelia/Core/Template/Loop/FeatureAvailability.php index 45eed6dc3..38bee46f0 100755 --- a/core/lib/Thelia/Core/Template/Loop/FeatureAvailability.php +++ b/core/lib/Thelia/Core/Template/Loop/FeatureAvailability.php @@ -129,7 +129,8 @@ class FeatureAvailability extends BaseI18nLoop ->set("TITLE",$featureAv->getVirtualColumn('i18n_TITLE')) ->set("CHAPO", $featureAv->getVirtualColumn('i18n_CHAPO')) ->set("DESCRIPTION", $featureAv->getVirtualColumn('i18n_DESCRIPTION')) - ->set("POSTSCRIPTUM", $featureAv->getVirtualColumn('i18n_POSTSCRIPTUM')); + ->set("POSTSCRIPTUM", $featureAv->getVirtualColumn('i18n_POSTSCRIPTUM')) + ->set("POSITION", $featureAv->getPosition()); $loopResult->addRow($loopResultRow); } diff --git a/core/lib/Thelia/Core/Template/Loop/FeatureValue.php b/core/lib/Thelia/Core/Template/Loop/FeatureValue.php index 700eff39c..998dfe4e0 100755 --- a/core/lib/Thelia/Core/Template/Loop/FeatureValue.php +++ b/core/lib/Thelia/Core/Template/Loop/FeatureValue.php @@ -149,7 +149,8 @@ class FeatureValue extends BaseI18nLoop ->set("TITLE",$featureValue->getVirtualColumn(FeatureAvTableMap::TABLE_NAME . '_i18n_TITLE')) ->set("CHAPO", $featureValue->getVirtualColumn(FeatureAvTableMap::TABLE_NAME . '_i18n_CHAPO')) ->set("DESCRIPTION", $featureValue->getVirtualColumn(FeatureAvTableMap::TABLE_NAME . '_i18n_DESCRIPTION')) - ->set("POSTSCRIPTUM", $featureValue->getVirtualColumn(FeatureAvTableMap::TABLE_NAME . '_i18n_POSTSCRIPTUM')); + ->set("POSTSCRIPTUM", $featureValue->getVirtualColumn(FeatureAvTableMap::TABLE_NAME . '_i18n_POSTSCRIPTUM')) + ->set("POSITION", $featureValue->getPosition()); $loopResult->addRow($loopResultRow); } diff --git a/core/lib/Thelia/Core/Template/Loop/Title.php b/core/lib/Thelia/Core/Template/Loop/Title.php index 38dcb3fe3..4243f83f1 100755 --- a/core/lib/Thelia/Core/Template/Loop/Title.php +++ b/core/lib/Thelia/Core/Template/Loop/Title.php @@ -89,7 +89,8 @@ class Title extends BaseI18nLoop ->set("LOCALE",$locale) ->set("DEFAULT", $title->getByDefault()) ->set("SHORT", $title->getVirtualColumn('i18n_SHORT')) - ->set("LONG", $title->getVirtualColumn('i18n_LONG')); + ->set("LONG", $title->getVirtualColumn('i18n_LONG')) + ->set("POSITION", $title->getPosition()); $loopResult->addRow($loopResultRow); } diff --git a/core/lib/Thelia/Core/Template/Smarty/Assets/SmartyAssetsManager.php b/core/lib/Thelia/Core/Template/Smarty/Assets/SmartyAssetsManager.php index 17fe122d3..f19eded95 100755 --- a/core/lib/Thelia/Core/Template/Smarty/Assets/SmartyAssetsManager.php +++ b/core/lib/Thelia/Core/Template/Smarty/Assets/SmartyAssetsManager.php @@ -34,18 +34,22 @@ class SmartyAssetsManager private $web_root; private $path_relative_to_web_root; + private $developmentMode; /** * Creates a new SmartyAssetsManager instance * - * @param string $web_root the disk path to the web root - * @param string $path_relative_to_web_root the path (relative to web root) where the assets will be generated + * @param string $web_root the disk path to the web root + * @param string $path_relative_to_web_root the path (relative to web root) where the assets will be generated + * @param boolean $developmentMode true / false. If true, assets are not cached, and always generated. */ - public function __construct($web_root, $path_relative_to_web_root) + public function __construct($web_root, $path_relative_to_web_root, $developmentMode) { $this->web_root = $web_root; $this->path_relative_to_web_root = $path_relative_to_web_root; + $this->developmentMode = $developmentMode; + $this->assetic_manager = new AsseticHelper(); } @@ -73,7 +77,8 @@ class SmartyAssetsManager URL::getInstance()->absoluteUrl($this->path_relative_to_web_root, null, URL::PATH_TO_FILE /* path only */), $assetType, $filters, - $debug + $debug, + $this->developmentMode ); return $url; diff --git a/core/lib/Thelia/Core/Template/Smarty/Plugins/AdminUtilities.php b/core/lib/Thelia/Core/Template/Smarty/Plugins/AdminUtilities.php index fcea9ffd6..bb9770520 100644 --- a/core/lib/Thelia/Core/Template/Smarty/Plugins/AdminUtilities.php +++ b/core/lib/Thelia/Core/Template/Smarty/Plugins/AdminUtilities.php @@ -71,11 +71,11 @@ class AdminUtilities extends AbstractSmartyPlugin if ($permissions == null || $this->securityContext->isGranted("ADMIN", array($permission))) { return sprintf( '%s', - URL::getInstance()->absoluteUrl("$path/positionUp", array($url_parameter => $id)), + URL::getInstance()->absoluteUrl($path, array('mode' => 'up', $url_parameter => $id)), $in_place_edit_class, $id, $position, - URL::getInstance()->absoluteUrl("$path/positionDown", array($url_parameter => $id)) + URL::getInstance()->absoluteUrl($path, array('mode' => 'down', $url_parameter => $id)) ); } else { @@ -121,7 +121,7 @@ class AdminUtilities extends AbstractSmartyPlugin } if (! empty($icon)) - $output = sprintf(' ', $icon); + $output = sprintf(' ', $icon); else $output = ''; diff --git a/core/lib/Thelia/Core/Template/Smarty/Plugins/Assetic.php b/core/lib/Thelia/Core/Template/Smarty/Plugins/Assetic.php index f8ea1c2ef..b7bb95b83 100755 --- a/core/lib/Thelia/Core/Template/Smarty/Plugins/Assetic.php +++ b/core/lib/Thelia/Core/Template/Smarty/Plugins/Assetic.php @@ -32,13 +32,13 @@ class Assetic extends AbstractSmartyPlugin { public $assetManager; - public function __construct() + public function __construct($developmentMode) { $web_root = THELIA_WEB_DIR; $asset_dir_from_web_root = ConfigQuery::read('asset_dir_from_web_root', 'assets'); - $this->assetManager = new SmartyAssetsManager($web_root, $asset_dir_from_web_root); + $this->assetManager = new SmartyAssetsManager($web_root, $asset_dir_from_web_root, $developmentMode == 'dev'); } public function blockJavascripts($params, $content, \Smarty_Internal_Template $template, &$repeat) diff --git a/core/lib/Thelia/Core/Template/Smarty/Plugins/DataAccessFunctions.php b/core/lib/Thelia/Core/Template/Smarty/Plugins/DataAccessFunctions.php index ee65f34b3..1fdb6e4bf 100755 --- a/core/lib/Thelia/Core/Template/Smarty/Plugins/DataAccessFunctions.php +++ b/core/lib/Thelia/Core/Template/Smarty/Plugins/DataAccessFunctions.php @@ -23,10 +23,20 @@ namespace Thelia\Core\Template\Smarty\Plugins; +use Propel\Runtime\ActiveQuery\ModelCriteria; +use Symfony\Component\HttpFoundation\Request; use Thelia\Core\Template\Smarty\AbstractSmartyPlugin; use Thelia\Core\Security\SecurityContext; use Thelia\Core\Template\ParserContext; use Thelia\Core\Template\Smarty\SmartyPluginDescriptor; +use Thelia\Model\CategoryQuery; +use Thelia\Model\ContentQuery; +use Thelia\Model\FolderQuery; +use Thelia\Model\Product; +use Thelia\Model\ProductQuery; +use Thelia\Model\Tools\ModelCriteriaTools; +use Thelia\Tools\DateTimeFormat; + /** * Implementation of data access to main Thelia objects (users, cart, etc.) * @@ -37,10 +47,13 @@ class DataAccessFunctions extends AbstractSmartyPlugin { private $securityContext; protected $parserContext; + protected $request; - public function __construct(SecurityContext $securityContext, ParserContext $parserContext) + public function __construct(Request $request, SecurityContext $securityContext, ParserContext $parserContext) { $this->securityContext = $securityContext; + $this->parserContext = $parserContext; + $this->request = $request; } /** @@ -52,7 +65,7 @@ class DataAccessFunctions extends AbstractSmartyPlugin */ public function adminDataAccess($params, &$smarty) { - return $this->userDataAccess("Admin User", $this->securityContext->getAdminUser(), $params); + return $this->dataAccess("Admin User", $params, $this->securityContext->getAdminUser()); } /** @@ -64,37 +77,146 @@ class DataAccessFunctions extends AbstractSmartyPlugin */ public function customerDataAccess($params, &$smarty) { - return $this->userDataAccess("Customer User", $this->securityContext->getCustomerUser(), $params); + return $this->dataAccess("Customer User", $params, $this->securityContext->getCustomerUser()); } + public function productDataAccess($params, &$smarty) + { + $productId = $this->request->get('product_id'); + + if($productId !== null) { + + $search = ProductQuery::create() + ->filterById($productId); + + return $this->dataAccessWithI18n("Product", $params, $search); + } + } + + public function categoryDataAccess($params, &$smarty) + { + $categoryId = $this->request->get('category_id'); + + if($categoryId !== null) { + + $search = CategoryQuery::create() + ->filterById($categoryId); + + return $this->dataAccessWithI18n("Category", $params, $search); + } + } + + public function contentDataAccess($params, &$smarty) + { + $contentId = $this->request->get('content_id'); + + if($contentId !== null) { + + $search = ContentQuery::create() + ->filterById($contentId); + + return $this->dataAccessWithI18n("Content", $params, $search); + } + } + + public function folderDataAccess($params, &$smarty) + { + $folderId = $this->request->get('folder_id'); + + if($folderId !== null) { + + $search = FolderQuery::create() + ->filterById($folderId); + + return $this->dataAccessWithI18n("Folder", $params, $search); + } + } + /** - * Provides access to user attributes using the accessors. + * @param $objectLabel + * @param $params + * @param ModelCriteria $search + * @param array $columns + * @param null $foreignTable + * @param string $foreignKey * - * @param array $params - * @param unknown $smarty - * @return string the value of the requested attribute - * @throws InvalidArgumentException if the object does not have the requested attribute. + * @return string */ - protected function userDataAccess($objectLabel, $user, $params) - { - $attribute = $this->getNormalizedParam($params, array('attribute', 'attrib', 'attr')); + protected function dataAccessWithI18n($objectLabel, $params, ModelCriteria $search, $columns = array('TITLE', 'CHAPO', 'DESCRIPTION', 'POSTSCRIPTUM'), $foreignTable = null, $foreignKey = 'ID') + { + $lang = $this->getNormalizedParam($params, array('lang')); + if($lang === null) { + $lang = $this->request->getSession()->getLang()->getId(); + } - if (! empty($attribute)) { + ModelCriteriaTools::getI18n( + false, + $lang, + $search, + $this->request->getSession()->getLang()->getLocale(), + $columns, + $foreignTable, + $foreignKey, + true + ); - if (null != $user) { - $getter = sprintf("get%s", ucfirst($attribute)); + $data = $search->findOne(); - if (method_exists($user, $getter)) { - return $user->$getter(); - } + $noGetterData = array(); + foreach($columns as $column) { + $noGetterData[$column] = $data->getVirtualColumn('i18n_' . $column); + } - throw new \InvalidArgumentException(sprintf("%s has no '%s' attribute", $objectLabel, $attribute)); + return $this->dataAccess($objectLabel, $params, $data, $noGetterData); + } - } - } + /** + * @param $objectLabel + * @param $params + * @param $data + * @param array $noGetterData + * + * @return string + * @throws \InvalidArgumentException + */ + protected function dataAccess($objectLabel, $params, $data, $noGetterData = array()) + { + $attribute = $this->getNormalizedParam($params, array('attribute', 'attrib', 'attr')); + + if (! empty($attribute)) { + + if (null != $data) { + + $keyAttribute = strtoupper($attribute); + if(array_key_exists($keyAttribute, $noGetterData)) { + return $noGetterData[$keyAttribute]; + } + + $getter = sprintf("get%s", ucfirst($attribute)); + if (method_exists($data, $getter)) { + $return = $data->$getter(); + + if($return instanceof \DateTime) { + if (array_key_exists("format", $params)) { + $format = $params["format"]; + } else { + $format = DateTimeFormat::getInstance($this->request)->getFormat(array_key_exists("output", $params) ? $params["output"] : null); + } + + $return = $return->format($format); + } + + return $return; + } + + throw new \InvalidArgumentException(sprintf("%s has no '%s' attribute", $objectLabel, $attribute)); + + } + } + + return ''; + } - return ''; - } /** * Define the various smarty plugins hendled by this class * @@ -104,7 +226,11 @@ class DataAccessFunctions extends AbstractSmartyPlugin { return array( new SmartyPluginDescriptor('function', 'admin', $this, 'adminDataAccess'), - new SmartyPluginDescriptor('function', 'customer', $this, 'customerDataAccess') + new SmartyPluginDescriptor('function', 'customer', $this, 'customerDataAccess'), + new SmartyPluginDescriptor('function', 'product', $this, 'productDataAccess'), + new SmartyPluginDescriptor('function', 'category', $this, 'categoryDataAccess'), + new SmartyPluginDescriptor('function', 'content', $this, 'contentDataAccess'), + new SmartyPluginDescriptor('function', 'folder', $this, 'folderDataAccess'), ); } } diff --git a/core/lib/Thelia/Core/Template/Smarty/Plugins/Format.php b/core/lib/Thelia/Core/Template/Smarty/Plugins/Format.php index a095f214a..daaff3fc1 100644 --- a/core/lib/Thelia/Core/Template/Smarty/Plugins/Format.php +++ b/core/lib/Thelia/Core/Template/Smarty/Plugins/Format.php @@ -27,6 +27,7 @@ use Thelia\Core\HttpFoundation\Request; use Thelia\Core\Template\Smarty\AbstractSmartyPlugin; use Thelia\Core\Template\Smarty\Exception\SmartyPluginException; use Thelia\Core\Template\Smarty\SmartyPluginDescriptor; +use Thelia\Tools\DateTimeFormat; /** * @@ -79,29 +80,10 @@ class Format extends AbstractSmartyPlugin return ""; } - $format = null; - $output = array_key_exists("output", $params) ? $params["output"] : null; - if (array_key_exists("format", $params)) { $format = $params["format"]; } else { - $session = $this->request->getSession(); - $lang = $session->getLang(); - - if($lang) { - switch ($output) { - case "date" : - $format = $lang->getDateFormat(); - break; - case "time" : - $format = $lang->getTimeFormat(); - break; - default: - case "datetime" : - $format = $lang->getDateTimeFormat(); - break; - } - } + $format = DateTimeFormat::getInstance($this->request)->getFormat(array_key_exists("output", $params) ? $params["output"] : null); } return $date->format($format); diff --git a/core/lib/Thelia/Core/Template/Smarty/Plugins/UrlGenerator.php b/core/lib/Thelia/Core/Template/Smarty/Plugins/UrlGenerator.php index 72b3b88fb..f6c20ecfb 100755 --- a/core/lib/Thelia/Core/Template/Smarty/Plugins/UrlGenerator.php +++ b/core/lib/Thelia/Core/Template/Smarty/Plugins/UrlGenerator.php @@ -169,7 +169,7 @@ class UrlGenerator extends AbstractSmartyPlugin protected function getCurrentUrl() { - return URL::getInstance()->retrieveCurrent()->toString(); + return URL::getInstance()->retrieveCurrent($this->request)->toString(); } protected function getReturnToUrl() diff --git a/core/lib/Thelia/Form/BaseDescForm.php b/core/lib/Thelia/Form/BaseDescForm.php index c4f4f90c3..2b35f3e6e 100644 --- a/core/lib/Thelia/Form/BaseDescForm.php +++ b/core/lib/Thelia/Form/BaseDescForm.php @@ -43,12 +43,31 @@ abstract class BaseDescForm extends BaseForm ->add("title", "text", array( "constraints" => array( new NotBlank() + ), + "label" => "Title", + "label_attr" => array( + "for" => "title" ) ) ) - ->add("chapo", "text", array()) - ->add("description", "text", array()) - ->add("postscriptum", "text", array()) + ->add("chapo", "text", array( + "label" => "Summary", + "label_attr" => array( + "for" => "summary" + ) + )) + ->add("description", "text", array( + "label" => "Detailed description", + "label_attr" => array( + "for" => "detailed_description" + ) + )) + ->add("postscriptum", "text", array( + "label" => "Conclusion", + "label_attr" => array( + "for" => "conclusion" + ) + )) ; } } \ No newline at end of file diff --git a/core/lib/Thelia/Form/CategoryCreationForm.php b/core/lib/Thelia/Form/CategoryCreationForm.php index 9935eec19..a125ad090 100755 --- a/core/lib/Thelia/Form/CategoryCreationForm.php +++ b/core/lib/Thelia/Form/CategoryCreationForm.php @@ -32,6 +32,10 @@ class CategoryCreationForm extends BaseForm ->add("title", "text", array( "constraints" => array( new NotBlank() + ), + "label" => "Category title *", + "label_attr" => array( + "for" => "title" ) )) ->add("parent", "integer", array( diff --git a/core/lib/Thelia/Form/ConfigCreationForm.php b/core/lib/Thelia/Form/ConfigCreationForm.php index 5594830bc..b2a0c11bb 100644 --- a/core/lib/Thelia/Form/ConfigCreationForm.php +++ b/core/lib/Thelia/Form/ConfigCreationForm.php @@ -40,11 +40,19 @@ class ConfigCreationForm extends BaseForm $this->formBuilder ->add("name", "text", array( - "constraints" => $name_constraints + "constraints" => $name_constraints, + "label" => "Name *", + "label_attr" => array( + "for" => "name" + ) )) ->add("title", "text", array( "constraints" => array( new Constraints\NotBlank() + ), + "label" => "Purpose *", + "label_attr" => array( + "for" => "purpose" ) )) ->add("locale", "hidden", array( @@ -52,9 +60,16 @@ class ConfigCreationForm extends BaseForm new Constraints\NotBlank() ) )) - ->add("value", "text", array()) + ->add("value", "text", array( + "label" => "Value *", + "label_attr" => array( + "for" => "value" + ) + )) ->add("hidden", "hidden", array()) - ->add("secured", "hidden", array()) + ->add("secured", "hidden", array( + "label" => "Prevent variable modification or deletion, except for super-admin" + )) ; } diff --git a/core/lib/Thelia/Form/ConfigModificationForm.php b/core/lib/Thelia/Form/ConfigModificationForm.php index dd0a0e42f..295c0403d 100644 --- a/core/lib/Thelia/Form/ConfigModificationForm.php +++ b/core/lib/Thelia/Form/ConfigModificationForm.php @@ -44,11 +44,22 @@ class ConfigModificationForm extends BaseDescForm ->add("name", "text", array( "constraints" => array( new NotBlank() + ), + "label" => "Name", + "label_attr" => array( + "for" => "name" + ) + )) + ->add("value", "text", array( + "label" => "Value", + "label_attr" => array( + "for" => "value" ) )) - ->add("value", "text", array()) ->add("hidden", "hidden", array()) - ->add("secured", "hidden", array()) + ->add("secured", "hidden", array( + "label" => "Prevent variable modification or deletion, except for super-admin" + )) ; } diff --git a/core/lib/Thelia/Form/CurrencyCreationForm.php b/core/lib/Thelia/Form/CurrencyCreationForm.php index a4d858ed6..3328cd342 100644 --- a/core/lib/Thelia/Form/CurrencyCreationForm.php +++ b/core/lib/Thelia/Form/CurrencyCreationForm.php @@ -40,11 +40,47 @@ class CurrencyCreationForm extends BaseForm } $this->formBuilder - ->add("name" , "text" , array("constraints" => array(new NotBlank()))) - ->add("locale" , "text" , array("constraints" => array(new NotBlank()))) - ->add("symbol" , "text" , array("constraints" => array(new NotBlank()))) - ->add("rate" , "text" , array("constraints" => array(new NotBlank()))) - ->add("code" , "text" , array("constraints" => $code_constraints)) + ->add("name" , "text" , array( + "constraints" => array( + new NotBlank() + ), + "label" => "Name *", + "label_attr" => array( + "for" => "name" + )) + ) + ->add("locale" , "text" , array( + "constraints" => array( + new NotBlank() + )) + ) + ->add("symbol" , "text" , array( + "constraints" => array( + new NotBlank() + ), + "label" => "Symbol *", + "label_attr" => array( + "for" => "symbol" + )) + ) + ->add("rate" , "text" , array( + "constraints" => array( + new NotBlank() + ), + "label" => "Rate from € *", + "label_attr" => array( + "for" => "rate" + )) + ) + ->add("code" , "text" , array( + "constraints" => array( + new NotBlank() + ), + "label" => "ISO 4217 code *", + "label_attr" => array( + "for" => "iso_4217_code" + )) + ) ; } diff --git a/core/lib/Thelia/Form/MessageCreationForm.php b/core/lib/Thelia/Form/MessageCreationForm.php index a3444c733..6ce84cb06 100644 --- a/core/lib/Thelia/Form/MessageCreationForm.php +++ b/core/lib/Thelia/Form/MessageCreationForm.php @@ -40,11 +40,19 @@ class MessageCreationForm extends BaseForm $this->formBuilder ->add("name", "text", array( - "constraints" => $name_constraints + "constraints" => $name_constraints, + "label" => "Name *", + "label_attr" => array( + "for" => "name" + ) )) ->add("title", "text", array( "constraints" => array( new Constraints\NotBlank() + ), + "label" => "Purpose *", + "label_attr" => array( + "for" => "purpose" ) )) ->add("locale", "hidden", array( diff --git a/core/lib/Thelia/Form/MessageModificationForm.php b/core/lib/Thelia/Form/MessageModificationForm.php index 539a8babc..a23f66e28 100644 --- a/core/lib/Thelia/Form/MessageModificationForm.php +++ b/core/lib/Thelia/Form/MessageModificationForm.php @@ -33,13 +33,43 @@ class MessageModificationForm extends BaseForm { $this->formBuilder ->add("id" , "hidden", array("constraints" => array(new GreaterThan(array('value' => 0))))) - ->add("name" , "text" , array("constraints" => array(new NotBlank()))) - ->add("secured" , "text" , array()) + ->add("name" , "text" , array( + "constraints" => array(new NotBlank()), + "label" => "Name *", + "label_attr" => array( + "for" => "name" + ) + )) + ->add("secured" , "text" , array( + "label" => "Prevent mailing template modification or deletion, except for super-admin" + )) ->add("locale" , "text" , array()) - ->add("title" , "text" , array("constraints" => array(new NotBlank()))) - ->add("subject" , "text" , array("constraints" => array(new NotBlank()))) - ->add("html_message" , "text" , array()) - ->add("text_message" , "text" , array()) + ->add("title" , "text" , array( + "constraints" => array(new NotBlank()), + "label" => "Title *", + "label_attr" => array( + "for" => "title" + ) + )) + ->add("subject" , "text" , array( + "constraints" => array(new NotBlank()), + "label" => "Message subject *", + "label_attr" => array( + "for" => "subject" + ) + )) + ->add("html_message" , "text" , array( + "label" => "HTML Message", + "label_attr" => array( + "for" => "html_message" + ) + )) + ->add("text_message" , "text" , array( + "label" => "Text Message", + "label_attr" => array( + "for" => "text_message" + ) + )) ; } diff --git a/core/lib/Thelia/Model/Currency.php b/core/lib/Thelia/Model/Currency.php index 20c36782d..ef8d73735 100755 --- a/core/lib/Thelia/Model/Currency.php +++ b/core/lib/Thelia/Model/Currency.php @@ -20,6 +20,9 @@ class Currency extends BaseCurrency { { $this->dispatchEvent(TheliaEvents::BEFORE_CREATECURRENCY, new CurrencyEvent($this)); + // Set the current position for the new object + $this->setPosition($this->getNextPosition()); + return true; } diff --git a/core/lib/Thelia/Model/Tools/ModelCriteriaTools.php b/core/lib/Thelia/Model/Tools/ModelCriteriaTools.php index 5e22f08e9..5e5dae010 100755 --- a/core/lib/Thelia/Model/Tools/ModelCriteriaTools.php +++ b/core/lib/Thelia/Model/Tools/ModelCriteriaTools.php @@ -113,7 +113,7 @@ class ModelCriteriaTools $localeSearch = LangQuery::create()->findOneById($requestedLangId); if ($localeSearch === null) { - throw new \InvalidArgumentException(sprintf('Incorrect lang argument given in attribute loop: lang ID %d not found', $requestedLangId)); + throw new \InvalidArgumentException(sprintf('Incorrect lang argument given : lang ID %d not found', $requestedLangId)); } $locale = $localeSearch->getLocale(); diff --git a/core/lib/Thelia/Model/Tools/ModelEventDispatcherTrait.php b/core/lib/Thelia/Model/Tools/ModelEventDispatcherTrait.php index 7e2e34d83..17af1e44d 100644 --- a/core/lib/Thelia/Model/Tools/ModelEventDispatcherTrait.php +++ b/core/lib/Thelia/Model/Tools/ModelEventDispatcherTrait.php @@ -44,6 +44,11 @@ trait ModelEventDispatcherTrait { return $this; } + public function getDispatcher() + { + return $this->dispatcher; + } + protected function dispatchEvent($eventName, ActionEvent $event) { if (!is_null($this->dispatcher)) { diff --git a/core/lib/Thelia/Model/Tools/PositionManagementTrait.php b/core/lib/Thelia/Model/Tools/PositionManagementTrait.php index eccbb00dd..9e0b1f35c 100644 --- a/core/lib/Thelia/Model/Tools/PositionManagementTrait.php +++ b/core/lib/Thelia/Model/Tools/PositionManagementTrait.php @@ -25,6 +25,7 @@ namespace Thelia\Model\Tools; use Propel\Runtime\ActiveQuery\PropelQuery; use Propel\Runtime\ActiveQuery\Criteria; +use Propel\Runtime\Propel; trait PositionManagementTrait { @@ -48,13 +49,15 @@ trait PositionManagementTrait { /** * Get the position of the next inserted object */ - public function getNextPosition($parent) { + public function getNextPosition($parent = null) { - $last = $this->createQuery() - ->filterByParent($parent) + $query = $this->createQuery() ->orderByPosition(Criteria::DESC) - ->limit(1) - ->findOne() + ->limit(1); + + if ($parent !== null) $last->filterByParent($parent); + + $last = $query->findOne() ; return $last != null ? $last->getPosition() + 1 : 1; @@ -63,14 +66,14 @@ trait PositionManagementTrait { /** * Move up a object */ - protected function movePositionUp() { + public function movePositionUp() { $this->movePositionUpOrDown(true); } /** * Move down a object */ - protected function movePositionDown() { + public function movePositionDown() { $this->movePositionUpOrDown(false); } @@ -85,8 +88,9 @@ trait PositionManagementTrait { $my_position = $this->getPosition(); // Find object to exchange position with - $search = $this->createQuery() - ->filterByParent($this->getParent()); + $search = $this->createQuery(); + + if (method_exists($this, 'getParent')) $search->filterByParent($this->getParent()); // Up or down ? if ($up === true) { @@ -103,18 +107,17 @@ trait PositionManagementTrait { // If we found the proper object, exchange their positions if ($result) { - $cnx = Propel::getWriteConnection(CategoryTableMap::DATABASE_NAME); + $cnx = Propel::getWriteConnection($this->getDatabaseName()); $cnx->beginTransaction(); try { $this - ->setDispatcher($this->getDispatcher()) ->setPosition($result->getPosition()) ->save() ; - $result->setPosition($my_position)->save(); + $result->setDispatcher($this->getDispatcher())->setPosition($my_position)->save(); $cnx->commit(); } catch (Exception $e) { @@ -123,12 +126,22 @@ trait PositionManagementTrait { } } + /** + * Simply return the database name, from the constant in the MAP class. + */ + protected function getDatabaseName() { + // Find DATABASE_NAME constant + $mapClassName = self::TABLE_MAP; + + return $mapClassName::DATABASE_NAME; + } + /** * Changes object position * * @param newPosition */ - protected function changeAbsolutePosition($newPosition) + public function changeAbsolutePosition($newPosition) { // The current position $current_position = $this->getPosition(); @@ -136,7 +149,9 @@ trait PositionManagementTrait { if ($newPosition != null && $newPosition > 0 && $newPosition != $current_position) { // Find categories to offset - $search = $this->createQuery()->filterByParent($this->getParent()); + $search = $this->createQuery(); + + if (method_exists($this, 'getParent')) $search->filterByParent($this->getParent()); if ($newPosition > $current_position) { // The new position is after the current position -> we will offset + 1 all categories located between us and the new position @@ -152,17 +167,16 @@ trait PositionManagementTrait { $results = $search->find(); - $cnx = Propel::getWriteConnection(CategoryTableMap::DATABASE_NAME); + $cnx = Propel::getWriteConnection($this->getDatabaseName()); $cnx->beginTransaction(); try { foreach ($results as $result) { - $result->setPosition($result->getPosition() + $delta)->save($cnx); + $result->setDispatcher($this->getDispatcher())->setPosition($result->getPosition() + $delta)->save($cnx); } $this - ->setDispatcher($this->getDispatcher()) ->setPosition($newPosition) ->save($cnx) ; diff --git a/core/lib/Thelia/Rewriting/RewritingResolver.php b/core/lib/Thelia/Rewriting/RewritingResolver.php index 900442db9..4c8bcba40 100755 --- a/core/lib/Thelia/Rewriting/RewritingResolver.php +++ b/core/lib/Thelia/Rewriting/RewritingResolver.php @@ -58,6 +58,8 @@ class RewritingResolver public function load($rewrittenUrl) { + $rewrittenUrl = ltrim($rewrittenUrl, '/'); + $this->search = $this->rewritingUrlQuery->getResolverSearch($rewrittenUrl); if($this->search->count() == 0) { diff --git a/core/lib/Thelia/Rewriting/RewritingRetriever.php b/core/lib/Thelia/Rewriting/RewritingRetriever.php index dfbe63517..8289942f2 100755 --- a/core/lib/Thelia/Rewriting/RewritingRetriever.php +++ b/core/lib/Thelia/Rewriting/RewritingRetriever.php @@ -66,6 +66,7 @@ class RewritingRetriever $allParametersWithoutView[$view . '_id'] = $viewId; } + $this->rewrittenUrl = null; $this->url = URL::getInstance()->viewUrl($view, $allParametersWithoutView); if($this->search !== null) { $this->rewrittenUrl = $this->search->getUrl(); @@ -93,6 +94,7 @@ class RewritingRetriever $allParametersWithoutView[$view . '_id'] = $viewId; } + $this->rewrittenUrl = null; $this->url = URL::getInstance()->viewUrl($view, $allParametersWithoutView); if($this->search !== null) { $this->rewrittenUrl = $this->search->getUrl(); diff --git a/core/lib/Thelia/Tests/Action/ImageTest.php b/core/lib/Thelia/Tests/Action/ImageTest.php index 526f7cb86..8cc6e5644 100755 --- a/core/lib/Thelia/Tests/Action/ImageTest.php +++ b/core/lib/Thelia/Tests/Action/ImageTest.php @@ -37,7 +37,7 @@ use Thelia\Tools\URL; * * @package Thelia\Tests\Action\ImageTest */ -class ImageTest extends \PHPUnit_Framework_TestCase +class ImageTest extends \Thelia\Tests\TestCaseWithURLToolSetup { protected $request; @@ -49,10 +49,7 @@ class ImageTest extends \PHPUnit_Framework_TestCase $dispatcher = $this->getMock("Symfony\Component\EventDispatcher\EventDispatcherInterface"); - $url = new URL($container, 'dev'); - $container->set("event_dispatcher", $dispatcher); - $container->set("thelia.url.manager", $dispatcher); $request = new Request(); $request->setSession($this->session); diff --git a/core/lib/Thelia/Tests/Command/CacheClearTest.php b/core/lib/Thelia/Tests/Command/CacheClearTest.php index ed2e512b6..741fad299 100755 --- a/core/lib/Thelia/Tests/Command/CacheClearTest.php +++ b/core/lib/Thelia/Tests/Command/CacheClearTest.php @@ -47,6 +47,7 @@ class CacheClearTest extends \PHPUnit_Framework_TestCase $fs = new Filesystem(); $fs->mkdir($this->cache_dir); + $fs->mkdir(THELIA_WEB_DIR . "/assets"); } public function testCacheClear() diff --git a/core/lib/Thelia/Tests/Controller/DefaultControllerTest.php b/core/lib/Thelia/Tests/Controller/DefaultControllerTest.php index 33ea807e3..177802078 100755 --- a/core/lib/Thelia/Tests/Controller/DefaultControllerTest.php +++ b/core/lib/Thelia/Tests/Controller/DefaultControllerTest.php @@ -23,7 +23,7 @@ namespace Thelia\Tests\Controller; -use Symfony\Component\HttpFoundation\Request; +use Thelia\Core\HttpFoundation\Request; use Thelia\Controller\Front\DefaultController; /** diff --git a/core/lib/Thelia/Tests/Core/Template/Element/BaseLoopTestor.php b/core/lib/Thelia/Tests/Core/Template/Element/BaseLoopTestor.php index c4b0192bc..7d14fbbc5 100755 --- a/core/lib/Thelia/Tests/Core/Template/Element/BaseLoopTestor.php +++ b/core/lib/Thelia/Tests/Core/Template/Element/BaseLoopTestor.php @@ -34,7 +34,7 @@ use Thelia\Core\HttpFoundation\Session\Session; * @author Etienne Roudeix * */ -abstract class BaseLoopTestor extends \PHPUnit_Framework_TestCase +abstract class BaseLoopTestor extends \Thelia\Tests\TestCaseWithURLToolSetup { protected $request; protected $dispatcher; diff --git a/core/lib/Thelia/Tests/TestCaseWithURLToolSetup.php b/core/lib/Thelia/Tests/TestCaseWithURLToolSetup.php new file mode 100644 index 000000000..927f7cf62 --- /dev/null +++ b/core/lib/Thelia/Tests/TestCaseWithURLToolSetup.php @@ -0,0 +1,64 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Tests; + +/** + * This class provides URL Tool class initialisation + * + * @package Thelia\Tests\TestCaseWithURLSetup + */ +class TestCaseWithURLToolSetup extends \PHPUnit_Framework_TestCase { + + + public function __construct() { + $this->setupURLTool(); + } + + protected function setupURLTool() { + + $container = new \Symfony\Component\DependencyInjection\ContainerBuilder(); + + $context = new \Symfony\Component\Routing\RequestContext( + '/thelia/index.php', + 'GET', + 'localhost', + 'http', + 80, + 443, + '/path/to/action' + ); + + $router = $this->getMockBuilder("Symfony\Component\Routing\Router") + ->disableOriginalConstructor() + ->getMock(); + + $router->expects($this->any()) + ->method('getContext') + ->will($this->returnValue($context)); + + $container->set("router.admin", $router); + + new \Thelia\Tools\URL($container); + } +} \ No newline at end of file diff --git a/core/lib/Thelia/Tests/Tools/URLTest.php b/core/lib/Thelia/Tests/Tools/URLTest.php index 0c99651b4..86804f5c0 100755 --- a/core/lib/Thelia/Tests/Tools/URLTest.php +++ b/core/lib/Thelia/Tests/Tools/URLTest.php @@ -28,10 +28,208 @@ use Thelia\Tools\URL; /** * * @author Etienne Roudeix + * @author Franck Allimant * */ class URLTest extends \PHPUnit_Framework_TestCase { + protected $context; + + public function setUp() + { + $container = new \Symfony\Component\DependencyInjection\ContainerBuilder(); + + $router = $this->getMockBuilder("Symfony\Component\Routing\Router") + ->disableOriginalConstructor() + ->getMock(); + + $this->context = new \Symfony\Component\Routing\RequestContext( + '/thelia/index.php', + 'GET', + 'localhost', + 'http', + 80, + 443, + '/path/to/action' + ); + + $router->expects($this->any()) + ->method('getContext') + ->will($this->returnValue($this->context)); + + $container->set("router.admin", $router); + + new \Thelia\Tools\URL($container); + } + + public function testGetIndexPage() { + + $this->context->setBaseUrl('/thelia/index.php'); + $url = \Thelia\Tools\URL::getInstance()->getIndexPage(); + $this->assertEquals('http://localhost/thelia/index.php', $url); + + $this->context->setBaseUrl('/thelia/'); + $url = \Thelia\Tools\URL::getInstance()->getIndexPage(); + $this->assertEquals('http://localhost/thelia/', $url); + + $this->context->setBaseUrl('/thelia'); + $url = \Thelia\Tools\URL::getInstance()->getIndexPage(); + $this->assertEquals('http://localhost/thelia', $url); + + $this->context->setBaseUrl('/'); + $url = \Thelia\Tools\URL::getInstance()->getIndexPage(); + $this->assertEquals('http://localhost/', $url); + } + + public function testGetBaseUrl() { + $this->context->setBaseUrl('/thelia/index.php'); + $url = \Thelia\Tools\URL::getInstance()->getBaseUrl(); + $this->assertEquals('http://localhost/thelia/index.php', $url); + + $this->context->setBaseUrl('/thelia/'); + $url = \Thelia\Tools\URL::getInstance()->getBaseUrl(); + $this->assertEquals('http://localhost/thelia/', $url); + + $this->context->setBaseUrl('/'); + $url = \Thelia\Tools\URL::getInstance()->getBaseUrl(); + $this->assertEquals('http://localhost/', $url); + } + + public function testAbsoluteUrl() { + $this->context->setBaseUrl('/'); + $url = \Thelia\Tools\URL::getInstance()->absoluteUrl('/path/to/action'); + $this->assertEquals('http://localhost/path/to/action', $url); + + $this->context->setBaseUrl('/thelia/'); + $url = \Thelia\Tools\URL::getInstance()->absoluteUrl('/path/to/action'); + $this->assertEquals('http://localhost/thelia/path/to/action', $url); + + $this->context->setBaseUrl('/thelia'); + $url = \Thelia\Tools\URL::getInstance()->absoluteUrl('/path/to/action'); + $this->assertEquals('http://localhost/thelia/path/to/action', $url); + + $this->context->setBaseUrl('/thelia/index.php'); + $url = \Thelia\Tools\URL::getInstance()->absoluteUrl('/path/to/action'); + $this->assertEquals('http://localhost/thelia/index.php/path/to/action', $url); + } + + public function testAbsoluteUrlOnAbsolutePath() { + + $this->context->setBaseUrl('/thelia/index.php'); + $url = \Thelia\Tools\URL::getInstance()->absoluteUrl('http://myhost/path/to/action'); + $this->assertEquals('http://myhost/path/to/action', $url); + + $this->context->setBaseUrl('/thelia/'); + $url = \Thelia\Tools\URL::getInstance()->absoluteUrl('http://myhost/path/to/action'); + $this->assertEquals('http://myhost/path/to/action', $url); + + $this->context->setBaseUrl('/'); + $url = \Thelia\Tools\URL::getInstance()->absoluteUrl('http://myhost/path/to/action'); + $this->assertEquals('http://myhost/path/to/action', $url); + } + + public function testAbsoluteUrlOnAbsolutePathWithParameters() { + + $this->context->setBaseUrl('/thelia/index.php'); + $url = \Thelia\Tools\URL::getInstance()->absoluteUrl('http://myhost/path/to/action', array("p1" => "v1", "p2" => "v2")); + $this->assertEquals('http://myhost/path/to/action?p1=v1&p2=v2', $url); + + $this->context->setBaseUrl('/thelia/'); + $url = \Thelia\Tools\URL::getInstance()->absoluteUrl('http://myhost/path/to/action', array("p1" => "v1", "p2" => "v2")); + $this->assertEquals('http://myhost/path/to/action?p1=v1&p2=v2', $url); + + $this->context->setBaseUrl('/'); + $url = \Thelia\Tools\URL::getInstance()->absoluteUrl('http://myhost/path/to/action', array("p1" => "v1", "p2" => "v2")); + $this->assertEquals('http://myhost/path/to/action?p1=v1&p2=v2', $url); + } + + public function testAbsoluteUrlOnAbsolutePathWithParametersAddParameters() { + $this->context->setBaseUrl('/thelia/index.php'); + $url = \Thelia\Tools\URL::getInstance()->absoluteUrl('http://myhost/path/to/action?p0=v0', array("p1" => "v1", "p2" => "v2")); + $this->assertEquals('http://myhost/path/to/action?p0=v0&p1=v1&p2=v2', $url); + + $this->context->setBaseUrl('/thelia/'); + $url = \Thelia\Tools\URL::getInstance()->absoluteUrl('http://myhost/path/to/action?p0=v0', array("p1" => "v1", "p2" => "v2")); + $this->assertEquals('http://myhost/path/to/action?p0=v0&p1=v1&p2=v2', $url); + + $this->context->setBaseUrl('/'); + $url = \Thelia\Tools\URL::getInstance()->absoluteUrl('http://myhost/path/to/action?p0=v0', array("p1" => "v1", "p2" => "v2")); + $this->assertEquals('http://myhost/path/to/action?p0=v0&p1=v1&p2=v2', $url); + } + + public function testAbsoluteUrlWithParameters() { + $this->context->setBaseUrl('/thelia/index.php'); + $url = \Thelia\Tools\URL::getInstance()->absoluteUrl('/path/to/action', array("p1" => "v1", "p2" => "v2")); + $this->assertEquals('http://localhost/thelia/index.php/path/to/action?p1=v1&p2=v2', $url); + + $this->context->setBaseUrl('/thelia/'); + $url = \Thelia\Tools\URL::getInstance()->absoluteUrl('/path/to/action', array("p1" => "v1", "p2" => "v2")); + $this->assertEquals('http://localhost/thelia/path/to/action?p1=v1&p2=v2', $url); + + $this->context->setBaseUrl('/thelia'); + $url = \Thelia\Tools\URL::getInstance()->absoluteUrl('/path/to/action', array("p1" => "v1", "p2" => "v2")); + $this->assertEquals('http://localhost/thelia/path/to/action?p1=v1&p2=v2', $url); + + $this->context->setBaseUrl('/thelia'); + $url = \Thelia\Tools\URL::getInstance()->absoluteUrl('path/to/action', array("p1" => "v1", "p2" => "v2")); + $this->assertEquals('http://localhost/thelia/path/to/action?p1=v1&p2=v2', $url); + + $this->context->setBaseUrl('/'); + $url = \Thelia\Tools\URL::getInstance()->absoluteUrl('/path/to/action', array("p1" => "v1", "p2" => "v2")); + $this->assertEquals('http://localhost/path/to/action?p1=v1&p2=v2', $url); + } + + public function testAbsoluteUrlPathOnly() { + $this->context->setBaseUrl('/thelia/index.php'); + $url = \Thelia\Tools\URL::getInstance()->absoluteUrl('/path/to/action', array(), URL::PATH_TO_FILE); + $this->assertEquals('http://localhost/thelia/path/to/action', $url); + } + + public function testAbsoluteUrlPathOnlyWithParameters() { + $this->context->setBaseUrl('/thelia/index.php'); + $url = \Thelia\Tools\URL::getInstance()->absoluteUrl('/path/to/action', array("p1" => "v1", "p2" => "v2"), URL::PATH_TO_FILE); + $this->assertEquals('http://localhost/thelia/path/to/action?p1=v1&p2=v2', $url); + + $this->context->setBaseUrl('/thelia/'); + $url = \Thelia\Tools\URL::getInstance()->absoluteUrl('/path/to/action', array("p1" => "v1", "p2" => "v2"), URL::PATH_TO_FILE); + $this->assertEquals('http://localhost/thelia/path/to/action?p1=v1&p2=v2', $url); + + $this->context->setBaseUrl('/'); + $url = \Thelia\Tools\URL::getInstance()->absoluteUrl('/path/to/action', array("p1" => "v1", "p2" => "v2"), URL::PATH_TO_FILE); + $this->assertEquals('http://localhost/path/to/action?p1=v1&p2=v2', $url); + + } + + public function testAbsoluteUrlFromIndexWithParameters() { + $this->context->setBaseUrl('/thelia/index.php'); + $url = \Thelia\Tools\URL::getInstance()->absoluteUrl('/', array("p1" => "v1", "p2" => "v2")); + $this->assertEquals('http://localhost/thelia/index.php/?p1=v1&p2=v2', $url); + + $this->context->setBaseUrl('/thelia/'); + $url = \Thelia\Tools\URL::getInstance()->absoluteUrl('/', array("p1" => "v1", "p2" => "v2")); + $this->assertEquals('http://localhost/thelia/?p1=v1&p2=v2', $url); + + $this->context->setBaseUrl('/'); + $url = \Thelia\Tools\URL::getInstance()->absoluteUrl('/', array("p1" => "v1", "p2" => "v2")); + $this->assertEquals('http://localhost/?p1=v1&p2=v2', $url); + + } + + public function testAbsoluteUrlPathOnlyFromIndexWithParameters() { + $this->context->setBaseUrl('/thelia/index.php'); + $url = \Thelia\Tools\URL::getInstance()->absoluteUrl('/', array("p1" => "v1", "p2" => "v2"), URL::PATH_TO_FILE); + $this->assertEquals('http://localhost/thelia/?p1=v1&p2=v2', $url); + + $this->context->setBaseUrl('/thelia/'); + $url = \Thelia\Tools\URL::getInstance()->absoluteUrl('/', array("p1" => "v1", "p2" => "v2"), URL::PATH_TO_FILE); + $this->assertEquals('http://localhost/thelia/?p1=v1&p2=v2', $url); + + $this->context->setBaseUrl('/'); + $url = \Thelia\Tools\URL::getInstance()->absoluteUrl('/', array("p1" => "v1", "p2" => "v2"), URL::PATH_TO_FILE); + $this->assertEquals('http://localhost/?p1=v1&p2=v2', $url); + + } + public function testRetrieve() { diff --git a/core/lib/Thelia/Controller/Front/UrlRewritingController.php b/core/lib/Thelia/Tools/DateTimeFormat.php similarity index 50% rename from core/lib/Thelia/Controller/Front/UrlRewritingController.php rename to core/lib/Thelia/Tools/DateTimeFormat.php index 2e725aecd..bd6161389 100755 --- a/core/lib/Thelia/Controller/Front/UrlRewritingController.php +++ b/core/lib/Thelia/Tools/DateTimeFormat.php @@ -20,62 +20,47 @@ /* along with this program. If not, see . */ /* */ /*************************************************************************************/ -namespace Thelia\Controller\Front; -use Thelia\Core\HttpFoundation\Request; -use Thelia\Exception\UrlRewritingException; -use Thelia\Model\ConfigQuery; -use Thelia\Tools\URL; +namespace Thelia\Tools; -class UrlRewritingController extends BaseFrontController +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\DependencyInjection\ContainerInterface; + +class DateTimeFormat { - public function check(Request $request, $rewritten_url) + protected $request; + + public function __construct(Request $request) { - if(ConfigQuery::isRewritingEnable()) { - try { - $rewrittenUrlData = URL::getInstance()->resolve($rewritten_url); - } catch(UrlRewritingException $e) { - switch($e->getCode()) { - case UrlRewritingException::URL_NOT_FOUND : - return $this->pageNotFound(); - break; - default: - throw $e; - } - } - - /* is the URL redirected ? */ - - if(null !== $rewrittenUrlData->redirectedToUrl) { - $this->redirect($rewrittenUrlData->redirectedToUrl, 301); - } - - /* define GET arguments in request */ - - if(null !== $rewrittenUrlData->view) { - $request->query->set('view', $rewrittenUrlData->view); - if(null !== $rewrittenUrlData->viewId) { - $request->query->set($rewrittenUrlData->view . '_id', $rewrittenUrlData->viewId); - } - } - if(null !== $rewrittenUrlData->locale) { - $request->query->set('locale', $rewrittenUrlData->locale); - } - - foreach($rewrittenUrlData->otherParameters as $parameter => $value) { - $request->query->set($parameter, $value); - } - } - - if (! $view = $request->query->get('view')) { - $view = "index"; - if ($request->request->has('view')) { - $view = $request->request->get('view'); - } - } - - $request->attributes->set('_view', $view); - + $this->request = $request; } -} + public static function getInstance(Request $request) + { + return new DateTimeFormat($request); + } + + public function getFormat($output = null) + { + $lang = $this->request->getSession()->getLang(); + + $format = null; + + if($lang) { + switch ($output) { + case "date" : + $format = $lang->getDateFormat(); + break; + case "time" : + $format = $lang->getTimeFormat(); + break; + default: + case "datetime" : + $format = $lang->getDateTimeFormat(); + break; + } + } + + return $format; + } +} \ No newline at end of file diff --git a/core/lib/Thelia/Tools/URL.php b/core/lib/Thelia/Tools/URL.php index f234f9086..161175bbf 100755 --- a/core/lib/Thelia/Tools/URL.php +++ b/core/lib/Thelia/Tools/URL.php @@ -27,33 +27,30 @@ use Thelia\Model\ConfigQuery; use Thelia\Rewriting\RewritingResolver; use Thelia\Rewriting\RewritingRetriever; -use Symfony\Component\DependencyInjection\ContainerAwareInterface; use Thelia\Core\HttpFoundation\Request; -use Symfony\Component\DependencyInjection\ContainerAware; use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\Routing\RequestContext; class URL { protected $resolver = null; protected $retriever = null; - protected $container; - protected $environment; + protected $requestContext; const PATH_TO_FILE = true; const WITH_INDEX_PAGE = false; - private static $instance = null; + protected static $instance = null; - public function __construct(ContainerInterface $container, $environment) + public function __construct(ContainerInterface $container) { // Allow singleton style calls once intanciated. // For this to work, the URL service has to be instanciated very early. This is done manually // in TheliaHttpKernel, by calling $this->container->get('thelia.url.manager'); self::$instance = $this; - $this->container = $container; - $this->environment = $environment; + $this->requestContext = $container->get('router.admin')->getContext(); $this->retriever = new RewritingRetriever(); $this->resolver = new RewritingResolver(); @@ -79,49 +76,31 @@ class URL */ public function getBaseUrl() { - $request = $this->container->get('request'); - $lang = $request->getSession()->getLang(); + if ($host = $this->requestContext->getHost()) { - // Check if we have a specific URL for each lang. - $one_domain_foreach_lang = ConfigQuery::read("one_domain_foreach_lang", false); + $scheme = $this->requestContext->getScheme(); - if ($one_domain_foreach_lang == true) { - // If it's the case, get the current lang URL - $base_url = $lang->getUrl(); + $port = ''; - $err_msg_part = 'base_url'; - } - else { - // Get the base URL - $base_url = ConfigQuery::read('base_url', $request->getSchemeAndHttpHost()); + if ('http' === $scheme && 80 != $this->requestContext->getHttpPort()) { + $port = ':'.$this->requestContext->getHttpPort(); + } elseif ('https' === $scheme && 443 != $this->requestContext->getHttpsPort()) { + $port = ':'.$this->requestContext->getHttpsPort(); + } - $err_msg_part = sprintf('base_url for lang %s', $lang->getCode()); + $schemeAuthority = "$scheme://$host"."$port"; } - // Be sure that base-url starts with http, give up if it's not the case. - if (substr($base_url, 0, 4) != 'http') { - throw new \InvalidArgumentException( - sprintf("The %s configuration parameter shoud contains the URL of your shop, starting with http or https.", $err_msg_part)); - } - - // Normalize the base_url - return rtrim($base_url, '/').'/'; + return $schemeAuthority.$this->requestContext->getBaseUrl(); } /** - * @return string the index page, which is basically the base_url in prod environment. + * @return string the index page, which is in fact the base URL. */ public function getIndexPage() { - // Get the base URL - $base_url = $this->getBaseUrl(); - - // For dev environment, add the proper page. - if ($this->environment == 'dev') { - $base_url .= "index_dev.php"; - } - - return $base_url; + // The index page is the base URL :) + return $this->getBaseUrl(); } /** @@ -140,14 +119,16 @@ class URL // Already absolute ? if (substr($path, 0, 4) != 'http') { - /** - * @etienne : can't be done here for it's already done in ::viewUrl / ::adminViewUrl - * @franck : should be done, as absoluteUrl() is sometimes called directly (see UrlGenerator::generateUrlFunction()) - */ - $root = $path_only == self::PATH_TO_FILE ? $this->getBaseUrl() : $this->getIndexPage(); + $base_url = $this->getBaseUrl(); - // Normalize root path - $base = rtrim($root, '/') . '/' . ltrim($path, '/'); + // If only a path is requested, be sure to remove the script name (index.php or index_dev.php), if any. + if ($path_only == self::PATH_TO_FILE) { + // As the base_url always ends with '/', if we don't find / at the end, we have a script. + if (substr($base_url, -1) != '/') $base_url = dirname($base_url); + } + + // Normalize the given path + $base = rtrim($base_url, '/') . '/' . ltrim($path, '/'); } else $base = $path; @@ -223,20 +204,20 @@ class URL public function retrieveCurrent(Request $request) { if(ConfigQuery::isRewritingEnable()) { - $view = $request->query->get('view', null); + $view = $request->attributes->get('_view', null); $viewLocale = $request->query->get('locale', null); $viewId = $view === null ? null : $request->query->get($view . '_id', null); $allOtherParameters = $request->query->all(); if($view !== null) { unset($allOtherParameters['view']); + if($viewId !== null) { + unset($allOtherParameters[$view . '_id']); + } } if($viewLocale !== null) { unset($allOtherParameters['locale']); } - if($viewId !== null) { - unset($allOtherParameters[$view . '_id']); - } $this->retriever->loadSpecificUrl($view, $viewLocale, $viewId, $allOtherParameters); } diff --git a/templates/admin/default/admin-layout.tpl b/templates/admin/default/admin-layout.tpl index 24febd759..0925f2ede 100644 --- a/templates/admin/default/admin-layout.tpl +++ b/templates/admin/default/admin-layout.tpl @@ -212,9 +212,7 @@ {block name="before-javascript-include"}{/block} - {javascripts file='assets/js/jquery.min.js'} - - {/javascripts} + {block name="after-javascript-include"}{/block} diff --git a/templates/admin/default/assets/img/flags/en.gif b/templates/admin/default/assets/img/flags/en.gif index 3a7661fdb..91b2b0090 100755 Binary files a/templates/admin/default/assets/img/flags/en.gif and b/templates/admin/default/assets/img/flags/en.gif differ diff --git a/templates/admin/default/assets/img/flags/es.gif b/templates/admin/default/assets/img/flags/es.gif index 9ac64ad37..bdf09f8f7 100755 Binary files a/templates/admin/default/assets/img/flags/es.gif and b/templates/admin/default/assets/img/flags/es.gif differ diff --git a/templates/admin/default/assets/img/flags/fr.gif b/templates/admin/default/assets/img/flags/fr.gif index 46f4d122d..2f6cf9ea3 100755 Binary files a/templates/admin/default/assets/img/flags/fr.gif and b/templates/admin/default/assets/img/flags/fr.gif differ diff --git a/templates/admin/default/assets/img/flags/it.gif b/templates/admin/default/assets/img/flags/it.gif index fddb02499..cdd750a54 100755 Binary files a/templates/admin/default/assets/img/flags/it.gif and b/templates/admin/default/assets/img/flags/it.gif differ diff --git a/templates/admin/default/assets/js/bootstrap-switch/bootstrap-switch.js b/templates/admin/default/assets/js/bootstrap-switch/bootstrap-switch.js new file mode 100644 index 000000000..1538f9df1 --- /dev/null +++ b/templates/admin/default/assets/js/bootstrap-switch/bootstrap-switch.js @@ -0,0 +1,382 @@ +/*! ============================================================ + * bootstrapSwitch v1.8 by Larentis Mattia @SpiritualGuru + * http://www.larentis.eu/ + * + * Enhanced for radiobuttons by Stein, Peter @BdMdesigN + * http://www.bdmdesign.org/ + * + * Project site: + * http://www.larentis.eu/switch/ + * ============================================================ + * Licensed under the Apache License, Version 2.0 + * http://www.apache.org/licenses/LICENSE-2.0 + * ============================================================ */ + +!function ($) { + "use strict"; + + $.fn['bootstrapSwitch'] = function (method) { + var inputSelector = 'input[type!="hidden"]'; + var methods = { + init: function () { + return this.each(function () { + var $element = $(this) + , $div + , $switchLeft + , $switchRight + , $label + , $form = $element.closest('form') + , myClasses = "" + , classes = $element.attr('class') + , color + , moving + , onLabel = "ON" + , offLabel = "OFF" + , icon = false + , textLabel = false; + + $.each(['switch-mini', 'switch-small', 'switch-large'], function (i, el) { + if (classes.indexOf(el) >= 0) + myClasses = el; + }); + + $element.addClass('has-switch'); + + if ($element.data('on') !== undefined) + color = "switch-" + $element.data('on'); + + if ($element.data('on-label') !== undefined) + onLabel = $element.data('on-label'); + + if ($element.data('off-label') !== undefined) + offLabel = $element.data('off-label'); + + if ($element.data('label-icon') !== undefined) + icon = $element.data('label-icon'); + + if ($element.data('text-label') !== undefined) + textLabel = $element.data('text-label'); + + $switchLeft = $('') + .addClass("switch-left") + .addClass(myClasses) + .addClass(color) + .html(onLabel); + + color = ''; + if ($element.data('off') !== undefined) + color = "switch-" + $element.data('off'); + + $switchRight = $('') + .addClass("switch-right") + .addClass(myClasses) + .addClass(color) + .html(offLabel); + + $label = $('