ZF2 - How To Translate Zend Form Validation Error Messages? - php

I have the .po and compiled .mo language files for diffrent languages.
But language translation is not working on zend form validation error messages.
I dont want to use extra .php file like fr.php for it.
I got this code from click here
$translator = new Zend\I18n\Translator\Translator();
$translator->addTranslationFile(
'phpArray'
'resources/languages/en.php',
'default',
'en_US'
);
Zend\Validator\AbstractValidator::setDefaultTranslator($translator);
Any solution how to implement it in ZF2.

I do not approve of the selected answer :P
When adding a new translator to your configuration, do NOT use the default translator-text-domain. The Syntax is as follows:
$translator->addTranslationFile(
$type,
$resource,
$textDomain, //<-- this is the important one
$lang
);
In your example you've added a file to the default-textdomain. This, sadly, brings lots of troubles with it, at it will not always work as expected. Whenever you're adding translation files, add them to your own text-domain!
After that, all you need to do is to assign the Zend\Form\View\Helper your text-domain. This is done by the following:
// For Labels
$this->formLabel()->setTranslatorTextDomain('your-textdomain');
// For Buttons (input type submit)
$this->formButton()->setTranslatorTextDomain('your-textdomain');
// For Error-Messages
$this->formElementErrors()->setTranslatorTextDomain('your-textdomain');
How to get the ServiceManager into the Form?
This is pretty easy, too. The simples one is to use constructor-injection and inject the ServiceManager or ServiceLocator into the __construct() of your Form. On a Controller-Level this would look something like this:
$serviceLocator = $this->getServiceLocator();
$form = new My\Form($serviceLocator);
A more in-depth introduction to Form-Dependencies can be found on my Blog, where i illustrate the population of a Zend\Form\Element\Select-Element on dependent Database-Connections.
About the Translator itself
Another thing to note is: as long as there is a Translator-Service attached to your configuration with the name translator, it will automatically be attached to the form as default translator. This is a sample configuration i use within my modules regularly:
'translator' => array(
'locale' => 'de_DE',
'translation_file_patterns' => array(
array(
'type' => 'phparray',
'base_dir' => __DIR__ . '/lang',
'pattern' => '%s.php',
'text_domain' => __NAMESPACE__,
),
),
),

Simply add your .po or .mo files instead of the .php ones, i.e. like this:
$translator = new Zend\I18n\Translator\Translator();
$translator->addTranslationFile(
'gettext'
'resources/languages/fr.mo',
'default',
'fr_FR'
);
Zend\Validator\AbstractValidator::setDefaultTranslator($translator);
And then to translate it, use
echo $this->formElementErrors($form->get("username"),
array('message' => $this->translate("errormessage"))
);
I don't know how it is with performance of the translation in ZF2, but in ZF1 using arrays in .php files was way faster than any other method.

Related

Moodle Error: build_navigation() can not be used any more, please use $PAGE->navbar methods instead

I'm pretty new to Moodle and I tried installing some blocks.
After installing a block, I'm getting this error: build_navigation() can not be used any more, please use $PAGE->navbar methods instead.
I think the part of the php file with the error is:
$navigation = array(
array('name' => format_string($course->shortname),
'link' => "$CFG->wwwroot/course/view.php?id=$course_id",
'type' => 'course'
),
array('name' => get_string('pluginname', $BLOCK_NAME),
'link' => "$CFG->wwwroot/blocks/user_preferences?id=$course_id",
'type' => 'config'
),
);
build_navigation($navigation);
I know I'm supposed to use methods as described here, but I don't know how to go about it. Thanks
build_navigation is deprecated since a long time ago. Use this instead:
$mycoursestr = format_string($course->shortname);
$mycourseurl = new moodle_url('/course/view.php', ['id' => $courseid])
$PAGE->navbar->add($mycoursestr, $mycourseurl);
Notice that $PAGE is available in the global scope so you don't need to instantiate it.
Also, depending on what you want to do, for example: depending on where you want this navigation node to appear or wether you are writing this code within an entry point/page (before calling $OUTPUT->header()) or elsewhere... you may need to work with the nodes differently.

Silverstripe i18n collecting translations in the templates only creates en.yaml?

