Welcome to Abdul Malik Ikhsan's Blog

Symfony 2.6.1 : Using class_alias of Debug’s FlattenException to work with Error page previews

Posted in Symfony2 Framework, Tutorial PHP by samsonasik on December 19, 2014

Error page previews is one of the new features that land in Symfony 2.6. You should be able to access /_error/{statusCode}.{format}. Unfortunatelly, when I try in Symfony 2.6.1, It doesn’t work. The reason of issue is that in TwigBundle\Controller\ExceptionController::showAction() require HttpKernel’s FlattenException that should be require Debug’s FlattenException.
symfony2-exception-error-preview
The HttpKernel’s FlattenException is deprecated from Symfony 2.3 and should be removed in 3.0.
If you see the Symfony\Bundle\TwigBundle\Controller\ExceptionController, you will see :

use Symfony\Component\HttpKernel\Exception\FlattenException;
// ...
// ...
    public function showAction(
       Request $request,
       FlattenException $exception,
       DebugLoggerInterface $logger = null)
    {

    }
// ...
// ...

So, You just cannot make custom exception that extends the ExceptionController because of the typehint requirement. What we can do ? The issue already reported in github so we just can wait to make it work in next maintenance release – OR – do tricky in the skeleton! Don’t do it in vendor libraries directly. You shouldn’t touch it anymore. We can edit our symfony-standard skeleton application in web/app_dev.php by apply class_alias after loader loaded :

// web/app_dev.php
// ...
$loader = require_once __DIR__.'/../app/bootstrap.php.cache';
class_alias(
    'Symfony\Component\Debug\Exception\FlattenException',
    'Symfony\Component\HttpKernel\Exception\FlattenException'
);
// ...

That’s it, so when you try access : http://127.0.0.1:8000/_error/404.html or whatever your Symfony url skeleton application with /_error/404.html, you will get something like this :
symfony2-404-error-preview

Done 😉

Symfony 2.6 : The good momentum to implement “official” Symfony best practices

Posted in Symfony2 Framework, Tutorial PHP by samsonasik on November 30, 2014

Symfony 2.6 released yesterday. There are ton of features/bug fixes added. There is another thing that awesome! We can implements the “AppBundle way” of the official best practices. Although the AppBundle that mentioned in the official documentation brought by Symfony 2.6, is not in Symfony-standard yet ( at least until now), we can generate it by new updated SensioGeneratorBundle that already shipped by new symfony-standard.


So, after you generate :

php app/console generate:bundle --namespace=AppBundle \
--dir=src --format=annotation --no-interaction

Now, you can have bundle without “vendor” namespace.

Then, if you do what mentioned in the best practices, that template location in app/Resources instead (for templates that the bundle only used in your application). The project structure will like the following :
template-loc
There are complete list of “official” recommended ways to build application using Symfony application including configuration, controllers, templates, forms, internationalization, security, web assets, and tests.

One more thing, now, we can use Symfony Installer to create a new Symfony application that you can download from https://github.com/symfony/symfony-installer . The console interface of installer is pretty good :
symfony-installer1
symfony-installer2

References :
1. http://symfony.com/doc/current/best_practices/index.html
2. https://twitter.com/weaverryan/status/538610340020649984
3. https://github.com/symfony/symfony-installer

Symfony 2 : Using Symfony2 Bundle in Zend Framework 2 Project

Posted in Symfony2 Framework, Tutorial PHP, Zend Framework 2 by samsonasik on March 2, 2013

symfony2-distributionsSymfony2 comes with Bundle, Zend Framework 2 comes with Module, The reusability code is coming. We can use a piece of them in other framework if we want. I think, besides of write about using ZF2 Module in SF2 project, it worth to write about it ( SF2 Bundle in ZF2 Project ).

Ok, let’s start, for example, I have an SF2 Bundle like the following :
SF2BUNDLE
Which has classes like the following :
a. ExampleDependentInterface

namespace San\MySFBundle\Classes;

interface ExampleDependentInterface
{
    public function run($parameter);
}

b. ExampleDependent class that implement ExampleDependentInterface

namespace San\MySFBundle\Classes;

class ExampleDependent implements ExampleDependentInterface
{
    public function run($environment)
    {
        echo 'ExampleDependent run in '.$environment;
    }
}

