ZF2 - ZfcUser unable to change view scripts - zend-framework2

I'm very new to Zend Framework. I can't manage to override the view scripts of the ZfcUser module. I downloaded ZfcUser into the vendor directory. And I made the custom module and changed the routing. However, no luck changing the viewscripts.
I changed the url to profile instead of user. And made these configurations to include the override of the view scripts. However I am still getting the default scripts from the vendors folder. Would truly appreciate your help.
<?php
namespace Profile;
use Zend\Mvc\MvcEvent;
class Module
{
public function getConfig()
{
return array (
'router' => array (
'routes' => array (
'zfcuser' => array (
'options' => array (
'route' => '/profile',
),
),
),
),
'view_manager' => array(
'template_path_stack' => array(
'profile' => __DIR__ . '/../view',
),
),
);
}
}
And here's an image of the directory

Ok here's how I got it fixed.. seems like it's nowhere in the documentation but it worked. I changed the view manager to look like this:
'zfcuser' => __DIR__ . '/view',
instead of
'profile' => __DIR__ . '/../view',
The only issue is that all the view scripts have to be imported in the custom module and overridden. Here's the results from the Module.php file in the custom module.
<?php
namespace Profile;
use Zend\Mvc\MvcEvent;
class Module
{
public function getConfig()
{
return array (
'router' => array (
'routes' => array (
'zfcuser' => array (
'options' => array (
'route' => '/profile',
),
),
),
),
'view_manager' => array(
'template_path_stack' => array(
'zfcuser' => __DIR__ . '/view',
),
),
);
}
}

Related

ZF2 translator is not working in controller?