I am building a site that uses ar and en languages, and according to the silverstripe docs here, I did the text collection process and went successful. but only one en.yaml file is created in the lang folder in my current theme. there should be another ar.yaml file!.
here's my _config.php file:
<?php
global $project;
$project = 'mysite';
FulltextSearchable::enable();
global $databaseConfig;
$databaseConfig = array(
'type' => 'MySQLDatabase',
'server' => 'localhost',
'username' => 'dbuser',
'password' => '123',
'database' => 'cont_learning_2',
'path' => ''
);
// Set the site locale
i18n::set_locale('ar_EG');
Director::set_environment_type('dev');
if(!Director::isDev()) {
// log errors and warnings
SS_Log::add_writer(new SS_LogFileWriter('../silverstripe-errors-warnings.log'), SS_Log::WARN, '<=');
// or just errors
SS_Log::add_writer(new SS_LogFileWriter('../silverstripe-errors.log'), SS_Log::ERR);
// or notices (e.g. for Deprecation Notifications)
SS_Log::add_writer(new SS_LogFileWriter('../silverstripe-errors-notices.log'), SS_Log::NOTICE);
}
Security::setDefaultAdmin('admin','admin');
// multi-language configuration - translatable module
Translatable::set_default_locale('ar_EG');
Translatable::set_allowed_locales(array(
'ar_EG',
'en_US',
));
SiteTree::add_extension('Translatable');
The text-collector task isn't aware of the possible locales your installation will/can have. So it basically just collects all strings and puts them in a default yml file.
If you have an en.yml file, copy it as ar.yml, make sure it starts with ar: instead of en: and translate all text to Arabic.
Using https://github.com/Zauberfisch/silverstripe-better-i18n you are able to create and update different languages in one task. You can install it with composer as a development-only requirement.
I run it like
http://localhost/dev/tasks/BetterI18nTextCollectorTask?module=mysite,themes/my-theme&targetlocale=de,en
to create german and english yml files in mysite and themes/my-theme.
It will create a bunch of items prefixed with double underscore (as pseudo comments) and also the default keys for your database fields.

Drupal 8 custom module add php classes

I have created a custom Drupal 8 module that works as is with a custom block and block form to collect some info.
This is all good.
I also have a twig template that I want to render a twitter feed using a php feed class I bought. I just don't know how it integrate this into the module.
This is the setup for the class: http://austinbrunkhorst.com/demos/twitter-class/#setup
It contains two files:
ultimate.twitter.feed.php
and
tmhOAuth.php
Which is currently a require_once 'tmhOAuth.php'; in the head of ultimate.twitter.feed.php
According to the instruction I should be creating a php file that has this:
$options = array(
'screen_name' => 'FeedTestUser',
'consumer_key' => '...',
'consumer_secret' => '...',
'user_token' => '...',
'user_secret' => '...',
);
$twitter = new Twitter($options);
$twitter->PrintFeed();
Which I'm guessing is also a hurdle as twig files are not php
Any help with this is very much appreciated.
C
I would setup the class as a Service in your module. Your block will then implement that service and do the handling. You don't really want to use require_once() if you can avoid it, rather use Drupal constructs (in part so that if you reorganize things later Drupal will help find the files in their new location).
Place the class in your module's src directory, and add a namespace to the start of the file (assuming there isn't one there already). Then in your block's class file you should be able to add a use statement that references that name space (even better would be to use a dependency injection, but the details on that would get in your way here).
In your block class's build() method you then instantiate the class as described in your question, but instead of just letting the module print HTML, you can want to capture that HTML and place it into your block as markup. If the class allows you to do that without using a buffer, you should (but I didn't see anything in the docs to support that), and then attempt to theme the structured data. If not, you can use PHP's output buffering to capture its attempt to print:
ob_start();
$twitter->PrintFeed();
$content= ob_get_contents();
ob_end_clean();
Then place the generated markup into a render array:
return [
'my_twitter_block' => [
'#markup' => $content,
],
];
Create a custom block and add the result of PrintFeed() to the render array. Just as with any usual custom block. In the render array you can specify a template which should be used (if needed). If you wanna output pure html without any template you could use the '#markup' key.
Small example:
Your block render array:
return array(
'#theme' => 'name_of_your_theme',
'#some_twig_variable' => $twitter->PrintFeed();
);
your your_module.module file (in the root of your module folder):
function your_module_theme() {
return array(
'name_of_your_theme' => array(
'variables' => array(
'some_twig_variable' => some-default-value,
),
),
);
}
your name-of-your-theme.html.twig template (should be under your_module/templates):
{{ some_twig_variable }}
As far as using the class: I see no problem using a require_once for that matter (in your Block php file). Of course it's always better/nicer if you can require the library/package via the make file or composer and then use the autoloader, but if that's not possible just put it e.g. in your drupal root under /libraries/twitter or so and then require it. If you do it like that you have to check that library into your git repository obviously.
have you use ultimate.twitter.feed.php in your TwitterBlock.php file
If not then try adding this line before class block beginns:
require_once 'path/to/twitter_class/ultimate.twitter.feed.php';

