Revision handling in OXID

The revision is used to identify new or manipulated records in OXID. As OXID does not know revisions by default the connect module introduces a new table called makaira_connect_changes. To fill the revision table with data the module hooks into several OXID objects.

⚠️ When you are running a big data import by using OXID objects it might be costly to set the revision on each save event. Therefore we recommend the following approach while you are doing a lot of transactions.

<?php>

/* ... */

// instance of oxArticle
$oxArticle = oxNew('oxarticle');

// disable touch on save, delete, ...
$oxArticle->disableMakairaTouch();

/* ... */

// oxArticle is saved
$oxArticle->save();

/* ... */

// oxArticle is saved again
$oxArticle->save();

// call explicit touch for this product
$oxArticle->touch();
<?php

$sMetadataVersion = '1.1';

$aModule = array(
    'id'          => 'makaira/demo',
    'title'       => 'Makaira trim modifier',
    'files'       => array(
        'makaira_demo_modifier' => '<module_root>/makaira_demo_modifier.php',
    ),
    'extend'      => array(),
    'blocks'      => array(),
    'settings'    => array(),
);

ℹ️ The method disableMakairaTouch is provided by the Connect for the models oxArticle, oxCategory, oxManufacturer, and oxobject2category and disables the touch when saving or deleting the objects for the duration of the PHP process.


Modifier

As you know modifiers help you to transform data before they are sent to Makaira. We stronly recommend to develop your modifiers in a separate OXID module to ensure the compatibility and maintainability.
To do so the connect module comes with events that can be used to trigger the modifier. Please consider the usage of Makaira types during the development.

Example for removing blanks for a product title

The Modifier::apply() method is used to overwrite the default behavior.

<?php
$sMetadataVersion = '1.1';

$aModule = array(
    'id'          => 'makaira/demo',
    'title'       => 'Makaira :: Trim Title Modifier',
    'files'       => array(
        'makaira_demo_modifier' => '<module_root>/TrimTitleModifier.php',
    ),
    'extend'      => array(),
    'blocks'      => array(),
    'settings'    => array(),
);
<?php

namespace AwesomeShop\Makaira\Modifier\Product;

use Makaira\Connect\Modifier;
use Makaira\Connect\Type;
use Makaira\Connect\Type\Common\BaseProduct;

class TrimTitleModifier extends Modifier
{
    /**
     * Modify product and return modified product
     *
     * @param BaseProduct $product
     *
     * @return BaseProduct
     */
    public function apply(Type $product)
    {
        $product->title = trim($product->title);

        return $product;
    }
}
services:
  AwesomeShop\Makaira\Modifier\Product\TrimTitleModifier:
    tags:
      - { name: 'kernel.event_listener', event: 'makaira.importer.modifier.product', priority: -1, method: addModifier }

Once the modifier class has been created and can be loaded by the autoloader, it needs to be registered as a modifier. This is done in the services.yaml in the root directory of your OXID module.

For more information regarding the DI container, see Symfony-documentation and the OXID-blog.

List of available events for modifiers

Event nameModifier for
makaira.importer.modifier.productProducts
(parent products)
makaira.importer.modifier.variantVariants
makaira.importer.modifier.categoryCategories
makaira.importer.modifier.manufacturerManufacurer

📘

The loading of multiple modifiers can be specified via priority whereby the higher priority is loaded first.

The function of the modifier can be checked by calling the plugin endpoint with the corresponding action.

Migration from older connect modules

If you still have an OXID connect module which is based on the marmalade :: Yamm module, the container configuration must be migrated from dic.php to services.yaml.

<?php
$dic['awesome_shop.makaira.product_modifier.trim_title'] = static function () {
  return new \AwesomeShop\Makaira\Modifier\Product\TrimTitleModifier();
};
$dic->tag('awesome_shop.makaira.product_modifier.trim_title', 'makaira.importer.modifier.product', -1);

Field mapping

MakairaProduct (oxarticle)Category (oxcategory)Manufacturer (oxmanufacturer)
idOXIDOXIDOXID
titleOXTITLEOXTITLEOXTITLE
searchkeysOXSEARCHKEYSno default availableno default available
category_title-OXTITLE-
hidden-OXHIDDEN-
sortOXSORTOXSORT-
activeuse OXID model to get the active state as there exists some logic
longdescOXLONGDESCOXLONGDESC-
shortdescOXSHORTDESCOXDESCOXSHORTDESC
onstockuse OXID model to get the onstock status as there exists some logic--
manufactureridOXMANUFACTURERID--
category_title-OXTITLE-
priceOXPRICE--
insertOXINSERT--
soldamountOXSOLDAMOUNT--
ratingOXRATING--
picture_url_mainOXPIC1--
searchableOXISSEARCH--
stockOXSTOCK / OXVARSTOCK--
eanOXEAN / OXARTNUM--
maincategoryOXID of the main category
maincategoryurlSEO URL of the main category--

Templating

The OXID Connect module is shipped with several templates for the rendering of the Makaira responses. Those template are based on the flow theme and the corresponding blocks. Please have a look at the blocks section of the module to see which ones are used in the module. If they do not exist in your template set , please add them.

Filter section

The filer section is rendered on top of the product lists for consistency as the flow theme does not have a sidebar on each type where you can use filtering.

