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.
Related
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).
When i try to start album application an error message appears:
Fatal error: Class 'Album\Controller\AlbumController' not found in
C:\xampp\htdocs\ZendSkeletonApplication\vendor\zendframework\zendframework\library\Zend\ServiceManager\AbstractPluginManager.php
on line 170
This is my module.config.php file code
<?php
return array(
'controllers' => array(
'invokables' => array(
'Album\Controller\Album' => 'Album\Controller\AlbumController',
),
),
// Added to make router
'router' => array(
'routes' => array(
'album' => array(
'type' => 'segment',
'options' => array(
'route' => '/album[/][:action][/:id]',
'constraints' => array(
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'id' => '[0-9]+'
),
'defaults' => array(
'controller' => 'Album\Controller\Album',
'action' => 'index',
),
),
),
),
),
'view_manager' => array(
'template_path_stack' => array(
'album' => __DIR__ . '/../view',
),
),
);
And this is AlbumController.php file code:
<?php
namespace Album\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
class AlbumController extends AbstractActionController {
protected $albumTable;
public function indexAction() {
return new ViewModel(array(
'album' => $this->getAlbumTable()->fetchAll(),
));
}
public function addAction() {
}
public function editAction() {
}
public function deleteAction() {
}
public function getAlbumTable () {
if (!$this->albumTable) {
$sm = $this->getServiceLocator();
$this->albumTable = $sm->get('Album\Model\AlbumTable');
}
return $this->albumTable;
}
}
i see you are just getting started, so i would refer to this code by Martin Shwalbe and find out if you have any typo. If everything looks good, then you probably have issue in the way you are accessing it.
https://github.com/Hounddog/Album
hope this helps...
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',
),
),
);
}
}
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);
This is the Rob Allen's Quick start Tutorial for Zend Framework beta4.
Error Message:Zend\ServiceManager\ServiceManager::get was unable to fetch or create an instance for album-table
It seems like it fails trying to make a connection to the db, but I have not found way to tell. It's uses a closure to return an instance from the ServiceManager, but gets the above error message.
module/Album/Module.php
namespace Album;
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()
{
$albumTable = array(
'factories' => array(
'album-table' => function($sm) {
$dbAdapter = $sm->get('db-adapter');
$table = new AlbumTable($dbAdapter);
return $table;
},
),
);
return $albumTable;
}
}
namespace Application;
use Zend\Db\Adapter\Adapter as DbAdapter,
class Module
{
public function getConfig()
{
return include __DIR__ . '/config/module.config.php';
}
public function getServiceConfiguration()
{
$factoryDBAdaptor = array(
'factories' => array(
'db-adapter' => function($sm) {
$config = $sm->get('config');
$config = $config['db'];
$dbAdapter = new DbAdapter($config);
return $dbAdapter;
},
),
);
return $factoryDBAdaptor;
}
}
config\autoload\global.php
return array(
'db' => array(
'driver' => 'PDO',
'dsn' => 'mysql:dbname=zf2tutorial;hostname=localhost',
'username' => 'user',
'password' => 'password',
'driver_options' => array(
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''
),
),
);
It's related to the fact that Zend Framework's master has changed since Beta 4 and so my beta 4-targeted tutorial no longer works with latest ZF master.
Also, the SM may have previous exceptions, so you should check if there are any previous exceptions as that may show an underlying error.
Update
As of 11th July 2012, my tutorial is now updated for Beta 5. It now uses the Db Adapter's ServiceFactory to create the adapter and so you don't even need to modify Application's Module class any more.
Make sure the main Module.php has a reference the getServiceConfiguration(). I had the same problem and had forgotten to include it.
module/Application/Module.php:
<?php
namespace Application;
use Zend\Db\Adapter\Adapter as DbAdapter;
class Module
{
public function getConfig()
{
return include __DIR__ . '/config/module.config.php';
}
public function getServiceConfiguration()
{
return array(
'factories' => array(
'db-adapter' => function($sm) {
$config = $sm->get('config');
$config = $config['db'];
$dbAdapter = new DbAdapter($config);
return $dbAdapter;
},
),
);
}
}
update your composer.json file with following line.
"zendframework/zendframework": "dev-master#18c8e223f070deb07c17543ed938b54542aa0ed8"
run following commands you will be good to go.
php composer.phar self-update
php composer.phar update
php composer.phar install
Fixed this error by disabling toolbar. Just go to config/autoload/zend-developer-tools.local-development and set toolbar to false.
'toolbar' => [
/**
* Enables or disables the Toolbar.
*
* Expects: bool
* Default: false
*/
'enabled' => false,