Exemple #1
0
 /**
  * @group ZF2-5648
  */
 public function testCountZeroValidateInternalInputWithCollectionInputFilter()
 {
     $inputFilter = new InputFilter();
     $inputFilter->add(new Input(), 'name');
     $collection = new CollectionInputFilter();
     $collection->setInputFilter($inputFilter);
     $collection->setCount(0);
     $this->filter->add($collection, 'people');
     $data = array('people' => array(array('name' => 'Wanderson')));
     $this->filter->setData($data);
     $this->assertTrue($this->filter->isvalid());
     $this->assertSame($data, $this->filter->getValues());
 }
 private function setAllInputFilters()
 {
     $finalInputFilter = $this->createBaseInputFilter();
     //set filters for entityProperties collection
     $propertyFieldset = new PropertyFieldset();
     $propertiesFilter = new CollectionInputFilter();
     $propertiesFilter->setInputFilter($propertyFieldset->getInputFilter());
     $finalInputFilter->add($propertiesFilter, 'entityProperties');
     //set filters for indexes collection
     $indexFieldset = new IndexFieldset();
     $indexesFilter = new CollectionInputFilter();
     $indexesFilter->setInputFilter($indexFieldset->getInputFilter());
     $finalInputFilter->add($indexesFilter, 'indexes');
     //set the completed input filter as the form's filter
     $this->setInputFilter($finalInputFilter);
 }
 public function setInputFilter($inputFilter)
 {
     if (is_string($inputFilter)) {
         $inputFilters = $this->getFactory()->getInputFilterManager();
         $inputFilter = $inputFilters->get($inputFilter);
     }
     return parent::setInputFilter($inputFilter);
 }
 /**
  * @param Collection $collection
  */
 protected function configureInputFilter(Collection $collection)
 {
     // Make it a collection input filter
     $inputFilter = new CollectionInputFilter();
     $inputFilter->setIsRequired(false);
     // Add the input filter of the target document as the real input filter:
     $targetElement = $collection->getTargetElement();
     if ($targetElement instanceof InputFilterProviderInterface) {
         $configuredFilter = $targetElement->getInputFilterSpecification();
         $inputFilter->setInputFilter($configuredFilter);
     }
     // Replace the current input filter in the actual form:
     $collectionName = $collection->getName();
     $formFilter = $this->form->getInputFilter();
     $formFilter->remove($collectionName);
     $formFilter->add($inputFilter, $collectionName);
 }
 public function testSetRequired()
 {
     $this->filter->setIsRequired(true);
     $this->assertEquals(true, $this->filter->getIsRequired());
 }
