I am wondering if it possible to configure some of the shop’s options when enabling a theme.
Let me explain, I am already generating a config.xml in the root of the theme zip to enable/disable some modules or hooks. But I want to do more.
Indeed, I would like to be able to, for example, enable the CCC “Move JavaScript to the end” when the theme.
I see that some themes (including the community theme) include a config.xml inside the theme folder. I often see stuff like <ccc available="true" />.
But I’m not sure it does anything. Does it do anything?
I can’t find any reference for that config.xml file, is there any way to achieve what I want?
Using the latest Prestashop 1.6.
Those lines check configuration values but only when <ccc available="false" />.
So if you have <ccc available="true" /> you are saying that your theme is CCC compatible and it doesn't matter if the shop has CCC enabled or not.
If you set that to false, the installation will check if settings related to CCC are disabled, otherwise it will throw an error to the user that their CCC configurations will not work with your theme.
You can see feature definitions here.
'ccc' => array(
'attributes' => array(
'available' => array(
'value' => 'true',
/*
* accepted attribute value if value doesn't match, prestashop configuration value must have those values
*/
'check_if_not_valid' => array(
'PS_CSS_THEME_CACHE' => 0,
'PS_JS_THEME_CACHE' => 0,
'PS_HTML_THEME_COMPRESSION' => 0,
'PS_JS_HTML_THEME_COMPRESSION' => 0,
),
),
),
'error' => 'This theme may not correctly use PrestaShop\'s "combine, compress and cache" options.',
'tab' => 'AdminPerformance',
)
So if you set in your config.xml <ccc available="false" /> it will check that all four configurations in check_if_not_valid array are set to 0, otherwise it's gonna throw out an error message This theme may not correctly use PrestaShop's "combine, compress and cache" options..
As for configuring settings on theme install, I don't see a way to do it with xml config without overriding AdminThemesController class but I'm guessing you want to distribute this theme so overriding is not an option.
What you could do though is install a simple configuration setter module along with the theme that hooks to displayAfterThemeInstallation.
public function hookDisplayAfterThemeInstallation($params)
{
$theme_name = $params['theme_name'];
if ($theme_name != 'mythemename') {
return false;
}
// Enable Move JS to bottom setting
Configuration::updateValue('PS_JS_DEFER', 1);
// Optional text or html to display
return 'Your settings have been changed';
}
Related
I am using yii2-formwizard and I want to insert a checkbox as form input field for the field is_legal in a tabular step. So in fieldConfig array, reading the documentation, I inserted the following code:
'is_legal' => [
'options' => [
'type' => 'checkbox',
'template' => '{input}{beginLabel}{labelTitle}{endLabel}{error}{hint}',
],
'labelOptions' => ['label' => \Yii::t('app', 'Legal Representative')],
],
If I select the checkbox or not the value of the field is always 1 as shown on: .
However, when I add another instance of the model, in the preview step I have NA as value of the legal representative field :
Yes, you are correct about it. It incorrectly shows the value even if the check box is not checked i have updated the section and added a fix.
//check if single checkbox input
if (inputType.attr("type") == 'checkbox') {
return inputType.is(":checked") ? inputType.val() : '';
}
To get the latest code you need to repeat the steps for running composer using,
composer update
and clear the browser cache along with clearing the assets folder in the web directory.
Normally when i am working locally with extensions or if there is an update for an extension which includes javascript updates i add the following settings under the components array in my local config file that takes care of getting the latest files from, and the assets are force copied every time to the web/assets/ directory whenever you refresh the browser or the page reloads.
'components'=>[
'assetManager' => [
'forceCopy' => true,
],
]
Note: Dont leave it open on live site as it would make the page load slower.
I'm using URL manager like the following:
'urlManager' => [
'enablePrettyUrl' => true,
'showScriptName' => false,
'rules' => [
'verses/view/<id:\d+>' => 'verses/view',
],
],
It works fine to make access using mysite.com/verses/view/158. The problem is, it is still possible to access the same content using non pretty URL i.e using plain get parameter such as mysite.com/verses/view?id=158. I need any way to restrict the access using the pretty URL.
I have tried the following couples of rules separately, but nothing I have gotten:
'verses/view<?id=>' => 'Error404',
'verses/view?id=<\d+>' => 'Error404',
What is the point of such restriction?
Anyway, one way to do it is something like this:
public function actionView($id)
{
if (strpos(\Yii::$app->request->getUrl(), '?') !== false) {
throw new \yii\web\BadRequestHttpException;
}
// ... the rest of action
}
No changes in UrlManager needed.
Try using UrlManager parameter enableStrictParsing = true.
What happens. UrlManager checks all rulls and they all do not match the request. Thus, by default it checks all default rules. Among default rules it finds the rule with ?id= and preforms routing to that one.
So, in order to avoid that route, you need to list all possible routes in the UrlManger rules and make enableStrictParsing = true. The routes not listed in the config rules parameter will be ignored.
Im relatively new to the Yii framework. I'm trying to get leaflet extension to work on my project. I installed it via composer and everything seems to be installed properly but when I try to insert it into an activeForm it throws me this error:
The file or directory to be published does not exist: /vendor/bower/leaflet/dist
Im trying to build a Geosearch field with a map.
The extensions I have installed are:
"2amigos/yii2-leaflet-extension": "~1.0",
"2amigos/yii2-leaflet-geocoder-plugin": "~1.0",
"2amigos/yii2-leaflet-geosearch-plugin": "~1.0"
This is my code on the ActiveForm (its just the same as the provided on GitHub):
use dosamigos\leaflet\layers\TileLayer;
use dosamigos\leaflet\LeafLet;
use dosamigos\leaflet\types\LatLng;
use dosamigos\leaflet\plugins\geosearch\GeoSearch;
use dosamigos\leaflet\widgets\Map;
<?php
$center = new LatLng(['lat' => 39.67442740076734, 'lng' => 2.9347229003906246]);
$geoSearchPlugin = new GeoSearch([
'service' => GeoSearch::SERVICE_OPENSTREETMAP
]);
$tileLayer = new TileLayer([
'urlTemplate' => 'link not allowed because its one of my first posts...',
'clientOptions' => [
'attribution' => 'Tiles Courtesy of MapQuest ' . ', ' . 'Map data © OpenStreetMap contributors, ' . 'CC-BY-SA', 'subdomains' => '1234'
]
]);
$leafLet = new LeafLet([
'name' => 'geoMap',
'tileLayer' => $tileLayer,
'center' => $center,
'zoom' => 10,
'clientEvents' => [ // setting up one of the geo search events for fun
'geosearch_showlocation' => 'function(e){ console.log(e.target); }'
]
]);
// add the plugin
$leafLet->installPlugin($geoSearchPlugin);
// run the widget (you can also use Map::widget([...]))
echo $leafLet->widget();
?>
Is there something I'm missing or doing wrong?
Thanks in advanced
Your problem is that the original Leaflet js and css files are no longer available through Bower, and 2amigos have not changed their composer file to reflect the changes. Yii is attempting to publish a css file from the requested location, and the file doesn't yet exist, hence the error message. You'll either need to go to the original Leaflet repository and copy the relevant files into the required directories, or update the composer file to point to the original files on GitHub. Sorry, I don't know enough about composer to be able to help with this bit!
In a ZF2 application I have some cofigs, that: 1. need to be different dependening on the environment; 2. are specific for a concrete module. I'm curently using it like here described:
global.php & local.php
return array(
...
'modules' => array(
'Cache' => array(
'ttl' => 1, // 1 second
)
)
...
);
Module class
Module {
...
public function getServiceConfig() {
try {
return array (
'factories' => array(
'Zend\Cache\Adapter\MemcachedOptions' => function ($serviceManager) {
return new MemcachedOptions(array(
'ttl' => $this->getConfig()['modules']['Cache']['ttl'],
...
));
},
...
)
);
}
...
}
...
}
It's working fine, but I believe, that the module specific settings should be accessed over one central place in the module -- the getConfig() method of the Module class. Like this:
class Module {
public function getConfig() {
$moduleConfig = include __DIR__ . '/config/module.config.php';
$application = $this->getApplicationSomehow(); // <-- how?
$applicationModuleConfig = $application->getConfig()['modules'][__NAMESPACE__];
$config = array_merge($moduleConfig, $applicationModuleConfig);
return $config;
}
...
public function getServiceConfig() {
try {
return array (
'factories' => array(
'Zend\Cache\Adapter\MemcachedOptions' => function ($serviceManager) {
return new MemcachedOptions(array(
'ttl' => $serviceManager->get('Config')['modules']['Cache']['ttl'],
...
));
},
...
)
);
}
...
}
...
}
The problem is, that I don't get, how to access the global.php/local.php configs in the getConfig() of a module. How can I do it?
Every single configuration of every single loaded Module will be merged into one single config. Namely this would be:
$serviceManager->get('config');
The reason behind (global|local).config.php is merely for usage purpose. Global configuration files should always be deployed. Local configuration files however should only be deployed as distributionables, alias local.config.php.dist.
Distributionals will not be loaded, no matter where they are places. However common notion of ZF2 is to copy the distributionables into the /config/autoload-directory of the ZF2 Application and rename them to local.config.php
One example:
// YourModule/config/module.config.php
return array(
'key' => 1337
);
// YourModule/config/local.yourmodule.php.dist
return array(
'key' => 7331
);
Now when you publish / deploy your application, only module.config.php will be used. If someone wants to change the configuration of your Module, they would never touch module.config.php, as this file would constantly be overwritten when your module will be updated.
However what people can do is to copy:
YourModule/config/local.yourmodule.php.dist
to
/config/autoload/local.yourmodule.php
And change the config values inside this local configuration.
To understand:
You should always configure your module as best as possible for a LIVE-Scenario.
If you have environment-specific needs, overwrite this config using a local-config
local configs are never deployed automatically, this is a manual task needing to be done from inside the environment itself
Hope this got a little more clear
Ultimately:
configure your module for a LIVE-Scenario
On your development machine create a /config/autoload/mymodule.local.php and overwrite your ttl with it's development value
LoadOrder:
The last interesting part, which i have completely forgotten about, would be the load order of the configuration files. As all files are merged, this is important to note!
First to load is /config/application.config.php
Second to load would be each Modules /modules/{module}/config/module.config.php *
Last but not least the autoloadable files will be loaded /config/autoload/{filename}.php
asterix It is actually NOT module.config.php which is called, but rather the Module-classes configuration functions. Mainly these are:
getConfig()
getServiceConfig()
getViewHelperConfig()
ultimately everything under Zend\ModuleManager\Feature\{feature}ProviderInterface
If i understand this part of the ConfigListener correctly, then getConfig() will be called first and all of the specialiced {feature}ProviderInterfaces will overwrite the data of getConfig(), but don't take this for granted, it would need a check!
You're not supposed to access other Modules setting in your Module#getConfig(). If you rely on other configuration, that CAN ONLY BE for service purposes. Ergo you'd rely on Module#getServiceConfig() and inside the factories you do have access to the ServiceManagerand access your configs with $serviceManager->get('config');. (see Sam's comment)
The loading order of the configs is by default:
/config/application.config.php, that is the initial config file; not for module configs; here is the filename pattern for the config files to load defined ('config_glob_paths' => array('config/autoload/{,*.}{global,local}.php')).
{ModuleNamespace}\Module#getConfig() (e.g. Cache\Module#getConfig()), that by convention should load its /module/{ModuleNamespace}/config/module.config.php;
/config/autoload/global.php, that should not contain any module specific configs (see below);
/config/autoload/local.php, that contains environment specific settings also should not contain any module specific configs (see below); it should not versioned/deployed;
/config/autoload/{ModuleNamespaceLowerCased}.local.php (e.g. cache.local.php), that contains only the module AND environment specific settings and should not be versioned/;
For the Cache module above there can be following config files:
/module/Cache/config/module.config.php -- a complete set of module configs; loaded by Cache\Module#getConfig()
/module/Cache/config/cache.local.php.dist -- an example for /config/autoload/cache.local.php
/config/autoload/cache.local.php -- environment specific module configs
The setting ttl can be accessed from any place, where one has access to the Service Locator. For example in factory methods of Cache\Module#getServiceConfig()
class Module {
public function getConfig() {
$moduleConfig = include __DIR__ . '/config/module.config.php';
$application = $this->getApplicationSomehow(); // <-- how?
$applicationModuleConfig = $application->getConfig()['modules'][__NAMESPACE__];
$config = array_merge($moduleConfig, $applicationModuleConfig);
return $config;
}
...
public function getServiceConfig() {
try {
return array (
'factories' => array(
'Zend\Cache\Adapter\MemcachedOptions' => function ($serviceManager) {
return new MemcachedOptions(array(
'ttl' => $serviceManager->get('Config')['ttl'],
...
));
},
...
)
);
}
...
}
...
}
For futher information about how configs are managed in ZF2 see Sam's answer and blog article.
I have been following this guide to load my menu configuration and i think it is very nice and clean way to load the menu.
My question is simple, is there a way to load your ACL configuration on the same way with a config array and some kinda of factory?
If there isn't, how do i load a ACL configuration and use with that menu in a easy way?
Thanks!
Edit:
This is a very good blog post on why use modules that is already done and not make your own, http://hounddog.github.com/blog/there-is-a-module-for-that/
ZF2 contains ACL and also RBAC (role based ACL - might be in ZF2.1), but to put it in place, easier is to use module which you can plug into your application. BjyAuthorize seems to me a bit bloated, you have to use ZfcUser module. I prefer ZfcRbac, the ACL rules are based on user roles (group) and their access to controller, action or route. Configuration stored in one config file, really easy to implement.
Most likely there are several ways to do it, but I prefer to do it in getViewHelperConfig() of application's Module.php (here I use BjyAuthorize module to simplify work with ACL, and in particular it allows to set ACL rules in configuration file module.bjyauthorize.global.php)
public function getViewHelperConfig()
{
return array(
'factories' => array(
'navigation' => function($sm) {
$auth = $sm->getServiceLocator()->get('BjyAuthorize\Service\Authorize');
$role = $auth->getIdentityProvider()->getIdentityRoles();
if (is_array($role))
$role = $role[0];
$navigation = $sm->get('Zend\View\Helper\Navigation');
$navigation->setAcl($auth->getAcl())->setRole($role);
return $navigation;
}
)
);
}
Play with This structure . get role and resource from database and save this in session for or any caching .
You are right, there is no out-of-the-box-all-in-one solution. You have to build some bridges between the modules.
Another easy way to integrate BjyAuthorize is using **Zend Navigation**s default methods as described by Rob Allen:
Integrating BjyAuthorize with ZendNavigation
$sm = $e->getApplication()->getServiceManager();
// Add ACL information to the Navigation view helper
$authorize = $sm->get('BjyAuthorizeServiceAuthorize');
$acl = $authorize->getAcl();
$role = $authorize->getIdentity();
ZendViewHelperNavigation::setDefaultAcl($acl);
ZendViewHelperNavigation::setDefaultRole($role);
You can also use ZfcRbac and use a listener to make it work with Zend Navigation.
Since this is a lot of code I simply post the link here:
Check Zend Navigation page permissions with ZfcRbac – Webdevilopers Blog
I've just created an ACL module that creates an ACL Service parsing the routes.
To manage your access control to your application you only need to define roles and add a new key 'roles' in every route. If you do not define that key or its array is empty, then the route becomes public. It also works with child routes.
As an example:
array(
'router' => array(
'routes' => array(
'user\users\view' => array(
'type' => 'Segment',
'options' => array(
'route' => '/admin/users/view/id/:id/',
'constraints' => array(
'id' => '[0-9]+',
),
'defaults' => array(
'controller' => 'User\Controller\Users',
'action' => 'view',
'roles' => ['admin', 'user'],
),
),
),
),
),
);
The module can be installed via composer and it is now listed in the zend modules repository: http://zfmodules.com/itrascastro/TrascastroACL
You can get more detailed info about use and installation from my blog: http://www.ismaeltrascastro.com/acl-module-zend-framework/