--- /dev/null
+[submodule "library/ZendFramework"]
+ path = library/ZendFramework
+ url = git://github.com/zendframework/zf2.git
--- /dev/null
+<?php
+return new Zend\Config\Config(array(
+ 'module_paths' => array(
+ realpath(__DIR__ . '/../modules'),
+ ),
+ 'modules' => array(
+ 'Application',
+ ),
+ 'module_config' => array(
+ 'cache_config' => false,
+ 'cache_dir' => realpath(__DIR__ . '/../data/cache'),
+ ),
+));
--- /dev/null
+Subproject commit 795d6aeeb3694d17cf151ad0c7a9b9af8382144f
--- /dev/null
+<?php
+
+namespace Application;
+
+use InvalidArgumentException,
+ Zend\Module\Manager,
+ Zend\Config\Config,
+ Zend\Di\Locator,
+ Zend\EventManager\EventCollection,
+ Zend\EventManager\StaticEventCollection;
+
+class Module
+{
+ protected $appListeners = array();
+ protected $staticListeners = array();
+ protected $viewListener;
+
+ public function init(Manager $moduleManager)
+ {
+ $this->initAutoloader($moduleManager->getOptions()->getApplicationEnv());
+ }
+
+ protected function initAutoloader($env = null)
+ {
+ require __DIR__ . '/autoload_register.php';
+ }
+
+ public static function getConfig()
+ {
+ return new Config(include __DIR__ . '/configs/module.config.php');
+ }
+
+ public function registerApplicationListeners(EventCollection $events, Locator $locator, Config $config)
+ {
+ $view = $locator->get('view');
+ $viewListener = $this->getViewListener($view, $config);
+ $events->attachAggregate($viewListener);
+ }
+
+ public function registerStaticListeners(StaticEventCollection $events, Locator $locator, Config $config)
+ {
+ $view = $locator->get('view');
+ $viewListener = $this->getViewListener($view, $config);
+
+ $viewListener->registerStaticListeners($events, $locator);
+ }
+
+ protected function getViewListener($view, $config)
+ {
+ if ($this->viewListener instanceof View\Listener) {
+ return $this->viewListener;
+ }
+
+ $viewListener = new View\Listener($view, $config->layout);
+ $viewListener->setDisplayExceptionsFlag($config->display_exceptions);
+
+ $this->viewListener = $viewListener;
+ return $viewListener;
+ }
+}
--- /dev/null
+<?php
+return array (
+ 'Application\\View\\Listener' => __DIR__ . DIRECTORY_SEPARATOR . 'src' . DIRECTORY_SEPARATOR . 'Application' . DIRECTORY_SEPARATOR . 'View' . DIRECTORY_SEPARATOR . 'Listener.php',
+ 'Application\\View\\Helper\\Url' => __DIR__ . DIRECTORY_SEPARATOR . 'src' . DIRECTORY_SEPARATOR . 'Application' . DIRECTORY_SEPARATOR . 'View' . DIRECTORY_SEPARATOR . 'Helper' . DIRECTORY_SEPARATOR . 'Url.php',
+ 'Application\\Bootstrap' => __DIR__ . DIRECTORY_SEPARATOR . 'src' . DIRECTORY_SEPARATOR . 'Application' . DIRECTORY_SEPARATOR . 'Bootstrap.php',
+ 'Application\\Controller\\IndexController' => __DIR__ . DIRECTORY_SEPARATOR . 'src' . DIRECTORY_SEPARATOR . 'Application' . DIRECTORY_SEPARATOR . 'Controller' . DIRECTORY_SEPARATOR . 'IndexController.php',
+ 'Application\\Controller\\ErrorController' => __DIR__ . DIRECTORY_SEPARATOR . 'src' . DIRECTORY_SEPARATOR . 'Application' . DIRECTORY_SEPARATOR . 'Controller' . DIRECTORY_SEPARATOR . 'ErrorController.php',
+ 'Application\\Module' => __DIR__ . DIRECTORY_SEPARATOR . 'Module.php',
+);
\ No newline at end of file
--- /dev/null
+<?php
+return function ($class) {
+ static $map;
+ if (!$map) {
+ $map = include __DIR__ . '/autoload_classmap.php';
+ }
+
+ if (!isset($map[$class])) {
+ return false;
+ }
+ return include $map[$class];
+};
--- /dev/null
+<?php
+spl_autoload_register(include __DIR__ . '/autoload_function.php');
--- /dev/null
+<?php
+return array(
+ 'bootstrap_class' => 'Application\Bootstrap',
+ 'layout' => 'layouts/layout.phtml',
+ 'di' => array(
+ 'instance' => array(
+ 'alias' => array(
+ 'index' => 'Application\Controller\IndexController',
+ 'error' => 'Application\Controller\ErrorController',
+ 'view' => 'Zend\View\PhpRenderer',
+ ),
+
+ 'Zend\View\HelperLoader' => array(
+ 'parameters' => array(
+ 'map' => array(
+ 'url' => 'Application\View\Helper\Url',
+ ),
+ ),
+ ),
+
+ 'Zend\View\HelperBroker' => array(
+ 'parameters' => array(
+ 'loader' => 'Zend\View\HelperLoader',
+ ),
+ ),
+
+ 'Zend\View\PhpRenderer' => array(
+ 'methods' => array(
+ 'setResolver' => array(
+ 'resolver' => 'Zend\View\TemplatePathStack',
+ 'options' => array(
+ 'script_paths' => array(
+ 'application' => __DIR__ . '/../views',
+ ),
+ ),
+ ),
+ ),
+ 'parameters' => array(
+ 'broker' => 'Zend\View\HelperBroker',
+ ),
+ ),
+ ),
+ ),
+
+ 'routes' => array(
+ 'default' => array(
+ 'type' => 'Zend\Mvc\Router\Http\Regex',
+ 'options' => array(
+ 'regex' => '/(?P<controller>[^/]+)(/(?P<action>[^/]+)?)?',
+ 'spec' => '/%controller%/%action%',
+ 'defaults' => array(
+ 'controller' => 'error',
+ 'action' => 'index',
+ ),
+ ),
+ ),
+ 'home' => array(
+ 'type' => 'Zend\Mvc\Router\Http\Literal',
+ 'options' => array(
+ 'route' => '/',
+ 'defaults' => array(
+ 'controller' => 'index',
+ 'action' => 'index',
+ ),
+ ),
+ ),
+ ),
+);
--- /dev/null
+<?php
+namespace Application;
+
+use Zend\Config\Config,
+ Zend\Di\Configuration,
+ Zend\Di\Definition,
+ Zend\Di\DependencyInjector,
+ Zend\EventManager\StaticEventManager,
+ Zend\Module\Manager as ModuleManager,
+ Zend\Mvc\Application;
+
+class Bootstrap
+{
+ protected $config;
+ protected $modules;
+
+ public function __construct(Config $config, ModuleManager $modules)
+ {
+ $this->config = $config;
+ $this->modules = $modules;
+ }
+
+ public function bootstrap(Application $app)
+ {
+ $this->setupLocator($app);
+ $this->setupRoutes($app);
+ $this->setupEvents($app);
+ }
+
+ protected function setupLocator(Application $app)
+ {
+ $definition = new Definition\AggregateDefinition;
+ $definition->addDefinition(new Definition\RuntimeDefinition);
+
+ $di = new DependencyInjector;
+ $di->setDefinition($definition);
+
+ $config = new Configuration($this->config->di);
+ $config->configure($di);
+
+ $app->setLocator($di);
+ }
+
+ protected function setupRoutes(Application $app)
+ {
+ $router = $app->getLocator()->get('Zend\Mvc\Router\SimpleRouteStack');
+ foreach ($this->config->routes as $name => $config) {
+ $class = $config->type;
+ $options = $config->options;
+ $route = new $class($options);
+ $router->addRoute($name, $route);
+ }
+ $app->setRouter($router);
+ }
+
+ protected function setupEvents(Application $app)
+ {
+ $view = $this->getView($app);
+ $locator = $app->getLocator();
+ $events = $app->events();
+ $staticEvents = StaticEventManager::getInstance();
+
+ foreach ($this->modules->getLoadedModules() as $name => $module) {
+ if (method_exists($module, 'registerApplicationListeners')) {
+ $module->registerApplicationListeners($events, $locator, $this->config);
+ }
+
+ if (method_exists($module, 'registerStaticListeners')) {
+ $module->registerStaticListeners($staticEvents, $locator, $this->config);
+ }
+ }
+ }
+
+ protected function getView($app)
+ {
+ $di = $app->getLocator();
+ $view = $di->get('view');
+ $url = $view->plugin('url');
+ $url->setRouter($app->getRouter());
+
+ $view->plugin('headTitle')->setSeparator(' - ')
+ ->setAutoEscape(false)
+ ->append('Application');
+ return $view;
+ }
+}
--- /dev/null
+<?php
+
+namespace Application\Controller;
+
+use Zend\Mvc\Controller\ActionController;
+
+class ErrorController extends ActionController
+{
+ const ERROR_NO_ROUTE = 404;
+ const ERROR_NO_CONTROLLER = 404;
+
+ public function indexAction()
+ {
+ $error = $this->request->getMetadata('error', false);
+ if (!$error) {
+ $error = array(
+ 'type' => 404,
+ 'message' => 'Page not found',
+ );
+ }
+
+ switch ($error['type']) {
+ case self::ERROR_NO_ROUTE:
+ case self::ERROR_NO_CONTROLLER:
+ default:
+ // 404 error -- controller or action not found
+ $this->response->setStatusCode(404);
+ break;
+ }
+
+ return array('message' => $error['message']);
+ }
+}
--- /dev/null
+<?php
+
+namespace Application\Controller;
+
+use Zend\Mvc\Controller\ActionController;
+
+class IndexController extends ActionController
+{
+ public function indexAction()
+ {
+ return array();
+ }
+}
--- /dev/null
+<?php
+namespace Application\View\Helper;
+
+use Zend\View\Helper\AbstractHelper,
+ Zend\Mvc\Router\RouteStack;
+
+class Url extends AbstractHelper
+{
+ protected $router;
+
+ public function setRouter(RouteStack $router)
+ {
+ $this->router = $router;
+ }
+
+ public function direct($params = array(), $options = array())
+ {
+ if (null === $this->router) {
+ return '';
+ }
+
+ // Remove trailing '/index' from generated URLs.
+ $url = $this->router->assemble($params, $options);
+ if ((6 <= strlen($url)) && '/index' == substr($url, -6)) {
+ $url = substr($url, 0, strlen($url) - 6);
+ }
+
+ return $url;
+ }
+}
--- /dev/null
+<?php
+
+namespace Application\View;
+
+use ArrayAccess,
+ Zend\Di\Locator,
+ Zend\EventManager\EventCollection,
+ Zend\EventManager\ListenerAggregate,
+ Zend\EventManager\StaticEventCollection,
+ Zend\Http\Response,
+ Zend\Mvc\Application,
+ Zend\Mvc\MvcEvent,
+ Zend\View\Renderer;
+
+class Listener implements ListenerAggregate
+{
+ protected $layout;
+ protected $listeners = array();
+ protected $staticListeners = array();
+ protected $view;
+ protected $displayExceptions = false;
+
+ public function __construct(Renderer $renderer, $layout = 'layout.phtml')
+ {
+ $this->view = $renderer;
+ $this->layout = $layout;
+ }
+
+ public function setDisplayExceptionsFlag($flag)
+ {
+ $this->displayExceptions = (bool) $flag;
+ return $this;
+ }
+
+ public function displayExceptions()
+ {
+ return $this->displayExceptions;
+ }
+
+ public function attach(EventCollection $events)
+ {
+ $this->listeners[] = $events->attach('dispatch.error', array($this, 'renderError'));
+ $this->listeners[] = $events->attach('dispatch', array($this, 'render404'), -80);
+ $this->listeners[] = $events->attach('dispatch', array($this, 'renderLayout'), -1000);
+ }
+
+ public function detach(EventCollection $events)
+ {
+ foreach ($this->listeners as $key => $listener) {
+ $events->detach($listener);
+ unset($this->listeners[$key]);
+ unset($listener);
+ }
+ }
+
+ public function registerStaticListeners(StaticEventCollection $events, $locator)
+ {
+ $ident = 'Application\Controller\PageController';
+ $handler = $events->attach($ident, 'dispatch', array($this, 'renderPageController'), -50);
+ $this->staticListeners[] = array($ident, $handler);
+
+ $ident = 'Zend\Mvc\Controller\ActionController';
+ $handler = $events->attach($ident, 'dispatch', array($this, 'renderView'), -50);
+ $this->staticListeners[] = array($ident, $handler);
+ }
+
+ public function detachStaticListeners(StaticEventCollection $events)
+ {
+ foreach ($this->staticListeners as $i => $info) {
+ list($id, $handler) = $info;
+ $events->detach($id, $handler);
+ unset($this->staticListeners[$i]);
+ }
+ }
+
+ public function renderPageController(MvcEvent $e)
+ {
+ $page = $e->getResult();
+ if ($page instanceof Response) {
+ return;
+ }
+
+ $response = $e->getResponse();
+ if ($response->isNotFound()) {
+ return;
+ }
+
+ $routeMatch = $e->getRouteMatch();
+
+ if (!$routeMatch) {
+ $page = '404';
+ } else {
+ $page = $routeMatch->getParam('action', '404');
+ }
+
+ if ($page == '404') {
+ $response->setStatusCode(404);
+ }
+
+ $script = 'pages/' . $page . '.phtml';
+
+ // Action content
+ $content = $this->view->render($script);
+ $e->setResult($content);
+
+ return $this->renderLayout($e);
+ }
+
+ public function renderView(MvcEvent $e)
+ {
+ $response = $e->getResponse();
+ if (!$response->isSuccess()) {
+ return;
+ }
+
+ $routeMatch = $e->getRouteMatch();
+ $controller = $routeMatch->getParam('controller', 'index');
+ $action = $routeMatch->getParam('action', 'index');
+ $script = $controller . '/' . $action . '.phtml';
+
+ $vars = $e->getResult();
+ if (is_scalar($vars)) {
+ $vars = array('content' => $vars);
+ } elseif (is_object($vars) && !$vars instanceof ArrayAccess) {
+ $vars = (array) $vars;
+ }
+
+ $content = $this->view->render($script, $vars);
+
+ $e->setResult($content);
+ return $content;
+ }
+
+ public function renderLayout(MvcEvent $e)
+ {
+ $response = $e->getResponse();
+ if (!$response) {
+ $response = new Response();
+ $e->setResponse($response);
+ }
+ if ($response->isRedirect()) {
+ return $response;
+ }
+
+ $footer = $e->getParam('footer', false);
+ $vars = array('footer' => $footer);
+
+ if (false !== ($contentParam = $e->getParam('content', false))) {
+ $vars['content'] = $contentParam;
+ } else {
+ $vars['content'] = $e->getResult();
+ }
+
+ $layout = $this->view->render($this->layout, $vars);
+ $response->setContent($layout);
+ return $response;
+ }
+
+ public function render404(MvcEvent $e)
+ {
+ $vars = $e->getResult();
+ if ($vars instanceof Response) {
+ return;
+ }
+
+ $response = $e->getResponse();
+ if ($response->getStatusCode() != 404) {
+ // Only handle 404's
+ return;
+ }
+
+ $vars = array('message' => 'Page not found.');
+
+ $content = $this->view->render('pages/404.phtml', $vars);
+
+ $e->setResult($content);
+
+ return $this->renderLayout($e);
+ }
+
+ public function renderError(MvcEvent $e)
+ {
+ $error = $e->getError();
+ $app = $e->getTarget();
+ $response = $e->getResponse();
+ if (!$response) {
+ $response = new Response();
+ $e->setResponse($response);
+ }
+
+ switch ($error) {
+ case Application::ERROR_CONTROLLER_NOT_FOUND:
+ case Application::ERROR_CONTROLLER_INVALID:
+ $vars = array(
+ 'message' => 'Page not found.',
+ );
+ $response->setStatusCode(404);
+ break;
+
+ case Application::ERROR_EXCEPTION:
+ default:
+ $exception = $e->getParam('exception');
+ $vars = array(
+ 'message' => 'An error occurred during execution; please try again later.',
+ 'exception' => $e->getParam('exception'),
+ 'display_exceptions' => $this->displayExceptions(),
+ );
+ $response->setStatusCode(500);
+ break;
+ }
+
+ $content = $this->view->render('error.phtml', $vars);
+
+ $e->setResult($content);
+
+ return $this->renderLayout($e);
+ }
+}
--- /dev/null
+<h1>An error occurred</h1>
+<h2><?php echo $this->vars('message') ?></h2>
+
+<?php if (isset($this->vars()->exception)): ?>
+
+<h3>Exception information:</h3>
+<p>
+ <b>Message:</b> <?php echo $this->vars('exception')->getMessage() ?>
+</p>
+
+<h3>Stack trace:</h3>
+<pre><?php echo $this->vars('exception')->getTraceAsString() ?></pre>
+
+<?php endif ?>
--- /dev/null
+application module -> index controller -> index action
--- /dev/null
+<?php echo $this->plugin('doctype') ?>
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <?php echo $this->plugin('headTitle') ?>
+
+</head>
+<body>
+<?php echo $this->vars()->getRawValue('content'); ?>
+</body>
+</html>
--- /dev/null
+SetEnv APPLICATION_ENV development
+
+RewriteEngine On
+RewriteCond %{REQUEST_FILENAME} -s [OR]
+RewriteCond %{REQUEST_FILENAME} -l [OR]
+RewriteCond %{REQUEST_FILENAME} -d
+RewriteRule ^.*$ - [NC,L]
+RewriteRule ^.*$ index.php [NC,L]
--- /dev/null
+<?php
+// Define application environment
+defined('APPLICATION_ENV')
+ || define('APPLICATION_ENV', (getenv('APPLICATION_ENV') ? getenv('APPLICATION_ENV') : 'production'));
+
+// Ensure ZF is on the include path
+set_include_path(implode(PATH_SEPARATOR, array(
+ realpath(__DIR__ . '/../library/ZendFramework/library'),
+ get_include_path(),
+)));
+
+require_once 'Zend/Loader/AutoloaderFactory.php';
+Zend\Loader\AutoloaderFactory::factory(array('Zend\Loader\StandardAutoloader' => array()));
+
+$appConfig = include __DIR__ . '/../configs/application.config.php';
+
+$moduleLoader = new Zend\Loader\ModuleAutoloader($appConfig->module_paths);
+$moduleLoader->register();
+
+$moduleManager = new Zend\Module\Manager(
+ $appConfig->modules,
+ new Zend\Module\ManagerOptions($appConfig->module_config)
+);
+
+// Get the merged config object
+$config = $moduleManager->getMergedConfig();
+
+// Create application, bootstrap, and run
+$bootstrap = new $config->bootstrap_class($config, $moduleManager);
+$application = new Zend\Mvc\Application;
+$bootstrap->bootstrap($application);
+$application->run()->send();