How to make ZfcUser use an abstract db_adapter - zend-framework2

I'm using Zend Framework 2 and I've installed the module ZfcUser.
Everything was working correctly until I've decided to add a second db adapter in my config/autoload/global.php
<?php
return array(
'db' => array(
'adapters' => array(
'cleardb' => array(
'driver' => 'Pdo',
'dsn' => 'mysql:dbname=secret;host=secret.com',
'driver_options' => array(
...
),
),
'other' => array(...)
)
),
'service_manager' => array(
'abstract_factories' => array(
'Zend\Db\Adapter\AdapterAbstract'
=> 'Zend\Db\Adapter\AdapterAbstractServiceFactory',
),
),
);
Now, ZfcUser can't find my default db adapter.
In the zfcuser.global.php I've updated this line:
'zend_db_adapter' => 'cleardb'
This is the error I get when I try to login:
An alias "zfcuser_zend_db_adapter" was requested but no service could be found.
Your help is really appreciated.

Related

Zend framework 2 translate Image captcha messages

I have this Image captcha thats is working correctly, but I can't get the "badCaptcha" validation error translated.
I have the key Captcha value is wrong translated in my .po file with PoEdit.
This is my CAPTCHA form element:
$this->form->add(array(
'name' => 'captcha',
'type' => 'Zend\Form\Element\Captcha',
'options' => array(
'captcha' => new \Zend\Captcha\Image(array(
'imgDir' => './public/assets/images/captcha',
'ImgUrl' => '/assets/images/captcha',
'width' => 330,
'height' => 90,
'wordlen' => 3,
'dotNoiseLevel' => 30,
'lineNoiseLevel' => 3,
'font' => './data/captcha/font/monofont.ttf',
'fontSize' => 52,
'expiration' => 600,
)),
'messages' => array(
'badCaptcha' => $this->getTranslatorHelper()->translate('Captcha value is wrong', 'csnuser'),
),
),
));
PS: $this->getTranslatorHelper() retrieves the MvcTranslator service.
This is all wrong...ZF2 documentation in this topic is at least innacurate.
You may activate this very basic function this way:
In your Application (yes, I'm using Skeleton App) module config file (module.config.php)
...
...
'translator' => array(
'locale' => 'xx_XX', //Or whatever you want
'translation_file_patterns' => array(
array(
'type' => 'gettext',
'base_dir' => __DIR__ . '/../language',
'pattern' => '%s.mo',
),
// Add this new file pattern
array(
'type' => 'phparray',
//You get this translated files from vendor/zendframework/zendframework/resources/languages
'base_dir' => __DIR__ . '/../language/validation',
//You may rename it to xx_XX.php for the pattern to match!
'pattern' => '%s.php',
),
...
...
...
After that, you may create Application module onBootstrap event listener in Module.php file, like this:
public function onBootstrap(MvcEvent $event)
{
...
...
\Zend\Validator\AbstractValidator::setDefaultTranslator($event->getApplication()->getServiceManager()->get('MvcTranslator'));
...
...
}
This way I got Captcha value is wrong translated!
ZF2 has already translate all forms messages zend_validate.php and captacha_validate.php are already translated them
you can find them here :
vendor\zendframework\zendframework\resources\languages\fr
Copy this files into your application langage folder and call them into your config
'translator' => array(
'locale' => 'fr_FR',
'translation_files' => array(
array(
'type' => 'phpArray',
'filename' => 'resources/languages/fr.php'
),
),
),
for example
You can have both php translation file AND po file.
EDIT :
'translator' => array(
'locale' => 'fr_FR',
'translation_file_patterns' => array(
array(
'type' => 'gettext',
'base_dir' => __DIR__ . '/../language',
'pattern' => '%s.mo', //<-%s is important
),
array(
'type' => 'phpArray',
'base_dir' => './module/Application/language/Zend_Validate/',
'pattern' => '%s-Zend_Validate.php',
),
),
),
When you have multiple lang to handle you have to load different file according to the lang choosen. %s take 'locale'.
Check if it's your problem :)
No renaming nescecary:
'pattern' => '%2.2s/Zend_Validate.php'

Zend Framework 2: How to properly replace Figlet with reCaptcha on zfcUser

I am trying to replace Figlet with reCaptcha on a zfcUser registration form. Partial instruction on how to accomplish this can be found on https://github.com/ZF-Commons/ZfcUser#changing-registration-captcha-element but no complete instruction exists.
Checking the README.md file has a two-step instruction on how to accomplish this but still the CAPTCHA uses Figlet when rendered on the form.
Has anyone successfully implemented this? I really need a hand on this one.
Thanks in advance.
EDIT: Here is a proven working solution I developed:
1. Add to composer.json
// Add the lines below under the "require" element:
"require": {
"php": ">=5.3.3",
"zendframework/zendframework": ">2.2.0rc1",
"zendframework/zendservice-recaptcha": "2.*"
}
2. Goto to your project's ZF2 installation directory and execute this command:
php composer.phar update
3. Replace or Create config/autoload/database.global.php with:
<?php
$config = array(
'dbdriver' => 'pdo',
'dbhost' => 'localhost',
'dbport' => '3306',
'dbname' => 'CHANGEME',
'dbuser' => 'CHANGEME',
'dbpass' => 'CHANGEME',
);
return array(
'service_manager' => array(
'factories' => array(
'Zend\Db\Adapter\Adapter' => 'Zend\Db\Adapter\AdapterServiceFactory',
),
),
'db' => array(
'driver' => 'pdo',
'dsn' => 'mysql:dbname='.$config['dbname'].';host='.$config['dbhost'],
'username' => $config['dbuser'],
'password' => $config['dbpass'],
),
);
4: Execute this on your mySQL server:
CREATE TABLE `user`
(
`user_id` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
`username` VARCHAR(255) DEFAULT NULL UNIQUE,
`email` VARCHAR(255) DEFAULT NULL UNIQUE,
`display_name` VARCHAR(50) DEFAULT NULL,
`password` VARCHAR(128) NOT NULL,
`state` SMALLINT UNSIGNED
) ENGINE=InnoDB CHARSET="utf8";
5. Create/Replace config/autoload/recaptcha.global.php with:
<?php
define('RECAPTCHA_PRIVATE_KEY','CHANGEME');
define('RECAPTCHA_PUBLIC_KEY','CHANGEME');
return array(
'zfcuser' => array(
'form_captcha_options' => array(
'class' => 'Zend\Captcha\ReCaptcha',
'options' => array(
'privkey' => RECAPTCHA_PRIVATE_KEY,
'pubkey' => RECAPTCHA_PUBLIC_KEY,
),
),
),
'di'=> array(
'instance'=>array(
'alias'=>array(
'recaptcha_element' => 'Zend\Form\Element\Captcha',
),
'ZfcUser\Form\Register' => array(
'parameters' => array(
'captcha_element'=>'recaptcha_element',
),
),
),
),
);
6. Create/Replace config/autoload/zfcuser.global.php with:
<?php
$settings = array(
'enable_registration' => true,
'enable_username' => true,
'auth_adapters' => array( 100 => 'ZfcUser\Authentication\Adapter\Db' ),
'enable_display_name' => false,
'auth_identity_fields' => array( 'email' ),
'use_registration_form_captcha' => true,
'user_login_widget_view_template' => 'zfc-user/user/login.phtml',
);
return array(
'zfcuser' => $settings,
'service_manager' => array(
'aliases' => array(
'zfcuser_zend_db_adapter' => (isset($settings['zend_db_adapter'])) ? $settings['zend_db_adapter']: 'Zend\Db\Adapter\Adapter',
),
),
);
7. Navigate to http://yourdomain.com/user
8. Enjoy! :)
This is how I did it, it might not be the best or correct way but it worked for me:
Add the recaptcha service to your composer.json file:
"require": {
"Zendframework/zendservice-recaptcha": "2.*"
}
Run composer to get the service. Then you need to specify the ReCaptcha config.
I created a separate config file to store the ReCaptcha keys:
//zfcuser.local.php
return array(
'zfcuser' => array(
'form_captcha_options' => array(
'options' => array(
'privkey' => RECAPTCHA_PRIVATE_KEY,
'pubkey' => RECAPTCHA_PUBLIC_KEY,
),
),
),
);
Then ZfcUser captcha config looks like so, telling it to use the ReCaptcha service:
//zfcuser.global.php
'form_captcha_options' => array(
'class' => 'Zend\Captcha\ReCaptcha',
'options' => array(
'wordLen' => 6,
'expiration' => 300,
'timeout' => 300,
),
),
Edit:
You don't need the recaptcha.global.php. You can call the config file whatever you like aslong as it ends with .global.php or .local.php. You usually name things .local.php when you don't want them in version control.
In this case I named the file zfcuser.local.php because all it does is store the ReCaptcha keys and I didn't want them in version control.
All the config files get merged in to one array when the application is started. So basically, ignore the ZfcUser documentation. Or maybe someone else can explain how to get it working that way.
The third block of code is the zfcuser.global.php.

ZF2 An alias "translator" was requested but no service could be found. error on creating new skeleton project

I just downloaded the ZendFrameworkSkeleton for ZF2 from github. Everything is in order, but I am getting this error:
An alias "translator" was requested but no service could be found.
I know nothing about ZF2. Can someone assist?
Heres where I got it: ZF2Skeleton
EDIT***
I found this code in module/Application/config/module.config.php:
'service_manager' => array(
'abstract_factories' => array(
'Zend\Cache\Service\StorageCacheAbstractServiceFactory',
'Zend\Log\LoggerAbstractServiceFactory',
),
'aliases' => array(
'translator' => 'MvcTranslator',
),
),
'translator' => array(
'locale' => 'en_US',
'translation_file_patterns' => array(
array(
'type' => 'gettext',
'base_dir' => __DIR__ . '/../language',
'pattern' => '%s.mo',
),
),
),
Try doing a composer update first. There was an issue with conflicting service names which has been fixed a few days ago.

zf2 router: One module makes the router unable to find another module. How can I make both work?

We're just starting out with zf2, so someone else made a Thumbnail server module, and then I added a Lookup server module. I call these servers because they're both RESTful apis. Initially they seemed to work together, but someone made some changes to my module, and now the Thumbnail server won't work unless Lookup is removed from the application.config.php list of modules. The Lookup server works regardless. Looking over the code, I don't see how the changes made to Lookup would affect Thumbnail. The error I'm getting looks like this:
<h1>A 404 error occurred</h1>
<h2>Page not found.</h2>
<p>The requested controller was unable to dispatch the request.</p>
<dl>
<dt>Controller:</dt>
<dd>Lookup\Controller\Lookup</dd>
</dl>
Here's what application.config.php looks like:
<?php
return array(
'modules' => array(
'Application',
'SanRestful',
'Album',
'AlbumRest',
'Thumbnail',
'Lookup',
'AP_XmlStrategy',
),
'module_listener_options' => array(
'config_glob_paths' => array(
'config/autoload/{,*.}{global,local}.php',
'config/autoload/{,*.}' . (getenv('APPLICATION_ENV') ?: 'production') . '.php',
),
'module_paths' => array(
'./module',
'./vendor',
),
),
);
As you can see, there's the initial Album module, and a few other experimental ones. My Lookup module uses the excellent AP_XmlStrategy module by Allessandro Pietrobelli.
Below is the Thumbnail module.config.php. It has a constraint that's probably not being used because there are no arguments called "id", but that shouldn't mess things up, should it?
<?php
return array(
'controllers' => array(
'invokables' => array(
'Thumbnail\Controller\Thumbnail' => 'Thumbnail\Controller\ThumbnailController',
),
),
// The following section is new and should be added to your file
'router' => array(
'routes' => array(
'thumbnail' => array(
'type' => 'segment',
'options' => array(
'route' => '/thumbnail[/:action][/:output]',
'constraints' => array(
'id' => '[0-9]+',
),
'defaults' => array(
'controller' => 'Thumbnail\Controller\Thumbnail',
'action' => 'index',
),
),
),
),
),
'view_manager' => array(
'template_path_stack' => array(
'thumbnail' => __DIR__ . '/../view',
),
),
);
And the Lookup module.config.php, with identifiers obfuscated:
<?php
return array(
'db' => array(
'driver' => 'Pdo',
'dsn' => 'pgsql:dbname=<dbname>;host=<host>;port=<port>',
'username' => '<username>',
'password' => '<password>',
),
'service_manager' => array(
'factories' => array(
'Zend\Db\Adapter\Adapter'
=> 'Zend\Db\Adapter\AdapterServiceFactory',
),
'aliases' => array(
'db' => 'Zend\Db\Adapter\Adapter',
),
),
'controllers' => array(
'invokables' => array(
'Lookup\Controller\Lookup' => 'Lookup\Controller\LookupController',
),
),
// The following section is new and should be added to your file
'router' => array(
'routes' => array(
'lookup' => array(
'type' => 'segment',
'options' => array(
'route' => '[/:action][/:version][/:resource][/:code][/:resource_xref]',
'constraints' => array(
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'version' => '[a-zA-Z][a-zA-Z0-9_-]*',
'resource' => '[a-zA-Z][a-zA-Z0-9_-|\.]*',
'code' => '[a-zA-Z][a-zA-Z0-9_-]*',
'resource_xref' => '[a-zA-Z][a-zA-Z0-9_-|\.]*',
),
'defaults' => array(
'controller' => 'Lookup\Controller\Lookup',
'action' => 'index',
),
),
),
),
),
'view_manager' => array(
'template_path_stack' => array(
'lookup' => __DIR__ . '/../view',
),
'strategies' => array(
'ViewJsonStrategy',
'ViewXmlStrategy',
),
),
);
Are there any obvious mistakes here that I'm missing?
Requests can be matched by multiple routes. An example: the url /foo can be matched by a literal route /foo and also the route [/:action]. To distinguish the two routes, the order how you configure them matters.
What happens, the routes are matched in LIFO order, so the last route must be the most explicit. In the "/foo" example, this config will match the literal:
'router' => array(
'routes' => array(
'test1' => array(
'type' => 'segment',
'options' => array(
'route' => '[/:action]',
'defaults' => array(
//
),
),
),
'test2' => array(
'type' => 'literal',
'options' => array(
'route' => '/foo',
'defaults' => array(
//
),
),
),
),
),
However, in the below config, the literal will never be matched, because [/:action] is a possible match for /foo.
'router' => array(
'routes' => array(
'test2' => array(
'type' => 'literal',
'options' => array(
'route' => '/foo',
'defaults' => array(
//
),
),
),
'test1' => array(
'type' => 'segment',
'options' => array(
'route' => '[/:action]',
'defaults' => array(
//
),
),
),
),
),
Now take a look at your two modules. The first (Thumbnail) has a route /thumbnail[/:action][/:output]. it starts with a literal part. Then your second module (Lookup) has a route [/:action][/:version][/:resource][/:code][/:resource_xref].
Now if you get back to the LIFO order, any route starting with /thumbnail will match already at the Lookup route.
Solution
There are two options. First is to swap the order of the modules. This is always an important order if you have inter-dependent relations between modules. Load Lookup first and then Thumnnail, so the thumbnail route is put later in the config. Thus, it matches first. Thus, your app works again.
Then there is the second solution (and imho, the better). You have a "one route to rule them all" in the Lookup, which is not a really good practice. You can get into trouble exactly like you are now, having no idea what went wrong. Thus, specify as much as possible in your routes. Make the first part of the Lookup also literal (is /lookup[/:action][/:version][/:resource][/:code][/:resource_xref] not an option?). Or remove action as parameter and make those literal:
'router' => array(
'routes' => array(
'view' => array(
'type' => 'segemnt',
'options' => array(
'route' => '/view[/:version][/:resource][/:code][/:resource_xref]',
'defaults' => array(
'action' => 'view',
//
),
),
),
'create' => array(
'type' => 'segment',
'options' => array(
'route' => '/create[/:version][/:resource][/:code][/:resource_xref]',
'defaults' => array(
'action' => 'create',
//
),
),
),
'update' => array(
'type' => 'segment',
'options' => array(
'route' => '/update[/:version][/:resource][/:code][/:resource_xref]',
'defaults' => array(
'action' => 'update',
//
),
),
),
// And so on
),
),
This way, your lookup module has a fixed starting point and matches only if those first parts are in the request uri. Then your /thumbnail[/:action][/:output] is completely decoupled from the Lookup routes.

404 error, Zend Framework 2 The requested URL could not be matched by routing

I'm getting:
A 404 error occurred
Page not found. The requested URL could not be matched by routing.
My module.config.php file is:
'router' => array(
'router' => array(
'Test' => array(
'type' => 'Segment',
'options' => array(
//http://localhost/Test/Test
'route' => '/Test[/[:action]]',
'constraints' => array(
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
),
'defaults' => array(
'controller' => 'Test\Controller\Test',
'action' => 'Test'
),
),
),
),
),
help please, i am new in Zend Framework 2 !
You should use configuration like Application module in ZendSkeletonApplication:
'router' => array(
'routes' => array(
'test' => array(
'type' => 'Literal',
'options' => array(
'route' => '/book',
'defaults' => array(
'__NAMESPACE__' => 'Test\Controller',
'controller' => 'Test',
'action' => 'index',
),
),
'may_terminate' => true,
'child_routes' => array(
'default' => array(
'type' => 'Segment',
'options' => array(
'route' => '/[:controller[/:action]]',
'constraints' => array(
'controller' => '[a-zA-Z][a-zA-Z0-9_-]*',
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
),
'defaults' => array(
),
),
),
),
),
),
),
You just add the following code:
'test' => array(
'type' => 'Segment',
'options' => array(
'route' => '[/:action][/:id]',
'constraints' => array(
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'id' => '[0-9]*',
),
'defaults' => array(
'__NAMESPACE__' => 'Test\Controller',
'controller' => 'Test',
'action' => 'index',
),
),
),
add this code to 'child-routes' key and after that you'll access to url: localhost/:controller_name/:action_name/:id (example : http://zf.dev/test/index or http://zf.dev/test/add/1). And now it's work!
This code can fix error 404 for tutorial in zf2 documentation.
You have a typo, try this:
'router' => array(
'routes' => array(
Routes rather than router twice..
Achieve fix it, I was missing the letter "d", was thus: Zend \ Loader \ StandarAutoloader I added the "d": Zend \ Loader \ StandardAutoloader. Greetings Friends. TIP: Zend Studio 10 and his version de ZF2 run perfect for this moment !
Please check the .htaccess file and index.php files. If these are exist in public folder means, you have to use the url as
http://localhost/public/Test/Test.
Your codes are almost right. Andrew has guided you well. Let me know your response.
1.You should check also application.config.php
and add your module name into RETURN array.
return array(
'modules' => array(
'Application',
'your_module',
.....
),
2.If Doesn't.Check route array in module.config.php
I will suggest also check the data folder that has cached config files, config files being cached in dev install also may cause this issue.
delete files inside data/cache and try.
PS: if you are just starting try with blog module on zend site it is for beginners and more updated with new versions.
https://framework.zend.com/manual/2.4/en/in-depth-guide/first-module.html

Resources