Session handling in OXID eShop 6

With OXID eShop 6, there will be some changes in the session storage system. Until now there was the regular PHP session handling using the file system. Optionally, with the config option blAdodbSessionHandler, a feature of ADOdb lite was used to store sessions directly to the OXID database.

As we replaced ADOdb lite with the more modern Doctrine DBAL database layer, this feature will not be available any longer. There are clever alternatives that will make your OXID eShop project even more scalable, better performing and getting better fail-over capabilities.

When working on regular web space, a vServer or even a root server, nothing will change for you. This blog post is interesting for you if you’re running multiple application servers or hosting in the scalable cloud.

Sticky Sessions

By default, PHP handles sessions on basis of the file system. This works perfectly as long as you run a small or medium sized online business with one server or a hosting package. Although this solution is very easy to implement, there are some disadvantages when it comes to multiple application servers with an upstream load balancer:

A load balancer assigns the first client request to a physical application server (see figure below), and all following requests of this client to the same physical server. In order to remember the client, the load balancer tries to identify it via:

  • it’s IP address
  • TCP payload offset and length
  • HTTP query string elements
  • header field values
  • cookies
  • etc.


As mentioned above, using sticky sessions, sessions are saved locally in the file system of the application server. This may provoke problems if a client with an active session is assigned to another application server because his session data is suddenly lost. This may occur for example if

  • the application server has to much load and the load balancer can’t assign more clients to this application server
  • during the maintenance time of an application server
  • a user is not identified correctly because it’s IP changes, NAT networking, etc.

Non-sticky sessions

In order to resolve these issues, there’s another concept known as “non sticky sessions”. In this scenario, the load balancer may assign any of the physical application servers to serve a request. The session data is saved centrally:


Until now we supported the non-sticky session concept by writing the sessions into the OXID database via ADOdb lite using the OXID eShop option blAdodbSessionHandler. Unfortunately, using the application server database as session storage, has some disadvantages as well:

  • the more application servers used, the less scalable it is to use the application server database.
  • the application database server gets even more load by the sessions. Sessions ususally have a read/write ration of 1/1.
  • the application database can become very large.

Use your own session storage

ADOdb lite was replaced with Doctrine from OXID eShop 6 on, so the feature of writing sessions by simply switching on an option is not available any longer.

Also, there are manifold other solutions out there for session handling like Memcached Session Manager or Redis. The setup is simple as there are already PHP plugins available (php5-redis) – you just have to tell your PHP installation to use Redis as a session handler. Please read this blop post for more information:

If you want to store your sessions into a database anyway, you have the possibility to write your own session handler. Here are some hints on how to do that. First, you have to implement a class which has access to your session storage and implements some standard methods like read and write (like the old adodb class core/adodblite/session/adodb-session.php).

In order to make this class work with OXID eShop, you have to extend the OXID eShop Session class with a module.

If you have questions, please don’t hesitate to comment this blog post.

Language handling

Translation and language maintenance software

For translations and maintenance of language keys, we decided to use oTrance, the Online Translation Center (available under GPLv2) and installed it on

Download language packs

You cannot help with language translations? No problem. Simply go to to get logged in as a guest.

If you need help with the translation software, please refer to this wiki page where the handling with a guest account is explained:

There’s also a forum available for your questions at

If you are familiar with using GitHub, you can also check out for available languages. will export to this repository regularly.

Additionally, we offer downloads of single language packs (per language) marked as “OK” or “perfect” from the download area of this site.

Help translating

If you want to help translating and/or maintaining the languages, please register at After that, please wait for the system administrator to activate your account before you can start translating.

If you want, you can also maintain your translations with this tool. The advantage is that there will be no hassle with character encoding or possible mistakes – for example, if you forgot a comma or a quote.

If you have already files translated into your language, please send them to We will import them into the system and make them available to the community.

If you need help with the software, please refer to this wiki page where is explained how to use oTranCe as a translator:

There’s also a forum available for your questions at

For OXID specific translation questions and announcements please refer to

But first, you might want to watch this screen cast about working with oTranCe as a translator:

