eZ Community » Forums » eZ Publish 5 Platform » How to properly inject our own legacy...
expandshrink

How to properly inject our own legacy controller

How to properly inject our own legacy controller

Wednesday 05 June 2013 3:11:10 pm - 8 replies

The use case is simple : we need to properly alter the behavior of the LegacyKernelController's indexAction. It looks that there's no way to controle the Response object from elsewhere, so I'm now trying to inject my own LegacyKernelController or anything I could... Any hints would be appreciated happy.gif Emoticon

Note : In our specific case, we are trying to reproduce a similar behavior to what was possible to do with the HTTPHeaderSettings section in site.ini... This feature seems to be not working through the legacy kernel controller and we always get cache-control=private headers whatever we do... Hacking the legacy kernel controller to add something like $response->set(MaxAge|Public)() is part of the solution but we don't want to hack the original one for long term maintenance consideration...

Wednesday 05 June 2013 3:39:12 pm

Asking for feedback. Got something working but I'm not sure if it's the right way :

1. Create a new bundle

2. Modify YourBundle/.../services.yml to override ezpublish_legacy.controller.class such as

parameters:
    ezpublish_legacy.controller.class: MyVendorName\EzPublish\LegacyBundle\Controller\MyVendorNameLegacyKernelController

3. In MyVendorNameLegacyKernelController

<?php
 
namespace MyVendorName\EzPublish\LegacyBundle\Controller;
 
use eZ\Bundle\EzPublishLegacyBundle\Controller\LegacyKernelController as LegacyKernelController;
 
class MyVendorNameLegacyKernelController extends LegacyKernelController
{
    public function indexAction()
    {
        $response = parent::indexAction();
        $response->setPublic();
        $response->setMaxAge( 300 );
        $response->setSharedMaxAge( 300 );
        return $response;
    }
}

Is this correct ? How am I sure that my services.yml file will be always loaded on top of the original one ?

Modified on Wednesday 05 June 2013 3:39:35 pm by Arnaud Lafon

Thursday 06 June 2013 10:01:03 am

Did you file a feature request? Imho this feature should go in the standard LegacyKernelController...

Thursday 06 June 2013 10:23:47 am

Hi Arnaud

It seems that you didn't listen to the workshop in Montpellier carefully blunk.gif Emoticon.

Instead of extending the LegacyKernelController (which is OK how you do it, but clearly overkill), you can simply create an event listener for kernel.response event. And if this is only related to cache, you can also consider using LiipCacheControlBundle (which works with kernel.response event as well).

Quote from Gaetano Giunta :

Did you file a feature request? Imho this feature should go in the standard LegacyKernelController...

No need, since this is a built-in feature in Symfony...

Thursday 06 June 2013 12:10:47 pm

Quote from Jérôme Vieilledent :

Hi Arnaud

It seems that you didn't listen to the workshop in Montpellier carefully blunk.gif Emoticon.

...

I did listen to the workshop but maybe not that carefully, you're right happy.gif Emoticon

I think that using the kernel.response cannot be a solution in this case because I need to alter the response depending on the result sent by the legacy kernel, which, If I'm not wrong, seems to be not persistent. How could we make the result of $this->kernel->run(); available in the event itself ?

At least, that would be nice to store the result in a protected member of the original LegacyKernelController, so that it can be used by a controller extending it.

In my case :

 <?php
namespace MyVendorName\EzPublish\LegacyBundle\Controller;
use eZ\Bundle\EzPublishLegacyBundle\Controller\LegacyKernelController as LegacyKernelController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\ResponseHeaderBag;
use Symfony\Component\Templating\EngineInterface;
use eZ\Publish\Core\MVC\ConfigResolverInterface;
/**
 * Controller embedding legacy kernel.
 */
