Magento translations ok in online program but not run as cronjob - magento

I created a module (extends Mage_Core_Model_Abstract) and an admin controller.
When I run this module online translations are going right.
When I run this module as cronjob, everything goes allright but translations are not done, I specified translation file in config.xml in as well frontend as adminhtml.
What I am doing wrong?

I see this is a very old question. I've posted here to future reference and others.
Quick and dirty solution
// Fix unitialized translator
Mage::app()->getTranslator()->init('frontend', true);
just after
$initialEnvironmentInfo = $appEmulation>startEnvironmentEmulation($storeId);
for instance. Or in a foreach loop of your own, which is called via cron/admin. Since you're talking about crons, I assume that you know what you are doing.
The real problem
In Magento 1.9 in Mage_Core_Model_App_Emulation (in app/code/core/Mage/Core/Model/App/Emulation.php), there's this function:
/**
* Apply locale of the specified store
*
* #param integer $storeId
* #param string $area
*
* #return string initial locale code
*/
protected function _emulateLocale($storeId, $area = Mage_Core_Model_App_Area::AREA_FRONTEND)
{
$initialLocaleCode = $this->_app->getLocale()->getLocaleCode();
$newLocaleCode = $this->_getStoreConfig(Mage_Core_Model_Locale::XML_PATH_DEFAULT_LOCALE, $storeId);
if ($initialLocaleCode != $newLocaleCode) {
$this->_app->getLocale()->setLocaleCode($newLocaleCode);
$this->_factory->getSingleton('core/translate')->setLocale($newLocaleCode)->init($area, true);
}
return $initialLocaleCode;
}
The $initialLocaleCode != $newLocaleCode seems to be the issue here. When iteration orders/customers/subscribers/*, the locale could stay the same, which then prevents executing the code in the statement. And the locale is thus not set in the Translator (Mage::app()->getTranslator()).
We've yet to fix the issue, but you could change if ($initialLocaleCode != $newLocaleCode) { to if (true) { straight in the core source. Off course, this is ugly. I suggest something like extending the class and then :
/**
* Apply locale of the specified store. Extended
* to fix Magento's uninitialized translator.
*
* #see http://stackoverflow.com/questions/19940733/magento-translations-ok-in-online-program-but-not-run-as-cronjob#
* #param integer $storeId
* #param string $area
*
* #return string initial locale code
*/
protected function _emulateLocale($storeId, $area = Mage_Core_Model_App_Area::AREA_FRONTEND)
{
$initialLocaleCode = $this->_app->getLocale()->getLocaleCode();
$newLocaleCode = $this->_getStoreConfig(Mage_Core_Model_Locale::XML_PATH_DEFAULT_LOCALE, $storeId);
$this->_app
->getLocale()
->setLocaleCode($newLocaleCode);
$this->_factory
->getSingleton('core/translate')
->setLocale($newLocaleCode)
->init($area, true);
return $initialLocaleCode;
}
Magento 2
I guess the developers became aware it was borked and they changed the code in Magento 2. The _emulateLocale() function is gone all together and they added this line to the startEnvironmentEmulation() function, without any conditional around it:
$this->_localeResolver->setLocale($newLocaleCode);

It's a bug even with CE 1.9.0.1!
See what I've done about it:
https://magento.stackexchange.com/questions/25612/cron-job-template-block-not-being-translated-but-testobserver-is/25920#25920

Related

How to use php-cs-fixer with vim for laravel?

I have installed php-cs-fixer & using with vim plugin https://github.com/stephpy/vim-php-cs-fixer. I am using custom config file from https://github.com/laravel/framework/blob/5.4/.php_cs. But I am having this issue where extra space after #param from comment block gets deleted.
How can I fix this? Thanks for in advance.
Laravel uses PSR2 coding standard.
From laravel.com about documentation -
Note that the #param attribute is followed by two spaces, the argument type, two more spaces, and finally the variable name:
/**
* Register a binding with the container.
*
* #param string|array $abstract
* #param \Closure|string|null $concrete
* #param bool $shared
* #return void
*/
public function bind($abstract, $concrete = null, $shared = false)
{
//
}
Thanks.
You are probably looking for "phpdoc_align" fixer. See docs:
Laravel uses many more from Symfony standard (marked by "#Symfony").
But the best way to find all fixers for Laravel, would be in PHP-CS-Fixer configuration in Laravel repostiory.

Joomla! 3.xx *onUserLogout* event not working