c. ExampleClass class that pass class implemented ExampleDependentInterface

namespace San\MySFBundle\Classes;

class ExampleClass
{
    protected $dependent;

    public function __construct(ExampleDependentInterface $dependent)
    {
        $this->dependent = $dependent;
    }

    public function run($env = 'Symfony2')
    {
       $this->dependent->run($env);
    }
}

Now, register ExampleClass in services.php ( resources/config/services.php)

use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Reference;

$container->setDefinition(
    'my_sample_service', new Definition('San\MySFBundle\Classes\ExampleDependent')
);

$container->setDefinition(
    'san_my_sf.example',
    new Definition(
        'San\MySFBundle\Classes\ExampleClass',
        array(
            new Reference('my_sample_service')
        )
    )
);

Bundle ‘definitions’ done!, let’s copy to ZF2 Project like the following :
ZF2withSF2Bundle

When Bundle copied, let’s configure Our ZF2 App.
1. create file named SF2AppKernel.php in ZF2 App ( config/SF2AppKernel.php )

use Symfony\Component\HttpKernel\Kernel;
use Symfony\Component\Config\Loader\LoaderInterface;

class SF2AppKernel extends Kernel
{
    public function registerBundles()
    {
        $bundles = array(
            new San\MySFBundle\SanMySFBundle(),
        );

        return $bundles;
    }

    public function registerContainerConfiguration(LoaderInterface $loader){}
}

2. add require symfony/symfony to your composer.json

........
    "require": {
        "php": ">=5.3.3",
        "zendframework/zendframework": "2.*",
        "zendframework/zftool": "dev-master",
        "symfony/symfony": "2.1.*"
    }
........

4. Type

composer update

3. modify init_autoloader.php

if (file_exists('vendor/autoload.php')) {
    $loader = include 'vendor/autoload.php';
    $loader->add('San\\', __DIR__.'/module/SF2Bundles');
}
..........

4. Modify public/index.php to initialize SF2 Bundles and SF2 Container, and register the Container into ZF2 ServiceManager

use Zend\ServiceManager\ServiceManager;
use Zend\Mvc\Service;

define('REQUEST_MICROTIME', microtime(true));
/**
 * This makes our life easier when dealing with paths. Everything is relative
 * to the application root now.
 */
chdir(dirname(__DIR__));

// Setup autoloading
require 'init_autoloader.php';

//load SF2 App Kernel here...
require 'config/SF2AppKernel.php';
$kernel = new SF2AppKernel('prod', true);
$kernel->loadClassCache();

//initialize Bundles and Container
$kernel->boot();

$SF2Container = $kernel->getContainer();

/* extract
    Zend\Mvc\Application::init(require 'config/application.config.php')->run();
    to the following to register SF2Container into ZF2 ServiceManager
*/
$configuration = require 'config/application.config.php';
$smConfig = isset($configuration['service_manager']) ? $configuration['service_manager'] : array();
$serviceManager = new ServiceManager(new Service\ServiceManagerConfig($smConfig));
$serviceManager->setService('ApplicationConfig', $configuration);
$serviceManager->get('ModuleManager')->loadModules();

$serviceManager->setService('SF2Container', $SF2Container);

//run...
$serviceManager->get('Application')->bootstrap()->run();

5. Ok, configuration done!, let’s call the SF2 Bundle Service via Controller in Zend Framework 2 App :

$sl = $this->getServiceLocator()
$sl->get('SF2Container')->get('san_my_sf.example')
                        ->run('ZF2');

References :
1. https://speakerdeck.com/skoop/zend-framework-2-and-symfony2-the-perfect-team-zendcon

Zend Framework 2 : Using Zend Framework 2 Module in Symfony 2 Project

Posted in Symfony2 Framework, Tutorial PHP, Zend Framework 2 by samsonasik on March 1, 2013

zf2-zendframework2In ZF2, Module completely become re-usable code, It can be called even without Zend Framework MVC stack. I will give you extreme example, I will call my ZF2 module that contains service called by Symfony 2 Framework. It’s very rare, but sometime, you don’t need to Reinvent Your created module, even it created in other environment.

For example, I have a ZF2 Module like the following :

zfmodule
Which has Service like the following :
a. Service Class ( ZFModule\Service\MySampleService.php )