Installation of new languages in OXID eShop

  1. Download the language packages from oTranCe.
  2. Extract them and upload them to the according paths of your shop installation.
  3. Go to the admin panel of your OXID eShop installation -> Master settings -> Languages. Add a new language and enter the abbreviation according to the one you found in oTranCe.
  4. In admin panel, go to Service -> Tools and push the “Update views” button.
  5. Clear the tmp/ folder in your installation and refresh your page.
  6. You are done 🙂

Language maintenance for German and English

OXID will take over the language maintenance for German and English as it will be delivered with each standard copy of OXID eShop in any edition. Any other translations can be contributed, maintained and downloaded by community members for free use under GPLv3 license. With every stable release of OXID eShop, OXID will update the oTranCe database with both languages. You don’t have to register at for helping with German or English 🙂 If you found something strange like a misspelled word or another typo in one of both languages, please simply open up a bug for it at or send a pull request via GitHub.

Integration with GitHub

oTranCe is able to export the ready-to-use language files to any SVN as well as to GitHub:

Here, we added map.php files, flags as well as transliteration lists. These files are also provided when downloading the package from

File structure

Digging deeper – which files to touch for translations

On we already use file templates for export so the right format. The exact number of files and the right folder structure will be available in the download packages.

The following points are just for your information.

Translating the store front, using the standard template “Azure”

If you want to translate the store front using “Azure” or a derived work from it, you have to translate the following files:

  • /application/translations/{LOCALE}/lang.php
  • /application/view/azure/{LOCALE}/lang.php

Translating the administration area

If you want to translate the administration area you have to translate the following files:

  • /application/views/admin/{LOCALE}/lang.php
  • /application/views/admin/{LOCALE}/help_lang.php
  • /application/views/azure/{LOCALE}/theme_options.php

Translating the setup

If you want to translate the setup routine you have to translate the following files:

  • /setup/{LOCALE}/lang.php

Other language related files

There’s a number of files related to languages but not to translations. These files are already implemented in the download packages on


Of course, a language needs a flag, doesn’t it 🙂 That’s why we put a flag into the language pack the first time we get in touch with that language. This can be when a translation is started, when we get language files or even when somebody registers for this translation at

The size of the flag is theme dependent, that’s why it was put to the folder /out/{theme}/img/lang/. So an image file with a language flag for the theme “azure” can be found at /out/azure/img/lang/{locale}.png and is adjusted to 14 x 10 px.

If you want to translate into a new language not listed yet we’d appreciate if you could provide the flag either by a pull request on GitHub or by sending it to

Transliteration lists

Why is a transliteration needed and what it is used for?
Well, in some languages you don’t just use pure Latin characters but also so called “Umlauts” for pronouncation purposes. In case these “Umlauts” appear in the title of a product, the class oxseourl tries to form a proper URL from it.

Just an example: If you sell belts, the German translation for it would be “Gürtel”, using the Umlaut “ü” in the product title. If you didn’t enter any transliteration, oxseourl would swallow the “Umlaut” and the URL would go like But who the heck of your potential customers is googling for “grtel”? So the correct URL should be as the search engines would understand “ue” for “ü”. For this reason, there has to be a transliteration array telling OXID eShop how to transliterate special characters like “ü” shall become an “ue” in the URL which is applicable.

Talking about non-Latin-based languages, it becomes even more complex. Let’s talk about Russian using the Cyrillic script. Here, the transliteration list is pretty much longer, containing “я”, “ю” and “ж” which can be transformed to “ya”, “yu” and “zh” in the URL.

In this manner, Cyrillic is still pretty simple as it uses just different characters. Another challenge are Asian languages as their scripts describe syllables as well as entire words. We are not really sure if pinyin for Chinese, for example, can resolve this 😉

Until OXID eShop v4.5, transliteration lists have been stored in the OXID eShop database. Maintenance was held inside the admin panel: Master settings -> Core settings -> SEO -> Characters which are replaced in SEO URLs.

In OXID eShop version 4.6, we stored transliteration lists inside the language files where needed. In version 4.7/5.0, the transliteration lists disappeared from the admin panel and will be stored separately from the general language files but at the same level as translit_lang.php, for example:

We’d be glad if you could share your transliteration lists with the community. Simply send a pull request via GitHub or drop an email to if you’re not familiar with version control systems.

Language key mapping – what is map.php

