prevent merging two module config in Zend Framework 2 - php

I have two module in my ZF2 application, both module have different configuration for themself, and both module have different Module.php with different configruation inside it.
I have a login process for Admin, which is defined in Module.php like below:
in onBootstrap funtion:
public function onBootstrap($e) {
$e->getApplication()->getEventManager()->getSharedManager()->attach('Zend\Mvc\Controller\AbstractActionController', 'dispatch', function($e) {
$controller = $e->getTarget();
$controllerClass = get_class($controller);
$moduleNamespace = substr($controllerClass, 0, strpos($controllerClass, '\\'));
if ('Admin' === $moduleNamespace) {
$controller->layout('layout/admin');
}
}, 100);
$application = $e->getApplication();
$eventManager = $application->getEventManager();
..........
..........
$eventManager->attach(MvcEvent::EVENT_DISPATCH, array($this, 'boforeDispatch'), 100);
}
boforeDispatch function which is called inside the onBootstrap for login process check
function boforeDispatch(MvcEvent $event) {
......
//did something
......
}
Whenever I am going to run Front module, Admin module's function beforeDispatch is running. I also tried to define another function inside Front module with no content inside so that it could not merge it.
2
I have written different 404 template for both module, but Front's template is running. Here is the code.:
'view_manager' => array(
'display_not_found_reason' => true,
'display_exceptions' => true,
'doctype' => 'HTML5',
'not_found_template' => 'error/404',
'exception_template' => 'error/index',
'template_map' => array(
'layout/front' => __DIR__ . '/../view/layout/layout.phtml',
'front/index/index' => __DIR__ . '/../view/front/index/index.phtml',
'error/404' => __DIR__ . '/../view/error/404.phtml',
'error/index' => __DIR__ . '/../view/error/index.phtml',
),
'template_path_stack' => array(
__DIR__ . '/../view',
),
),
both's files are inside its module folder with same structure.
Q: How to prevent merging one module configuration from another?

You shouldn't prevent merging. There is a similar problem with loading different layout for 2 modules - take a look https://stackoverflow.com/a/11921330/949273
Unfortunately, Your issue is a bit contradictory because if you got a 404 page, there is no way to know what module is that - because of that it's called 404 page not found.
Anyway you can dispatch MvcEvent::EVENT_DISPATCH_ERROR event and check with regular expression URL and set different view file.
Code example
in your admin module config
'template_map' => array(
'error-admin/404' => __DIR__ . '/../view/error/404.phtml',
),
than on EVENT_DISPATCH_ERROR inject your logic
public function onBootstrap(MvcEvent $e)
{
$app = $e->getTarget();
$em = $app->getEventManager();
$em->attach(MvcEvent::EVENT_DISPATCH_ERROR, function (\Zend\Mvc\MvcEvent $e) {
$app = $e->getParam('application');
$uri = $app->getRequest()->getUri()->getPath();
if(strpos($uri, '/admin') === 0){
$view = new \Zend\View\Model\ViewModel();
$view->setTemplate('error-admin/404');
$e->setViewModel($view);
}
});
}

After lots of search I got the solution of my question.
Main problem was getting the Module name. here is my code.
I generated it with the help of MvcEvent::getRouteMatch()->getParam()
function boforeDispatch(MvcEvent $event) {
$controller = $event->getRouteMatch()->getParam('controller');
$request_module = substr($controller, 0, strpos($controller, '\\'));
if ($request_module == __NAMESPACE__) {
//do stuff
}
}

Related

Why i do not gain performance using ClassMapAutoloader in Zend Framework 2?

