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

Symfony2's descend into phpDocumentor2

Ba4801d2cbcf2e649f3aedbfcbfb3c36?s=47 Mike van Riel
September 14, 2012

Symfony2's descend into phpDocumentor2

Ba4801d2cbcf2e649f3aedbfcbfb3c36?s=128

Mike van Riel

September 14, 2012
Tweet

Transcript

  1. joind.in / 7059 phpDocumentor A Symfony Components use-case by Mike

    van Riel
  2. 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)
  3. joind.in / 7059 phpDocumentor What is going to be covered?

    ➔ Introduction to Symfony Components ➔ Timeline of phpDocumentor2: Components ➔ Autoloader ➔ Console ➔ Finder ➔ EventDispatcher ➔ Twig
  4. 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.”
  5. joind.in / 7059 phpDocumentor Components

  6. 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
  7. 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
  8. joind.in / 7059 phpDocumentor Installing { "require": { "symfony/config": "2.*"

    } } $ pear channel-discover pear.symfony.com $ pear install symfony2/config Composer Pear
  9. joind.in / 7059 phpDocumentor

  10. joind.in / 7059 phpDocumentor “phpDocumentor did not use Symfony”

  11. joind.in / 7059 phpDocumentor First version

  12. joind.in / 7059 phpDocumentor Later

  13. joind.in / 7059 phpDocumentor Stuck on PHP 5.2.6

  14. joind.in / 7059 phpDocumentor Introducing plugins

  15. joind.in / 7059 phpDocumentor Moving to PHP 5.3.3 ➔ Faster

    performance ➔ Enabled Symfony2 Components ➔ Namespaces ➔ PSR-0 Compatibility
  16. joind.in / 7059 phpDocumentor Missing a lightweight framework

  17. joind.in / 7059 phpDocumentor Missing a lightweight framework

  18. joind.in / 7059 phpDocumentor Cilex was born Class Loader Console

    Pimple Cilex
  19. 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 : '')); } }
  20. joind.in / 7059 phpDocumentor Cilex

  21. joind.in / 7059 phpDocumentor Now with Cilex

  22. joind.in / 7059 phpDocumentor Components Class Loader

  23. 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
  24. joind.in / 7059 phpDocumentor Installing { "require": { "symfony/class-loader": "2.*"

    } } $ pear channel-discover pear.symfony.com $ pear install pear.symfony.com/ClassLoader Composer Pear
  25. 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();
  26. joind.in / 7059 phpDocumentor Components Console

  27. joind.in / 7059 phpDocumentor What does it do? ➔ Enables

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

    } } $ pear channel-discover pear.symfony.com $ pear install pear.symfony.com/Console Composer Pear
  29. 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
  30. 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
  31. 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 : '')); } }
  32. 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 : '')); } }
  33. joind.in / 7059 phpDocumentor Let's pause for a moment http://www.flickr.com/photos/nicsuzor/2554668884

  34. joind.in / 7059 phpDocumentor FileSet

  35. joind.in / 7059 phpDocumentor Gathering files

  36. joind.in / 7059 phpDocumentor Components Finder

  37. 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`
  38. joind.in / 7059 phpDocumentor Installing { "require": { "symfony/finder": "2.*"

    } } $ pear channel-discover pear.symfony.com $ pear install pear.symfony.com/Finder Composer Pear
  39. 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()); } );
  40. joind.in / 7059 phpDocumentor Plugins (revisited)

  41. joind.in / 7059 phpDocumentor Gathering files

  42. joind.in / 7059 phpDocumentor Components EventDispatcher

  43. 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
  44. joind.in / 7059 phpDocumentor Installing { "require": { "symfony/event-dispatcher": "2.*"

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

    event.log) ➔ Are objects too ➔ Are used to: ➔ Trigger listeners ➔ Transfer state
  46. 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 );
  47. 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 );
  48. joind.in / 7059 phpDocumentor Twig Templates

  49. joind.in / 7059 phpDocumentor Using Twig to generate artifacts

  50. joind.in / 7059 phpDocumentor Components Twig

  51. 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
  52. joind.in / 7059 phpDocumentor Installing { "require": { "twig/twig": "1.*"

    } } $ pear channel-discover pear.twig-project.org $ pear install twig/Twig Composer Pear
  53. 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)) ) );
  54. 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>
  55. 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
  56. 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