diff options
author | Ignace Nyamagana Butera <nyamsprod@gmail.com> | 2015-02-19 08:49:17 +0100 |
---|---|---|
committer | Ignace Nyamagana Butera <nyamsprod@gmail.com> | 2015-02-19 08:52:39 +0100 |
commit | 0a493cecf0216f4c797671601251e3c1a6452ffa (patch) | |
tree | a23aeb9c31d7e05ccffa30bd4e5dc46cd27a5139 /src/Modifier | |
parent | 959ede56075fec54891fad13744aeed6d42ad345 (diff) | |
download | csv-0a493cecf0216f4c797671601251e3c1a6452ffa.zip csv-0a493cecf0216f4c797671601251e3c1a6452ffa.tar.gz csv-0a493cecf0216f4c797671601251e3c1a6452ffa.tar.bz2 |
final package structure
Diffstat (limited to 'src/Modifier')
-rw-r--r-- | src/Modifier/MapIterator.php | 57 | ||||
-rw-r--r-- | src/Modifier/QueryFilter.php | 269 | ||||
-rw-r--r-- | src/Modifier/RowFilter.php | 151 | ||||
-rw-r--r-- | src/Modifier/StreamFilter.php | 271 |
4 files changed, 748 insertions, 0 deletions
diff --git a/src/Modifier/MapIterator.php b/src/Modifier/MapIterator.php new file mode 100644 index 0000000..7360f42 --- /dev/null +++ b/src/Modifier/MapIterator.php @@ -0,0 +1,57 @@ +<?php +/** +* This file is part of the League.csv library +* +* @license http://opensource.org/licenses/MIT +* @link https://github.com/thephpleague/csv/ +* @version 7.0.0 +* @package League.csv +* +* For the full copyright and license information, please view the LICENSE +* file that was distributed with this source code. +*/ +namespace League\Csv\Modifier; + +use IteratorIterator; +use Traversable; + +/** + * A simple MapIterator + * + * @package League.csv + * @since 3.3.0 + * @internal used internally to modify CSV content + * + */ +class MapIterator extends IteratorIterator +{ + /** + * The function to be apply on all InnerIterator element + * + * @var callable + */ + private $callable; + + /** + * The Constructor + * + * @param Traversable $iterator + * @param callable $callable + */ + public function __construct(Traversable $iterator, callable $callable) + { + parent::__construct($iterator); + $this->callable = $callable; + } + + /** + * Get the value of the current element + */ + public function current() + { + $iterator = $this->getInnerIterator(); + $callable = $this->callable; + + return $callable($iterator->current(), $iterator->key(), $iterator); + } +} diff --git a/src/Modifier/QueryFilter.php b/src/Modifier/QueryFilter.php new file mode 100644 index 0000000..229ea42 --- /dev/null +++ b/src/Modifier/QueryFilter.php @@ -0,0 +1,269 @@ +<?php +/** +* This file is part of the League.csv library +* +* @license http://opensource.org/licenses/MIT +* @link https://github.com/thephpleague/csv/ +* @version 7.0.0 +* @package League.csv +* +* For the full copyright and license information, please view the LICENSE +* file that was distributed with this source code. +*/ +namespace League\Csv\Modifier; + +use ArrayIterator; +use CallbackFilterIterator; +use InvalidArgumentException; +use Iterator; +use LimitIterator; + +/** + * A Trait to Query rows against a SplFileObject + * + * @package League.csv + * @since 4.2.1 + * + */ +trait QueryFilter +{ + /** + * Callables to filter the iterator + * + * @var callable[] + */ + protected $iterator_filters = []; + + /** + * Callables to sort the iterator + * + * @var callable[] + */ + protected $iterator_sort_by = []; + + /** + * iterator Offset + * + * @var int + */ + protected $iterator_offset = 0; + + /** + * iterator maximum length + * + * @var int + */ + protected $iterator_limit = -1; + + /** + * Set LimitIterator Offset + * + * @param $offset + * + * @return $this + */ + public function setOffset($offset = 0) + { + if (false === filter_var($offset, FILTER_VALIDATE_INT, ['options' => ['min_range' => 0]])) { + throw new InvalidArgumentException('the offset must be a positive integer or 0'); + } + $this->iterator_offset = $offset; + + return $this; + } + + /** + * Set LimitInterator Count + * + * @param int $limit + * + * @return $this + */ + public function setLimit($limit = -1) + { + if (false === filter_var($limit, FILTER_VALIDATE_INT, ['options' => ['min_range' => -1]])) { + throw new InvalidArgumentException('the limit must an integer greater or equals to -1'); + } + $this->iterator_limit = $limit; + + return $this; + } + + /** + * Sort the Iterator + * + * @param \Iterator $iterator + * + * @return \LimitIterator + */ + protected function applyIteratorInterval(Iterator $iterator) + { + if (0 == $this->iterator_offset && -1 == $this->iterator_limit) { + return $iterator; + } + $offset = $this->iterator_offset; + $limit = $this->iterator_limit; + + $this->iterator_limit = -1; + $this->iterator_offset = 0; + + return new LimitIterator($iterator, $offset, $limit); + } + + /** + * Set an Iterator sorting callable function + * + * @param callable $callable + * + * @return $this + */ + public function addSortBy(callable $callable) + { + $this->iterator_sort_by[] = $callable; + + return $this; + } + + /** + * Remove a callable from the collection + * + * @param callable $callable + * + * @return $this + */ + public function removeSortBy(callable $callable) + { + $res = array_search($callable, $this->iterator_sort_by, true); + if (false !== $res) { + unset($this->iterator_sort_by[$res]); + } + + return $this; + } + + /** + * Detect if the callable is already registered + * + * @param callable $callable + * + * @return bool + */ + public function hasSortBy(callable $callable) + { + return false !== array_search($callable, $this->iterator_sort_by, true); + } + + /** + * Remove all registered callable + * + * @return $this + */ + public function clearSortBy() + { + $this->iterator_sort_by = []; + + return $this; + } + + /** + * Sort the Iterator + * + * @param \Iterator $iterator + * + * @return \ArrayIterator + */ + protected function applyIteratorSortBy(Iterator $iterator) + { + if (! $this->iterator_sort_by) { + return $iterator; + } + $nb_callbacks = count($this->iterator_sort_by); + $this->iterator_sort_by = array_values($this->iterator_sort_by); + $res = iterator_to_array($iterator, false); + uasort($res, function ($rowA, $rowB) use ($nb_callbacks) { + $res = 0; + $index = 0; + while ($index < $nb_callbacks && 0 === $res) { + $res = $this->iterator_sort_by[$index]($rowA, $rowB); + ++$index; + } + + return $res; + }); + $this->clearSortBy(); + + return new ArrayIterator($res); + } + + /** + * Set the Iterator filter method + * + * @param callable $callable + * + * @return $this + */ + public function addFilter(callable $callable) + { + $this->iterator_filters[] = $callable; + + return $this; + } + + /** + * Remove a filter from the callable collection + * + * @param callable $callable + * + * @return $this + */ + public function removeFilter(callable $callable) + { + $res = array_search($callable, $this->iterator_filters, true); + if (false !== $res) { + unset($this->iterator_filters[$res]); + } + + return $this; + } + + /** + * Detect if the callable filter is already registered + * + * @param callable $callable + * + * @return bool + */ + public function hasFilter(callable $callable) + { + return false !== array_search($callable, $this->iterator_filters, true); + } + + /** + * Remove all registered callable filter + * + * @return $this + */ + public function clearFilter() + { + $this->iterator_filters = []; + + return $this; + } + + /** + * Filter the Iterator + * + * @param \Iterator $iterator + * + * @return \Iterator + */ + protected function applyIteratorFilter(Iterator $iterator) + { + foreach ($this->iterator_filters as $callable) { + $iterator = new CallbackFilterIterator($iterator, $callable); + } + $this->clearFilter(); + + return $iterator; + } +} diff --git a/src/Modifier/RowFilter.php b/src/Modifier/RowFilter.php new file mode 100644 index 0000000..b0aec16 --- /dev/null +++ b/src/Modifier/RowFilter.php @@ -0,0 +1,151 @@ +<?php +/** +* This file is part of the League.csv library +* +* @license http://opensource.org/licenses/MIT +* @link https://github.com/thephpleague/csv/ +* @version 7.0.0 +* @package League.csv +* +* For the full copyright and license information, please view the LICENSE +* file that was distributed with this source code. +*/ +namespace League\Csv\Modifier; + +/** + * Trait to format and validate the row before insertion + * + * @package League.csv + * @since 7.0.0 + * + */ +trait RowFilter +{ + /** + * Callables to validate the row before insertion + * + * @var callable[] + */ + protected $validators = []; + + /** + * Callables to format the row before insertion + * + * @var callable[] + */ + protected $formatters = []; + + /** + * add a formatter to the collection + * + * @param callable $callable + * + * @return $this + */ + public function addFormatter(callable $callable) + { + $this->formatters[] = $callable; + + return $this; + } + + /** + * Remove a formatter from the collection + * + * @param callable $callable + * + * @return $this + */ + public function removeFormatter(callable $callable) + { + $res = array_search($callable, $this->formatters, true); + if (false !== $res) { + unset($this->formatters[$res]); + } + + return $this; + } + + /** + * Detect if the formatter is already registered + * + * @param callable $callable + * + * @return bool + */ + public function hasFormatter(callable $callable) + { + return false !== array_search($callable, $this->formatters, true); + } + + /** + * Remove all registered formatter + * + * @return $this + */ + public function clearFormatters() + { + $this->formatters = []; + + return $this; + } + + /** + * add a Validator to the collection + * + * @param callable $callable + * @param string $name the rule name + * + * @return $this + */ + public function addValidator(callable $callable, $name) + { + $name = trim($name); + $this->validators[$name] = $callable; + + return $this; + } + + /** + * Remove a validator from the collection + * + * @param string $name the validator name + * + * @return $this + */ + public function removeValidator($name) + { + $name = trim($name); + if (array_key_exists($name, $this->validators)) { + unset($this->validators[$name]); + } + + return $this; + } + + /** + * Detect if a validator is already registered + * + * @param string $name the validator name + * + * @return bool + */ + public function hasValidator($name) + { + $name = trim($name); + + return array_key_exists($name, $this->validators); + } + + /** + * Remove all registered validatior + * + * @return $this + */ + public function clearValidators() + { + $this->validators = []; + + return $this; + } +} diff --git a/src/Modifier/StreamFilter.php b/src/Modifier/StreamFilter.php new file mode 100644 index 0000000..1bbdff5 --- /dev/null +++ b/src/Modifier/StreamFilter.php @@ -0,0 +1,271 @@ +<?php +/** +* This file is part of the League.csv library +* +* @license http://opensource.org/licenses/MIT +* @link https://github.com/thephpleague/csv/ +* @version 7.0.0 +* @package League.csv +* +* For the full copyright and license information, please view the LICENSE +* file that was distributed with this source code. +*/ +namespace League\Csv\Modifier; + +use LogicException; +use OutOfBoundsException; +use SplFileInfo; + +/** + * A Trait to ease PHP Stream Filters manipulation + * with a SplFileObject + * + * @package League.csv + * @since 6.0.0 + * + */ +trait StreamFilter +{ + /** + * collection of stream filters + * + * @var array + */ + protected $stream_filters = []; + + /** + * Stream filtering mode to apply on all filters + * + * @var int + */ + protected $stream_filter_mode = STREAM_FILTER_ALL; + + /** + *the real path + * + * @var string the real path to the file + * + */ + protected $stream_uri; + + /** + * Internal path setter + * + * The path must be an SplFileInfo object + * an object that implements the `__toString` method + * a path to a file + * + * @param \SplFileObject|string $path The file path + */ + protected function initStreamFilter($path) + { + if (! is_string($path)) { + $this->stream_uri = null; + $this->stream_filters = []; + + return; + } + + $this->extractStreamSettings($path); + } + + /** + * Extract Available stream settings from $path + * + * @param string $path the file path + */ + protected function extractStreamSettings($path) + { + if (! preg_match( + ',^php://filter/(?P<mode>:?read=|write=)?(?P<filters>.*?)/resource=(?P<resource>.*)$,i', + $path, + $matches + )) { + $this->stream_uri = $path; + $this->stream_filters = []; + + return; + } + $matches['mode'] = strtolower($matches['mode']); + $mode = STREAM_FILTER_ALL; + if ('write=' == $matches['mode']) { + $mode = STREAM_FILTER_WRITE; + } elseif ('read=' == $matches['mode']) { + $mode = STREAM_FILTER_READ; + } + $this->stream_filter_mode = $mode; + $this->stream_uri = $matches['resource']; + $this->stream_filters = explode('|', $matches['filters']); + } + + /** + * Check if the trait methods can be used + * + * @throws \LogicException If the API can not be use + */ + protected function assertStreamable() + { + if (! is_string($this->stream_uri)) { + throw new LogicException('The stream filter API can not be used'); + } + } + + /** + * Tells whether the stream filter capabilities can be used + * + * @return bool + */ + public function isActiveStreamFilter() + { + return is_string($this->stream_uri); + } + + /** + * stream filter mode Setter + * + * Set the new Stream Filter mode and remove all + * previously attached stream filters + * + * @param int $mode + * + * @throws \OutOfBoundsException If the mode is invalid + * + * @return $this + */ + public function setStreamFilterMode($mode) + { + $this->assertStreamable(); + if (! in_array($mode, [STREAM_FILTER_ALL, STREAM_FILTER_READ, STREAM_FILTER_WRITE])) { + throw new OutOfBoundsException('the $mode should be a valid `STREAM_FILTER_*` constant'); + } + + $this->stream_filter_mode = $mode; + $this->stream_filters = []; + + return $this; + } + + /** + * stream filter mode getter + * + * @return int + */ + public function getStreamFilterMode() + { + $this->assertStreamable(); + + return $this->stream_filter_mode; + } + + /** + * append a stream filter + * + * @param string $filter_name a string or an object that implements the '__toString' method + * + * @return $this + */ + public function appendStreamFilter($filter_name) + { + $this->assertStreamable(); + $this->stream_filters[] = $this->sanitizeStreamFilter($filter_name); + + return $this; + } + + /** + * prepend a stream filter + * + * @param string $filter_name a string or an object that implements the '__toString' method + * + * @return $this + */ + public function prependStreamFilter($filter_name) + { + $this->assertStreamable(); + array_unshift($this->stream_filters, $this->sanitizeStreamFilter($filter_name)); + + return $this; + } + + /** + * Sanitize the stream filter name + * + * @param string $filter_name the stream filter name + * + * @return string + */ + protected function sanitizeStreamFilter($filter_name) + { + $this->assertStreamable(); + $filter_name = (string) $filter_name; + + return trim($filter_name); + } + + /** + * Detect if the stream filter is already present + * + * @param string $filter_name + * + * @return bool + */ + public function hasStreamFilter($filter_name) + { + $this->assertStreamable(); + + return false !== array_search($filter_name, $this->stream_filters, true); + } + + /** + * Remove a filter from the collection + * + * @param string $filter_name + * + * @return $this + */ + public function removeStreamFilter($filter_name) + { + $this->assertStreamable(); + $res = array_search($filter_name, $this->stream_filters, true); + if (false !== $res) { + unset($this->stream_filters[$res]); + } + + return $this; + } + + /** + * Remove all registered stream filter + * + * @return $this + */ + public function clearStreamFilter() + { + $this->assertStreamable(); + $this->stream_filters = []; + + return $this; + } + + /** + * Return the filter path + * + * @return string + */ + protected function getStreamFilterPath() + { + $this->assertStreamable(); + if (! $this->stream_filters) { + return $this->stream_uri; + } + + $prefix = ''; + if (STREAM_FILTER_READ == $this->stream_filter_mode) { + $prefix = 'read='; + } elseif (STREAM_FILTER_WRITE == $this->stream_filter_mode) { + $prefix = 'write='; + } + + return 'php://filter/'.$prefix.implode('|', $this->stream_filters).'/resource='.$this->stream_uri; + } +} |