Exemple #6
0
 /**
  * Add inputs to CollectionInputFilter
  *
  * @param  CollectionInputFilter $inputFilter
  * @return CollectionInputFilter
  */
 private function addInputsToCollectionInputFilter(CollectionInputFilter $inputFilter)
 {
     foreach ($inputFilter->getInputs() as $name => $input) {
         if (!$inputFilter->getInputFilter()->has($name)) {
             $inputFilter->getInputFilter()->add($input, $name);
         }
     }
     return $inputFilter;
 }
 /**
  * Return a list of validation failure messages
  *
  * Should return an associative array of named input/message list pairs.
  * Pairs should only be returned for inputs that failed validation.
  *
  * @return array
  */
 public function getMessages()
 {
     $messages = parent::getMessages();
     return array_replace_recursive($messages, $this->collectionMessages);
 }
 public function testNestedCollectionWithEmptyData()
 {
     $items_inputfilter = new BaseInputFilter();
     $items_inputfilter->add(new Input(), 'id')->add(new Input(), 'type');
     $items = new CollectionInputFilter();
     $items->setInputFilter($items_inputfilter);
     $groups_inputfilter = new BaseInputFilter();
     $groups_inputfilter->add(new Input(), 'group_class')->add($items, 'items');
     $groups = new CollectionInputFilter();
     $groups->setInputFilter($groups_inputfilter);
     $inputFilter = new BaseInputFilter();
     $inputFilter->add($groups, 'groups');
     $data = array('groups' => array(array('group_class' => 'bar', 'items' => array(array('id' => 100, 'type' => 'item-1'))), array('group_class' => 'biz', 'items' => array()), array('group_class' => 'bar', 'items' => array(array('id' => 200, 'type' => 'item-2'), array('id' => 300, 'type' => 'item-3'), array('id' => 400, 'type' => 'item-4')))));
     $inputFilter->setData($data);
     $inputFilter->isValid();
     $values = $inputFilter->getValues();
     $this->assertEquals($data, $values);
 }
    /**
     * Attempt to validate the incoming request
     *
     * If an input filter is associated with the matched controller service,
     * attempt to validate the incoming request, and inject the event with the
     * input filter, as the "ZF\ContentValidation\InputFilter" parameter.
     *
     * Uses the ContentNegotiation ParameterDataContainer to retrieve parameters
     * to validate, and returns an ApiProblemResponse when validation fails.
     *
     * Also returns an ApiProblemResponse in cases of:
     *
     * - Invalid input filter service name
     * - Missing ParameterDataContainer (i.e., ContentNegotiation is not registered)
     *
     * @param MvcEvent $e
     * @return null|ApiProblemResponse
     */
    public function onRoute(MvcEvent $e)
    {
        $request = $e->getRequest();
        if (! $request instanceof HttpRequest) {
            return;
        }

        $method = $request->getMethod();
        if (in_array($method, $this->methodsWithoutBodies)) {
            return;
        }

        $routeMatches = $e->getRouteMatch();
        if (! $routeMatches instanceof RouteMatch) {
            return;
        }
        $controllerService = $routeMatches->getParam('controller', false);
        if (! $controllerService) {
            return;
        }

        $inputFilterService = $this->getInputFilterService($controllerService, $method);
        if (! $inputFilterService) {
            return;
        }

        if (! $this->hasInputFilter($inputFilterService)) {
            return new ApiProblemResponse(
                new ApiProblem(
                    500,
                    sprintf('Listed input filter "%s" does not exist; cannot validate request', $inputFilterService)
                )
            );
        }

        $dataContainer = $e->getParam('ZFContentNegotiationParameterData', false);
        if (! $dataContainer instanceof ParameterDataContainer) {
            return new ApiProblemResponse(
                new ApiProblem(
                    500,
                    'ZF\\ContentNegotiation module is not initialized; cannot validate request'
                )
            );
        }
        $data = $dataContainer->getBodyParams();
        if (null === $data || '' === $data) {
            $data = array();
        }

        $isCollection = $this->isCollection($controllerService, $data, $routeMatches, $request);

        $files = $request->getFiles();
        if (! $isCollection && 0 < count($files)) {
            // File uploads are not validated for collections; impossible to
            // match file fields to discrete sets
            $data = array_merge_recursive($data, $files->toArray());
        }

        $inputFilter = $this->getInputFilter($inputFilterService);

        if ($isCollection) {
            $collectionInputFilter = new CollectionInputFilter();
            $collectionInputFilter->setInputFilter($inputFilter);
            $inputFilter = $collectionInputFilter;
        }

        $e->setParam('ZF\ContentValidation\InputFilter', $inputFilter);

        $events = $this->getEventManager();
        $results = $events->trigger(self::EVENT_BEFORE_VALIDATE, $e, function ($result) {
            return ($result instanceof ApiProblem
                || $result instanceof ApiProblemResponse
            );
        });

        $last = $results->last();

        if ($last instanceof ApiProblem) {
            $last = new ApiProblemResponse($last);
        }

        if ($last instanceof ApiProblemResponse) {
            return $last;
        }

        $inputFilter->setData($data);

        $status = ($request->isPatch())
            ? $this->validatePatch($inputFilter, $data, $isCollection)
            : $inputFilter->isValid();

        if ($status instanceof ApiProblemResponse) {
            return $status;
        }

        // Invalid? Return a 422 response.
        if (false === $status) {
            return new ApiProblemResponse(
                new ApiProblem(422, 'Failed Validation', null, null, array(
                    'validation_messages' => $inputFilter->getMessages(),
                ))
            );
        }

        // Should we use the raw data vs. the filtered data?
        // - If no `use_raw_data` flag is present, always use the raw data, as
        //   that was the default experience starting in 1.0.
        // - If the flag is present AND is boolean true, that is also
        //   an indicator that the raw data should be present.
        if (! isset($this->config[$controllerService]['use_raw_data'])
            || (isset($this->config[$controllerService]['use_raw_data'])
                && $this->config[$controllerService]['use_raw_data'] === true)
        ) {
            $dataContainer->setBodyParams($data);
            return;
        }

        // If we don't have an instance of UnknownInputsCapableInterface, or no
        // unknown data is in the input filter, at this point we can just
        // set the input filter values directly into the data container.
        if (! $inputFilter instanceof UnknownInputsCapableInterface
            || ! $inputFilter->hasUnknown()
        ) {
            $dataContainer->setBodyParams($inputFilter->getValues());
            return;
        }

        $bodyParams = $inputFilter->getValues();
        $unknown    = $inputFilter->getUnknown();

        if ($this->allowsOnlyFieldsInFilter($controllerService)) {
            $fields  = implode(', ', array_keys($unknown));
            $detail  = sprintf('Unrecognized fields: %s', $fields);
            $problem = new ApiProblem(Response::STATUS_CODE_422, $detail);

            return new ApiProblemResponse($problem);
        }

        $dataContainer->setBodyParams(array_merge($bodyParams, $unknown));
    }
 /**
  * Attempt to validate the incoming request
  *
  * If an input filter is associated with the matched controller service,
  * attempt to validate the incoming request, and inject the event with the
  * input filter, as the "ZF\ContentValidation\InputFilter" parameter.
  *
  * Uses the ContentNegotiation ParameterDataContainer to retrieve parameters
  * to validate, and returns an ApiProblemResponse when validation fails.
  *
  * Also returns an ApiProblemResponse in cases of:
  *
  * - Invalid input filter service name
  * - Missing ParameterDataContainer (i.e., ContentNegotiation is not registered)
  *
  * @param MvcEvent $e
  * @return null|ApiProblemResponse
  */
 public function onRoute(MvcEvent $e)
 {
     $request = $e->getRequest();
     if (!$request instanceof HttpRequest) {
         return;
     }
     $routeMatches = $e->getRouteMatch();
     if (!($routeMatches instanceof RouteMatch || $routeMatches instanceof V2RouteMatch)) {
         return;
     }
     $controllerService = $routeMatches->getParam('controller', false);
     if (!$controllerService) {
         return;
     }
     $method = $request->getMethod();
     $inputFilterService = $this->getInputFilterService($controllerService, $method);
     if (!$inputFilterService) {
         return;
     }
     if (!$this->hasInputFilter($inputFilterService)) {
         return new ApiProblemResponse(new ApiProblem(500, sprintf('Listed input filter "%s" does not exist; cannot validate request', $inputFilterService)));
     }
     $dataContainer = $e->getParam('ZFContentNegotiationParameterData', false);
     if (!$dataContainer instanceof ParameterDataContainer) {
         return new ApiProblemResponse(new ApiProblem(500, 'ZF\\ContentNegotiation module is not initialized; cannot validate request'));
     }
     $data = in_array($method, $this->methodsWithoutBodies) ? $dataContainer->getQueryParams() : $dataContainer->getBodyParams();
     if (null === $data || '' === $data) {
         $data = [];
     }
     $isCollection = $this->isCollection($controllerService, $data, $routeMatches, $request);
     $files = $request->getFiles();
     if (!$isCollection && 0 < count($files)) {
         // File uploads are not validated for collections; impossible to
         // match file fields to discrete sets
         $data = ArrayUtils::merge($data, $files->toArray(), true);
     }
     $inputFilter = $this->getInputFilter($inputFilterService);
     if ($isCollection && !in_array($method, $this->methodsWithoutBodies)) {
         $collectionInputFilter = new CollectionInputFilter();
         $collectionInputFilter->setInputFilter($inputFilter);
         $inputFilter = $collectionInputFilter;
     }
     $e->setParam('ZF\\ContentValidation\\InputFilter', $inputFilter);
     $currentEventName = $e->getName();
     $e->setName(self::EVENT_BEFORE_VALIDATE);
     $events = $this->getEventManager();
     $results = $events->triggerEventUntil(function ($result) {
         return $result instanceof ApiProblem || $result instanceof ApiProblemResponse;
     }, $e);
     $e->setName($currentEventName);
     $last = $results->last();
     if ($last instanceof ApiProblem) {
         $last = new ApiProblemResponse($last);
     }
     if ($last instanceof ApiProblemResponse) {
         return $last;
     }
     $inputFilter->setData($data);
     $status = $request->isPatch() ? $this->validatePatch($inputFilter, $data, $isCollection) : $inputFilter->isValid();
     if ($status instanceof ApiProblemResponse) {
         return $status;
     }
     // Invalid? Return a 422 response.
     if (false === $status) {
         return new ApiProblemResponse(new ApiProblem(422, 'Failed Validation', null, null, ['validation_messages' => $inputFilter->getMessages()]));
     }
     // Should we use the raw data vs. the filtered data?
     // - If no `use_raw_data` flag is present, always use the raw data, as
     //   that was the default experience starting in 1.0.
     // - If the flag is present AND is boolean true, that is also
     //   an indicator that the raw data should be present.
     $useRawData = $this->useRawData($controllerService);
     if (!$useRawData) {
         $data = $inputFilter->getValues();
     }
     // If we don't have an instance of UnknownInputsCapableInterface, or no
     // unknown data is in the input filter, at this point we can just
     // set the current data into the data container.
     if (!$inputFilter instanceof UnknownInputsCapableInterface || !$inputFilter->hasUnknown()) {
         $dataContainer->setBodyParams($data);
         return;
     }
     $unknown = $inputFilter->getUnknown();
     if ($this->allowsOnlyFieldsInFilter($controllerService)) {
         if ($inputFilter instanceof CollectionInputFilter) {
             $unknownFields = [];
             foreach ($unknown as $key => $fields) {
                 $unknownFields[] = '[' . $key . ': ' . implode(', ', array_keys($fields)) . ']';
             }
             $fields = implode(', ', $unknownFields);
         } else {
             $fields = implode(', ', array_keys($unknown));
         }
         $detail = sprintf('Unrecognized fields: %s', $fields);
         $problem = new ApiProblem(Response::STATUS_CODE_422, $detail);
         return new ApiProblemResponse($problem);
     }
     // The raw data already contains unknown inputs, so no need to merge
     // them with the data.
     if ($useRawData) {
         $dataContainer->setBodyParams($data);
         return;
     }
     // When not using raw data, we merge the unknown data with the
     // validated data to get the full set of input.
     $dataContainer->setBodyParams(array_merge($data, $unknown));
 }