View Issue Details

IDProjectCategoryView StatusLast Update
0005659OXID eShop (all versions)[OXID ERP Interface] OXID ERP Interface - subpublic2017-01-17 10:43
ReporterMichaelZ 
PriorityhighSeveritycriticalReproducibilityalways
Status acknowledgedResolutionopen 
Platformno differenceOSno differenceOS Versionno difference
Product Version 
Target VersionFixed in Version 
Summary0005659: OXERPSetArticle deletes multi language data in conjunction with enabled caching
DescriptionWe found a problem considering updating article information using the ERP interface when the Content Cache is active.

We are currently using v2.11.0 of the ERP interface but as far as I can see (I looked at the changelog for the erp module on https://bugs.oxid-esales.com/) no bug has been fixed since this version that addresses this issue:

As far as we understand it, the erp interface works in "disabled multilanguage" mode, which means that during an update of say an article every article property is loaded in every language from the database (e.g. OXTITLE, OXTITLE_1, OXTITLE_2 and OXTITLE_3). All these properties are then updated and all the values are then written back to the database (including changed and unchanged values). Evidence that this behavior is actually intended may be found at the beginnig of oxERPType::saveObject() (objects/oxerptype.php:665sq) where oxI18n::setLanguage(0) and oxI18n::setEnableMultilang(false) are called on the created object.

Now this all works fine when caching is not involved as the data is always directly read from the database and as the multi language feature is disabled the data is read from the not language specific view, which is oxv_oxarticles_1 in our case, and therefore the shop object contains every property in every language after being loaded from the database.

When it comes to caching the oxArticle::_loadFromCache() method plays an important role. This method internally uses oxArticle::getCacheKey() to retrieve the cache key for the current article. oxArticle::getCacheKey() in turn does not respect the value of the oxI18n::$_blEmployMultilanguage property and always constructs the cache key following the pattern 'oxArticle_<articleId>_<shopId>_<languageIsoCode>'. In consequence, all properties are only loaded in one specific language in case the cache already contains an entry for the constructed key. The properties for the other languages are present (because the object has multilanguage mode disabled on the object) but empty (because they were not read from the cache). Let's say we now update the loaded article's price for example. At the moment the object is written back to the database the field for the other languages are overwritten with empty strings as the article object is missing values for the respective properties.

The result is, that all the values of multi language fields (except for language 0) are missing from the database after an article has been updated using the erp interface.

In order to quickly fix this problem, I created a module class for oxArticle containing the following method:

class ErpMultilangFixOxArticle extends ErpMultilangFixOxArticle_parent
{
    public function getCacheKey($articleId)
    {
        if($this->_blEmployMultilanguage)
        {
            return parent::getCacheKey($articleId);
        }

        if(!$articleId)
        {
            $articleId = $this->getId();
        }

        return 'oxArticle_' . $articleId . '_' . $this->getConfig()->getShopId();
    }
}

As you can see the cache key is constructed leaving the language iso code away in case oxI18n::$_blEmployMultilanguage is set to false on the oxArticle object. However I'm not quite sure if this problem should be fixed that way as, in my opinion, cache key generation and differentiation in cache key generation for different multi language settings should be done in the oxI18n class.

Can you please confirm this issue and provide information as to whether the fix we implemented is valid and does not cause any side effects that we are not aware of?
Steps To Reproduce1. Create an article for testing using the shop's backend. Specify at least one attribute in more than just the default language
2. Activate the "Default Cache Backend". We used Memcached, but as far as we understand the problem it doesn't make any difference which Cache Backend you use
3. Make sure a cache entry exists for the created article
4. Send an OXERPSetArticle call that updates just some properties (e.g. price).
5. Observe the article missing the information for the non default language fields.
TagsERP, Languages, Solution Provided
Theme
Browser
PHP Version
MySQL Version

Activities

There are no notes attached to this issue.