I have successfully implemented the onUserAuthenticate event to implement my custom authentication API inside the Joomla! site that I am working on.
Now I want to also have some custom code run on the onUserLogout event.
I have added the following code to the custom authentication plugin file.
But this method is not getting fired/invoked while the previous one(onUserAuthenticate) is working just fine.
/**
* Method to handle the SSO logout
*
* #param array $user Holds the user data.
* #param array $options Array holding options (client, ...).
*
* #return boolean Always returns true.
*
* #since 1.6
*/
public function onUserLogout($user, $options = array()) {
if (JFactory::getApplication()->isSite()) {
// Set the cookie to expired date.
setcookie('customAuth', '123', time() - (60 * 60 * 24 * 365), '/', '.customdomain.org');
}
return true;
}
Okay so I was getting it all wrong.
So I was adding the aforementioned method inside the same plugin file that handled the onUserAuthenticate.
For Joomla! the login is a separate process which has its respective events like onUserAuthenticate.
But it seems like the event onUserLogout has to be inside the plugin with the type of user.
So I created a separate plugin inside the user plugin type directory, installed it, and enabled it....And voila!! it worked.
This had me scratching my head for quite a while.

Can I use the Codeigniter redirect with probability?

We use a CMS, Fuel, built on Codeigniter, and use the redirect function often. I was wondering if there is a way to use probability with this function so that half (or whatever amount we set) the time it redirects to one page and half the time to another.
In general we will create a page with a redirect that looks like this:
<?=redirect('https://subdomian.onanotherserver.com/asdf')?>
We would love to make it looks similar:
<?=probabilityRedirect(0.5, 'https://subdomian.onanotherserver.com/asdf', 'https://subdomian.onanotherserver.com/jkl')?>
What would be the best way to go about this? Can we build off the redirect or just write a new function?
I would make a new function. Probably adding this to url_helper.php makes it the easiest to implement. Could be a stand-alone helper too but then you have to be certain url_helper is loaded.
if(!function_exists('randomRedirect'))
{
/**
* Randomized Header Redirect
*
* #param int $seed value optional
* #param array $list an indexed array of URL strings
* #return void
*/
function randomRedirect($seed = NULL, $list)
{
//list needs to be an array
if(!is_array($list OR ! isset($list)))
{
throw new Exception('randomRedirect() requires Array in second parameter');
}
if(!empty($seed))
{
mt_srand($seed);
}
$choice_count = count($list);
redirect($list[mt_rand(0, $choice_count)]);
}
}
Note: I did not test this! Results not guaranteed. :)
Revised code below.
Had some time to experiment with the above which eventually resulted in this.
randomURL_helper.php
<?php
if(!function_exists('p_redirect'))
{
/**
* Randomized Header Redirect
*
* #param array $list an indexed array of URL strings
* #param bool $seed optional when true, the random number generator will be seeded
*
* #return void
*
* Takes a list of URL strings in an array and randomly selects one as the
* input to the CodeIgniter function redirect.
* If you specify the full site URL that link will be built,
* but for local links simply providing the URI segments to the
* controller you want to direct to will create the link.
*
* The function will build the URL based on your config file values.
*
* This function requires the CodeIgniter helper "URL Helper"
* to be loaded using the following code: $this->load->helper('url');
*
* Use this line of code $this->load->helper('randomURL');
* to make p_redirect available to your CodeIgniter application.
*
*/
function p_redirect($list, $seed = FALSE)
{
if(!is_array($list))
{
// $list must be an array
throw new Exception('randomRedirect() requires Array as first parameter');
}
if($seed)
{
list($usec, $sec) = explode(' ', microtime());
$seed_val = (float) $sec + ((float) $usec * 100000);
mt_srand($seed_val);
}
redirect($list[mt_rand(0, count($list) - 1)]);
}
}
Tested it enough to see that it's not completely off-base.
Seems to get the job done. Enjoy!
You can just include it inside a rand 50/50 condition,
<?php
if (mt_rand(0,1)) {
redirect('https://subdomian.onanotherserver.com/asdf')
}
?>

Availability of $this->var in Phalcon\Mvc\View\Simple