With the introduction of theme handling in OXID eShop 4.5.0, there were different language strings for each theme. We were using two different theme-dependent language files for the basic and azure themes. To make this system more flexible and to avoid redundancy and repetition in language constants, we moved to a generic language file which is valid for all themes (even self-made themes) in version 4.5.1.

By this, it is possible to use different language strings per theme. Of course, the override functionality is still available for all of these files, so your system will remain easily updatable as long as you make use of the cust_lang.php file.

We implemented a mapping file to enable mapping between the generic language constants and the theme-specific constants. This is to ensure maximum flexibility when updating the system. In most cases, the language constants from the azure theme will be simplified and used as the basis for generic constant names.

Example: You will notice that there are many different definitions for email in both, your custom and azure theme, like the examples below:

The new generic language file has only one constant for email:

The mapping array will take care of defining the basic and azure theme constants’ relationships with the generic language file:

If a theme needs to change specific constants, it can do this by redefining the constants inside the theme-specific language file:

Language override system – cust_lang.php

For your own customizations, you can use custom language files per theme (remember that these will be excluded from update packages as well as from language packs). And if you’re a user of OXID eShop Enterprise Edition, there is also another override level for your subshops.

To summarize, the priority for language handling will be like this:

custom language file -> theme language file -> subshop language file -> general language file

Running tests using OXID testing library


This tutorial will show how to run unit/integration and selenium tests on OXID eShop using OXID testing library.

For tutorial I was using these versions of software:

Environment preparation

First of all you need to meet requirements for testing library: Also you’ll need module, which will have to be tested. In my case I have module called “example” which is under vendor “mv”.

Now in OXID eShop source directory create composer.json file with content which is described here: From now source directory file structure looks like this:

Locate with console to eShop source directory:

And run composer installation command:

Composer will do its job and shortly you’ll have to define 3 parameters:

  1. shop_path – your eShop location. If you are using default structure, you can leave it empty and click enter.
  2. shop_tests_path – eShop tests location. This one also can be left empty, as we are using default structure.
  3. partial_module_paths – module locations. This parameter should be set as we want to test our module. Type vendor name and module name:

    If you would have more modules, you could set paths separated with commas:

BTW: it’s possible to change these parameters in file which is newly generated and is called test_config.yml and locates in source directory.

 Creating tests

To run tests with OXID testing library you’ll have to define structure of directories as described bellow:

Unit/Integration tests

Let’s say we want customer would see additional text in mini basket, so for this purpose let’s overload oxArticle with our own class and let’s add functionality:

I know that it’s probably not the most beautiful code you have ever seen, but don’t forget that it’s only an example :) To test new functionality we have to write unit tests class which must extend oxUnitTestCase:

Here we have 2 test cases. To run only these test cases and not to run eShop tests, we need to change parameter run_tests_for_shop value in test_config.yml to “false”:

or when executing runtests command tests add environmental parameter in console:

When I executed command I got this output:

In this way you can run your modules tests + eShop tests, check test_config.yml for possible options.

Acceptance tests

Acceptance tests run using browser and executes any scenario you want. In OXID these tests run using selenium server which can be downloaded here.

First of all we need to activate it, because testing library has no such functionality at this moment. So activation part is up to you. I’ll just go to OXID admin and activate it.

We also don’t want to lose module activation changes in database during test run, so we will have to change test_config.yml file:

As now everything is prepared we can create test file called MiniBasket.php in acceptance tests directory:

Newly created test should extend oxAcceptanceTestCase:

Test adds to basket one product and checks if element with id – countValue has expected text.

So now we have activated module and test class. We can run the test with command:


LESS Layers

Lately I was thinking about a nice way of implementing Twitter Bootstrap and maybe other vendor libraries into my private eShop project. My main problem was: how can I keep it extendable, but yet simple enough to switch parts of the implementation very easily? I came up with a design sketch which might be a little bit over the top, but hey! No risk, no fun!

Some Forethoughts

First of all, I should emphasize that I will focus on LESS files only in this article. Many frontend libraries come with Javascript components too, but I didn’t thought about them yet. But I think that the following approach is also appliable for Javascript as well.

Second, my theme definitely will be extended by another developer or a customer in the future, so it should have a very maintainable structure which is also easy to understand (Note to myself: add some documentation!). I also will need some kind of graduated abstraction so that I can easily refactor parts of my implementation.

