Hybris CMS issue with pages in multicountry content catalog

Hybris OOTB have a bug in getting PageModel for multicountry content catalog. Issue is located in DefaultCMSPageService.getPageForId(id) method, which executes flexible search query for all session catalogs and returns (AbstractPageModel) pages.iterator().next(). In most cases it will return root global catalog page instead of page from country specific content catalog.

Idea of a fix is to filter pages which are not from country specific catalog. If page is from country specific catalog, than it would have assigned page.getOriginalPage() from parent content catalog. With help of this we can build hierarchy of dependend pages and take page, which is on bottom of hierarchy (page from most inner dependent catalog).

Possible implementation of such idea:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
  package com.blog.core.service.impl;

import com.google.common.collect.Iterables;
import de.hybris.platform.cms2.enums.CmsPageStatus;
import de.hybris.platform.cms2.exceptions.CMSItemNotFoundException;
import de.hybris.platform.cms2.model.pages.AbstractPageModel;
import de.hybris.platform.cms2.servicelayer.services.impl.DefaultCMSPageService;

import java.util.Collections;
import java.util.LinkedList;
import java.util.List;

public class CustomCMSPageServiceImpl extends DefaultCMSPageService {


    @Override
    public AbstractPageModel getPageForId(String id) throws CMSItemNotFoundException {
        List<AbstractPageModel> pages = this.getCmsPageDao().findPagesByIdAndPageStatuses(id, this.getCatalogVersionService().getSessionCatalogVersions(), Collections.singletonList(CmsPageStatus.ACTIVE));
        if (pages.isEmpty()) {
            throw new CMSItemNotFoundException("No page with id [" + id + "] found.");
        } else {
            List<AbstractPageModel> multiCountryPages = getMulticountryPages(pages);
            return Iterables.getLast(multiCountryPages);
        }
    }

    private List<AbstractPageModel> getMulticountryPages(List<AbstractPageModel> pages) {

        List<AbstractPageModel> originalPages = getAllOriginalPages(pages, new LinkedList<>());

        if (!originalPages.isEmpty()) {
            List<AbstractPageModel> onlyDependentPages = new LinkedList<>();
            for (AbstractPageModel page : pages) {
                if (!originalPages.contains(page)) {
                    onlyDependentPages.add(page);
                }
            }
            if (!onlyDependentPages.isEmpty()) {
                return onlyDependentPages;
            }
        }
        return pages;

    }

    private List<AbstractPageModel> getAllOriginalPages(List<AbstractPageModel> pages, List<AbstractPageModel> cumulativeOriginalPages) {
        List<AbstractPageModel> currentStepOriginalPages = new LinkedList<>();

        for (AbstractPageModel page : pages) {
            AbstractPageModel originalPage = page.getOriginalPage();
            if (originalPage != null) {
                currentStepOriginalPages.add(originalPage);
            }
        }

        if (!currentStepOriginalPages.isEmpty()) {
            cumulativeOriginalPages.addAll(currentStepOriginalPages);
            return getAllOriginalPages(currentStepOriginalPages, cumulativeOriginalPages);
        }
        return cumulativeOriginalPages;
    }


}

And don’t forget to replace bean in spring:

1
2
3
    <alias name="customCMSPageService" alias="cmsPageService"/>
    <bean id="customCMSPageService" class="com.blog.core.service.impl.CustomCMSPageServiceImpl"
          parent="defaultCMSPageService"/>
comments powered by Disqus