In Magento 1, you could retrieve the current currency code by doing:
Mage::app()->getStore()->getCurrentCurrencyCode()
I'm wondering what is the recommended way of doing it in Magento 2. In my case in a block.
blockscurrencymagento2
In Magento 1, you could retrieve the current currency code by doing:
Mage::app()->getStore()->getCurrentCurrencyCode()
I'm wondering what is the recommended way of doing it in Magento 2. In my case in a block.
Ok so I am not sure if this is the bug but if you compare the Magento 1.8 and Magento 1.7 versions of the function currency in Mage_Core_Model_Local you will notice a reference to a bug with Zend_Currency
Magento 1.7: Mage_Core_Model_Local->currency
/**
* Create Zend_Currency object for current locale
*
* @param string $currency
* @return Zend_Currency
*/
public function currency($currency)
{
Varien_Profiler::start('locale/currency');
if (!isset(self::$_currencyCache[$this->getLocaleCode()][$currency])) {
try {
$currencyObject = new Zend_Currency($currency, $this->getLocale());
} catch (Exception $e) {
$currencyObject = new Zend_Currency($this->getCurrency(), $this->getLocale());
$options = array(
'name' => $currency,
'currency' => $currency,
'symbol' => $currency
);
$currencyObject->setFormat($options);
}
self::$_currencyCache[$this->getLocaleCode()][$currency] = $currencyObject;
}
Varien_Profiler::stop('locale/currency');
return self::$_currencyCache[$this->getLocaleCode()][$currency];
}
Magento 1.8: Mage_Core_Model_Local->currency
/**
* Create Zend_Currency object for current locale
*
* @param string $currency
* @return Zend_Currency
*/
public function currency($currency)
{
Varien_Profiler::start('locale/currency');
if (!isset(self::$_currencyCache[$this->getLocaleCode()][$currency])) {
$options = array();
try {
$currencyObject = new Zend_Currency($currency, $this->getLocale());
} catch (Exception $e) {
/**
* catch specific exceptions like "Currency 'USD' not found"
* - back end falls with specific locals as Malaysia and etc.
*
* as we can see from Zend framework ticket
* http://framework.zend.com/issues/browse/ZF-10038
* zend team is not going to change it behaviour in the near time
*/
$currencyObject = new Zend_Currency($currency);
$options['name'] = $currency;
$options['currency'] = $currency;
$options['symbol'] = $currency;
}
$options = new Varien_Object($options);
Mage::dispatchEvent('currency_display_options_forming', array(
'currency_options' => $options,
'base_code' => $currency
));
$currencyObject->setFormat($options->toArray());
self::$_currencyCache[$this->getLocaleCode()][$currency] = $currencyObject;
}
Varien_Profiler::stop('locale/currency');
return self::$_currencyCache[$this->getLocaleCode()][$currency];
}
My suggestion would be to try updating the try catch to match that of Magento 1.8 (I know this is not the best solution and obviously I would not suggest editing the core files but adding a rewrite)
I spent a few hours investigating this. I agree it is the same code due to
file: magento/app/design/frontend/rwd/default/layout/directory.xml
<default>
<reference name="head">
<block type="core/template" name="optional_zip_countries" as="optional_zip_countries" template="directory/js/optional_zip_countries.phtml" />
</reference>
<reference name="header">
<block type="directory/currency" name="currency" as="currency_switcher" template="directory/currency.phtml"/>
</reference>
<reference name="footer">
<block type="directory/currency" name="footer_currency" after="footer_store_language" template="directory/currency.phtml"/>
</reference>
</default>
The big difference is that the footer block is cached. You can make the footer currency changeer show the correct currency if you refresh the BLOCK_HTML cache in the Magento admin and then refresh the front page in your browser.
The RWD development team seem to have missed this in its test phase. I think you have uncovered a genuine bug in the RWD theme.
How to fix it?
Well I am not a Magento expert for sure and I would have thought adjusting
<?php echo $this->getChildHtml() ?>
to
<?php echo $this->getChildHtml('',false,true) ?>
in
file: magento/app/design/fromtend/rwd/default/template/page/html/footer.phtml
and
<?php echo $this->getChildHtml('footer') ?>
to
<?php echo $this->getChildHtml('footer',false,true) ?>
in
file: magento/app/design/frontend/rwd/default/template/page/3columns.phtml
with reference to:
file: magento/app/code/core/Mage/Page/Block/Html/Footer.php
public function getChildHtml($name='', $useCache=true, $sorted=true)
{
return parent::getChildHtml($name, $useCache, $sorted);
}
would have solved it (by requesting the childHtml not be built from the cache). But Magento cacheing remains an enigma to me. Maybe you know more about it and can resolve this by .phtml file manipulation alone.
The solution I have for you is to extend the class Mage_Page_Block_Html_Footer
(file magento/app/code/core/Mage/Page/Block/Html/Footer.php
) and rewrite the function getCacheKeyInfo()
to add a currency code to the cache key. This has the advantage that you can continue to benefit from the speed enhancement of the Magento cache:
file: magento/app/code/core/Mage/Page/Block/Html/Footer.php
/**
* Get cache key informative items
*
* @return array
*/
public function getCacheKeyInfo()
{
return array(
'PAGE_FOOTER',
Mage::app()->getStore()->getId(),
(int)Mage::app()->getStore()->isCurrentlySecure(),
Mage::getDesign()->getPackageName(),
Mage::getDesign()->getTheme('template'),
Mage::getSingleton('customer/session')->isLoggedIn(),
//an extra line for when the currency switcher is in the footer:
Mage::app()->getStore()->getCurrentCurrency()->getCode()
);
}
Are you familiar with creating your own module and rewriting classes? - That is the way to put this new cache key into your theme rather than editing the core class file.
Best Answer
In a block
In Magento 2, you can use the
\Magento\Store\Model\StoreManagerInterface
which is stored in an accessible variable$_storeManager
for every class extending\Magento\Framework\View\Element\Template
so most of the block classes (Template
,Messages
,Redirect
block types but notText
norTextList
).This way in your block, you can directly type the following code to get the current currency code:
No need to inject the
\Magento\Store\Model\StoreManagerInterface
in your construct as it's a variable accessible from any block class.In any other class
You can inject the
\Magento\Store\Model\StoreManagerInterface
in your constructor:Then call the same function as the block: