Symfony 2.6.1 : Using class_alias of Debug’s FlattenException to work with Error page previews
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.
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 :
Done 😉
Symfony 2.6 : The good momentum to implement “official” Symfony best practices
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 :
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 :
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
Symfony2 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 :
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 :
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
In 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 :
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.
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
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.
Symfony2 : Assetic Bundle – Manage Your Assets
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.
leave a comment