joomla 1.7 : override a module helper.php

I want to override a helper.php file of a module, exactly
\administrator\modules\mod_quickicon\helper.php
what I want is to update the getButtons function in this file
what are the options I have to override this particular file ? its possible using a plugin ?
thanks
You can really only do a template override on the file in the tmpl folder called default.php. If you want to override helper.php, you're essentially rewriting the module itself. This isn't necessarily a bad thing, just copy the contents of the existing helper.php file into another file for backup, and hack away. The downside of doing this is that if someone updates the module, and you install that update, you'll have to redo your hack. Again, it's not that hard to work around. Just backup backup backup.
Some more thoughts:
You could also do the following:
1) Copy the module to a different folder, beginning with mod_ as well, but with a different name.
2) Modify the xml file, helper file, component file (and any others that are necessary) to account for the new name. Also do whatever you want to helper.php.
3) Go to extension manager and do a discover install of this new module
4) Go to module manager and make a new instance of the new module (using the same position as the old one).
5) Unpublish the module you're replacing
Doing this will keep you safe from update loss.
Here is what I've done with Joomla! 3.3.1 but it might be done with Joomla! 1.7, too:
Copy default.php from
/administrator/modules/mod_quickicon/tmpl/
to
/administrator/templates/YOUR_ADMIN_TEMPLATE_NAME/html/mod_quickicon/
Open the copied file and replace the line below
$html = JHtml::_('links.linksgroups', ModQuickIconHelper::groupButtons($buttons));
with these lines:
$myLinks = array(
'YOUR_QUICKICON_GROUP_NAME' => array(
array(
'link' => JRoute::_('index.php?option=com_YOURCOMPONENT'),
'image' => 'stack',
'icon' => 'header/icon-48-article-add.png',
'text' => JText::_('YOUR_QUICKICON_ITEM_NAME'),
'access' => array('core.manage', 'com_YOURCOMPONENT'),
'group' => 'YOUR_QUICKICON_GROUP_NAME'
)
)
);
$array = ModQuickIconHelper::groupButtons($buttons);
$array = array_merge($myLinks, $array);
$html = JHtml::_('links.linksgroups', $array);
That's it. You can edit or create /administrator/language/overrides/en-GB.override.ini and add these lines:
YOUR_QUICKICON_GROUP_NAME="The Group"
YOUR_QUICKICON_ITEM_NAME="The Item"
Enjoy!

how we could create translate validate error messages on zend framework?

how we could create translate validate error messages on zend framework?
someone could give a example ?
thanks
From the ZF Manual on Zend_Validate Validation Messages
$validator = new Zend_Validate_GreaterThan();
$validator->setMessage('Please enter a lower value',
Zend_Validate_GreaterThan::NOT_GREATER);
And also:
Zend Framework is shipped with more than 45 different validators with more than 200 failure messages. It can be a tendious task to translate all of these messages. But for your convinience Zend Framework comes with already pre-translated validation messages. You can find them within the path /resources/languages in your Zend Framework installation.
[...]
So to translate all validation messages to german for example, all you have to do is to attach a translator to Zend_Validate using these resource files.
$translator = new Zend_Translate(
'array',
'/resources/languages',
$language,
array('scan' => Zend_Locale::LOCALE_DIRECTORY)
);
Zend_Validate_Abstract::setDefaultTranslator($translator);
Of course, you can also provide your own translations. All you have to do is load make them available to the translation adapter. Basically you just swap out the part shown above to your custom path.
I just want to improve a little bit the answer from Gordon:
a working example is
$translator = new Zend_Translate(
'array',
'resources/languages', // you need to copy the resources folder
// (from your Zend Framework installation)
// in the application folder
'it', // 'it' for italian, 'fr' for french, etc.
// Just look at the directories
// Zend_Translate, NOT Zend_Locale
array(
'scan' => Zend_Translate::LOCALE_DIRECTORY
)
);
Zend_Validate_Abstract::setDefaultTranslator($translator);
Cheers!
Bruno

Categories