In my company we developing a ZF2 application, no programm;-), right now. We are at a point where we want to test some part of the application by bringing it into the public www.
We prepared a STAGE-environment and i do some performance tuning now. I read that using the ClassMapAutoloader is much faster than the StandardAutoLoader like described e.g. http://samminds.com/2012/11/zf2-performance-quicktipp-2-classmap-autoloading/ . I do understand why it should be faster but in my case i profiled the site with and without ClassMapAutoloader using xdebug profiling, WinCacheGring/QCacheGrind and it is slower about 0,2%.
Does anyone has an idea why this could be slower?
I am using CentOS and PHP Version => 5.6.12
EDIT ADDED INFORMATION:
Example of one autoload_classmap.php:
<?php
// Generated by ZF2's ./bin/classmap_generator.php
return array(
'Search\Elasticsearch\Document\AbstractDocument' => __DIR__ . '/src/Search/Elasticsearch/Document/AbstractDocument.php',
'Search\Elasticsearch\Document\ArticleDocument' => __DIR__ . '/src/Search/Elasticsearch/Document/ArticleDocument.php',
'Search\Elasticsearch\Document\BookingDocument' => __DIR__ . '/src/Search/Elasticsearch/Document/BookingDocument.php',
'Search\Elasticsearch\Document\DocumentType' => __DIR__ . '/src/Search/Elasticsearch/Document/DocumentType.php',
'Search\Elasticsearch\Document\InvoiceDocument' => __DIR__ . '/src/Search/Elasticsearch/Document/InvoiceDocument.php',
'Search\Elasticsearch\Document\OfficeDocument' => __DIR__ . '/src/Search/Elasticsearch/Document/OfficeDocument.php',
'Search\Elasticsearch\Document\OfficeMemberDocument' => __DIR__ . '/src/Search/Elasticsearch/Document/OfficeMemberDocument.php',
'Search\Elasticsearch\Document\ProductDocument' => __DIR__ . '/src/Search/Elasticsearch/Document/ProductDocument.php',
'Search\Elasticsearch\Document\ProfileDocument' => __DIR__ . '/src/Search/Elasticsearch/Document/ProfileDocument.php',
'Search\Elasticsearch\Document\RatingDocument' => __DIR__ . '/src/Search/Elasticsearch/Document/RatingDocument.php',
'Search\Elasticsearch\Document\AbstractWebSearchDocument' => __DIR__ . '/src/Search/Elasticsearch/Document/AbstractWebSearchDocument.php',
'Search\Elasticsearch\AutoSuggestionQueryHandler' => __DIR__ . '/src/Search/Elasticsearch/AutoSuggestionQueryHandler.php',
'Search\Elasticsearch\SearchStatisticIndexHandler' => __DIR__ . '/src/Search/Elasticsearch/SearchStatisticIndexHandler.php',
'Search\Elasticsearch\TermRecognizerQueryHandler' => __DIR__ . '/src/Search/Elasticsearch/TermRecognizerQueryHandler.php',
'Search\Elasticsearch\SearchIndexHandler' => __DIR__ . '/src/Search/Elasticsearch/SearchIndexHandler.php',
'Search\Elasticsearch\SearchQueryHandler' => __DIR__ . '/src/Search/Elasticsearch/SearchQueryHandler.php',
'Search\Elasticsearch\TermRecognizerIndexHandler' => __DIR__ . '/src/Search/Elasticsearch/TermRecognizerIndexHandler.php',
'Search\Exception\Exception' => __DIR__ . '/src/Search/Exception/Exception.php',
'Search\Factory\AutoSuggestQueryHandlerFactory' => __DIR__ . '/src/Search/Factory/AutoSuggestQueryHandlerFactory.php',
'Search\Factory\AutoSuggestServiceFactory' => __DIR__ . '/src/Search/Factory/AutoSuggestServiceFactory.php',
'Search\Factory\DocumentStorerServiceFactory' => __DIR__ . '/src/Search/Factory/DocumentStorerServiceFactory.php',
'Search\Factory\QueueWorkerServiceFactory' => __DIR__ . '/src/Search/Factory/QueueWorkerServiceFactory.php',
'Search\Factory\SearchIndexHandlerFactory' => __DIR__ . '/src/Search/Factory/SearchIndexHandlerFactory.php',
'Search\Factory\SearchQueryHandlerFactory' => __DIR__ . '/src/Search/Factory/SearchQueryHandlerFactory.php',
'Search\Factory\SearchServiceFactory' => __DIR__ . '/src/Search/Factory/SearchServiceFactory.php',
'Search\Factory\SearchSimpleServiceFactory' => __DIR__ . '/src/Search/Factory/SearchSimpleServiceFactory.php',
'Search\Factory\SearchStatistikIndexHandlerFactory' => __DIR__ . '/src/Search/Factory/SearchStatistikIndexHandlerFactory.php',
'Search\Factory\TermRecognizerServiceFactory' => __DIR__ . '/src/Search/Factory/TermRecognizerServiceFactory.php',
'Search\Factory\TermrecognizerIndexHandlerFactory' => __DIR__ . '/src/Search/Factory/TermrecognizerIndexHandlerFactory.php',
'Search\Factory\TermrecognizerQueryHandlerFactory' => __DIR__ . '/src/Search/Factory/TermrecognizerQueryHandlerFactory.php',
'Search\Factory\RequestHandlerFactory' => __DIR__ . '/src/Search/Factory/RequestHandlerFactory.php',
'Search\Logger\LoggerInterface' => __DIR__ . '/src/Search/Logger/LoggerInterface.php',
'Search\Logger\StatisticLogger' => __DIR__ . '/src/Search/Logger/StatisticLogger.php',
'DatabaseQueue' => __DIR__ . '/src/Search/Queue/DatabaseQueue.php',
'Search\Search\QueryWordReducer' => __DIR__ . '/src/Search/Search/QueryWordReducer.php',
'Search\Search\RecognizedTermConsumer' => __DIR__ . '/src/Search/Search/RecognizedTermConsumer.php',
'Search\Search\SearchService' => __DIR__ . '/src/Search/Search/SearchService.php',
'Search\Search\SuggestionListBuilder' => __DIR__ . '/src/Search/Search/SuggestionListBuilder.php',
'Search\Search\Util' => __DIR__ . '/src/Search/Search/Util.php',
'Search\Search\ViewState' => __DIR__ . '/src/Search/Search/ViewState.php',
'Search\Search\ViewStateToSearchRequestTransformer' => __DIR__ . '/src/Search/Search/ViewStateToSearchRequestTransformer.php',
'Search\Search\SearchSimpleService' => __DIR__ . '/src/Search/Search/SearchSimpleService.php',
'Search\AutoSuggester' => __DIR__ . '/src/Search/AutoSuggester.php',
'Search\QueryCleaner' => __DIR__ . '/src/Search/QueryCleaner.php',
'Search\Request' => __DIR__ . '/src/Search/Request.php',
'Search\RequestHandler' => __DIR__ . '/src/Search/RequestHandler.php',
'Search\SearchSource' => __DIR__ . '/src/Search/SearchSource.php',
'Search\Util' => __DIR__ . '/src/Search/Util.php',
'Search\QueueWorker' => __DIR__ . '/src/Search/QueueWorker.php',
'Search\AbstractDocumentStorer' => __DIR__ . '/src/Search/AbstractDocumentStorer.php',
'Search\DocumentStorer' => __DIR__ . '/src/Search/DocumentStorer.php',
'Search\TermRecognizer' => __DIR__ . '/src/Search/TermRecognizer.php',
'Search\Module' => __DIR__ . '/Module.php',
);
Extract from the correlating Module.php:
public function getAutoloaderConfig() {
return [
'Zend\Loader\ClassMapAutoloader' => [
__DIR__ . '/autoload_classmap.php'
],
'Zend\Loader\StandardAutoloader' => [
'namespaces' => [
__NAMESPACE__ => __DIR__ . '/src/' . str_replace('\\', '/', __NAMESPACE__)
]
]
];
}
I checked already that the Autoloader uses the classmap.
EDIT ADDED INFORMATION:
Sorry for the late answer. Right now your app loads for half a second - 0.6s to be precise. So I the autoloader is doing his works. Your queries are also executed fast. There are two more ways I can think of to speed up your applications.
First way - using template map
Locate your templatemap_generator.php file. It should be in your vendor/zendframework/zendframework/bin folder. Navigate to your module folder e.g. Application directory where the src, view, config folders are. Open a terminal and type php ../../vendor/zendframework/zendframework/bin/templatemap_generator.php ZF will create a template map in your module directory. Now to use this template, simply modify your module.config.php file. The file structure is similar to the one from clasmap_autoloader.php
return array(
// Telling where the views are
'view_manager' => array(
'display_not_found_reason' => true,
'display_exceptions' => true,
'doctype' => 'HTML5',
'not_found_template' => 'error/404',
'exception_template' => 'error/index',
'template_map' => include __DIR__ . '/../template_map.php', // <-- add this line. You can remove `template_path_stack`
),
In your controllersfor each action add a view template.
public indexAction()
{
$view = new ViewModel();
$view->setTemplate("aplication/index/index");
return $view;
}
Second way - Using module cache in production environment.
Let's say you have this line in your .htaccess - SetEnv APPLICATION_ENV "development"
In your public/index.php file if you haven't done something similar, add this:
/**
* Set global ENV. Used for debugging
*/
if (isset($_SERVER['APPLICATION_ENV']) && $_SERVER["APPLICATION_ENV"] === 'development') {
define("APP_ENV", 'development');
} else {
define("APP_ENV", "production");
}
This will ensure that you have a global env across your application which says if debugging is on or off and it helps you avoid DRY code.
Now from your root folder open config/application.config.php
<?php
$modules = [];
if (APP_ENV === 'development') {
$modules[] = 'ZendDeveloperTools';
$modules[] = 'BjyProfiler';
$modules[] = 'SanSessionToolbar';
}
$modules[] = 'Application';
$modules[] = 'Admin';
return [
// This should be an array of module namespaces used in the application.
'modules' => $modules,
// These are various options for the listeners attached to the ModuleManager
'module_listener_options' => [
// This should be an array of paths in which modules reside.
// If a string key is provided, the listener will consider that a module
// namespace, the value of that key the specific path to that module's
// Module class.
'module_paths' => [
'./module',
'./vendor',
],
// An array of paths from which to glob configuration files after
// modules are loaded. These effectively override configuration
// provided by modules themselves. Paths may use GLOB_BRACE notation.
'config_glob_paths' => [
'config/autoload/{{,*.}global,{,*.}local}.php',
],
// Whether or not to enable a configuration cache.
// If enabled, the merged configuration will be cached and used in
// subsequent requests.
'config_cache_enabled' => (APP_ENV === 'production'),
// The key used to create the configuration cache file name.
'config_cache_key' => md5('app_config'),
// Whether or not to enable a module class map cache.
// If enabled, creates a module class map cache which will be used
// by in future requests, to reduce the autoloading process.
'module_map_cache_enabled' => (APP_ENV === 'production'),
// The key used to create the class map cache file name.
'module_map_cache_key' => md5('module_map'),
// The path in which to cache merged configuration.
'cache_dir' => dirname(__DIR__)."/data/cache",
// Whether or not to enable modules dependency checking.
// Enabled by default, prevents usage of modules that depend on other modules
// that weren't loaded.
'check_dependencies' => (APP_ENV !== 'production'),
],
// Used to create an own service manager. May contain one or more child arrays.
//'service_listener_options' => [
// [
// 'service_manager' => $stringServiceManagerName,
// 'config_key' => $stringConfigKey,
// 'interface' => $stringOptionalInterface,
// 'method' => $stringRequiredMethodName,
// ],
// )
// Initial configuration with which to seed the ServiceManager.
// Should be compatible with Zend\ServiceManager\Config.
// 'service_manager' => [],
];
config_cache_* will activate and cache your route config when your app is in production. All your module routes will be cached. Also If the website is in production the debugging modules will not be loaded.
You can replace md5('app_config') with whatever you want.

Adding custom library in zend framework 2 (2.3) in layout template

I have a problem. I want to add my custom library when the webapplication starts and i want use it in application layout. I want to create a form (composed by 2 concatenated select with ajax functions) and it must be visible in all parts of the application. when i tried to use my helper custom library, this is the error message:
Fatal error: Class 'SelectSearchList' not found in C:\Program Files (x86)\xampp\htdocs\Easyanimal\module\Application\view\layout\layout.phtml on line 118
this is the code of vendor/composer/autoload_namespaces.php:
<?php
// autoload_namespaces.php generated by Composer
$vendorDir = dirname(__DIR__);
$baseDir = dirname($vendorDir);
return array(
'Zend\\' => $vendorDir . '/zendframework/zendframework/library/',
'ZendTest\\' => $vendorDir . '/zendframework/zendframework/tests/',
'MyHelpLib\\' => $vendorDir . '/MyHelpLib/',
);
this is my help library in vendor/MyHelpLib/LoaderSelect.php:
namespace MyHelpLib
class SelectSearchList {
public $select;
public function showOpt (){
return $select = '<option value="">Select...</option>';
}
}
and this my layout in application/view/layout
<?php
use MyHelpLib\LoaderSelect;
$Opt = new SelectSearchList();
echo $Opt->showOpt();
?>
i tried to add this in Application/module.php but it isn't work again!
public function getAutoloaderConfig()
{
return array(
'Zend\Loader\StandardAutoloader' => array(
'namespaces' => array(
__NAMESPACE__ => __DIR__ . '/src/' . __NAMESPACE__,
'MyHelpLib' => __DIR__ . '/../../vendor/MyHelpLib',
),
),
);
}
thanks so much for the help
Create view helper. http://framework.zend.com/manual/2.3/en/modules/zend.view.helpers.advanced-usage.html#writing-custom-helpers
Index\src\View\Helper\MyHelpLib
namespace Index\View\Helper;
use Zend\View\Helper\AbstractHelper;
class MyHelpLib extends AbstractHelper
{
public function __invoke()
{
return 'MyHelper'
}
}
Index\config\module.config.php
return array(
...
'view_helpers' => array(
'invokables' => array(
'MyHelpLib' => '\Index\View\Helper\MyHelpLib'
)
)
);
layout.phtml
echo $this->MyHelpLib();

hide database password in zend framework 2

I have a zend project which makes use of doctrine2.
My problem is that I can't disable errors with sensitive data. (i.e. when database connection fails an error is shown including the password).
What I have tried so far is changing the index.php file in the public folder as follows:
<?php
//Disable all error reporting
error_reporting(0); //Somehow this doesn't work
ini_set('display_errors', false); //Somehow this doesn't work
/**
* This makes our life easier when dealing with paths. Everything is relative
* to the application root now.
*/
chdir(dirname(__DIR__));
// Decline static file requests back to the PHP built-in webserver
if (php_sapi_name() === 'cli-server' && is_file(__DIR__ . parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH))) {
return false;
}
// Setup autoloading
require 'init_autoloader.php';
// Run the application!
try{
Zend\Mvc\Application::init(require 'config/application.config.php')->run();
}
catch(Exception $ex){
echo 'server error!';//This code is never reached although a PDOException is thrown!
}
What do I need to do to disable these kind of errors and hide sensitive data?
Check this out -> http://www.php.net/manual/en/pdo.connections.php Particularly the Warning Notice.
Using a Try / Catch in the index file isn't going to work for you. You'll need to put that into your Service Layer or where-ever else you are doing your DB Queries at (you didn't supply this code example).
You can also in your module.config.php file set:
'display_exceptions' => false
Also pay attention to the Exception handler you are using as different one could return different information.
Seems I had to change the view_manager configuration in my_project_folder/module/Application/config/module.config.php, by setting display_exceptions to false:
'view_manager' => array(
'display_not_found_reason' => true,
'display_exceptions' => false, //This line did the trick!
'doctype' => 'HTML5',
'not_found_template' => 'error/404',
'exception_template' => 'error/index',
'template_map' => array(
'layout/layout' => __DIR__ . '/../view/layout/layout.phtml',
'application/index/index' => __DIR__ . '/../view/application/index/index.phtml',
'error/404' => __DIR__ . '/../view/error/404.phtml',
'error/index' => __DIR__ . '/../view/error/index.phtml',
),
'template_path_stack' => array(
__DIR__ . '/../view',
),
),
EDIT: Didn't catch that this was ZEND 2. See my last comment below.
I am guessing the error level reporting is set with this line
Zend\Mvc\Application::init(require 'config/application.config.php')->run();
which is after you turn it off, so it is simply getting switched back on again.
Try this in application.ini
phpSettings.display_startup_errors = 0
phpSettings.display_errors = 0
resources.frontController.throwExceptions = 0
resources.frontController.params.displayExceptions = 0

Added template map dynamic in ZF2

I must hard code to add new layout. Then i want find some way to add template map dynamic in ZF2.
My module.config.php
'view_manager' => array (
'display_not_found_reason' => true,
'display_exceptions' => true,
'doctype' => 'HTML5',
'not_found_template' => 'error/404',
'exception_template' => 'error/index',
'template_map' => array (
'layout/layout' => __DIR__ . '/../../../template/layout/layout.phtml',
'layout/custom' => __DIR__ . '/../../../template/layout/custom.phtml',
'error/404' => __DIR__ . '/../../../template/error/404.phtml',
'error/index' => __DIR__ . '/../../../template/error/index.phtml'
),
'template_path_stack' => array (
__DIR__ . '/../view/'
)
)
And I set new layout by this way
$e->getApplication()->getEventManager()->getSharedManager()->attach('Zend\Mvc\Controller\AbstractActionController', 'dispatch', function($e) {
$controller = $e->getTarget();
$controller->layout('template_name');
}, 100);
Please lets me some advise/sample
Thanks !
==================
Update 12/08/2012:
I found the solution for this and apply to my "hierarchy template system"
Modify module.config.php
'template_path_stack' => array (
__DIR__ . '/../view/',
__DIR__ . '/../../../' //Parent folder of template path
)
In Module.php added :
$e->getApplication()->getEventManager()->getSharedManager()->attach('Zend\Mvc\Controller\AbstractActionController', 'dispatch', function($e) {
$controller = $e->getTarget();
$controllerClass = get_class($controller);
//Get routing info
$controllerArr = explode('\\', $controllerClass);
$currentRoute = array(
'module' => strtolower($controllerArr[0]),
'controller' => strtolower(str_replace("Controller", "", $controllerArr[2])),
'action' => strtolower($controller->getEvent()->getRouteMatch()->getParam('action'))
);
//Get curr route
$currAction = implode('/',$currentRoute);
$currController = $currentRoute['module'] . '/' . $currentRoute['controller'];
$currModule = $currentRoute['module'];
//Template file location
$templatePath = __DIR__ .'/../../template/';
//Set template
$template = 'layout/layout'; // Default template
if (file_exists($templatePath . $currAction.'.phtml')) {
$template = $currAction;
}else if(file_exists($templatePath . $currController.'.phtml')) {
$template = $currController;
}else if(file_exists($templatePath . $currModule.'.phtml')) {
$template = $currModule;
}else{
if($currentRoute['controller']=='admin'){
$template = 'admin/layout'; // Admin default template
}
}
$controller->layout('template/'.$template); //Pevert duplicate layout
}, 100);
Note: If you set the key same variable between your 'layout' and 'view'. It will render duplicate the 'layout' and don't understand your current view
In your controller when you create a new viewmodel you can set the template you've created there.
public function someAction() {
$viewModel = new ViewModel();
$viewModel->setTemplate('layout/custom');
return $viewModel;
}
Just make sure the layout.phtml file is in the path you set in your template_map

Translate Validation Messages in Silex

Code:
$app->register(new Silex\Provider\TranslationServiceProvider(), array(
'locale' => 'sr_Latn',
'translation.class_path' => __DIR__ . '/../vendor/symfony/src',
'translator.messages' => array('sr_Latn' => __DIR__ .'/../vendor/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/translations/validators.sr_Latn.xlf')
));
$app['translator.loader'] = new Symfony\Component\Translation\Loader\XliffFileLoader();
and I still get validation messages in english. any idea?
You need to add a call to Translator::addResource:
$file = __DIR__ .'/../vendor/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/translations/validators.sr_Latn.xlf';
$app['translator']->addResource('xliff', $file, 'sr_Latn', 'validators');
See also Symfony\Bundle\FrameworkBundle\DependencyInjection::registerTranslatorConfiguration.

Categories