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

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.

Related

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';

ZF2 project stops working when is cloned to local server

I would like to know why when I clone my ZF2 project to a local machine to do some testing it completly stops working.
In my local machine I have two subfolders, one with a cakePHP project and the other with the ZF2 I've cloned.
The cakePHP project is working fine since it was there first, but the ZF2, when I try to access to the public folder it prints me:
{"error":"Something went wrong"}
A really generic error... I have no clue about what is going on.
I've tried some general debug attemps like
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
with no success at all, I've also checked the .htaccess RewriteBase directive to match my subfolder and the DB configuration is done too.
I have researched a bit in the project and the file which displays the error is module/RestfulV2_2/Module.php (Reading the README.md I've discovered is part of ZF2 Restful Module Skeleton):
/**
* #param MvcEvent $e
* #return null|\Zend\Http\PhpEnvironment\Response
*/
public function errorProcess(MvcEvent $e)
{
/** #var \Zend\Di\Di $di */
$di = $e->getApplication()->getServiceManager()->get('di');
$eventParams = $e->getParams();
/** #var array $configuration */
$configuration = $e->getApplication()->getConfig();
$vars = array();
if (isset($eventParams['exception'])) {
/** #var \Exception $exception */
$exception = $eventParams['exception'];
if ($configuration['errors']['show_exceptions']['message']) {
$vars['error-message'] = $exception->getMessage();
}
if ($configuration['errors']['show_exceptions']['trace']) {
$vars['error-trace'] = $exception->getTrace();
}
}
if (empty($vars)) {
$vars['error'] = 'Something went wrong';
}
/** #var PostProcessor\AbstractPostProcessor $postProcessor */
$postProcessor = $di->get(
$configuration['errors']['post_processor'],
array('vars' => $vars, 'response' => $e->getResponse())
);
$postProcessor->process();
if (
$eventParams['error'] === \Zend\Mvc\Application::ERROR_CONTROLLER_NOT_FOUND ||
$eventParams['error'] === \Zend\Mvc\Application::ERROR_ROUTER_NO_MATCH
) {
$e->getResponse()->setStatusCode(\Zend\Http\PhpEnvironment\Response::STATUS_CODE_501);
} else {
$e->getResponse()->setStatusCode(\Zend\Http\PhpEnvironment\Response::STATUS_CODE_500);
}
$e->stopPropagation();
return $postProcessor->getResponse();
}
The line which is calling the error in my index.php is:
Zend\Mvc\Application::init(require 'config/application.config.php')- run();
And the only line I found where the error function is called some way is this one in my modele.php :
$sharedEvents->attach('Zend\Mvc\Application', MvcEvent::EVENT_DISPATCH_ERROR, array($this, 'errorProcess'), 999);
Can you help me to solve this? I'm inexperienced with ZF2 but I know that with cakePHP to make it work you need to clear the cache folder. Is there any similar process in ZF2? Should I virtualize two servers to avoid conflics?
Thank you in advance.
EDIT : I've already made virtual hosts to avoid any possible conflict between my two frameworks but the error output is still the same.
EDIT2 : Here is my application.config.php file:
return array(
// This should be an array of module namespaces used in the application.
'modules' => array(
'Restful',
'MvlabsSnappy',
'Qrcode',
'Application',
'RestfulV2',
'RestfulV2_2'
),
// These are various options for the listeners attached to the ModuleManager
'module_listener_options' => array(
// This should be an array of paths in which modules reside.
// If a string key is provided, the listener will consider that a module
// namespace, the value of that key the specific path to that module's
// Module class.
'module_paths' => array(
'./module',
'./vendor',
),
// An array of paths from which to glob configuration files after
// modules are loaded. These effectively override configuration
// provided by modules themselves. Paths may use GLOB_BRACE notation.
'config_glob_paths' => array(
'config/autoload/{,*.}{global,local}.php',
),
// Whether or not to enable a configuration cache.
// If enabled, the merged configuration will be cached and used in
// subsequent requests.
//'config_cache_enabled' => $booleanValue,
// The key used to create the configuration cache file name.
//'config_cache_key' => $stringKey,
// Whether or not to enable a module class map cache.
// If enabled, creates a module class map cache which will be used
// by in future requests, to reduce the autoloading process.
//'module_map_cache_enabled' => $booleanValue,
// The key used to create the class map cache file name.
//'module_map_cache_key' => $stringKey,
// The path in which to cache merged configuration.
//'cache_dir' => $stringPath,
// Whether or not to enable modules dependency checking.
// Enabled by default, prevents usage of modules that depend on other modules
// that weren't loaded.
// 'check_dependencies' => true,
),
// Used to create an own service manager. May contain one or more child arrays.
//'service_listener_options' => array(
// array(
// 'service_manager' => $stringServiceManagerName,
// 'config_key' => $stringConfigKey,
// 'interface' => $stringOptionalInterface,
// 'method' => $stringRequiredMethodName,
// ),
// )
// Initial configuration with which to seed the ServiceManager.
// Should be compatible with Zend\ServiceManager\Config.
// 'service_manager' => array(),
);
First I would open index.php or whatever used as initial file (DirectoryIndex) and temporarily completely replace whole its content with something very base and simple, for example just these two lines:
<?php
phpinfo();
And then make sure that it started to work after that - with that simple code which just displays your php configuration. So we'll find out that there is no error in server configurations, permissions and etc. and nothing prevents your script from run.
Then I would do the same at your old project location just to get phpinfo() from that place too and waste some time trying to compare them. Maybe you missed something important and you'll now see it.
If no - next step I would check your DB connectivity if your project uses any DB... also with some very simple commands like connect, bind, ....
And finally I'd try to restore original project content step by step from its begin, and look at which step it will fail. It doesn't matter that there maybe no any output - you may put echo __LINE__ . ' works!<br/>'; between blocks, so your index.php will look like:
<?php
// original code block 1
echo __LINE__ . ' works!<br/>';
// original code block 2
echo __LINE__ . ' works!<br/>';
And you'll see in browser where it fails.
This is a very base description of my debug principals, but hope it will help.
The error could be anything. However, assuming the posted code is executed, it will suppress an error message without the correct configuration.
Try adding the following config to local.config.php.
return [
'errors'=> [
'show_exceptions' => [
'message' => true,
'trace' => true
],
],
];
If an exception is being thrown and that listener is catching it, then the $eventParams is something you should debug.

laravel: config file name convention?

foo_constants.php or fooConstants.php?
It seems laravel would do some name conversion when you use Config::get('...'), which one do you use?
foo.php
Why specify constants at all? Convention I've generally seen is single word filenames. I think in general most 'config' type settings will be constant in an environment even if it is variable between environments.
Take a look at the aws/aws-sdk-php-laravel composer package as an example. That file is named config.php in the package, but gets published to aws.php.
rydurham/Sentinel is another popular package. It also only has a single-word filename.
Update
In the situation you describe in your comment, I would do something like this:
<?php // File: foo.php
return [
'sheep' => [
'clothing' => 'wool',
'chews_on' => 'cud',
],
'wolf' => [
'clothing' => 'fur',
'chews_on' => 'sheep',
],
];
And you can access both of those via Config::get('foo.sheep') and Config::get('foo.wolf'), respectively. When they're defined on the server, they're still 'on the server' so to speak. If you wish to release the values stored in foo.sheep to the public you can, and you can do so without also exposing foo.wolf.

Adding a version parameter to YII for application version

We are building a web application using Yii as the framework. Where would be a good location for us to put a version information array?
This version array is not the version of Yii but the version our application is on. This way we can use it global throughout the application. Example when deploy the application on our servers we can have a conditional that compares the required_php_version against the server's php version (phpversion()) to throw errors. This is just a simple example.
The array would consist of (with possibility to evolve later):
<?php
array(
'version' => '2.0.1',
'required_php_version' => '5.4.4'
);
?>
As far as I know, The best place to put your configurations in an application based on Yii, is main.php config file, which is situated in protected/config/main.php. But it is important to put your custom configurations in a right place. That is in params array. You can put your configs like below in config file:
'params' => array(
'webmaster' => 'YourEmail#example.com',
'required_php_version' => '5.4.1',
'my_app_version'=>'2.0.1.1',
'info_in_array'=>array(1,2,3,4,'so on ...')
// and so on
),
You can use these information in everywhere of your application like below:
Yii::app()->params['required_php_version'] //which returns 5.4.1 in this example.

ZF2 - How To Translate Zend Form Validation Error Messages?

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.

Categories