Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Symfony2's descend into phpDocumentor2

Mike van Riel
September 14, 2012

Symfony2's descend into phpDocumentor2

Mike van Riel

September 14, 2012
Tweet

More Decks by Mike van Riel

Other Decks in Technology

Transcript

  1. joind.in / 7059 phpDocumentor Who am I? Mike van Riel

    ➔ @mvriel ➔ Lead Developer for phpDocumentor 2 ➔ Core Developer for Cilex ➔ Contributor for many others ➔ Foster-father of 2 (dogs)
  2. joind.in / 7059 phpDocumentor What is going to be covered?

    ➔ Introduction to Symfony Components ➔ Timeline of phpDocumentor2: Components ➔ Autoloader ➔ Console ➔ Finder ➔ EventDispatcher ➔ Twig
  3. joind.in / 7059 phpDocumentor “With this presentation I intend to

    inspire you to reduce the amount of code you maintain, and use Symfony Components to help you achieve that.”
  4. joind.in / 7059 phpDocumentor Benefits Less maintenance Reliable Easy To

    use ➔ Unit-tested ➔ Peer- reviewed ➔ Widely used ➔ Community Support ➔ Automatic updates ➔ Less code to maintain
  5. joind.in / 7059 phpDocumentor Which components are there? ➔ Browserkit

    ➔ Classloader ➔ Config ➔ Console ➔ CssSelector ➔ Dependency Injection ➔ DomCrawler ➔ Event Dispatcher ➔ Finder ➔ Form ➔ Http Foundation ➔ HttpKernel ➔ Locale ➔ Process ➔ Routing ➔ Security ➔ Serializer ➔ Templating ➔ Translation ➔ Validator ➔ Yaml
  6. joind.in / 7059 phpDocumentor Installing { "require": { "symfony/config": "2.*"

    } } $ pear channel-discover pear.symfony.com $ pear install symfony2/config Composer Pear
  7. joind.in / 7059 phpDocumentor Moving to PHP 5.3.3 ➔ Faster

    performance ➔ Enabled Symfony2 Components ➔ Namespaces ➔ PSR-0 Compatibility
  8. joind.in / 7059 phpDocumentor Minimal CLI Application <?php require_once __DIR__

    . '/cilex.phar'; $app = new \Cilex\Application('Cilex'); $app->command(new \Cilex\Command\GreetCommand()); $app->run(); <?php namespace Cilex\Command; use Symfony\Component\Console\Input\InputArgument, Symfony\Component\Console\Input\InputInterface, Symfony\Component\Console\Input\InputOption, Symfony\Component\Console\Output\OutputInterface; class GreetCommand extends Command { protected function configure() { $this->setName('demo:greet') ->setDescription('Greet someone') ->addArgument('name', InputArgument::OPTIONAL, 'Who do you want to greet?') } protected function execute(InputInterface $input, OutputInterface $output) { $name = $input->getArgument('name'); $output->writeln('Hello'.($name ? ' '.$name : '')); } }
  9. joind.in / 7059 phpDocumentor What does it do? ➔ Autoloader

    ➔ PSR-0 compatible ➔ PEAR compatible ➔ Can use classmaps for extra performance ➔ Can use APC to cache
  10. joind.in / 7059 phpDocumentor Installing { "require": { "symfony/class-loader": "2.*"

    } } $ pear channel-discover pear.symfony.com $ pear install pear.symfony.com/ClassLoader Composer Pear
  11. joind.in / 7059 phpDocumentor Example $loader = new UniversalClassLoader(); $loader->registerNamespaces(array(

    'Symfony' => __DIR__.'/../vendor/symfony/symfony/src', 'Monolog' => __DIR__.'/../vendor/monolog/monolog/src', )); $loader->register();
  12. joind.in / 7059 phpDocumentor What does it do? ➔ Enables

    Commands ➔ Provides default list command ➔ Provides default help command ➔ Interactive Commands ➔ Testability
  13. joind.in / 7059 phpDocumentor Installing { "require": { "symfony/console": "2.*"

    } } $ pear channel-discover pear.symfony.com $ pear install pear.symfony.com/Console Composer Pear
  14. joind.in / 7059 phpDocumentor Commands ➔ a single activity of

    a command line application ➔ Example: `phpdoc template:list` ➔ May have options ➔ Example: --help ➔ May have one or more arguments ➔ Example: `scrybe manual:to-html file1.rst file2.rst` ➔ Can be interactive ➔ Question-based instead of option-based
  15. joind.in / 7059 phpDocumentor Example from phpDocumentor $console = new

    Console\Application($name, $version); protected function addCommandsForProjectNamespace() { $this->command( new \phpDocumentor\Command\Project\ParseCommand() ); $this->command( new \phpDocumentor\Command\Project\RunCommand() ); $this->command( new \phpDocumentor\Command\Project\TransformCommand() ); } Convenience method provided by Cilex $console->add(new GreetCommand()); $console->run(); without Cilex
  16. joind.in / 7059 phpDocumentor Creating a command (with Cilex) <?php

    namespace Cilex\Command; use Symfony\Component\Console\Input\InputArgument, Symfony\Component\Console\Input\InputInterface, Symfony\Component\Console\Input\InputOption, Symfony\Component\Console\Output\OutputInterface; class GreetCommand extends Command { protected function configure() { $this->setName('demo:greet') ->setDescription('Greet someone') ->addArgument('name', InputArgument::OPTIONAL, 'Who do you want to greet?') } protected function execute(InputInterface $input, OutputInterface $output) { $name = $input->getArgument('name'); $output->writeln('Hello'.($name ? ' '.$name : '')); } }
  17. joind.in / 7059 phpDocumentor Creating a command (without Cilex) <?php

    namespace My\Application\Command; use Symfony\Component\Console\Input\InputArgument, Symfony\Component\Console\Input\InputInterface, Symfony\Component\Console\Input\InputOption, Symfony\Component\Console\Output\OutputInterface, Symfony\Component\Console\Command\Command; class GreetCommand extends Command { protected function configure() { $this->setName('demo:greet') ->setDescription('Greet someone') ->addArgument('name', InputArgument::OPTIONAL, 'Who do you want to greet?') } protected function execute(InputInterface $input, OutputInterface $output) { $name = $input->getArgument('name'); $output->writeln('Hello'.($name ? ' '.$name : '')); } }
  18. joind.in / 7059 phpDocumentor What does it do? ➔ Finds

    files and folders ➔ Returns them as SplFileInfo objects ➔ Provides a DSL to retrieve a specific set of files ➔ Highly configurable and filterable ➔ Can use streams to find files in ➔ Example: `\Zend_Service_Amazon_S3`
  19. joind.in / 7059 phpDocumentor Installing { "require": { "symfony/finder": "2.*"

    } } $ pear channel-discover pear.symfony.com $ pear install pear.symfony.com/Finder Composer Pear
  20. joind.in / 7059 phpDocumentor Example from phpDocumentor $finder = new

    \Symfony\Component\Finder\Finder(); $finder ->files() ->in($path) ->name( '/\.('.implode('|', $this->allowed_extensions).')$/' ) ->ignoreDotFiles($this->getIgnoreHidden()) ->filter( function(\SplFileInfo $file) use ($patterns) { if (!$patterns) { return true; } // apply ignore list on path instead of file, finder // can't do that by default return !preg_match($patterns, $file->getPathname()); } );
  21. joind.in / 7059 phpDocumentor What does it do? ➔ Allows

    a non-linear approach ➔ For example: hooks for a plugin ➔ Similar to: concepts from Aspect Oriented Programming ➔ Provide third-parties with controlled interaction ➔ Observer variant: Event Dispatcher pattern
  22. joind.in / 7059 phpDocumentor Installing { "require": { "symfony/event-dispatcher": "2.*"

    } } $ pear channel-discover pear.symfony.com $ pear install pear.symfony.com/EventDispatcher Composer Pear
  23. joind.in / 7059 phpDocumentor Events ➔ Have a name (eg.

    event.log) ➔ Are objects too ➔ Are used to: ➔ Trigger listeners ➔ Transfer state
  24. joind.in / 7059 phpDocumentor Stock example $listener = new AcmeListener();

    $dispatcher->addListener( 'foo.action', array($listener, 'onFooAction') ); use Symfony\Component\EventDispatcher\EventDispatcher; $dispatcher = new EventDispatcher(); $event = new FilterOrderEvent($order); $dispatcher->dispatch( StoreEvents::STORE_ORDER, $event );
  25. joind.in / 7059 phpDocumentor Example from phpDocumentor $this->event_dispatcher->addListener( $event->getDescription(), array($this,

    $method->getName()) ); * @phpdoc-event reflection.docblock.tag.export */ public function exportTag($data) { /** @var \phpDocumentor\Reflection\BaseReflector $subject */ $subject = $data->getSubject(); ... } $event = ..\Event\ExportDocBlockExtractionEvent::createInstance($this) ->setDocblock($this->doc_block) \phpDocumentor\Event\Dispatcher::getInstance()->dispatch( 'reflection.docblock-extraction.export', $event );
  26. joind.in / 7059 phpDocumentor What does it do? ➔ Converts

    a template into any text format ➔ Is inspired on Jinja, the Python templating engine ➔ Provides a concise, readable interface
  27. joind.in / 7059 phpDocumentor Installing { "require": { "twig/twig": "1.*"

    } } $ pear channel-discover pear.twig-project.org $ pear install twig/Twig Composer Pear
  28. joind.in / 7059 phpDocumentor Example from phpDocumentor $base_extension = new

    \phpDocumentor\Plugin\Twig\Extension( $structure, $transformation ); $env->addExtension($base_extension); $env = new \Twig_Environment( new \Twig_Loader_Filesystem( $transformation->getTransformer()->getTemplatesPath().'/..' .DIRECTORY_SEPARATOR.$template_path ) ); file_put_contents( $destination, $environment->render( substr($transformation->getSource(), strlen($template_path)) ) );
  29. joind.in / 7059 phpDocumentor Example template <!DOCTYPE html> <html> <head>

    <title>My Webpage</title> </head> <body> <ul id="navigation"> {% for item in navigation %} <li> <a href="{{ item.href }}"> {{ item.caption }} </a> </li> {% endfor %} </ul> <h1>My Webpage</h1> {{ a_variable }} </body> </html>
  30. joind.in / 7059 phpDocumentor Conclusion ➔ Reduce the amount of

    LOC you need to maintain ➔ Use Components ➔ Build on the shoulders of giants ➔ It's easy
  31. joind.in / 7059 phpDocumentor Questions? ➔ Please rate this talk

    on http://joind.in/7059 ➔ More information can be found at: http://symfony.com/components ➔ You can follow me on twitter: @mvriel