Now try to imagine the whole thing as a nice Black Forest Cake with its specific layers. It must be possible to add more layers to the cake as well as adding multiple ingrediences within a layer. So with this picture in your mind, let’s crack on!

Add LESS Layers

Implementing Vendor Libraries

01-vendor-libraries First, let’s add some vendor libraries, e. g. our frontend framework, Twitter Bootstrap. I also added a corresponding file to the libraries directory which contain styles to overwrite Bootstrap defaults. This way, it should be very easy to implement new versions of Bootstrap via Bower or something similar.

To continue with LESS Layers, we need some kind of base for our theme now. After implementing all vendor libraries, this base will contain stuff which will affect the global scope of our theme.

Starting the Theme Base

02-theme-base As a theme base I will definitely need some variables to declare font faces, grids and other stuff I want to store at a central place. Additionally, I want to declare some LESS Mixins. In the past, I saw some implementations with different files for utilities, helpers and so on, but I don’t see the necessity for this differentiation (if you do, please let me know down below in the comments!).

All these files will be imported BEFORE the vendor libraries so that the styles which overwrite e. g. Twitter Bootstrap can use that declarations.

Paint the Bigger Picture

03-theme Now here it comes! I splitted my theme related stuff into global styles and template specific stuff and imported it via a theme.less file (just for convenience purposes).

In my experience you will definitely run into trouble if you work with template related styles only, because that will cause doublettes in your compiled CSS as well as a lot of efford to refactor all that crap. And YES: this. is. crap! Don’t deny it …

The structure of my global styles is kind of copied from Twitter Bootstrap, so you will find a media.less (for images, videos, …) and a typography.less (font faces, lists, blockquotes etc.) file. The structure will be extended as needed.

04-final Next, I added some template based files, meaning that these last styles are specifically only for that single piece/ page. As you can see in the theme.less file, I grouped all page related files so that I can overwrite partials in the main file for that specific page.

