{"action":"created","issue":{"url":"https://api.github.com/repos/zendframework/zend-inputfilter/issues/168","repository_url":"https://api.github.com/repos/zendframework/zend-inputfilter","labels_url":"https://api.github.com/repos/zendframework/zend-inputfilter/issues/168/labels{/name}","comments_url":"https://api.github.com/repos/zendframework/zend-inputfilter/issues/168/comments","events_url":"https://api.github.com/repos/zendframework/zend-inputfilter/issues/168/events","html_url":"https://github.com/zendframework/zend-inputfilter/issues/168","id":333613364,"node_id":"MDU6SXNzdWUzMzM2MTMzNjQ=","number":168,"title":"collectionRawValues not populated in setData of CollectionInputFilter","user":{"login":"rkeet","id":3327864,"node_id":"MDQ6VXNlcjMzMjc4NjQ=","avatar_url":"https://avatars0.githubusercontent.com/u/3327864?v=4","gravatar_id":"","url":"https://api.github.com/users/rkeet","html_url":"https://github.com/rkeet","followers_url":"https://api.github.com/users/rkeet/followers","following_url":"https://api.github.com/users/rkeet/following{/other_user}","gists_url":"https://api.github.com/users/rkeet/gists{/gist_id}","starred_url":"https://api.github.com/users/rkeet/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rkeet/subscriptions","organizations_url":"https://api.github.com/users/rkeet/orgs","repos_url":"https://api.github.com/users/rkeet/repos","events_url":"https://api.github.com/users/rkeet/events{/privacy}","received_events_url":"https://api.github.com/users/rkeet/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":9,"created_at":"2018-06-19T10:34:14Z","updated_at":"2018-06-20T09:33:26Z","closed_at":null,"author_association":"NONE","body":"Narrative:\r\nI use the following `isValid` function in my InputFilter class:\r\n\r\n    public function isValid($context = null)\r\n    {\r\n        if ( ! $this->isRequired() && $this->arrayFilterIsEmpty($this->getRawValues())) {\r\n\r\n            return true;\r\n        }\r\n\r\n        return parent::isValid();\r\n    }\r\n\r\nThe `function arrayFilterIsEmpty()` checks whether or not the current `$input` contains any data and is required. The `parent::isValid()` calls the normal isValid function.\r\n\r\nAny input (normal Input or Collection) has the function `getRawValues` to get the raw input data. I use it to check if any data is present combined with a required property to see if a both not-required and empty fieldset/collection can be skipped during validation and just be marked as valid. \r\n\r\nDuring `isValid` in `CollectionInputFilter.php` ([line 195](https://github.com/zendframework/zend-inputfilter/blob/4901fc67554efbb7c292ae499129792977df1220/src/CollectionInputFilter.php#L195)) the function `setData` is called ([here](https://github.com/zendframework/zend-inputfilter/blob/4901fc67554efbb7c292ae499129792977df1220/src/CollectionInputFilter.php#L140)). \r\n\r\nHowever, `setData` breaks of setting data if the data is an array or Traversable ([here](https://github.com/zendframework/zend-inputfilter/blob/4901fc67554efbb7c292ae499129792977df1220/src/CollectionInputFilter.php#L151)). This causes the `collectionRawValues` property to never be set.\r\n\r\nAs such, I suggest updating the function to set this value after the initial check, where it's still handling the collection as a whole instead of per item (before the `foreach()`)\r\n\r\n    public function setData($data)\r\n    {\r\n        if ( ! (is_array($data) || $data instanceof Traversable)) {\r\n            throw new InvalidArgumentException(\r\n                sprintf(\r\n                    '%s expects an array or Traversable collection; invalid collection of type %s provided',\r\n                    __METHOD__,\r\n                    is_object($data) ? get_class($data) : gettype($data)\r\n                )\r\n            );\r\n        }\r\n\r\n        $this->collectionRawValues = $data; // added line \r\n\r\n        foreach ($data as $item) {\r\n            if (is_array($item) || $item instanceof Traversable) {\r\n                continue;\r\n            }\r\n\r\n            throw new InvalidArgumentException(\r\n                sprintf(\r\n                    '%s expects each item in a collection to be an array or Traversable; '\r\n                    . 'invalid item in collection of type %s detected',\r\n                    __METHOD__,\r\n                    is_object($item) ? get_class($item) : gettype($item)\r\n                )\r\n            );\r\n        }\r\n\r\n        $this->data = $data;\r\n        return $this;\r\n    }\r\n\r\n### Code to reproduce the issue\r\n\r\nWould be a lot of code. Setup to reproduce would require following form setup:\r\n\r\nForm > BaseFieldset > Fieldset > Collection with Fieldset target\r\nFormInputFilter > BaseFieldsetInputFilter > FieldsetInputFilter > CollectionInputFilter pointing to FieldsetInputFilter\r\n\r\n### Expected results\r\n\r\nExpected `collectionRawValues` to return raw data using `getRawValues()` function.\r\n\r\n### Actual results\r\n\r\nReturns empty array.\r\n\r\n### Received Raw data (example data, concerns \"**shops**\" array)\r\n\r\nAs you can see in the image below, data is received for \"shops\" to be created.\r\n\r\n![image](https://user-images.githubusercontent.com/3327864/41592053-b861f3c4-73bb-11e8-8e5e-391f491e71b7.png)\r\n\r\n### Debugging `getRawValues()` (**fix not applied!**)\r\n\r\nAs you can see here, when I try to get the raw values, the array is empty. \r\n\r\n![image](https://user-images.githubusercontent.com/3327864/41592146-024a8938-73bc-11e8-83c9-d0d16253e925.png)\r\n\r\n### Debugging `getRawValues()` (**fix applied!**)\r\n\r\nHere with the fix applied\r\n\r\n![image](https://user-images.githubusercontent.com/3327864/41592268-4c1df4dc-73bc-11e8-9406-b76eb68d6b54.png)\r\n\r\n---\r\n\r\n### Fixing\r\n\r\nI've read the contributing guidelines. In case you'd like me to create a PR for this I can do so, might take some time (I'm sneaking this in at work as I bumped into it, face first), when I get around to it at home. \r\n\r\nIn the mean time I'm open to alternative methods of fixing the setting of raw data, if any present. "},"comment":{"url":"https://api.github.com/repos/zendframework/zend-inputfilter/issues/comments/398686890","html_url":"https://github.com/zendframework/zend-inputfilter/issues/168#issuecomment-398686890","issue_url":"https://api.github.com/repos/zendframework/zend-inputfilter/issues/168","id":398686890,"node_id":"MDEyOklzc3VlQ29tbWVudDM5ODY4Njg5MA==","user":{"login":"rkeet","id":3327864,"node_id":"MDQ6VXNlcjMzMjc4NjQ=","avatar_url":"https://avatars0.githubusercontent.com/u/3327864?v=4","gravatar_id":"","url":"https://api.github.com/users/rkeet","html_url":"https://github.com/rkeet","followers_url":"https://api.github.com/users/rkeet/followers","following_url":"https://api.github.com/users/rkeet/following{/other_user}","gists_url":"https://api.github.com/users/rkeet/gists{/gist_id}","starred_url":"https://api.github.com/users/rkeet/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rkeet/subscriptions","organizations_url":"https://api.github.com/users/rkeet/orgs","repos_url":"https://api.github.com/users/rkeet/repos","events_url":"https://api.github.com/users/rkeet/events{/privacy}","received_events_url":"https://api.github.com/users/rkeet/received_events","type":"User","site_admin":false},"created_at":"2018-06-20T09:33:26Z","updated_at":"2018-06-20T09:33:26Z","author_association":"NONE","body":"The way it works is that a `CollectionInputFilter` has a target `InputFilter` class (done using `setInputFilter` function on `CollectionInputFilter`). When data is received it is determined how many instances need to be created of said target, which are then held by the `CollectionInputFilter`. As such, a `CollectionInputFilter` should contain the raw values of the entire collection of data (this is broken and is what this fix is about). \r\n\r\nAn `InputFilter` instance should contain only the raw values specific for that `InputFilter` (this works). \r\n\r\nAs such, both the `InputFilter` instances and the `CollectionInputFilter` instance should be able to return the raw data pertaining to each particular instance. Currently this is broken for the `CollectionInputFilter`. \r\n\r\nI really don't know how to make that any clearer than that. \r\n\r\n>that's also not true \r\n\r\nWhat else is not true? Because I'm here arguing to get something broken fixed and I'm thinking your understanding of the implementations of `CollectionInputFilter` and `InputFilter` is mixed with that of specific `Element` instances from zend-form, thus not contained to zend-inputfilter. \r\n\r\n> can you write a test to compare getRawValues with before isValid() and after when data contains more data than inputs in input\r\n\r\nNext to \"inputs\", by which I'm assuming you mean instances of `InputFilter` (in the code: `$firstInputFilter = new InputFilter()`), what else would you like me to add? Things that can be added to a `CollectionInputFilter` are literally limited to instances extending `BaseInputFilter` as defined in the `setInputFilter` function [here](https://github.com/rkeet/zend-inputfilter/blob/ae5df37e48933a52a92afd6a8678eb65bbad3fd0/src/CollectionInputFilter.php#L59). As I mentioned before, implementation of `InputFilter` is not changed by this. \r\n\r\nIf you see any issues, could you provide detailed examples of how this fix negatively impacts existing implementations?"}}
{"actor":{"display_login":"rkeet"}}