namespace ZFModule\Service;

class MySampleService
{
    protected $config;
    
    public function getConfig()
    {
        return $this->config;
    }
    
    public function setConfig(array $config)
    {
        $this->config = $config;
    }
}

b. The Service Factory ( ZFModule\Service\MySampleServiceFactory )

namespace ZFModule\Service;

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

class MySampleServiceFactory implements FactoryInterface
{
    public function createService(ServiceLocatorInterface $serviceLocator)
    {
        $config = $serviceLocator->get('Config');
        
        $service  = new MySampleService;
        $service->setConfig($config);

        return $service;
    }
}

c. Register MySampleService into ZF2 Service Manager

namespace ZFModule;

class Module
{
    public function getConfig(){/*common code here */}
    public function getAutoloaderConfig(){/*common code here*/}

    public function getServiceConfig()
    {
        return array(
            'factories' => array(
                'MySampleService' => 'ZFModule\Service\MySampleServiceFactory'  
            ),
        );
    }
}

Ok, let’s go step by step :
1. Copy the module to Your Symfony Project.
symfonyprjzfmodule
2. add require zendframework/zendframework to your composer.json

.....
require {
"php": ">=5.3.3",
"symfony/symfony": "2.1.*",
"zendframework/zendframework" : "2.1.3"
}
.....

3. Type :

composer update

4. Create a class to get Service From Your ZF2Module (SymfonyPrj/src/Acme\DemoBundle\Service\MyZFModuleService.php )

namespace Acme\DemoBundle\Service;

use Zend\ServiceManager\ServiceManager;
use Zend\Mvc\Service\ServiceManagerConfig;

class MyZFModuleService 
{
    protected $sampleZFService;
    
    public function __construct()
    {
        $serviceManager = new ServiceManager(new ServiceManagerConfig(array()));
        $serviceManager->setService('ApplicationConfig', array(
               'modules' => array(
                   'ZFModule'
               ),
               'module_listener_options' => array()
        ));
        $serviceManager->get('ModuleManager')->loadModules();
        
        //MySampleService is a Service from Your ZF2 Module 
        $this->sampleZFService = $serviceManager->get('MySampleService');
    }
    
    public function dump()
    {
        echo '<pre>';
        print_r($this->sampleZFService->getConfig());
        echo '</pre>';
    }
}

5. Register to Symfony Services :

...
       <service id="MyZFModuleService" class="Acme\DemoBundle\Service\MyZFModuleService">
       </service>
...

6. Ok, check it in your Symfony2 Controller Action :

$serviceZF = $this->get('MyZFModuleService');
$serviceZF->dump();

References :
1. http://zend-framework-community.634137.n4.nabble.com/Doctrine-2-module-is-tight-to-MVC-td4659346.html

Symfony2 : Snappy Bundle – Create PDF from HTML

Posted in Symfony2 Framework, Tutorial PHP by samsonasik on August 15, 2011

Snappy adalah Bundle yang digunakan untuk utilitas konversi wkhtmltopdf di PHP 5.3, memungkinkan kita untuk  menghasilkan file Pdf dari dokumen html. KnpSnappyBundle menyediakan integrasi dengan Symfony2 Framework. Untuk bisa dapat melakukan konversi, terlebih dahulu kita download dulu binary wkhtmltopdf di sini : http://code.google.com/p/wkhtmltopdf/ . Setelah dapat file binary-nya, kita install deh. Setelah kita install, kita bisa mengintegrasikan dengan Symfony2 dengan cepat dan mudah.

Baca Selengkapnya

Symfony2 : Assetic Bundle – Manage Your Assets

Posted in Symfony2 Framework, Tutorial PHP by samsonasik on July 30, 2011

Tentu tak perlu diperdebatkan, bahwa “A poorly optimized frontend can destroy UX ( User eXperience ), and SEO”. Management asset yang baik sangatlah penting dalam mengoptimalisasikannya. Assetic adalah sebuah asset management library yang powerful yang tersedia dalam Symfony2 Framework Standard Edition. Salah satu dari 14 Performance rule dalam web application development adalah Make few HttpRequest, dan salah satu dari bermacam fitur Assetic Bundle adalah dapat meng-combine assets sehingga dapat me-reduce HttpRequest itu sendiri.

Baca Selengkapnya