diff --git a/.coveralls.yml b/.coveralls.yml
new file mode 100644
index 0000000..bc71b62
--- /dev/null
+++ b/.coveralls.yml
@@ -0,0 +1,2 @@
+coverage_clover: clover.xml
+json_path: coveralls-upload.json
diff --git a/.docheader b/.docheader
new file mode 100644
index 0000000..2d9cad4
--- /dev/null
+++ b/.docheader
@@ -0,0 +1,20 @@
+/*
+ * This file is part of eldnp/export.zend.
+ *
+ * Eldnp/export.zend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Eldnp/export.zend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with eldnp/export.zend. If not, see .
+ *
+ * @see https://github.com/eldnp/export.zend for the canonical source repository
+ * @copyright Copyright (c) %regexp:(20\d{2}-)?20\d{2}% Oleg Verevskoy
+ * @license https://github.com/eldnp/export.zend/blob/master/LICENSE GNU GENERAL PUBLIC LICENSE Version 3
+ */
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..3a3f1ff
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,8 @@
+/.coveralls.yml export-ignore
+/.docheader export-ignore
+/.gitattributes export-ignore
+/.gitignore export-ignore
+/.travis.yml export-ignore
+/phpcs.xml export-ignore
+/phpunit.xml.dist export-ignore
+/test export-ignore
diff --git a/.gitignore b/.gitignore
index c422267..0716f01 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,4 @@
-composer.phar
-/vendor/
-
-# Commit your application's lock file http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file
-# You may choose to ignore a library lock file http://getcomposer.org/doc/02-libraries.md#lock-file
-# composer.lock
+.idea/
+vendor/
+composer.lock
+phpunit.xml
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..b6e7ac3
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,43 @@
+sudo: false
+
+language: php
+
+cache:
+ directories:
+ - $HOME/.composer/cache
+
+env:
+ global:
+ - COMPOSER_ARGS="--no-interaction"
+ - COVERAGE_DEPS="satooshi/php-coveralls"
+
+matrix:
+ include:
+ - php: 5.3
+ dist: precise
+ env:
+ - CS_CHECK=true
+ - TEST_COVERAGE=true
+ - php: 5.4
+ dist: precise
+ - php: 5.5
+ dist: precise
+ - php: 5.6
+
+before_install:
+ - if [[ $TEST_COVERAGE != 'true' && "$(php --version | grep xdebug -ci)" -ge 1 ]]; then phpenv config-rm xdebug.ini || return 0 ; fi
+ - travis_retry composer self-update
+
+install:
+ - travis_retry composer install $COMPOSER_ARGS
+ - if [[ $TEST_COVERAGE == 'true' ]]; then travis_retry composer require --dev $COMPOSER_ARGS $COVERAGE_DEPS ; fi
+ - stty cols 120 && composer show
+script:
+ - if [[ $TEST_COVERAGE == 'true' ]]; then composer test-coverage ; else composer test ; fi
+ - if [[ $CS_CHECK == 'true' ]]; then composer cs-check ; fi
+
+after_script:
+ - if [[ $TEST_COVERAGE == 'true' ]]; then composer upload-coverage ; fi
+
+notifications:
+ email: false
diff --git a/README.md b/README.md
index dbb44d6..def3dc5 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,6 @@
# export.zend
+
+[](https://travis-ci.org/eldnp/export.zend)
+[](https://coveralls.io/github/eldnp/export.zend?branch=master)
+
export.zend
diff --git a/composer.json b/composer.json
new file mode 100644
index 0000000..ddf5e75
--- /dev/null
+++ b/composer.json
@@ -0,0 +1,48 @@
+{
+ "name": "eldnp/export.zend",
+ "type": "library",
+ "license": "GPL-3.0",
+ "authors": [
+ {
+ "name": "Oleg Verevskoy",
+ "email": "verevskoy@gmail.com",
+ "role": "Developer"
+ }
+ ],
+ "extra": {
+ "branch-alias": {
+ "dev-master": "0.1-dev",
+ "dev-develop": "0.2-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Eldnp\\Export\\Zend\\": "lib/"
+ }
+ },
+ "autoload-dev": {
+ "psr-4": {
+ "EldnpTest\\Export\\Zend\\": "test/"
+ }
+ },
+ "require": {
+ "php": "^5.3",
+ "eldnp/export.map": "^0.2",
+ "zendframework/zend-inputfilter": "^2.5"
+ },
+ "require-dev": {
+ "phpunit/PHPUnit": "^4.8",
+ "zendframework/zend-coding-standard": "~1.0.0"
+ },
+ "scripts": {
+ "check": [
+ "@cs-check",
+ "@test"
+ ],
+ "upload-coverage": "coveralls -v",
+ "cs-check": "phpcs",
+ "cs-fix": "phpcbf",
+ "test": "phpunit --colors=always",
+ "test-coverage": "phpunit --coverage-clover clover.xml"
+ }
+}
diff --git a/lib/DataSource/FilterableDataSourceDecorator.php b/lib/DataSource/FilterableDataSourceDecorator.php
new file mode 100644
index 0000000..1e0bfab
--- /dev/null
+++ b/lib/DataSource/FilterableDataSourceDecorator.php
@@ -0,0 +1,125 @@
+.
+ *
+ * @see https://github.com/eldnp/export.zend for the canonical source repository
+ * @copyright Copyright (c) 2017 Oleg Verevskoy
+ * @license https://github.com/eldnp/export.zend/blob/master/LICENSE GNU GENERAL PUBLIC LICENSE Version 3
+ */
+
+namespace Eldnp\Export\Zend\DataSource;
+
+use Eldnp\Export\Map\AbstractMapDataSource;
+use Zend\InputFilter\InputFilterInterface;
+
+/**
+ * Class FilterableDataSourceDecorator
+ *
+ * @package Eldnp\Export\Zend\DataSource
+ */
+class FilterableDataSourceDecorator extends AbstractMapDataSource
+{
+ /**
+ * @var AbstractMapDataSource
+ */
+ private $dataSource;
+
+ /**
+ * @var InputFilterInterface
+ */
+ private $inputFilter;
+
+ /**
+ * @var ValidationCallbackHandlerInterface
+ */
+ private $validationCallbackHandler;
+
+ /**
+ * @var array
+ */
+ private $currentData;
+
+ /**
+ * FilterableDataSourceDecorator constructor.
+ *
+ * @param AbstractMapDataSource $dataSource
+ * @param InputFilterInterface $inputFilter
+ * @param ValidationCallbackHandlerInterface $validationCallbackHandler
+ */
+ public function __construct(
+ AbstractMapDataSource $dataSource,
+ InputFilterInterface $inputFilter,
+ ValidationCallbackHandlerInterface $validationCallbackHandler
+ ) {
+ $this->dataSource = $dataSource;
+ $this->inputFilter = $inputFilter;
+ $this->validationCallbackHandler = $validationCallbackHandler;
+ }
+
+ /**
+ * @inheritdoc
+ */
+ protected function currentMap()
+ {
+ return $this->currentData;
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function next()
+ {
+ do {
+ $this->currentData = false;
+ $this->dataSource->next();
+ if (false === $this->dataSource->valid()) {
+ return;
+ }
+ $newData = $this->dataSource->current();
+ $this->inputFilter->setData($newData);
+ if (!$this->inputFilter->isValid()) {
+ $this->validationCallbackHandler->handle($this->inputFilter->getMessages());
+ continue;
+ }
+ $this->currentData = $this->inputFilter->getValues();
+ return;
+ } while (true);
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function key()
+ {
+ return $this->dataSource->key();
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function valid()
+ {
+ return $this->dataSource->valid();
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function rewind()
+ {
+ $this->dataSource->rewind();
+ }
+}
diff --git a/lib/DataSource/ValidationCallbackHandlerInterface.php b/lib/DataSource/ValidationCallbackHandlerInterface.php
new file mode 100644
index 0000000..282faaf
--- /dev/null
+++ b/lib/DataSource/ValidationCallbackHandlerInterface.php
@@ -0,0 +1,38 @@
+.
+ *
+ * @see https://github.com/eldnp/export.zend for the canonical source repository
+ * @copyright Copyright (c) 2017 Oleg Verevskoy
+ * @license https://github.com/eldnp/export.zend/blob/master/LICENSE GNU GENERAL PUBLIC LICENSE Version 3
+ */
+
+namespace Eldnp\Export\Zend\DataSource;
+
+/**
+ * Interface ValidationCallbackHandlerInterface
+ *
+ * @package Eldnp\Export\Zend\DataSource
+ */
+interface ValidationCallbackHandlerInterface
+{
+ /**
+ * @param array $messages
+ *
+ * @return void
+ */
+ public function handle(array $messages);
+}
diff --git a/phpcs.xml b/phpcs.xml
new file mode 100644
index 0000000..1da2e64
--- /dev/null
+++ b/phpcs.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+ lib
+
diff --git a/phpunit.xml.dist b/phpunit.xml.dist
new file mode 100644
index 0000000..fbb29b3
--- /dev/null
+++ b/phpunit.xml.dist
@@ -0,0 +1,27 @@
+
+
+
+
+ ./test/
+
+
+
+
+
+ disable
+
+
+
+
+
+ ./lib
+
+
+
+
+
+
+
diff --git a/test/DataSource/FilterableDataSourceDecoratorTest.php b/test/DataSource/FilterableDataSourceDecoratorTest.php
new file mode 100644
index 0000000..83eec35
--- /dev/null
+++ b/test/DataSource/FilterableDataSourceDecoratorTest.php
@@ -0,0 +1,95 @@
+.
+ *
+ * @see https://github.com/eldnp/export.zend for the canonical source repository
+ * @copyright Copyright (c) 2017 Oleg Verevskoy
+ * @license https://github.com/eldnp/export.zend/blob/master/LICENSE GNU GENERAL PUBLIC LICENSE Version 3
+ */
+
+namespace EldnpTest\Export\Zend\DataSource;
+
+use Eldnp\Export\Map\DataSource\ArrayMapDataSource;
+use Eldnp\Export\Zend\DataSource\FilterableDataSourceDecorator;
+use Eldnp\Export\Zend\DataSource\ValidationCallbackHandlerInterface;
+use PHPUnit\Framework\TestCase;
+use Prophecy\Argument;
+use Zend\InputFilter\Input;
+use Zend\InputFilter\InputFilter;
+use Zend\Validator\Between;
+
+class FilterableDataSourceDecoratorTest extends TestCase
+{
+ public function testFilterableDataSourceIterator()
+ {
+ $validationCallbackHandlerProphecy = $this->prophesize('\Eldnp\Export\Zend\DataSource\ValidationCallbackHandlerInterface');
+ $validationCallbackHandlerProphecy
+ ->__call('handle', array(Argument::any()))
+ ->shouldBeCalledTimes(3)
+ ;
+ /** @var ValidationCallbackHandlerInterface $validationCallbackHandler */
+ $validationCallbackHandler = $validationCallbackHandlerProphecy->reveal();
+
+ $field1Input = new Input('field-1');
+ $field1Input->getValidatorChain()->attach(
+ new Between(array(
+ 'min' => 0,
+ 'max' => 3
+ ))
+ );
+
+ $field2Input = new Input('field-2');
+ $field2Input->getValidatorChain()->attach(
+ new Between(array(
+ 'min' => 3,
+ 'max' => 7
+ ))
+ );
+
+ $inputFilter = new InputFilter();
+ $inputFilter->add($field1Input);
+ $inputFilter->add($field2Input);
+
+ $arrayMapDataSource = new ArrayMapDataSource(array(
+ array(
+ 'field-1' => 1, //valid
+ 'field-2' => 4, //valid
+ ),
+ array(
+ 'field-1' => 4, //not valid
+ 'field-2' => 6, //valid
+ ),
+ array(
+ 'field-1' => 3, //valid
+ 'field-2' => 2, //not valid
+ ),
+ array(
+ 'field-1' => 7, //not valid
+ 'field-2' => 2, //not valid
+ ),
+ array(
+ 'field-1' => 3, //valid
+ 'field-2' => 5, //valid
+ ),
+ ));
+ $filterableDataSource = new FilterableDataSourceDecorator($arrayMapDataSource, $inputFilter, $validationCallbackHandler);
+ $counter = 0;
+ foreach ($filterableDataSource as $key => $value) {
+ $counter++;
+ }
+ $this->assertEquals(2, $counter);
+ }
+}