Loading client views before default views, if exist

In my project (BtoB project) I have a global application with a lot of modules. Each module provides common functionality for all of my clients.

I also have a client folder in the root directory, in it I have all the features of the clients in their folder. Thoses folders are not modules. Therefore, they do not load Zf2. I usually load these features with abstractFactories.

This architecture is consistent with what I have:

-   clients
    -   clientOne
        -   Invoice
        -   Cart
        -   Orders

    -   clientTwo
        -   Invoice
        -   Orders

    -   clientThree
        -   Reporting

-   module
    -   Application
    -   CartModule
    -   InvoiceModule
    -   OrdersModule
    -   Reporting

, . . , , , .

, , :

-   client
    -   clientOne
        -   Invoice
        -   Cart
            -   View
                - cartView.phtml
        -   Orders

EDIT:

(@AlexP @Wilt) :

, ClientStrategy; it factory is Like This:

<?php
namespace Application\View\Strategy;

use Zend\ServiceManager\FactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;

use Application\View\Resolver\TemplateMapResolver;
use Zend\View\Resolver;

class ClientStrategyFactory implements FactoryInterface
{
    public function createService(ServiceLocatorInterface $serviceLocator)
    {
        $viewRenderer = $serviceLocator->get('ViewRenderer');
        $session = new \Zend\Session\Container('Session');

        $map = $serviceLocator->get('config')['view_manager']['template_map'];
        $resolver = new Resolver\AggregateResolver();
        $map = new TemplateMapResolver($map, $this->clientMap($session->offsetGet('cod_entprim')));

        $resolver
            ->attach($map)
            ->attach(new Resolver\RelativeFallbackResolver($map));

        $viewRenderer->setResolver($resolver);

        return new ClientStrategy($viewRenderer);
    }


    /**
     * permet de retourner le namespace du client selectionné avec la relation codpriml / nom de dossier
     * @return array
     */
    public function clientMap($codprim)
    {
        $clients = array(
            21500 => 'clientOne',
            32000 => 'clientTwo',
            // ..
        );

        return (isset($clients[$codprim])) ? $clients[$codprim]: false;
    }
}

clientMap , , , :

class ClientOne
{
    /**
     * get The main Code
     * @return integer
     */
    public function getCodEntPrim()
    {
        return 21500;
    }

    /**
     * Load all customs views
     * @return array
     */
    public function customViews()
    {
        return array(
            'addDotations' => __DIR__ . '/Dotations/view/dotations/dotations/add-dotations.phtml',
        );
    }

    /**
     * GetName 
     * @return string
     */
    public function getName()
    {
        return get_class();
    }
}

, TemplateMapResolver, , :

<?php
namespace Application\View\Resolver;

class TemplateMapResolver extends \Zend\View\Resolver\TemplateMapResolver
{
    /**
     * Client name to use when retrieving view.
     *
     * @param  string $clientName
     */
    protected $clientName;

    /**
     * Merge nos vues avec celle clients avant de repeupler l'arrayMap global
     * @param array $map [description]
     */
    public function __construct(array $map, $client)
    {
        $this->setClientName($client);
        if ($this->getCLientName()) {
            $map = $this->mergeMap($map);
        }
        parent::__construct($map);
    }

    /**
     * Merge les map normales avec les map clients, pas propre ?
     * @param  array $map
     * @return array
     */
    public function mergeMap($map)
    {
        $name = $this->getClientName() . '\\' . $this->getClientName() ;
        $class = new $name;
        $clientMap = $class->customViews();
        return array_replace_recursive($map, $clientMap);
    }

    /**
     * Retrieve a template path by name
     *
     * @param  string $name
     * @return false|string
     * @throws Exception\DomainException if no entry exists
     */
    public function get($name)
    {
        return parent::get($name);
    }

    /**
     * Gets the Client name to use when retrieving view.
     *
     * @return string
     */
    public function getClientName()
    {
        return $this->clientName;
    }

    /**
     * Sets the Client name to use when retrieving view.
     *
     * @param mixed $clientName the client name
     *
     * @return self
     */
    public function setClientName($clientName)
    {
        $this->clientName = $clientName;

        return $this;
    }
}

, , :

  • My template_path_stack , .
  • , , , .
  • .
  • , , .
+4
4

, , , . , - , , .

:

/**
 * Factory permettant d'établir que les vues client soient chargé si elle existent, avant les vues par défaut.
 */
class ClientStrategyFactory implements FactoryInterface
{
    public function createService(ServiceLocatorInterface $serviceLocator)
    {
        $viewRenderer = $serviceLocator->get('ViewRenderer');
        $session = new \Zend\Session\Container('Session');
        $clientList = $serviceLocator->get('Config')['customers_list'];
        $clientName = $this->clientMap($session->offsetGet('cod_entprim'), $clientList);
        $clientMap = new TemplateMapResolver($clientName);
        $viewRenderer->resolver()->getIterator()->insert($clientMap, 2);

        return new ClientStrategy($viewRenderer);
    }


