2016-05-17 6 views
1

Для моего проекта мне понадобилось несколько проектов тем для разных устройств, но в одном канале теперь можно выбрать только одну тему.Идея нескольких тем на одном канале в Sylius

Например, Если у меня есть канал «Япония», который продается в Японии, я хочу несколько тем для каждого устройства: мобильный, планшетный и ПК. Таким образом, пользователи будут видеть, что тема зависит от их устройства.

Мне нужны некоторые идеи о создании нескольких тем/стиля для разных устройств с одним каналом.

Итак, любые идеи?

ответ

2

Хорошо, поэтому сервис, отвечающий за текущую тему, - это услуга sylius.context.theme. Если вы используете полный стек Sylius, тогда будет использоваться ChannelBasedThemeContext (см.: https://github.com/Sylius/SyliusCoreBundle/blob/master/Theme/ChannelBasedThemeContext.php). Как вы можете видеть в исходном коде, он просто находит тему, которую вы установили по свойству темы themeName на текущем канале. Зная это, мы можем реализовать свои собственные путем внедрения ThemeContextInterface. Потому что в вашем случае вы, вероятно, захотите вернуться к поведению по умолчанию, когда темы japan_mobile не существует, мы собираемся украсить службу sylius.context.theme вместо того, чтобы ее заменять!

Итак, давайте начнем с создания Acme\AppBundle\Theme\DeviceBasedThemeContext:

namespace Acme\AppBundle\Theme\DeviceBasedThemeContext; 

use Sylius\Bundle\ThemeBundle\Context\ThemeContextInterface; 
use Sylius\Bundle\ThemeBundle\Repository\ThemeRepositoryInterface; 
use Sylius\Component\Channel\Context\ChannelContextInterface; 
use Sylius\Component\Channel\Context\ChannelNotFoundException; 
use Sylius\Component\Core\Model\ChannelInterface; 

final class DeviceBasedThemeContext implements ThemeContextInterface 
{ 
    /** 
    * @var ThemeContextInterface 
    */ 
    private $decoratedThemeContext; 

    /** 
    * @var ChannelContextInterface 
    */ 
    private $channelContext; 

    /** 
    * @var ThemeRepositoryInterface 
    */ 
    private $themeRepository; 

    /** 
    * @param ThemeContextInterface $decoratedThemeContext 
    * @param ChannelContextInterface $channelContext 
    * @param ThemeRepositoryInterface $themeRepository 
    */ 
    public function __construct(
     ThemeContextInterface decoratedThemeContext, 
     ChannelContextInterface $channelContext, 
     ThemeRepositoryInterface $themeRepository 
    ) { 
     $this->decoratedThemeContext = $decoratedThemeContext; 
     $this->channelContext = $channelContext; 
     $this->themeRepository = $themeRepository; 
    } 

    /** 
    * {@inheritdoc} 
    */ 
    public function getTheme() 
    { 
     try { 
      /** @var ChannelInterface $channel */ 
      $channel = $this->channelContext->getChannel(); 

      $deviceThemeName = $channel->getThemeName().’_’.$this->getDeviceName(); 

      // try to find a device specific version of this theme, if so, it will use that one 
      if ($theme = $this->themeRepository->findOneByName($deviceThemeName) { 
       return $theme; 
      } 

      // fallback to use the default theme resolving logic 
      return $this->decoratedThemeContext->getTheme(); 
     } catch (ChannelNotFoundException $exception) { 
      return null; 
     } catch (\Exception $exception) { 
      return null; 
     } 
    } 

    private function getDeviceName() 
    { 
     // here you should return the proper device name 
     return ‘mobile’; 
    } 
} 

Теперь, когда мы имеем контекст тема закончена, мы должны сделать контейнерный сервис признать это, мы делаем это, украшая существующий sylius.theme.context службы (ака ChannelBasedThemeContext).

Так что в вашем services.xml добавить следующие услуги:

<service id="acme.context.theme.device_based" class="Acme\AppBundle\Theme\DeviceBasedThemeContext" 
     decorates=“sylius.theme.context”> 
    <argument type=“service” id=“acme.context.theme.device_based.inner”/> 
    <argument type=“service” id=“sylius.context.channel”/> 
    <argument type=“service” id=“sylius.repository.theme”/> 
</service> 

И вы сделали! Если вы очистите кеши, теперь нужно попробовать сначала загрузить japan_mobile, если он не существует, он просто загрузит тему japan (при условии, что текущий канал имеет japan в качестве названия своей темы).

Я надеюсь, что это достаточно ясная инструкция, чтобы помочь вам двигаться, для инъекции службы, которая может обнаружить правильное имя устройства, не так сложно сделать, я думаю, но если вы не можете понять это, дайте мне знать и я продолжу это, реализуя это тоже.