I am trying to translate in the controller by ServiceLocator, but this is not translating and I have tried many sulotions in stackoverflow but with out success. My system uses multiple languages and my goal is to use transtor in view, controller, form and filter. Tranlator in my view is working. Any sugestion and help will be appreciated.
Not working in controller:
$this->getServiceLocator()->get('translator')->translate('my text',$myLocale);
My Application mudole.config.php:
'service_manager' => array(
'abstract_factories' => array(
'Zend\Cache\Service\StorageCacheAbstractServiceFactory',
'Zend\Log\LoggerAbstractServiceFactory',
),
'factories' => array(
'translator' => 'Zend\I18n\Translator\TranslatorServiceFactory',
),
),
'translator' => array(
'locale' => 'en_US',// 'locale' => 'dk_DK',
'translation_file_patterns' => array(
array(
'type' => 'gettext',
'base_dir' => __DIR__ . '/../language',
'pattern' => '%s.mo',
),
),
),
I changed the local in mudole.config.php to another language but still not translating.
View Helper/Forms
ZF2 ships with the view helper Zend\I18n\View\Helper\Translate; this is why you can already use the method $this->translate($text) in the view.
However all view helper classes that extend from Zend\I18n\View\Helper\AbstractTranslatorHelper (which includes all form view helpers) are also 'translation capable'.
You would need to pass in the translator using $viewHelper->setTranslator($translator) and enabling translation via $viewHelper->setTranslatorEnabled(true).
Controller Plugin
Unfortunately there is no default plugin (that I could find) to handle translators in controllers; I guess you could argue that text content shouldn't be in the controller anyway.
You could easily create one such as the example below. The key is to pass your new translator service as a dependency via a factory.
namespace MyModule\Controller\Plugin;
use Zend\Mvc\Controller\AbstractPlugin;
use Zend\I18n\Translator\Translator as TranslatorService;
class Translator extends AbstractPlugin
{
protected $translatorService;
public function __construct(TranslatorService $translatorService)
{
$this->translatorService = $translatorService;
}
public function invoke($text = null, array $options = [])
{
if (null == $text) {
return $this;
}
return $this->translate($text, $options);
}
public function translate($text, array $options = [])
{
return $this->translatorService->translate($text);
}
}
And create the factory class.
namespace MyModule\Controller\Plugin;
use MyModule\Controller\Plugin\Translator;
use Zend\ServiceManager\ServiceLocatorInterface;
use Zend\ServiceManager\FactoryInterface;
class TranslatorFactory implements FactoryInterface
{
public function createService(ServiceLocatorInterface $controllerPluginManager)
{
$serviceManager = $controllerPluginManager->getServiceLocator();
return new Translator($serviceManager->get('translator'));
}
}
Register the service in module.config.php.
return [
'controller_plugins' => [
'factories' => [
'translate' => 'MyModule\\Controller\\Plugin\\TranslateFactory',
]
],
];
Then you can just call it within a controller class.
// Directly
$this->translate($text, $options);
// Or fetch the plugin first
$this->translate()->translate($text, $options);
It seems that the locale is sets not directly in the translating text, but by $this->getServiceLocator()->get('translator')->setLocale($locale), and now it is translating my text.
My Application mudole.config.php:
'service_manager' => array(
'factories' => array(
'translator' => 'Zend\I18n\Translator\TranslatorServiceFactory',
),
),
'translator' => array(
'locale' => 'en_US',
'translation_file_patterns' => array(
array(
'type' => 'gettext',
'base_dir' => __DIR__ . '/../language',
'pattern' => '%s.mo',
),
),
),
And in the controller:
$this->getServiceLocator()->get('translator')->setLocale($locale);
echo $c=$this->getServiceLocator()->get('translator')->translate('Book'); // Print(Danish): Bog
You can use my ZfTranslate controller plugin.
installation
composer require mikica/zf2-translate-plugin
You need to register new module. Add in file config/application.config.php:
'modules' => array(
'...',
'ZfTranslate'
),
Usage in controller
<?php
$this->translate('translate word');
$this->translate('translate word', 'locale');
AlexP answer is the best way to do it.
But remains a question, why your way doesn't work?
It should work. But it doesn't because you are in different namespaces, so you are using distinct domains among the files. You doing something like that:
namespace MyModule\Controller;
class MyController {
public function someAction() {
$this->getServiceLocator()->get('translator')->translate('my text',__NAMESPACE__,$myLocale);
}
}
While at your `module.config.php', you probably using this namespace:
namespace MyModule;
return array(
//...
'translator' => array(
//...
),
);
Note that in the example of the controller __NAMESPACE__ is equals MyModule\Controller. While at the config file the __NAMESPACE__ is equals MyModule. You need to fix it, passing the same value in both cases.
In other words, there are several approachs to solve this, like AlexP's, for instance. But, any one of them need to have the domain of translator (the value of the 'text_domain' key) when you configure it equals the domain parameter (second paramater) of the translate method when you call it.
The faster solution is changing the $domain parameter to string at the controller file:
$this->getServiceLocator()->get('translator')->translate('my text','MyModule',$myLocale);
Another solution should be creating a constant and using it at the files (controllers, views and config).

ZF2: Zend Framework 2.3.0: Fatal Error: class IndexController not found

I'm studying the Zend Framework by building a tutorial application.
I've checked my code a couple of times comparing it to the source code
of the book.
I can't come up with a solution or explanation as to why
this error keeps occuring. Can anyone help me out?
Fatal error: Class 'Wall\Controller\IndexController' not found in C:\xampp\htdocs\Connect\client\vendor\zendframework\zendframework\library\Zend\ServiceManager\AbstractPluginManager.php on line 170
Call Stack
# Time Memory Function
1 0.0010 138824 {main}( ) ..\index.php:0
2 0.1250 4071920 Zend\Mvc\Application->run( ) ..\index.php:12
3 0.1260 4090064 Zend\EventManager\EventManager->trigger( ) ..\Application.php:316
4 0.1260 4090072 Zend\EventManager\EventManager->triggerListeners( ) ..\EventManager.php:207
5 0.1270 4091280 call_user_func ( ) ..\EventManager.php:468
6 0.1270 4091568 Zend\Mvc\DispatchListener->onDispatch( ) ..\EventManager.php:468
7 0.1270 4091752 Zend\Mvc\Controller\ControllerManager->get( ) ..\DispatchListener.php:97
8 0.1270 4091936 Zend\ServiceManager\AbstractPluginManager->get( ) ..\ControllerManager.php:137
9 0.1270 4091904 Zend\ServiceManager\ServiceManager->get( ) ..\AbstractPluginManager.php:103
10 0.1270 4092584 Zend\ServiceManager\ServiceManager->create( ) ..\ServiceManager.php:504
11 0.1270 4092728 Zend\ServiceManager\ServiceManager->doCreate( ) ..\ServiceManager.php:572
12 0.1270 4092816 Zend\ServiceManager\AbstractPluginManager->createFromInvokable( ) ..\ServiceManager.php:616
module.config.php
return array(
'router' => array(
'routes' => array(
'wall' => array(
'type' => 'Zend\Mvc\Router\Http\Segment',
'options' => array(
'route' => '/:username',
'constraints' => array(
'username' => '\w+'
),
'defaults' => array(
'controller' => 'Wall\Controller\Index',
'action' => 'index',
),
),
),
),
),
'controllers' => array(
'invokables' => array(
'Wall\Controller\Index' => 'Wall\Controller\IndexController',
),
),
'view_manager' => array(
'template_path_stack' => array(
__DIR__ . '/../view',
),
),
);
module.php
namespace Wall;
use Zend\Mvc\ModuleRouteListener;
use Zend\Mvc\MvcEvent;
class Module
{
public function getConfig()
{
return include __DIR__ . '/config/module.config.php';
}
public function getAutoloaderConfig()
{
return array(
'Zend\Loader\StandardAutoloader' => array(
'namespaces' => array(
__NAMESPACE__ => __DIR__ . '/src/' , __NAMESPACE__
),
),
);
}
}
IndexController.php
namespace Wall\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\Stdlib\Hydrator\ClassMethods;
use Users\Entity\User;
use Api\Client\ApiClient as ApiClient;
class IndexController extends AbstractActionController
{
public function indexAction()
{
$viewData = array();
$username = $this->params()->fromRoute('username');
$this->layout()->username = $username;
$response = ApiClient::getWall($username);
if ($response !== FALSE) {
$hydrator = new ClassMethods();
$user = $hydrator->hydrate($response, new User());
} else {
$this->getResponse()->setStatusCode(404);
return;
}
$viewData['profileData'] = $user;
return $viewData;
}
}
The error is highly likely within your autoloading configuration
public function getAutoloaderConfig()
{
return array(
'Zend\Loader\StandardAutoloader' => array(
'namespaces' => array(
__NAMESPACE__ => __DIR__ . '/src/' , __NAMESPACE__
// ^-- that should be a DOT .
),
),
);
}

Chaining Dependency Injection in ZF2

I am trying to create a simple email templating test in ZF2, I am using Dependency injection in order to create an instance of the PhpRenderer class, with all the dependencies set.
It appears that I may be struggling with chaining the injections as the path 'email' is not present in the AggregateResolver.
inside module.config.php
'di' => array(
'instance' => array(
'Zend\View\Resolver\TemplatePathStack' => array(
'options' => array(
'script_paths' => array(
'email' => __DIR__ . '/../view/application/email',
),
),
),
'Zend\View\Resolver\AggregateResolver' => array(
'attach' => array(
'Zend\View\Resolver\TemplatePathStack',
),
),
'Zend\View\Renderer\PhpRenderer' => array(
'setResolver' => 'Zend\View\Resolver\AggregateResolver',
),
),
),
inside TestController.php
$di = new \Zend\Di\Di;
$renderer = $di->get('Zend\View\Renderer\PhpRenderer');
$content = $renderer->render('email/test', null);
echo($content);
Message:
Zend\View\Renderer\PhpRenderer::render: Unable to render template "email/test"; resolver could not resolve to a file
Any help would be gratefully received.
Since writing the above, I was playing around and removed the TemplatePathStack from the di array and this had no effect at all, So I am not sure it is being used at all by the AggregateResolver, so it may be a chaining issue:
'di' => array(
'instance' => array(
/*'Zend\View\Resolver\TemplatePathStack' => array(
'addPaths' => array(
'paths' => array(
'email' => __DIR__ . '/../view/application/email',
),
),
),*/
'Zend\View\Resolver\AggregateResolver' => array(
'attach' => array(
'Zend\View\Resolver\TemplatePathStack',
),
),
'Zend\View\Renderer\PhpRenderer' => array(
'setResolver' => 'Zend\View\Resolver\AggregateResolver',
),
),
),
Aborgrove
In the end I solved it by moving the di array out of the module.conf.php and recreating it in the Module getServiceConf() method. (Although I am not sure this is the best place to put it)
public function getServiceConfig()
{
return array(
'factories' => array(
// using the Session Manger to create one instance of the follwing models
......... more code here ............
'EmailTemplatePathStack' => function($sm) {
$template_path_stack = new \Zend\View\Resolver\TemplatePathStack();
$paths = array('emailfolder' => __DIR__ . '/view/application/email');
$template_path_stack->addPaths($paths);
return $template_path_stack;
},
'EmailAggregateResolver' => function($sm) {
$resolver = new \Zend\View\Resolver\AggregateResolver();
$resolver->attach($sm->get('EmailTemplatePathStack'));
var_dump($resolver);
return $resolver;
},
'EmailPhpRenderer' => function($sm) {
$php_renderer = new \Zend\View\Renderer\PhpRenderer();
$php_renderer->setResolver($sm->get('EmailAggregateResolver'));
return $php_renderer;
},
),
);
}
Then changing the controller to:
$sm = \Application\Model\ServiceLocatorFactory::getInstance();
$renderer = $sm->get('EmailPhpRenderer');
$content = $renderer->render('test.phtml', null);
echo($content);

ZF2 autoloading custom modules with composer

I'm trying to setup a ZF2 project (slightly different from the zf2skeleton) and I want to use composer to deal with all the autoloading, not only from the vendor ones (installed through composer) but also those modules I create.
For some reason, i can't get access to my Application module Index controller. I think its the autoloading that's not working... I just don't know what i might be doing wrong..
Thanks!
Files and data below:
This is my folder structure:
index.php
private
- modules
-- Aplication
--- src
----- Aplication
------- Controller
---------- IndexController.php
- vendor
-- zendframework
-- composer
-- autoload.php
- composer.json
- composer.phar
main.config.php
return array(
'modules' => array(
'Application',
),
'module_listener_options' => array(
'config_glob_paths' => array(
'private/config/autoload/{,*.}{global,local}.php',
),
'cache_dir' => realpath(dirname(__DIR__) . '/../../data/cache'),
'module_paths' => array(
realpath(__DIR__ . '/../module'),
realpath(__DIR__ . '/../vendor'),
),
),
);
index.php
include_once 'private/vendor/autoload.php';
$application = Zend\Mvc\Application::init(include 'private/config/main.config.php');
return $application;
composer.json
{
"repositories": [
{
"type": "composer",
"url": "http://packages.zendframework.com/"
}
],
"require": {
"php": ">=5.3.3",
"zendframework/zendframework": "2.*"
},
"autoload": {
"psr-0": {
"Application\\": "module/Application/src"
}
}
}
Application config
return array(
'router' => array(
'routes' => array(
'home' => array(
'type' => 'Zend\Mvc\Router\Http\Literal',
'options' => array(
'route' => '/',
'defaults' => array(
'controller' => 'Application\Controller\Index',
'action' => 'index',
),
),
),
),
),
'controllers' => array(
'invokables' => array(
'Application\Controller\Index' => 'Application\Controller\IndexController'
),
),
);
IndexController
namespace Application\Controller;
use Zend\Mvc\Controller\AbstractActionController;
class IndexController extends AbstractActionController {
public function indexAction() {
die("app ok");
}
}
First, from what I see, you don't run your application :
$application = Zend\Mvc\Application::init(include 'private/config/main.config.php');
$application->run();
Another point is that, you don't have to use composer to load your modules. As your application config already include the module directory, the Module loading process will automatically scan the directory and use the loading strategy defined at the level your Module classes.

ServiceNotFoundException in ZendFramework 2, example from Rob Allen

for the past few weeks I have been following ZF2 especially Rob Allen's 'Album' example , I have created the example DB-'zf2tutorial' and example table-'album', which works fine fetching all the items when I use php-mysql, so problems with the data in the DB.
My local.php looks like this
config.autoload/local.php:
return array(
'db' => array
(
'driver' => "Pdo",
'dsn' => "mysql:dbname=zf2tutorial;hostname=localhost",
'username' => "user", //here I added my valid username
'password' => "password", //here I added my valid password
'driver_options' => array
(
PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'UTF8'"
),
),
);
Module.php
**module/Album/Model.php
<?php
namespace Album;
use Album\Model\AlbumTable;
class Module
{
public function getAutoloaderConfig()
{
return array(
'Zend\Loader\ClassMapAutoloader' => array(
__DIR__ . '/autoload_classmap.php',
),
'Zend\Loader\StandardAutoloader' => array(
'namespaces' => array(
__NAMESPACE__ => __DIR__ . '/src/' . __NAMESPACE__,
),
),
);
}
public function getConfig()
{
return include __DIR__ . '/config/module.config.php';
}
public function getServiceConfiguration()
{
return array(
'factories' => array(
'album-table' => function($sm) //also tried this 'Album\Model\AlbumTable' => function($sm)
{
$dbAdapter = $sm->get('db-adapter');//also tried this $dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
$table = new AlbumTable($dbAdapter);
return $table;
},
),
);
}
}
I just wanted to check whether the zf2turorial/album works or not it does throw this error which is similar to this post here in stackoverlow.
The error which it is throwing is:
Additional information:
Zend\ServiceManager\Exception\ServiceNotFoundException
File:
..\vendor\zendframework\zendframework\library\Zend\ServiceManager\ServiceManager.php:392
Message:
Zend\ServiceManager\ServiceManager::get was unable to fetch or create an instance for Album\Model\AlbumTable
I have followed ZF2 Beta 5 tutorial as well, but still encountering this problem. In case if anyone has a solution, please do share with us.
Thanks
seems like somebody has forgotten to update the newest changes in zf2.
the solution:
the file module/Album/Module.php has to contain this content:
<?php
namespace Album;
use Album\Model\AlbumTable;
use Zend\ModuleManager\Feature\ServiceProviderInterface;
class Module implements ServiceProviderInterface
then you have to rename
public function getServiceConfig()
to
public function getServiceConfiguration()
public function getServiceConfiguration() is not the correct function name
rename getServiceConfiguration() to getServiceConfig()
although it is not mandatory you should declare the class Module as
class Module implements ServiceProviderInterface
I am not sure but try to put the code into
config.autoload/global.php: like this way
return array(
'db' => array(
'driver' => 'Pdo',
'dsn' => 'mysql:dbname=kd_tutorial;host=localhost',
'driver_options' => array(
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''
),
),
'service_manager' => array(
'factories' => array(
'Zend\Db\Adapter\Adapter'
=> 'Zend\Db\Adapter\AdapterServiceFactory',
),
),
);
I have encoutered the same problem when try to implement code follow zend tutorial. The main reason is order-folder
module
ModuleX
config
src
ModuleX //may be you forget this one
Controller
Factory
Model
...
view
Module.php
in Module.php, getConfig(), getAutoloaderConfig() is enough to run
class Module implements AutoloaderProviderInterface, ConfigProviderInterface{
public function getAutoloaderConfig(){
return array(
'Zend\Loader\StandardAutoloader' => array(
'namespaces' => array(
__NAMESPACE__ => __DIR__ . '/src/' . __NAMESPACE__,
),
),
);
}
public function getConfig(){
return include __DIR__ . '/config/module.config.php';
}
Modify config/autoload/global.php with following code:
return array(
'db' => array(
'driver' => 'Pdo',
'dsn' => 'mysql:dbname=YourDBName;host=localhost',
'driver_options' => array(
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''
),
),
'service_manager' => array(
'factories' => array(
'Zend\Db\Adapter\Adapter'
=> 'Zend\Db\Adapter\AdapterServiceFactory',
),
),
);
and You should put your database credentials in config/autoload/local.php so that they are not in the git repository (as local.php is ignored):
return array(
'db' => array(
'username' => 'YourDBUsername',
'password' => 'YourDBPassword',
),
);
If you want more details refer link1 or link2
Just got the same issue.
Zend\ServiceManager\Exception\ServiceNotFoundException: Zend\ServiceManager\ServiceManager::get was unable to fetch or create an instance for Cache\Model\UniversityStorage
In my case the problem was, that PHPUnit could not find the key Cache\Model\UniversityStorage in the service manager (registry) because it's being added in the Module class of the Cache module and the Cache module was missing in the PHPUnit config file and was also not being loaded:
/module/Application/test/phpunit.config.php
<?php
return array(
'modules' => array(
'Application',
'Cache', // <- was missing
),
'module_listener_options' => array(
'config_glob_paths' => array(
'../../../config/autoload/{,*.}{global,local}.php',
),
'module_paths' => array(
'module',
'vendor',
),
),
);
I've added the Cache module to the module list. Now it works.
The problem is that within config/autoload/global.php the service is named "Zend\Db\Adapter\Adapter" while within module/Album/Module.php it was searching for "Zend\Db\Adapter" (missing additional \Adapter).
Adding missing "\Adapter" within module/Album/Module.php like this fixed it for me.
'AlbumTableGateway' => function($sm) {
$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
In module/Album/src/Album/Model/Album.php, use instead:
array('name' => 'striptags'),
array('name' => 'stringtrim'),
See the above namespaces created by Zend at vendor/zendframework/zendframework/library/Zend/Filter/FilterPluginManager.php
If you are getting similar error for different modules and the code seems jus right then ADD an entry in composer.json
"Album\": "module/Album/src/"
in autoload and autoload-dev section like this where Album is the name of your Module
"autoload": {
"psr-4": {
"Application\\": "module/Application/src/",
"Album\\": "module/Album/src/"
}
},
"autoload-dev": {
"psr-4": {
"ApplicationTest\\": "module/Application/test/",
"Album\\": "module/Album/src/"
}
},
after this run "composer update" and reload the page. check if error is gone.

Resources