I localize product, and i'm newb in PHP,ZF2. I have .PO/.MO files with english and japanese translation. How to configure ZF2 to use these .mo translation in all library\Zend\Validator\* files instead of default messages e.g
protected $messageTemplates = array(
self::NOT_GREATER => "The input is not greater than '%min%'",
self::NOT_GREATER_INCLUSIVE => "The input is not greater or equal than '%min%'"
);
I've read these link but it doesnt help me.
I'm have custom Translator which extends MvcTranslator and config looks like:
```
),
'service_manager' => array(
'aliases' => array(
'translator' => 'MvcTranslator',
),
'factories' => array(
// ...
'MvcTranslator' => function ($services) {
$config = $services->get('config');
$config = isset($config['translator']) ? $config['translator'] : array();
$translator = \Application\I18n\Translator::factory($config);
$translator->setEscaper(new \Application\Escaper\Escaper);
// add event listener for context fallback on missing translations
$translator->enableEventManager();
$translator->getEventManager()->attach(
$translator::EVENT_MISSING_TRANSLATION,
array($translator, 'handleMissingTranslation')
);
// establish default locale settings
$translator->setLocale($translator->getLocale() ?: 'en_US');
$translator->setFallbackLocale($translator->getFallbackLocale() ?: 'en_US');
// try to guess locale from browser language header (using intl if available)
if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])
&& (!isset($config['detect_locale']) || $config['detect_locale'] !== false)
) {
$locale = extension_loaded('intl')
? \Locale::acceptFromHttp($_SERVER['HTTP_ACCEPT_LANGUAGE'])
: str_replace('-', '_', current(explode(',', $_SERVER['HTTP_ACCEPT_LANGUAGE'])));
$translator->setLocale(strlen($locale) ? $locale : $translator->getLocale());
}
return $translator;
},
),
),
'translator' => array(
'locale' => 'en_US',
'detect_locale' => true,
'translation_file_patterns' => array(
array(
'type' => 'gettext',
'base_dir' => __DIR__ . '/../language',
'pattern' => '%s.mo'
),
),
),
```
I thought i should put Zend\Validator\AbstractValidator::setDefaultTranslator($translator);
somewhere there..but nothing changed..Should i write some code in validators or what ?
Related
I'm working on zf2 to make one of my routes only accessible when a query string parameter is passed. Otherwise, it will not. I've added a filter on the route section but when accessing the page without the query parameter, it is still going thru.
'router' => array(
'routes' => array(
'show_post' => array(
'type' => 'segment',
'options' => array(
'route' => '[/]show/post/:filter',
'constraints' => array(
'filter' => '[a-zA-Z0-9-.]*',
),
'defaults' => array(
'controller' => 'blog_controller',
'action' => 'show'
)
),
),
),
),
http://example.com/show/post/?postId=1235 = This should work
http://example.com/show/post?postId=1235 = This should work
http://example.com/show/post/ = This should not work
http://example.com/show/post = This should not work
The way you currently have this setup you would have to structure your url like this
http://example.com/show/post/anything?postId=1235
I think what you are wanting is to structure your route like this
'route' => '[/]show/post',
Not sure what you are trying to accomplish with [/] before show though, you are making that dash optional there?
I would write it like this
'route' => '/show/post[/:filter]',
This way you can structure your urls like this
http://example.com/show/post/anything?postId=1235
or
http://example.com/show/post?postId=1235
Then in your action you can access those parameters like this
$filter = $this->params('filter');
$post_id = $this->params()->fromQuery('post_id');
or just
$post_id = $this->params()->fromQuery('post_id');
***************UPDATE***************
It looks like zf2 used to include what you are trying to do and removed it because of security reasons.
http://framework.zend.com/security/advisory/ZF2013-01
Don't try to bend ZF2 standard classes to your way. Instead write your own route class, a decorator to the segment route, which will do exactly as you please:
<?php
namespace YourApp\Mvc\Router\Http;
use Zend\Mvc\Router\Http\Segment;
use use Zend\Mvc\Router\Exception;
use Zend\Stdlib\RequestInterface as Request;
class QueryStringRequired extends Segment
{
public static function factory($options = [])
{
if (!empty($options['string'])) {
throw new Exception\InvalidArgumentException('string parameter missing');
}
$object = parent::factory($options);
$this->options['string'] = $options['string'];
return $object;
}
public function match(Request $request, $pathOffset = null, array $options = [])
{
$match = parent::match($request, $pathOffset, $options);
if (null === $match) {
// no match, bail early
return null;
}
$uri = $request->getUri();
$path = $uri->getPath();
if (strpos($path, $this->options['string']) === null) {
// query string parametr not found in the url
// no match
return null;
}
// no query strings parameters found
// return the match
return $match;
}
}
This solution is very easy to unit test as well, it does not validate any OOP principles and is reusable.
Your new route definition would look like this now:
// route definition
'router' => array(
'routes' => array(
'show_post' => array(
'type' => YourApp\Mvc\Router\Http\QueryStringRequired::class,
'options' => array(
'string' => '?postId=',
'route' => '[/]show/post/:filter',
'constraints' => array(
'filter' => '[a-zA-Z0-9-.]*',
),
'defaults' => array(
'controller' => 'blog_controller',
'action' => 'show'
)
),
),
),
),
I am working through the zend framework 2 tutorial application. I have set up my Album Module directory as follows:
I am running into an error when I start my MAMP server, Fatal error: Uncaught exception 'Zend\ModuleManager\Exception\RuntimeException' with message 'Module (Album) could not be initialized.'
If I comment out the Album module from the following code (in /config/application.config.php):
'modules' => array(
'Application',
'Album',
),
I get to the skeleton application homepage.
Here is my /module/Album/Module.php code:
namespace Album;
use Zend\ModuleManager\Feature\AutoloaderProviderInterface;
use Zend\ModuleManager\Feature\ConfigProviderInterface;
use Album\Model\Album;
use Album\Model\AlbumTable;
use Zend\Db\ResultSet\ResultSet;
use Zend\Db\TableGateway\TableGateway;
class Module implements AutoloaderProviderInterface, ConfigProviderInterface {
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 getServiceConfig() {
return array(
’factories’ => array(
’Album\Model\AlbumTable’ => function($sm) {
$tableGateway = $sm->get(’AlbumTableGateway’);
$table = new AlbumTable($tableGateway);
return $table;
},
’AlbumTableGateway’ => function ($sm) {
$dbAdapter = $sm->get(’Zend\Db\Adapter\Adapter’);
$resultSetPrototype = new ResultSet(); $resultSetPrototype->setArrayObjectPrototype(new Album());
return new TableGateway(’album’, $dbAdapter, null, $resultSetPrototype);
},
),
);
}
}
And here is my module.config.php code in /module/Album/config/:
return array(
’controllers’ => array(
’invokables’ => array(
’Album\Controller\Album’ => ’Album\Controller\AlbumController’,
),
),
’view_manager’ => array(
’template_path_stack’ => array(
’album’ => __DIR__ . ’/../view’,
),
),
'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',
),
),
),
),
),'
);
I have read through a few people who have ran in to similar situations, but their issues were due to misspelled/incorrectly named classes. I don't see anything wrong with my code (even went as far as copying/pasting directly from tutorial).
Can someone give me some suggestions?
Thanks
I had the same problem, and the solution was to start every .php file with <?php
This is not clear in the tutorial (if you just copy the code from there), and it was the reason I was getting the same exception.
The only reason i could see is that you should replace all ’ with normal single quotes '.
using ’ can results in unexpected behaviors.
There is an error in the tutorials module.config.php file.
Change 'id' => '[0-9]+',
to 'id' => '[0-9]*',
+ means one or more digits. If you just call http://zf2-tutorial.localhost/album/ there is no digit in the url so the rewriterule doesn't match. Change from + to * (0 or more)
I had the exact same issue, my issue and solution were
the very first command in the tutorial is:
php composer.phar create-project --stability="dev" zendframework/skeleton-application path/to/install
It was cut off my screen so I copy/pasted the command to the command line without reading the end. So my app directory structure included a directory ./path/to/install where all of the installation files were, including application.config.php.
Moving everything in /path/to/install/ to the root directory of the app allowed Zend to find the Album module.
Note: /path/to/install/module contains the album module but will fail if you do
mv ./path/to/install/* .
so be sure to move the Application module at /path/to/install/module into app_root_dir/module/.
You can check composer.json weather include the following:
"autoload": {
"psr-4": {
"Application\\": "module/Application/src/",
"Album\\": "module/Album/src"
}
},
Please check your Module::getConfig() ,
and play with :
return include __DIR__ . '/../config/module.config.php';
I have added '../' prefix and it works well .
My application uses Zend Framework 2 and I am trying to pass some options to it when ran via command line:
php index.php generate --date="2015-01-01"
However I am getting the error: Invalid arguments or no arguments provided
My controller looks like:
namespace Application\Controller;
use Zend\Mvc\Controller\AbstractActionController;
class GenerateController extends AbstractActionController
{
public function indexAction()
{
$longopts = array(
'date::',
);
$opts = getopt('', $longopts);
if (isset($opts['date'])) {
$date = $opts['date'];
} else {
$date = date('Y-m-d');
}
var_dump($date);
die();
}
}
I would like the var_dump to show the date provided in the options or today's date. The script runs but just gives the above error. Any help is greatly appreciated.
My module.config.php is functioning correctly:
// Placeholder for console routes
'console' => array(
'router' => array(
'routes' => array(
'get-happen-use' => array(
'options' => array(
//php index.php get happen --verbose apache2
// add [ and ] if optional ( ex : [<doname>] )
'route' => 'generate',
'defaults' => array(
'__NAMESPACE__' => 'Application\Controller',
'controller' => 'generate',
'action' => 'index'
),
),
),
)
)
),
You need to define your console params or flags in route. According documentation, your route definition should looks like
'route' => 'generate [--date=]',
for optional value flag date, or if flag date is mandatory:
'route' => 'generate --date=',
Then you can access value of this flag in controller from request (documentation):
$date = $this->getRequest()->getParam('date', null); // default null
I have update zf2 on the latest version and i receive this error:
http://jsfiddle.net/8Ft6d/
Some mandatory parameter was added for translation?
This is my translator config:
'translator' => array(
'locale' => 'it_IT',
'translation_file_patterns' => array(
array(
'type' => 'gettext',
'base_dir' => __DIR__ . '/../language',
'pattern' => '%s.mo',
),
),
),
'service_manager' => array(
'aliases' => array(
'translator' => 'MvcTranslator',
),
),
and this is what i call inside the Module.php::onBootstrap()
$translator = $serviceManager->get('translator’);
Thanks
What is happening here is that most probably, the DiAbstractServiceFactory is kicking in before an abstract factory that is responsible of fetching the MvcTransator instance.
You will likely have to switch the order in which abstract factories are being used, or remove your 'di' config from your modules or autoload config, since its presence will automatically cause addition of the DiAbstractServiceFactory to the ServiceManager.
I've had the same issue myself this morning after upgrading from 2.2.6 to 2.3.0.
There's a bug in ZF2.3.0 which causes the Di module to fail when trying to create an instance of the MvcTranslator (see: https://github.com/zendframework/zf2/pull/5959, where #Ocramius and noopable came up with the solution).
Until the fix is rolled out to the framework, you'll need to change the following code in Zend\ServiceManager\Di\DiAbstractServiceFactory from:
public function canCreateServiceWithName(ServiceLocatorInterface $serviceLocator, $name, $requestedName)
{
return $this->instanceManager->hasSharedInstance($requestedName)
|| $this->instanceManager->hasAlias($requestedName)
|| $this->instanceManager->hasConfig($requestedName)
|| $this->instanceManager->hasTypePreferences($requestedName)
|| $this->definitions->hasClass($requestedName);
}
to:
public function canCreateServiceWithName(ServiceLocatorInterface $serviceLocator, $name, $requestedName)
{
if ($this->instanceManager->hasSharedInstance($requestedName)
|| $this->instanceManager->hasAlias($requestedName)
|| $this->instanceManager->hasConfig($requestedName)
|| $this->instanceManager->hasTypePreferences($requestedName)
) {
return true;
}
if (! $this->definitions->hasClass($requestedName) || interface_exists($requestedName)) {
return false;
}
return true;
}
I'm having troubles with (german) special characters in URIs and want to try to resolve it with a RegEx Route and a PCRE pattern modifier for UTF-8 u.
'router' => array(
'routes' => array(
// ...
'city' => array(
'type' => 'regex',
'options' => array(
'regex' => '/catalog/(?<city>[a-zA-Z0-9_-äöüÄÖÜß]*)\/u',
'defaults' => array(
'controller' => 'Catalog\Controller\Catalog',
'action' => 'list-sports',
),
'spec' => '/catalog/%city%',
),
'may_terminate' => true,
),
),
),
But when I set it, the route stopps to work at all (error 404) -- neither for URIs with nor to ones without special characters.
How to set the modifier correctly?
Since I already had this open here's a handler that solves the problem.
<?php
namespace Application\Mvc\Router\Http;
use Zend\Mvc\Router\Http\Regex;
use Zend\Mvc\Router\Http\RouteMatch;
use Zend\Stdlib\RequestInterface as Request;
class UnicodeRegex extends Regex
{
/**
* match(): defined by RouteInterface interface.
*
* #param Request $request
* #param integer $pathOffset
* #return RouteMatch
*/
public function match(Request $request, $pathOffset = null)
{
if (!method_exists($request, 'getUri')) {
return null;
}
$uri = $request->getUri();
// path decoded before match
$path = rawurldecode($uri->getPath());
// regex with u modifier
if ($pathOffset !== null) {
$result = preg_match('(\G' . $this->regex . ')u', $path, $matches, null, $pathOffset);
} else {
$result = preg_match('(^' . $this->regex . '$)u', $path, $matches);
}
if (!$result) {
return null;
}
$matchedLength = strlen($matches[0]);
foreach ($matches as $key => $value) {
if (is_numeric($key) || is_int($key) || $value === '') {
unset($matches[$key]);
} else {
$matches[$key] = $value;
}
}
return new RouteMatch(array_merge($this->defaults, $matches), $matchedLength);
}
}
Assuming you place the file in Application/Mvc/Router/Http/UnicodeRegex your route definition should look like this
'router' => array(
'routes' => array(
// ...
'city' => array(
'type' => 'Application\Mvc\Router\Http\UnicodeRegex',
'options' => array(
'regex' => '/catalog/(?<city>[\p{L}]+)',
// or if you prefer, your original regex should work too
// 'regex' => '/catalog/(?<city>[a-zA-Z0-9_-äöüÄÖÜß]*)',
'defaults' => array(
'controller' => 'Catalog\Controller\Catalog',
'action' => 'list-sports',
),
'spec' => '/catalog/%city%',
),
'may_terminate' => true,
),
),
),
Well,
I guess you can solve it as easily as many other ones had this same problem. So take a look at some of them:
UTF-8 in * regular expressions
There uses the following modifiers like \\s, \\p{L}, and \\u to help you. I hope it solves! Good luck.
Edit
See my own test:
<?php
$toss_the_dice = utf8_decode ("etc/catalog/Nürnberg");
preg_match ('/\/catalog\/([\\s\\p{L}]*)/m', $toss_the_dice, $dice);
echo utf8_encode ($dice[1]);
// Now it prints
// Nürnberg
?>
Can you realize?
Edit 2
It can be better for you!
<?php
$toss_the_dice = "etc/catalog/Nürnberg";
preg_match ('/\/catalog\/([\\s\\p{L}]*)/u', $toss_the_dice, $dice);
echo $dice[1];
// Now it also prints
// Nürnberg
?>