André Roaldseth
Developer at NAV
André Roaldseth - @androa
interface BootstrapListenerInterface { /** * Listen to the bootstrap event * * @param EventInterface $e * @return array */ public function onBootstrap(EventInterface $e); }
interface ConfigProviderInterface { /** * Returns configuration to merge with application configuration * * @return array|\Traversable */ public function getConfig(); }
interface ControllerPluginProviderInterface { /** * Expected to return \Zend\ServiceManager\Config object or array * to seed such an object. * * @return array|\Zend\ServiceManager\Config */ public function getControllerPluginConfig(); }
interface ControllerProviderInterface { /** * Expected to return \Zend\ServiceManager\Config object or array * to seed such an object. * * @return array|\Zend\ServiceManager\Config */ public function getControllerConfig(); }
interface InitProviderInterface { /** * Initialize workflow * * @param ModuleManagerInterface $manager * @return void */ public function init(ModuleManagerInterface $manager); }
interface ServiceProviderInterface { /** * Expected to return \Zend\ServiceManager\Config object or array * to seed such an object. * * @return array|\Zend\ServiceManager\Config */ public function getServiceConfig(); }
interface ViewHelperProviderInterface { /** * Expected to return \Zend\ServiceManager\Config object or array * to seed such an object. * * @return array|\Zend\ServiceManager\Config */ public function getViewHelperConfig(); }
interface Breakfast { /** * Every Breakfast requires Bacon! * * @param Bacon $bacon ALL the bacon you have! */ function __construct(Bacon $bacon); /** * But Eggs can be optional. * * @param Eggs $eggs Some eggs if you have :) */ function setEggs(Egg $eggs); }
$bacon = $serviceManager->get('Bacon'); $eggs = $serviceManager->get('Eggs'); $breakfast = new Breakfast($bacon); // Did we have any eggs? if ($eggs) { $breakfast->setEggs($eggs); }
class Users { public function __construct() { $this->pdo = new PDO('mysql:..'); } public function hasValidMembership($userId) { $sql = 'SELECT 1 FROM users WHERE userId = :userId'; } }
class Users { public function __construct($pdo = null) { $this->pdo = $pdo; } public function getUser($userId) { // Get the user from MySQL return new User($data); } public function hasValidMembership(User $user) { return $user->membershipEndsDate > time(); } }
class Users { public function hasValidMembership( User $user, DateTime $now = null) { if ($now === null) { $now = new DateTime(); } return $user->membershipEndsDate > $now->getTimestamp(); } }
'invokables' => array( 'Bacon' => 'Breakfast\Refrigerator\Bacon', 'Eggs' => 'Breakfast\Refrigerator\Eggs', );
'breakfast' => function($serviceManager) { $bacon = $serviceManager->get('Bacon'); $eggs = $serviceManager->get('Eggs'); $breakfast = new Breakfast($bacon); $breakfast->setEggs($eggs); return $breakfast; }
'initializers' => array( function($instance, $sm) { if ($instance instanceof LoggerAwareInterface) { $instance->setLogger($sm->get('logger')); } } ),
'shared' => array( 'breakfast' => false );
. ├── config │ └── application.config.php ├── modules │ └── SomeModule ├── public │ ├── css │ ├── index.php │ └── js ├── tests │ └── phpunit.xml.dist └── vendor
. ├── config │ └── module.config.php ├── Module.php ├── src │ └── SomeModule │ └── Controller │ └── SomeController.php └── tests └── phpunit.xml.dist
{ "name": "vgno/article-export", "description": "A CLI tool for exporting articles from Edrum.", "license": "MIT", "authors": [ { "name": "André Roaldseth", "email": "andrer@vg.no" } ], "require": { "php": ">=5.3", "symfony/console": "2.3.*", "symfony/process": "2.3.*", "ezyang/htmlpurifier": "4.5.*" }, "require-dev": { "phpunit/phpunit": "3.7.*" }, "autoload": { "psr-0": { "ArticleExport": "src" } } }
class IndexController extends AbstactActionController { public function indexAction() { if (!$this->hasAccess()) { return $this->getResponse()->setStatusCode(401); } // Tons of more logic to do if user has access return new ViewModel(); } }
class Module implements BootstrapInterface { public function onBootstrap(EventInterface $event) { $application = $event->getTarget(); $serviceManager = $application->getServiceManager(); $application->getEventManager() ->attach(function (MvcEvent $event) use ($serviceManager) { $request = $event->getRequest(); $response = $event->getResponse(); if ($serviceManager->get('AuthHandler') ->hasAccess($request)) { return; // Carry on } $response->setStatusCode(401); // Stop the rest application to run $event->setResult($response); return false; // Stop other event listeners }, MvcEvent::EVENT_DISPATCH); } }
class Module implements BootstrapInterface { public function onBootstrap(EventInterface $event) { // ... Same as previous slide ->attach(function (MvcEvent $event) use ($serviceManager) { $response = $event->getResponse(); $routeMatch = $event->getRouteMatch(); if ($routeMatch ->getMatchedRouteName() === 'articles') { $articleId = $routeMatch->getParam('articleId'); $article = $serviceManager->get('ArticleLoader') ->fetchArticle($articleId)); if (!$article) { $event->setResult($reponse->setStatusCode(404)); return false; } $routeMatch->setParam('article', $article); } }, MvcEvent::EVENT_DISPATCH); } }
class SomeArticleController extends AbstractActionController { public function articleAction() { $article = $this->getParam('article'); // Do article stuff // Give the article to the view layer. return new ViewModel('article', $article); } }
class SomeController extends AbstractActionController { public function getAction() { $something = $this->getSomeServiceLayer() ->get($this->getParam('id')); // We always want to deliver this as JSON, // so we make JsonModel instead of ViewModel. return new JsonModel($something); } }
class SomeController extends AbstractActionController { protected $acceptCriteria = array( 'Zend\View\Model\JsonModel' => array( 'application/json', // <- content-type, supports * ), // ... ); public function getAction() { $something = $this->getSomeServiceLayer() ->get($this->getParam('id')); // We want to do content negotiation so we use the, // acceptableViewModelSelector which looks at the // HTTP Accept header and returns a correct ViewModel. $viewModel = $this->acceptableViewModelSelector( $this->acceptCriteria ); $viewModel->setVariables($something); return $viewModel; } }
By André Roaldseth
A short introduction to Zend Framework 2 intended for my co-workers at VG.