class MyVendorNameLegacyKernelController extends LegacyKernelController
{
    private $kernel;
    public function __construct( \Closure $kernelClosure, EngineInterface $templateEngine, ConfigResolverInterface $configResolver )
    {
        $this->kernel = $kernelClosure();
        $this->templateEngine = $templateEngine;
        $this->legacyLayout = $configResolver->getParameter( 'module_default_layout', 'ezpublish_legacy' );
        $this->configResolver = $configResolver;
    }
    /**
     * Base fallback action.
     * Will be basically used for every legacy module.
     *
     * @return \Symfony\Component\HttpFoundation\Response
     */
    public function indexAction()
    {
        $legacyMode = $this->configResolver->getParameter( 'legacy_mode' );
        $this->kernel->setUseExceptions( false );
        $result = $this->kernel->run();
        $this->kernel->setUseExceptions( true );
        $moduleResult = $result->getAttribute( 'module_result' );
        if ( isset( $this->legacyLayout ) && !$legacyMode )
        {
            $response = $this->render(
                $this->legacyLayout,
                array( 'module_result' => $moduleResult )
            );
        }
        else
        {
            $response = new Response( $result->getContent() );
        }
        // Handling error codes sent from the legacy stack
        if ( isset( $moduleResult['errorCode'] ) )
        {
            $response->setStatusCode(
                $moduleResult['errorCode'],
                isset( $moduleResult['errorMessage'] ) ? $moduleResult['errorMessage'] : null            );
        }
        if( isset( $moduleResult['content_info'] ) )
        {
            $contentInfo = $moduleResult['content_info'];
            $viewMode = $contentInfo['viewmode'];
            $uri = $moduleResult['uri'];
            $cachedViewModes =
                explode( ';',
                         $this->configResolver->getParameter( 'ContentSettings.CachedViewModes' ) );
            if( in_array( $viewMode , $cachedViewModes ) )
            {
                $expireHeaderTTL = null;
                if( \eZHTTPHeader::enabled() )
                {
                    $legacyCustomHeaders = new ResponseHeaderBag(
                        \eZHTTPHeader::headerOverrideArray( \eZURI::instance( $uri ) ) );
                    // set maxage and s-maxage based on the expire header value if available
                    if( $legacyCustomHeaders->has( 'Expires' ) )
                    {
                        $expireHeaderTTL = strtotime( $headerValue ) - mktime();
                        if( !$legacyCustomHeaders->hasCacheControlDirective( 'max-age' ) )
                        {
                            $response->setMaxAge( $expireHeaderTTL );
                        }
                        if( !$legacyCustomHeaders->hasCacheControlDirective( 's-maxage' ) )
                        {
                            $response->setSharedMaxAge( $expireHeaderTTL );
                        }
                    }
                }
                // makes sure that the response can be cached by the Symfony reverse proxy
                // (we only do that for contents)
                $response->setPublic();
            }
        }
        return $response;
    }
}

I had to copy/paste the original indexAction to be able to capture $moduleResult, and I'm thinking of a PR that would simply replace $moduleResult by $this->moduleResult. 

Modified on Thursday 06 June 2013 12:19:29 pm by Arnaud Lafon

Thursday 06 June 2013 2:41:39 pm

So you need access to the ezpKernelResult object then ? This is indeed not possible yet. However, keeping it as a member variable is not a good idea IMHO. A better alternative would be to extend the Response class in order to store the whole ezpKernelResult object in it.

Pull request accepted by principle happy.gif Emoticon

Friday 07 June 2013 5:12:32 pm

Will do as soon as I find some time happy.gif Emoticon

Friday 14 June 2013 4:12:36 pm

Issue created: https://jira.ez.no/browse/EZP-21064

Pull-request by Yannick: https://github.com/ezsystems/ezpublish-kernel/pull/411

Monday 17 June 2013 11:56:53 am

Great. Just commented the PR.

expandshrink

You must be logged in to post messages in this topic!

36 542 Users on board!

Forums menu

Proudly Developed with from