Skip to content
This repository has been archived by the owner on Jan 8, 2020. It is now read-only.

Commit

Permalink
Merge branch 'hotfix/3557' into develop
Browse files Browse the repository at this point in the history
Close #3557
  • Loading branch information
weierophinney committed Jan 25, 2013
2 parents 2b79424 + 7c15887 commit 08c3cb9
Show file tree
Hide file tree
Showing 2 changed files with 100 additions and 47 deletions.
126 changes: 79 additions & 47 deletions library/Zend/Mvc/Controller/Plugin/FilePostRedirectGet.php
Expand Up @@ -11,13 +11,12 @@
namespace Zend\Mvc\Controller\Plugin;

use Zend\Filter\FilterChain;
use Zend\Form\Form;
use Zend\Form\FormInterface;
use Zend\Http\Response;
use Zend\InputFilter\FileInput;
use Zend\InputFilter\InputFilterInterface;
use Zend\Mvc\Exception\RuntimeException;
use Zend\Session\Container;
use Zend\Stdlib\ArrayUtils;
use Zend\Validator\ValidatorChain;

/**
Expand All @@ -38,12 +37,12 @@ class FilePostRedirectGet extends AbstractPlugin
protected $sessionContainer;

/**
* @param Form $form
* @param string $redirect Route or URL string (default: current route)
* @param boolean $redirectToUrl Use $redirect as a URL string (default: false)
* @param FormInterface $form
* @param string $redirect Route or URL string (default: current route)
* @param boolean $redirectToUrl Use $redirect as a URL string (default: false)
* @return boolean|array|Response
*/
public function __invoke(Form $form, $redirect = null, $redirectToUrl = false)
public function __invoke(FormInterface $form, $redirect = null, $redirectToUrl = false)
{
$request = $this->getController()->getRequest();
if ($request->isPost()) {
Expand All @@ -54,12 +53,12 @@ public function __invoke(Form $form, $redirect = null, $redirectToUrl = false)
}

/**
* @param Form $form
* @param string $redirect Route or URL string (default: current route)
* @param boolean $redirectToUrl Use $redirect as a URL string (default: false)
* @param FormInterface $form
* @param string $redirect Route or URL string (default: current route)
* @param boolean $redirectToUrl Use $redirect as a URL string (default: false)
* @return Response
*/
protected function handlePostRequest(Form $form, $redirect, $redirectToUrl)
protected function handlePostRequest(FormInterface $form, $redirect, $redirectToUrl)
{
$container = $this->getSessionContainer();
$request = $this->getController()->getRequest();
Expand All @@ -81,19 +80,22 @@ function($input, $value) {
// Run the form validations/filters and retrieve any errors
$postFiles = $request->getFiles()->toArray();
$postOther = $request->getPost()->toArray();
$post = ArrayUtils::merge($postOther, $postFiles);
$post = array_merge_recursive($postOther, $postFiles);

// Validate form, and capture data and errors
$form->setData($post);
$isValid = $form->isValid();
$data = $form->getData(Form::VALUES_AS_ARRAY);
$data = $form->getData(FormInterface::VALUES_AS_ARRAY);
$errors = (!$isValid) ? $form->getMessages() : null;

// Loop through data and merge previous files with new valid files
$postFiles = ArrayUtils::merge(
$previousFiles,
$this->filterInvalidFileInputPostData($inputFilter, $data)
// Merge and replace previous files with new valid files
$prevFileData = $this->getEmptyUploadData($inputFilter, $previousFiles);
$newFileData = $this->getNonEmptyUploadData($inputFilter, $data);
$postFiles = array_merge_recursive(
$prevFileData ?: array(),
$newFileData ?: array()
);
$post = ArrayUtils::merge($post, $postFiles);
$post = array_merge_recursive($postOther, $postFiles);

// Save form data in session
$container->setExpirationHops(1, array('post', 'errors', 'isValid'));
Expand All @@ -106,10 +108,10 @@ function($input, $value) {
}

/**
* @param Form $form
* @param FormInterface $form
* @return boolean|array
*/
protected function handleGetRequest(Form $form)
protected function handleGetRequest(FormInterface $form)
{
$container = $this->getSessionContainer();
if (null === $container->post) {
Expand Down Expand Up @@ -171,21 +173,33 @@ public function getSessionContainer()
}

/**
* @param Form $form
* @param Container $container
* @return FilePostRedirectGet
*/
public function setSessionContainer(Container $container)
{
$this->sessionContainer = container;
return $this;
}

/**
* @param FormInterface $form
* @param string $property
* @param mixed $value
* @return FilePostRedirectGet
*/
protected function setProtectedFormProperty(Form $form, $property, $value)
protected function setProtectedFormProperty(FormInterface $form, $property, $value)
{
$formClass = new \ReflectionClass('Zend\Form\Form');
$formClass = new \ReflectionClass($form);
$property = $formClass->getProperty($property);
$property->setAccessible(true);
$property->setValue($form, $value);
return $this;
}

/**
* Traverse the InputFilter and run a callback against each Input and associated value
*
* @param InputFilterInterface $inputFilter
* @param array $values
* @param callable $callback
Expand Down Expand Up @@ -217,44 +231,62 @@ protected function traverseInputs(InputFilterInterface $inputFilter, $values, $c
}

/**
* Traverse the InputFilter and only return the data of FileInputs that have an upload
*
* @param InputFilterInterface $inputFilter
* @param array $data
* @return array
*/
protected function filterInvalidFileInputPostData(InputFilterInterface $inputFilter, $data)
protected function getNonEmptyUploadData(InputFilterInterface $inputFilter, $data)
{
$returnValues = array();
$validInputs = $inputFilter->getValidInput();
foreach ($validInputs as $name => $input) {
if (!isset($data[$name])) {
continue;
}
$dataValue = $data[$name];

if ($input instanceof InputFilterInterface && is_array($dataValue)) {
$retVal = $this->filterInvalidFileInputPostData($input, $dataValue);
if (!empty($retVal)) {
$returnValues[$name] = $retVal;
return $this->traverseInputs(
$inputFilter,
$data,
function($input, $value) {
$messages = $input->getMessages();
if (is_array($value) && $input instanceof FileInput && empty($messages)) {
$rawValue = $input->getRawValue();
if ( (isset($rawValue['error']) && $rawValue['error'] !== UPLOAD_ERR_NO_FILE)
|| (isset($rawValue[0]['error']) && $rawValue[0]['error'] !== UPLOAD_ERR_NO_FILE)
) {
return $value;
}
}
continue;
return null;
}
);
}

$messages = $input->getMessages();
if (is_array($dataValue)
&& $input instanceof FileInput
&& empty($messages)
) {
if ( (isset($dataValue['error']) && $dataValue['error'] === UPLOAD_ERR_OK)
|| (isset($dataValue[0]['error']) && $dataValue[0]['error'] === UPLOAD_ERR_OK)
) {
$returnValues[$name] = $dataValue;
/**
* Traverse the InputFilter and only return the data of FileInputs that are empty
*
* @param InputFilterInterface $inputFilter
* @param array $data
* @return array
*/
protected function getEmptyUploadData(InputFilterInterface $inputFilter, $data)
{
return $this->traverseInputs(
$inputFilter,
$data,
function($input, $value) {
$messages = $input->getMessages();
if (is_array($value) && $input instanceof FileInput && empty($messages)) {
$rawValue = $input->getRawValue();
if ( (isset($rawValue['error']) && $rawValue['error'] === UPLOAD_ERR_NO_FILE)
|| (isset($rawValue[0]['error']) && $rawValue[0]['error'] === UPLOAD_ERR_NO_FILE)
) {
return $value;
}
}
return null;
}
}
return $returnValues;
);
}

/**
* TODO: Good candidate for traits method in PHP 5.4 with PostRedirectGet plugin
*
* @param string $redirect
* @param boolean $redirectToUrl
* @return Response
Expand Down
21 changes: 21 additions & 0 deletions library/Zend/Mvc/Controller/Plugin/PostRedirectGet.php
Expand Up @@ -62,6 +62,9 @@ public function __invoke($redirect = null, $redirectToUrl = false)
}
}

/**
* @return Container
*/
public function getSessionContainer()
{
if (!isset($this->sessionContainer)) {
Expand All @@ -70,6 +73,24 @@ public function getSessionContainer()
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 boolean $redirectToUrl
* @return Response
* @throws \Zend\Mvc\Exception\RuntimeException
*/
protected function redirect($redirect, $redirectToUrl)
{
$controller = $this->getController();
Expand Down

0 comments on commit 08c3cb9

Please sign in to comment.