I'm responsible for a rather large web app I built 8 years ago, then later refactored using ZF1 and now trying to move beyond that into more modern framework components. At the moment am trying to see if I can swap out Zend_View for Phalcon\Mvc\View\Simple without having to touch every .phtml file.
Problem I've run into is that while both assign a variable to the view in the same way (e.g. $this->view->foo = 'bar'), in Zend_View in the template you would <?=$this->foo;?> to print the var but in Phalcon it is <?=$foo;?>.
As I mentioned I don't want to go through each of several hundred .phtml files to remove $this->. Is there a way I can override Phalcon's render() or otherwise enable access to the view params using $this?
Here's what I came up with after fiddling with it all day. Simply extend the PHP view engine:
class Engine extends \Phalcon\Mvc\View\Engine\Php
{
/**
* Renders a view using the template engine
*
* #param string $path
* #param array $params
* #param boolean $mustClean
* #return string
*/
public function render($path, $params = null, $mustClean = null)
{
/**
* extract view params into current object scope
* so we can access them with <?=$this->foo;?>
* Maintains backward compat with all the .phtml templates written for Zend_View
*/
foreach($this->_view->getParamsToView() as $key => $val) {
$this->$key = $val;
}
return parent::render($path, $params, $mustClean);
}
You can use DI container to access any registered services in the view, so just put your variables into DI (in the action for example):
public function indexAction()
{
$this->getDi()->set('hello', function() { return 'world'; });
...
And then use it in the template via $this variable:
<div>
<?php echo $this->hello; ?>
</div>
P.S. This is not a good way to assign variables to the view, but should help in your particular case.

Magento - How I can Run Store by Country by GeoIP?

I want run store by IP of the customer.
In the backend of Magento, the user may configure the concret Store to load per country.
Taking a glance, I see the method at class Mage_Core_Model_App
public function run($params)
{
$options = isset($params['options']) ? $params['options'] : array();
$this->baseInit($options);
if ($this->_cache->processRequest()) {
$this->getResponse()->sendResponse();
} else {
$this->_initModules();
$this->loadAreaPart(Mage_Core_Model_App_Area::AREA_GLOBAL, Mage_Core_Model_App_Area::PART_EVENTS);
if ($this->_config->isLocalConfigLoaded()) {
//$scopeCode = isset($params['scope_code']) ? $params['scope_code'] : '';
//===============custom scope by country======================
$scopeCode = Mage::helper('custom/module')->getStoreByGeoip();
//===============custom scope by country======================
$scopeType = isset($params['scope_type']) ? $params['scope_type'] : 'store';
$this->_initCurrentStore($scopeCode, $scopeType);
$this->_initRequest();
Mage_Core_Model_Resource_Setup::applyAllDataUpdates();
}
$this->getFrontController()->dispatch();
}
return $this;
}
In my progress to get a good solution, I thought another alternative.
In the index.php write the next code:
Mage::app();
Mage::Helper('custom/helper')->getRunCodeByGeoio();
Mage::run($mageRunCode, $mageRunType);
I thinks this haven´t dangerous of performance because this method only create object if you not have before
/**
* Get initialized application object.
*
* #param string $code
* #param string $type
* #param string|array $options
* #return Mage_Core_Model_App
*/
public static function app($code = '', $type = 'store', $options = array())
{
if (null === self::$_app) {
self::$_app = new Mage_Core_Model_App();
self::setRoot();
self::$_events = new Varien_Event_Collection();
self::$_config = new Mage_Core_Model_Config();
Varien_Profiler::start('self::app::init');
self::$_app->init($code, $type, $options);
Varien_Profiler::stop('self::app::init');
self::$_app->loadAreaPart(Mage_Core_Model_App_Area::AREA_GLOBAL, Mage_Core_Model_App_Area::PART_EVENTS);
}
return self::$_app;
}
And my question is......
Are this the best approach for get the solution??
I think is very dangerous modify Mage_Core_Model_App even using rewrite
I don´t have any event at tier
Another option is made the business in the index.php but lost the management by the backend
Searching...., found a extension that cover many of my requirements,
http://www.mageworx.com/store-and-currency-auto-switcher-magento-extension.html
then I'll buy this or made a similar extension.
You shyould never touch any core files when developing with Magento, or any other application if you can avoid it.
Doing this will mean possible future upgrades will overwrite your changes and break your store.
The simplest way would be to do everything index.php as this is the entry point where the store is selected anyway, all you are doing is selecting the store on different criteria (ie IP address).
One simple way would be to use a free library, such as maxmind GeoLite: http://dev.maxmind.com/geoip/geolite
You can either load an apache module, or via a pecl extensions, or even plain PHP.
This will return you the iso country code for the country of your visitor.
You could then name your stores with a country iso code for the store code, and this will make it really simple to load the correct store depending on IP
something simple like this:
$countryCode = getUsersCountryCode(); // which ever method you use in here...
$stores = array(
'gb',
'us',
'fr',
);
if(in_array(countryCode, $stores)) {
Mage::run(countryCode, 'store');
}
else {
Mage::run($mageRunCode, $mageRunType);
}
You could of course make it into a Magento extensions, but this is by far the simplest way. You could even get a list of the countries/stores from Magento rather than hard coding them if you required.

Resources