At least, you can add some kind of documentary comment on top of your style.less file, e. g. in the WordPress format or with some copyright hints and rules. You should beware of the different comment types in LESS, which is also the reason why I mostly two slashes (“// …”) for comments.

I know, that’s a lot of stuff to swallow. I hope that my explanations were clear, but if you have questions, don’t hesitate and write a comment! Constructive criticism and helpful tips are also very welcome. A .zip download of the shown structure will be provided later on. All files except style.less and theme.less will contain an explanatory comment only, so feel free to fill it with life by yourself.

So, I hope you enjoyed that “little” explanation of LESS Layers, and I am really looking forward for some feedback!

BR Matt

Edit: as promised, LESS Layers as a .zip-Archive. Feel free to download!



Build an Infinite Scroll List for OXID eShop – Implementation

In the previous part we have examined the step-by-step process of back-end implementation for the module serving the infinite scrolling list. We also added some code for the controller but it didn’t bring any clear-cut result at that moment.

This second part will help you finish the remaining tasks to achieve an infinite scrolling list. Let’s see how to work with the new template and JavaScript code to handle the logic of infinite scrolling. I will then show you the proper way of activating a new module, and will include some hints that will keep you away from unexpected issues.

Customizing the OXID locator bar

It feels pretty good to find out you only have to replace some blocks of the current template. Sometimes, you don’t get that lucky, and you need to have a whole template file replaced.

Please open the template /application/views/azure/tpl/page/list/list.tpl, copy its content and paste it into the new file /modules/aho_infinitescroll/views/page/list/aho_infinitescroll_list.tpl.

Open the file aho_infinitescroll_list.tpl, and search for the line containing the following code:

  • locator=$oView->getPageNavigationLimitedTop() will display the traditional pagination that will no longer be necessary.
  • listDisplayType=true lists out all available view options. We don’t need this either. The new module will use the view type defined in the module’s settings.
  • itemsPerPage=true determines whether the user can select how many articles to display per page. In this tutorial, we also turn off this feature.
  • sort=true controls the sorting conditions. We’ll leave this on.

Let’s examine the below figure to study the locator’s elements with their corresponding position:

"locator noted"

Please replace the above line with the below line to drop unnecessary elements:

We also look for and remove the following line to turn off the bottom locator:

Here is the result:

"final Locator bar"

Implementing Infinite Scrolling Load

1- Preparing the stylesheet

Open the file /modules/aho_infinitescroll/out/css/infiniteloading.css and paste the following code:

2- HTML elements
Reopen aho_infinitescroll_list.tpl. After the line of including the template locator.tpl, we put the following lines:

  • The first line defines a variable to get the proper module’s URL. If you have several JavaScript or CSS files to include, this will be really useful. Please note that you should never add any raw URL for such files, they may fail to load due to different OXID versions.
  • The second line will include a stylesheet for this module.
  • The third line adds a div that will temporarily hold next-page loaded articles.
  • The next block will create a wrapper with two subsequent elements: loader icon and button to trigger an Ajax request.

The result after applying CSS will be:

"List with CSS"

3- Adding JavaScript code

Put the below JavaScript code into the opening aho_infinitescroll_list.tpl, just after div.loader-container

  • The first line defines an important template variable. It will fetch essential values such as total pages, current page, next page, first page, last page and URLs for each page returned. You can use [{$pages|var_dump}] to examine all values of $pages.
  • The remaining code implements the logic of infinite loading with the below workflow.
    • We will have an extra button to trigger the request to load articles of the next page.
    • A hidden loading image toggles to prevent re-clicking.
    • New articles will be appended to the end of the list.
    • Every click of the button will repeat that process until there are no more articles to be loaded. At that moment, the button is disabled.

4- Front-end translation

Please go to /modules/aho_infinitescroll/translations/.
For bothen/aho_infinitescroll_lang.php and de/aho_infinitescroll_lang.php, we add the following:

Please assign the correct value of variable $sLangName for each file. The name of the front-end language file always follows this formula:

module folder name+ _ + lang.php

Activating the module

Activating the module usually seems totally effortless with a couple of clicks in the back-end. Sometimes, however, the module might not work for an unknown reason. If you encounter such a problem, please check the following steps:

  • If you make any changes in metadata.php, you have to disable the module, then re-enable it.
  • If you have made any changes relating to the database, you have to update the database view. You can do it via Service > Tools > Update DB Views now.
  • You have to clear the tmp folder after any changes.
  • You should always set proper permission mode for /log/EXCEPTION_LOG.txt to inspect the logs.

To help your testing to go well, you can go to the back-end and decrease the number of items per page.
Go to Extensions > Themes > {Pick active theme} > Settings > Display, change the value as in the follwing figure:

"config change"

The above adjustment is just for OXID’s default data, which has few articles . If you already have a long-list of articles of your own data installed, that change is unnecessary.

Further Enhancements

There will be a variety of approaches to implement infinite scrolling for OXID eShop. We’ve attempted to bring you an essential implementation from back-end to front-end. There will be a lot of improvements that you can do for this module:

  • Using a third party jQuery plugin to achieve infinite scrolling effect instead of using manual trigger. You can grab a good plugin from by Paul Irish.
  • We have set the view option to line as default value. You can customize this to make it work for all view options.
  • Applying the SEO-friendly approach for your module. This article seems very helpful for reference.
  • Extending the functionality to the search page.


You can watch the final result on YouTube and download the code from GitHub.

Despite the old-fashioned appearance of the back-end, OXID eShop is flexible enough to achieve as much functionality as other e-commerce systems. I hope this tutorial taught you something new, and that you may find out that OXID is a worthy option to consider for your next e-shop.

Please feel free to share your perspectives with me in the comments below!

How to move a database bigger 2MB

How to move a database > 2MB


Most hosting provider set the limit to the PHP upload function to 2MB which makes it not easy importing databases > 2MB to your new installation if you use e.g. phpMyAdmin as your database management tool. For this cases, you might want to install another application that works differently like MySQL Dumper or use just the most easy way if you have SSH access to your server.

  • Upload the sql file to your server.
  • Move to the folder the sql file is situated.
  • Use the following command to insert the sql file to your database

    Of course, you have to replace the values for [database_user] – your specific database user [database_password] – your spacific database password [Port] – the portnumber of your database in case it is different then 3306 [your_file] – your source database dump
  • Take care: No progress bar is shown while uploading the dump. For huge databases, just wait for the next prompt.


For dumping your existing database > 2MB to a sql file, type the following:

[Update 30th June 2016]

In case Profihost is your hosting provider, please use the following command for a database dump: