diff --git a/core/lib/Thelia/Command/GenerateResources.php b/core/lib/Thelia/Command/GenerateResources.php index 217672797..46924ac99 100644 --- a/core/lib/Thelia/Command/GenerateResources.php +++ b/core/lib/Thelia/Command/GenerateResources.php @@ -29,6 +29,7 @@ use Symfony\Component\Console\Output\OutputInterface; use Thelia\Command\ContainerAwareCommand; use Thelia\Model\Admin; +use Thelia\Model\Map\ResourceI18nTableMap; use Thelia\Model\Map\ResourceTableMap; class GenerateResources extends ContainerAwareCommand @@ -46,7 +47,7 @@ class GenerateResources extends ContainerAwareCommand 'output', null, InputOption::VALUE_OPTIONAL, - 'Output format amid (string, sql)', + 'Output format amid (string, sql, sql-i18n)', null ) ; @@ -55,7 +56,7 @@ class GenerateResources extends ContainerAwareCommand protected function execute(InputInterface $input, OutputInterface $output) { - $class = new \ReflectionClass('Thelia\Core\Event\AdminResources'); + $class = new \ReflectionClass('Thelia\Core\Security\Resource\AdminResources'); $constants = $class->getConstants(); @@ -69,12 +70,36 @@ class GenerateResources extends ContainerAwareCommand $output->writeln( 'INSERT INTO ' . ResourceTableMap::TABLE_NAME . ' (`id`, `code`, `created_at`, `updated_at`) VALUES ' ); + $compteur = 0; foreach($constants as $constant => $value) { if($constant == 'SUPERADMINISTRATOR') { continue; } + $compteur++; $output->writeln( - "(NULL, '$value', NOW(), NOW())" . ($constant === key( array_slice( $constants, -1, 1, TRUE ) ) ? '' : ',') + "($compteur, '$value', NOW(), NOW())" . ($constant === key( array_slice( $constants, -1, 1, true ) ) ? ';' : ',') + ); + } + break; + case 'sql-i18n': + $output->writeln( + 'INSERT INTO ' . ResourceI18nTableMap::TABLE_NAME . ' (`id`, `locale`, `title`) VALUES ' + ); + $compteur = 0; + foreach($constants as $constant => $value) { + if($constant == 'SUPERADMINISTRATOR') { + continue; + } + + $compteur++; + + $title = ucwords( str_replace('.', ' / ', str_replace('admin.', '', $value) ) ); + + $output->writeln( + "($compteur, 'en_US', '$title')," + ); + $output->writeln( + "($compteur, 'fr_FR', '$title')" . ($constant === key( array_slice( $constants, -1, 1, true ) ) ? ';' : ',') ); } break; diff --git a/core/lib/Thelia/Config/Resources/config.xml b/core/lib/Thelia/Config/Resources/config.xml index 493f9fbf8..9e7d86c3d 100755 --- a/core/lib/Thelia/Config/Resources/config.xml +++ b/core/lib/Thelia/Config/Resources/config.xml @@ -35,6 +35,7 @@ + diff --git a/core/lib/Thelia/Controller/Admin/BaseAdminController.php b/core/lib/Thelia/Controller/Admin/BaseAdminController.php index 186727ed5..fdbb6c1c4 100755 --- a/core/lib/Thelia/Controller/Admin/BaseAdminController.php +++ b/core/lib/Thelia/Controller/Admin/BaseAdminController.php @@ -128,7 +128,7 @@ class BaseAdminController extends BaseController } // Log the problem - $this->adminLogAppend("User is not granted for permissions %s", implode(", ", $permArr)); + $this->adminLogAppend("User is not granted for resources %s with accesses %s", implode(", ", $resources), implode(", ", $accesses)); // Generate the proper response $response = new Response(); diff --git a/core/lib/Thelia/Core/Security/AccessManager.php b/core/lib/Thelia/Core/Security/AccessManager.php index cdf7105a8..229c07a00 100644 --- a/core/lib/Thelia/Core/Security/AccessManager.php +++ b/core/lib/Thelia/Core/Security/AccessManager.php @@ -63,8 +63,9 @@ class AccessManager $this->accessValue = $accessValue; foreach($this->accessPows as $type => $value) { - if($accessValue >= $value) { - $accessValue -= $value; + $pow = pow(2, $value); + if($accessValue >= $pow) { + $accessValue -= $pow; $this->accessGranted[$type] = true; } else { $this->accessGranted[$type] = false; diff --git a/core/lib/Thelia/Core/Template/Loop/Admin.php b/core/lib/Thelia/Core/Template/Loop/Admin.php index fe4b280ad..378bcaf31 100755 --- a/core/lib/Thelia/Core/Template/Loop/Admin.php +++ b/core/lib/Thelia/Core/Template/Loop/Admin.php @@ -25,6 +25,7 @@ namespace Thelia\Core\Template\Loop; use Propel\Runtime\ActiveQuery\Criteria; use Thelia\Core\Template\Element\BaseI18nLoop; +use Thelia\Core\Template\Element\BaseLoop; use Thelia\Core\Template\Element\LoopResult; use Thelia\Core\Template\Element\LoopResultRow; @@ -44,7 +45,7 @@ use Thelia\Type\BooleanOrBothType; * @package Thelia\Core\Template\Loop * @author Etienne Roudeix */ -class Admin extends BaseI18nLoop +class Admin extends BaseLoop { public $timestampable = true; @@ -83,17 +84,17 @@ class Admin extends BaseI18nLoop $search->orderByFirstname(Criteria::ASC); /* perform search */ - $features = $this->search($search, $pagination); + $admins = $this->search($search, $pagination); - $loopResult = new LoopResult($features); + $loopResult = new LoopResult($admins); - foreach ($features as $feature) { - $loopResultRow = new LoopResultRow($loopResult, $feature, $this->versionable, $this->timestampable, $this->countable); - $loopResultRow->set("ID", $feature->getId()) - ->set("PROFILE",$feature->getProfileId()) - ->set("FIRSTNAME",$feature->getFirstname()) - ->set("LASTNAME",$feature->getLastname()) - ->set("LOGIN",$feature->getLogin()) + foreach ($admins as $admin) { + $loopResultRow = new LoopResultRow($loopResult, $admin, $this->versionable, $this->timestampable, $this->countable); + $loopResultRow->set("ID", $admin->getId()) + ->set("PROFILE",$admin->getProfileId()) + ->set("FIRSTNAME",$admin->getFirstname()) + ->set("LASTNAME",$admin->getLastname()) + ->set("LOGIN",$admin->getLogin()) ; $loopResult->addRow($loopResultRow); diff --git a/core/lib/Thelia/Core/Template/Loop/Auth.php b/core/lib/Thelia/Core/Template/Loop/Auth.php index f5691cbd6..cdb668978 100755 --- a/core/lib/Thelia/Core/Template/Loop/Auth.php +++ b/core/lib/Thelia/Core/Template/Loop/Auth.php @@ -23,6 +23,7 @@ namespace Thelia\Core\Template\Loop; +use Thelia\Core\Security\AccessManager; use Thelia\Core\Template\Element\BaseLoop; use Thelia\Core\Template\Element\LoopResult; use Thelia\Core\Template\Element\LoopResultRow; @@ -45,7 +46,7 @@ class Auth extends BaseLoop { return new ArgumentCollection( new Argument( - 'roles', + 'role', new TypeCollection( new AlphaNumStringListType() ), @@ -61,7 +62,7 @@ class Auth extends BaseLoop new Argument( 'access', new TypeCollection( - new EnumListType(array("view", "create", "update", "delete")) + new EnumListType(array(AccessManager::VIEW, AccessManager::CREATE, AccessManager::UPDATE, AccessManager::DELETE)) ) ), Argument::createAnyTypeArgument('context', 'front', false) @@ -75,7 +76,7 @@ class Auth extends BaseLoop */ public function exec(&$pagination) { - $roles = $this->getRoles(); + $roles = $this->getRole(); $resource = $this->getResource(); $access = $this->getAccess(); diff --git a/core/lib/Thelia/Core/Template/Loop/Profile.php b/core/lib/Thelia/Core/Template/Loop/Profile.php index a7a2e170e..4ac43d25a 100755 --- a/core/lib/Thelia/Core/Template/Loop/Profile.php +++ b/core/lib/Thelia/Core/Template/Loop/Profile.php @@ -79,20 +79,20 @@ class Profile extends BaseI18nLoop $search->orderById(Criteria::ASC); /* perform search */ - $features = $this->search($search, $pagination); + $profiles = $this->search($search, $pagination); - $loopResult = new LoopResult($features); + $loopResult = new LoopResult($profiles); - foreach ($features as $feature) { - $loopResultRow = new LoopResultRow($loopResult, $feature, $this->versionable, $this->timestampable, $this->countable); - $loopResultRow->set("ID", $feature->getId()) - ->set("IS_TRANSLATED",$feature->getVirtualColumn('IS_TRANSLATED')) + foreach ($profiles as $profile) { + $loopResultRow = new LoopResultRow($loopResult, $profile, $this->versionable, $this->timestampable, $this->countable); + $loopResultRow->set("ID", $profile->getId()) + ->set("IS_TRANSLATED",$profile->getVirtualColumn('IS_TRANSLATED')) ->set("LOCALE",$locale) - ->set("CODE",$feature->getCode()) - ->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("CODE",$profile->getCode()) + ->set("TITLE",$profile->getVirtualColumn('i18n_TITLE')) + ->set("CHAPO", $profile->getVirtualColumn('i18n_CHAPO')) + ->set("DESCRIPTION", $profile->getVirtualColumn('i18n_DESCRIPTION')) + ->set("POSTSCRIPTUM", $profile->getVirtualColumn('i18n_POSTSCRIPTUM')) ; $loopResult->addRow($loopResultRow); diff --git a/core/lib/Thelia/Core/Template/Loop/Resource.php b/core/lib/Thelia/Core/Template/Loop/Resource.php new file mode 100755 index 000000000..949cb5e00 --- /dev/null +++ b/core/lib/Thelia/Core/Template/Loop/Resource.php @@ -0,0 +1,115 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Core\Template\Loop; + +use Propel\Runtime\ActiveQuery\Criteria; +use Thelia\Core\Security\AccessManager; +use Thelia\Core\Template\Element\BaseI18nLoop; +use Thelia\Core\Template\Element\LoopResult; +use Thelia\Core\Template\Element\LoopResultRow; + +use Thelia\Core\Template\Loop\Argument\ArgumentCollection; +use Thelia\Core\Template\Loop\Argument\Argument; + +use Thelia\Model\ResourceQuery; +use Thelia\Type; +use Thelia\Type\BooleanOrBothType; + +/** + * + * Resource loop + * + * + * Class Resource + * @package Thelia\Core\Template\Loop + * @author Etienne Roudeix + */ +class Resource extends BaseI18nLoop +{ + public $timestampable = true; + + /** + * @return ArgumentCollection + */ + protected function getArgDefinitions() + { + return new ArgumentCollection( + Argument::createIntTypeArgument('profile') + ); + } + + /** + * @param $pagination + * + * @return \Thelia\Core\Template\Element\LoopResult + */ + public function exec(&$pagination) + { + $search = ResourceQuery::create(); + + /* manage translations */ + $locale = $this->configureI18nProcessing($search); + + $profile = $this->getProfile(); + + if (null !== $profile) { + $search->leftJoinProfileResource('profile_resource') + ->withColumn('profile_resource.access', 'access'); + //$search->filterById($id, Criteria::IN); + } + + $search->orderById(Criteria::ASC); + + /* perform search */ + $resources = $this->search($search, $pagination); + + $loopResult = new LoopResult($resources); + + foreach ($resources as $resource) { + $loopResultRow = new LoopResultRow($loopResult, $resource, $this->versionable, $this->timestampable, $this->countable); + $loopResultRow->set("ID", $resource->getId()) + ->set("IS_TRANSLATED",$resource->getVirtualColumn('IS_TRANSLATED')) + ->set("LOCALE",$locale) + ->set("CODE",$resource->getCode()) + ->set("TITLE",$resource->getVirtualColumn('i18n_TITLE')) + ->set("CHAPO", $resource->getVirtualColumn('i18n_CHAPO')) + ->set("DESCRIPTION", $resource->getVirtualColumn('i18n_DESCRIPTION')) + ->set("POSTSCRIPTUM", $resource->getVirtualColumn('i18n_POSTSCRIPTUM')) + ; + + if (null !== $profile) { + $accessValue = $resource->getVirtualColumn('access'); + $manager = new AccessManager($accessValue); + $loopResultRow->set("VIEWABLE", $manager->can(AccessManager::VIEW)) + ->set("CREATABLE", $manager->can(AccessManager::CREATE)) + ->set("UPDATABLE", $manager->can(AccessManager::UPDATE)) + ->set("DELETABLE", $manager->can(AccessManager::DELETE)); + } + + $loopResult->addRow($loopResultRow); + } + + return $loopResult; + } +} diff --git a/install/insert.sql b/install/insert.sql index 80ab5a844..b4b7a764f 100755 --- a/install/insert.sql +++ b/install/insert.sql @@ -1193,7 +1193,6 @@ INSERT INTO `order_status_i18n` (`id`, `locale`, `title`, `description`, `chapo` (5, 'en_US', 'Canceled', '', '', ''), (5, 'fr_FR', 'Annulée', '', '', ''); - /** generated with command : php Thelia thelia:generate-resources --output sql */ @@ -1220,4 +1219,55 @@ INSERT INTO resource (`id`, `code`, `created_at`, `updated_at`) VALUES (NULL, 'admin.configuration.profile', NOW(), NOW()), (NULL, 'admin.configuration.shipping-zone', NOW(), NOW()), (NULL, 'admin.configuration.tax', NOW(), NOW()), -(NULL, 'admin.configuration.template', NOW(), NOW()) +(NULL, 'admin.configuration.template', NOW(), NOW()); + +/** +generated with command : php Thelia thelia:generate-resources --output sql-i18n + */ +INSERT INTO resource_i18n (`id`, `locale`, `title`) VALUES +(1, 'en_US', 'Address'), +(1, 'fr_FR', 'Address'), +(2, 'en_US', 'Configuration / Admin'), +(2, 'fr_FR', 'Configuration / Admin'), +(3, 'en_US', 'Configuration / Area'), +(3, 'fr_FR', 'Configuration / Area'), +(4, 'en_US', 'Configuration / Attribute'), +(4, 'fr_FR', 'Configuration / Attribute'), +(5, 'en_US', 'Category'), +(5, 'fr_FR', 'Category'), +(6, 'en_US', 'Configuration'), +(6, 'fr_FR', 'Configuration'), +(7, 'en_US', 'Content'), +(7, 'fr_FR', 'Content'), +(8, 'en_US', 'Configuration / Country'), +(8, 'fr_FR', 'Configuration / Country'), +(9, 'en_US', 'Coupon'), +(9, 'fr_FR', 'Coupon'), +(10, 'en_US', 'Configuration / Currency'), +(10, 'fr_FR', 'Configuration / Currency'), +(11, 'en_US', 'Customer'), +(11, 'fr_FR', 'Customer'), +(12, 'en_US', 'Configuration / Feature'), +(12, 'fr_FR', 'Configuration / Feature'), +(13, 'en_US', 'Folder'), +(13, 'fr_FR', 'Folder'), +(14, 'en_US', 'Configuration / Language'), +(14, 'fr_FR', 'Configuration / Language'), +(15, 'en_US', 'Configuration / Mailing-system'), +(15, 'fr_FR', 'Configuration / Mailing-system'), +(16, 'en_US', 'Configuration / Message'), +(16, 'fr_FR', 'Configuration / Message'), +(17, 'en_US', 'Configuration / Module'), +(17, 'fr_FR', 'Configuration / Module'), +(18, 'en_US', 'Order'), +(18, 'fr_FR', 'Order'), +(19, 'en_US', 'Product'), +(19, 'fr_FR', 'Product'), +(20, 'en_US', 'Configuration / Profile'), +(20, 'fr_FR', 'Configuration / Profile'), +(21, 'en_US', 'Configuration / Shipping-zone'), +(21, 'fr_FR', 'Configuration / Shipping-zone'), +(22, 'en_US', 'Configuration / Tax'), +(22, 'fr_FR', 'Configuration / Tax'), +(23, 'en_US', 'Configuration / Template'), +(23, 'fr_FR', 'Configuration / Template'); diff --git a/templates/admin/default/admin-layout.tpl b/templates/admin/default/admin-layout.tpl index 743264d7a..3d671ecb2 100644 --- a/templates/admin/default/admin-layout.tpl +++ b/templates/admin/default/admin-layout.tpl @@ -44,7 +44,7 @@ {* display top bar only if admin is connected *} - {loop name="top-bar-auth" type="auth" roles="ADMIN"} + {loop name="top-bar-auth" type="auth" role="ADMIN"} {* -- Brand bar section ------------------------------------------------- *} @@ -107,13 +107,13 @@ {intl l="Home"} - {loop name="menu-auth-customer" type="auth" roles="ADMIN" permissions="admin.customers.view"} + {loop name="menu-auth-customer" type="auth" role="ADMIN" resource="admin.customer" access="VIEW"}
  • {intl l="Customers"}
  • {/loop} - {loop name="menu-auth-order" type="auth" roles="ADMIN" permissions="admin.orders.view"} + {loop name="menu-auth-order" type="auth" role="ADMIN" resource="admin.order" access="VIEW"} {/loop} - {loop name="menu-auth-catalog" type="auth" roles="ADMIN" permissions="admin.catalog.view"} + {loop name="menu-auth-catalog" type="auth" role="ADMIN" resource="admin.category" access="VIEW"}
  • {intl l="Catalog"}
  • {/loop} - {loop name="menu-auth-content" type="auth" roles="ADMIN" permissions="admin.folders.view"} + {loop name="menu-auth-content" type="auth" role="ADMIN" resource="admin.folder" access="VIEW"}
  • {intl l="Folders"}
  • {/loop} - {loop name="menu-auth-coupon" type="auth" roles="ADMIN" permissions="admin.coupon.view"} + {loop name="menu-auth-coupon" type="auth" role="ADMIN" resource="admin.coupon" access="VIEW"}
  • {intl l="Coupons"}
  • {/loop} - {loop name="menu-auth-config" type="auth" roles="ADMIN" permissions="admin.config.view"} + {loop name="menu-auth-config" type="auth" role="ADMIN" resource="admin.config" access="VIEW"}
  • {intl l="Configuration"}
  • {/loop} - {loop name="menu-auth-modules" type="auth" roles="ADMIN" permissions="admin.modules.view"} + {loop name="menu-auth-modules" type="auth" role="ADMIN" resource="admin.module" access="VIEW"}
  • {intl l="Modules"}
  • @@ -174,7 +174,7 @@ {/loop} - {loop name="top-bar-search" type="auth" roles="ADMIN" permissions="admin.search"} + {loop name="top-bar-search" type="auth" role="ADMIN" resource="admin.search" access="VIEW"}