    /**
     * permet de retourner le namespace du client selectionné avec la relation codpriml / nom de dossier
     * @param integer $codprim
     * @param array $clientList
     * @return array
     */
    public function clientMap($codprim, $clientList)
    {
        return (isset($clientList[$codprim])) ? $clientList[$codprim]: false;
    }
}

, TemplateMapResolver clientName, . : Resolver, Resolver :

$viewRenderer->resolver()->getIterator()->insert($clientMap, 2);

, ( - 1)

My TemplateMapResolver , :

 public function __construct($client)
    {
        $this->setClientName($client);
        if ($this->getCLientName()) {
            $map = $this->getMap();
        } else {
            $map = array();
        }
        parent::__construct($map);
    }

    /**
     * Return all custom views for one client
     * @param  array $map
     * @return array
     */
    public function getMap()
    {
        $name = $this->getClientName() . '\\' . $this->getClientName() ;
        $class = new $name;
        return $class->customViews();
    }

, , , clientName - TrumanShow, , :

- [clients]
-- [TrumanShow]
--- TrumanShow.php
--- [Cart]
---- [view]
----- [cart]
------ [index]
------- cart-view.phtml
--- [Invoice]
--- [Reporting]

, :

/**
     * Ici nous mettons nos custom views afin de les charger dans le template Map
     * @return array
     */
    public function customViews()
    {
        return array(
            'cartView' => __DIR__ . '/Cart/view/cart/index/cart-view.phtml',
        );
    }

, template_path_stack . setTemplate , :

// code ...

public function cartAction() {
    $view->setTemplate('cartView');

    return $view;
}

ZendFramework , , .

@Wilt @AlexP .

+1

( , ), TemplateMapResolver Renderer.

:

<?php
Application\View\Resolver

class TemplateMapResolver extends \Zend\View\Resolver\TemplateMapResolver
{
    /**
     * Client name to use when retrieving template.
     *
     * @param  string $clientName
     */
    protected $clientName; 

    /**
     * Retrieve a template path by name
     *
     * @param  string $name
     * @return false|string
     * @throws Exception\DomainException if no entry exists
     */
    public function get($name)
    {
        if ($this->has($clientName . '_' . $name)) {
            return $this->map[$clientName . '_' . $name];
        }
        if (!$this->has($name)) {
            return false;
        }
        return $this->map[$name];
    }
}

- :

$resolver = new TemplateMapResolver();
$resolver->setClientName($clientName);

// Get the renderer instance 
$renderer->setResolver($resolver);

. , ? ... . , .

, cart_view , client_name_cart_view, , cart_view.

UPDATE

, , ClientViewModel, ViewModel.
ClientViewModel , :

new ClientViewModel($client, $template, $variables, $options);

$variables $options parent::__construct ( ViewModel)

Application\View\ClientStrategy.

, ViewRenderer TemplateMapResolver. ViewModel TemplateMapResolver .

, . , , .

, ViewModel JsonModel , ClientViewModel . , .

+2

  • ,

, TemplateProviderService, .

interface ViewTemplateProviderInterface
{
    public function hasTemplate($name);
    public function getTemplates();
    public function setTemplates($templates);
    public function getTemplate($name);
    public function setTemplate($name, $template);
    public function removeTemplate($name);
    public function removeTemplates();

}

.

// Some controller class
public function fooAction()
{
   $view = new ViewModel();
   $view->setTemplate($this->templateProvider->get('some_view_name'));

   return $view;
}

, script config . , , , .

class ViewTemplateProviderFactory
{
    public function __invoke($sm, $name, $rname)
    {
        $config = $sm->get('config');

        if (! isset($config['view_template_providers'][$rname])) {
            throw new ServiceNotCreatedException(sprintf('No view template provider config for \'%s\'.', $rname));
        }

        return new ViewTemplateProvider($config['view_template_providers'][$rname]);
    }
}

- , , "view_manager" , .

Edit

factory config (. ).

return [
    'view_template_providers' => [
        'ClientOneTemplateProvider' => [
            'some_view_name' => 'name_of_script_1'
        ],
        'ClientTwoTemplateProvider' => [
            'some_view_name' => 'name_of_script_2'
        ],
        'ClientThreeTemplateProvider' => [
            'some_view_name' => 'name_of_script_3',
        ],
    ],
    'service_manager' => [
        'factories' => [
            'ClientOneTemplateProvider'   => 'ViewTemplateProviderFactory',
            'ClientTwoTemplateProvider'   => 'ViewTemplateProviderFactory',
            'ClientThreeTemplateProvider' => 'ViewTemplateProviderFactory',
        ],
    ],
    'view_manager' => [
        'template_map' => [
            'name_of_script_1' => __DIR__ . 'file/path/to/script',
            'name_of_script_2' => __DIR__ . 'file/path/to/script',
            'name_of_script_3' => __DIR__ . 'file/path/to/script',
        ],
    ],
];
+2

. ViewModel .

$vm = new ViewModel();
$vm->setTemplate( $user_service->getTemplate( $this->getRequest() ) );
return $vm;

, , , .

The concern of $ user_service should be completely incomparable with taking care of your Controller action.

-1
source

Source: https://habr.com/ru/post/1619500/


All Articles