diff options
Diffstat (limited to 'zend-mvc-plugin-prg-8c7ccb9f0004e92ff258b483447d914f42cb7448/src')
-rw-r--r-- | zend-mvc-plugin-prg-8c7ccb9f0004e92ff258b483447d914f42cb7448/src/Module.php | 38 | ||||
-rw-r--r-- | zend-mvc-plugin-prg-8c7ccb9f0004e92ff258b483447d914f42cb7448/src/PostRedirectGet.php | 150 |
2 files changed, 188 insertions, 0 deletions
diff --git a/zend-mvc-plugin-prg-8c7ccb9f0004e92ff258b483447d914f42cb7448/src/Module.php b/zend-mvc-plugin-prg-8c7ccb9f0004e92ff258b483447d914f42cb7448/src/Module.php new file mode 100644 index 0000000..cc4345b --- /dev/null +++ b/zend-mvc-plugin-prg-8c7ccb9f0004e92ff258b483447d914f42cb7448/src/Module.php @@ -0,0 +1,38 @@ +<?php +/** + * @link http://github.com/zendframework/zend-mvc-plugin-prg for the canonical source repository + * @copyright Copyright (c) 2005-2016 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + */ + +namespace Zend\Mvc\Plugin\Prg; + +use Zend\ServiceManager\Factory\InvokableFactory; + +class Module +{ + /** + * Provide application configuration. + * + * Adds aliases and factories for the PostRedirectGet plugin. + * + * @return array + */ + public function getConfig() + { + return [ + 'controller_plugins' => [ + 'aliases' => [ + 'prg' => PostRedirectGet::class, + 'PostRedirectGet' => PostRedirectGet::class, + 'postRedirectGet' => PostRedirectGet::class, + 'postredirectget' => PostRedirectGet::class, + 'Zend\Mvc\Controller\Plugin\PostRedirectGet' => PostRedirectGet::class, + ], + 'factories' => [ + PostRedirectGet::class => InvokableFactory::class, + ], + ], + ]; + } +} diff --git a/zend-mvc-plugin-prg-8c7ccb9f0004e92ff258b483447d914f42cb7448/src/PostRedirectGet.php b/zend-mvc-plugin-prg-8c7ccb9f0004e92ff258b483447d914f42cb7448/src/PostRedirectGet.php new file mode 100644 index 0000000..9a6279b --- /dev/null +++ b/zend-mvc-plugin-prg-8c7ccb9f0004e92ff258b483447d914f42cb7448/src/PostRedirectGet.php @@ -0,0 +1,150 @@ +<?php +/** + * @link http://github.com/zendframework/zend-mvc-plugin-prg for the canonical source repository + * @copyright Copyright (c) 2005-2016 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + */ + +namespace Zend\Mvc\Plugin\Prg; + +use Zend\Mvc\Controller\Plugin\AbstractPlugin; +use Zend\Mvc\Controller\Plugin\Redirect; +use Zend\Mvc\Exception\RuntimeException; +use Zend\Session\Container; +use Zend\Stdlib\DispatchableInterface; + +/** + * Plugin to help facilitate Post/Redirect/Get (http://en.wikipedia.org/wiki/Post/Redirect/Get) + */ +class PostRedirectGet extends AbstractPlugin +{ + /** + * @var Container + */ + protected $sessionContainer; + + /** + * Perform PRG logic + * + * If a null value is present for the $redirect, the current route is + * retrieved and use to generate the URL for redirect. + * + * If the request method is POST, creates a session container set to expire + * after 1 hop containing the values of the POST. It then redirects to the + * specified URL using a status 303. + * + * If the request method is GET, checks to see if we have values in the + * session container, and, if so, returns them; otherwise, it returns a + * boolean false. + * + * @param null|string $redirect + * @param bool $redirectToUrl + * @return \Zend\Http\Response|array|\Traversable|false + */ + public function __invoke($redirect = null, $redirectToUrl = false) + { + $controller = $this->getController(); + $request = $controller->getRequest(); + $container = $this->getSessionContainer(); + + if ($request->isPost()) { + $container->setExpirationHops(1, 'post'); + $container->post = $request->getPost()->toArray(); + return $this->redirect($redirect, $redirectToUrl); + } + + if (null !== $container->post) { + $post = $container->post; + unset($container->post); + return $post; + } + + return false; + } + + /** + * @return Container + */ + public function getSessionContainer() + { + if (! $this->sessionContainer) { + $this->sessionContainer = new Container('prg_post1'); + } + return $this->sessionContainer; + } + + /** + * @param Container $container + * @return PostRedirectGet + */ + public function setSessionContainer(Container $container) + { + $this->sessionContainer = $container; + return $this; + } + + /** + * TODO: Good candidate for traits method in PHP 5.4 with FilePostRedirectGet plugin + * + * @param string $redirect + * @param bool $redirectToUrl + * @return \Zend\Http\Response + * @throws RuntimeException if route-based redirection is requested, but no + * plugin manager is composed in the controller. + */ + protected function redirect($redirect, $redirectToUrl) + { + $controller = $this->getController(); + $params = []; + $options = ['query' => $controller->params()->fromQuery()]; + $reuseMatchedParams = false; + + if (null === $redirect) { + $routeMatch = $controller->getEvent()->getRouteMatch(); + + $redirect = $routeMatch->getMatchedRouteName(); + // null indicates to redirect to self. + $reuseMatchedParams = true; + } + + $redirector = $this->marshalRedirectPlugin($controller, $redirectToUrl); + + // Redirect to route-based URL + if (false === $redirectToUrl) { + $response = $redirector->toRoute($redirect, $params, $options, $reuseMatchedParams); + $response->setStatusCode(303); + return $response; + } + + // Redirect to specific URL + $response = $redirector->toUrl($redirect); + $response->setStatusCode(303); + + return $response; + } + + /** + * Marshal a redirect plugin instance. + * + * @param DispatchableInterface $controller + * @param bool $redirectToUrl + * @return Redirect + * @throws RuntimeException if route-based redirection is requested, but no + * plugin manager is composed in the controller. + */ + private function marshalRedirectPlugin(DispatchableInterface $controller, $redirectToUrl) + { + if (method_exists($controller, 'getPluginManager')) { + // get the redirect plugin from the plugin manager + return $controller->getPluginManager()->get('Redirect'); + } + + // If the user wants to redirect to a route, the redirector has to come + // from the plugin manager; otherwise no router will be injected + if (false === $redirectToUrl) { + throw new RuntimeException('Could not redirect to a route without a router'); + } + + return new Redirect(); + } +} |