To render the filter we hooked into the blocks

Block nameTemplate
page_list_listbodypage/list/list.tpl
search_resultspage/search/search.tpl

You can overwrite those templates by the OXID standard mechanism to adjust templates. Just place your template files in your theme and they will be loaded as theme templates have a higher priority than the module templates in OXID.

Additional search results

Additional search results are shown by the template block search_results (page/search/search.tpl) which can be overwritten as well.

Filter customization

The connect module shipps with custom templates located under views/tpl/filter/custom/* which can be used to implement your own representation of a filter like color tiles. Just place the template into your theme folder as shown below.

<ul class="makaira-filter__list makaira-filter__list--colors">
    [{foreach from=$aggregation->values item="item" name="items"}]
        <li class="makaira-filter__color-item makaira-filter__color-item--[{$item->key|replace:" ":""}][{if $item->selected}] makaira-filter__color-item--active[{/if}]">
            <label>
                <input
                        type="checkbox"
                        name="makairaFilter[[{$aggregation->key}]][]"
                        class="makaira-input makaira-input--checkbox"
                        value="[{$item->key}]"
                        [{if $item->selected}]checked="checked"[{/if}]
                />
                [{$item->key}] [{if $blShowDocCount}]([{$item->count}])[{/if}]
            </label>
        </li>
    [{/foreach}]
</ul>
.makaira-filter__color-item {
    height: 30px;
    width: 30px;
    margin: 5px;
}

.makaira-filter__list--colors label {
    display: flex;
    height: 100%;
    font-size: 0;
    border: 1px solid #e6e7e7
}

.makaira-filter__color-item--Blau label {
    background-color: blue;
}

.makaira-filter__color-item--Clover label {
    background-color: #324D12;
}

// ...etc

Display variant image

Depending on the filter settings you might want to display the variant image instead of the parent when a color filter was chosen. This is possible by using the code below in your own module.

<?php

/**
 * @param array $productIds
 * @param Result $productResult
 * @return oxArticleList|oxarticlelist
 */
public function loadProducts(array $productIds = [], Result $productResult)
{
    /** @var oxArticleList $oxArticleList */
    $articleList = [];

    foreach ($productResult->items as $productItem) {
        $article = oxNew('oxarticle');
        $article->assign($productItem->fields);

        $article = $this->overrideImageIfColorFilterActive($article);

        $articleList[] = $article;
    }

    /** @var oxArticleList $oxArticleList */
    $oxArticleList = oxNew('oxarticlelist');
    $oxArticleList->assign($articleList);

    return $oxArticleList;
}

protected function overrideImageIfColorFilterActive($article)
{
    if (isset($this->query->aggregations['farbe'])) {
        $variantImage = $article->oxarticles__variant->rawValue['OXTHUMB'];

        if ($variantImage) {
            $article->oxarticles__oxthumb = new \OxidEsales\Eshop\Core\Field($variantImage);
        }
    }

    return $article;
}

Autosuggest

The autosuggest functionality is triggered by the default element for the search - an input with the ID #searchParam.
<input class="form-control" type="text" id="searchParam" name="searchparam" value="" placeholder="Search" autocomplete="off">

The response of asynchronous request to Makaira is rendered by the templates of the connect module. If you want to customize the rendering please adjust the given template as usual.

TypeTemplate
Productsviews/tpl/autosuggest/types/products.tpl
Categoriesviews/tpl/autosuggest/types/categories.tpl
Manufacturerviews/tpl/autosuggest/types/manufacturers.tpl
Searchable linksviews/tpl/autosuggest/types/links.tpl

Additionally, care was taken to keep the CSS specificity low to allow easy adjustments to the layout and styling through the CSS.

Reset sorting

The reset of the sorting can be done by overwriting the method getSorting() in the controllers alist, manufacturerlist and search.

<?php


public function getSorting($sSortIdent)
{
    $sortBy = oxRegistry::getConfig()->getRequestParameter($this->getSortOrderByParameterName());
    if ('none' === $sortBy) {
        $aSorting = oxRegistry::getSession()->getVariable('aSorting');
        unset($aSorting[$sSortIdent]);
        oxRegistry::getSession()->setVariable('aSorting', $aSorting);

        return null;
    }

    return parent::getSorting($sSortIdent);
}
[{block name="widget_locator_sort"}]
   ...
              
      [{* NEW LINK TO RESET THE SORTING *}]
      <li>
         <a href="[{$oView->getLink()|oxaddparams:"ldtype=$_listType&amp;_artperpage=$_artPerPage&amp;$_sortColumnVarName=none&amp;&amp;pgNr=0&amp;$_additionalParams"}]" title="NONE">Sort by:</a>
      </li>
      [{* END  *}]              
      
   ...
[{/block}]

Limits

Some OXID features are not covered by the connect module as they address special use cases.

  • Default Varnish caching of the EE high load option
  • Dynamic content caching of the EE on list pages
  • OXID EE oxfield2shop concept (there are solutions, depending on the scenario)
  • Indexing of SEO URLs of EE subshops
  • Attribute values with a slash (/) when the Generate SEO URLs for filtered category and manufacturer pages feature is enabled (see Allow encoded slashes on Apache)