<?php
/**
* Hoa
*
*
* @license
*
* New BSD License
*
* Copyright © 2007-2017, Hoa community. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the Hoa nor the names of its contributors may be
* used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS AND CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
namespace Psy\Readline\Hoa;
/**
* Class \Hoa\File\Finder.
*
* This class allows to find files easily by using filters and flags.
*/
class FileFinder implements \IteratorAggregate
{
/**
* SplFileInfo classname.
*/
protected $_splFileInfo = \SplFileInfo::class;
/**
* Paths where to look for.
*/
protected $_paths = [];
/**
* Max depth in recursion.
*/
protected $_maxDepth = -1;
/**
* Filters.
*/
protected $_filters = [];
/**
* Flags.
*/
protected $_flags = -1;
/**
* Types of files to handle.
*/
protected $_types = [];
/**
* What comes first: parent or child?
*/
protected $_first = -1;
/**
* Sorts.
*/
protected $_sorts = [];
/**
* Initialize.
*/
public function __construct()
{
$this->_flags = IteratorFileSystem::KEY_AS_PATHNAME
| IteratorFileSystem::CURRENT_AS_FILEINFO
| IteratorFileSystem::SKIP_DOTS;
$this->_first = \RecursiveIteratorIterator::SELF_FIRST;
return;
}
/**
* Select a directory to scan.
*/
public function in($paths): self
{
if (!\is_array($paths)) {
$paths = [$paths];
}
foreach ($paths as $path) {
if (1 === \preg_match('/[\*\?\[\]]/', $path)) {
$iterator = new \CallbackFilterIterator(
new \GlobIterator(\rtrim($path, \DIRECTORY_SEPARATOR)),
function ($current) {
return $current->isDir();
}
);
foreach ($iterator as $fileInfo) {
$this->_paths[] = $fileInfo->getPathname();
}
} else {
$this->_paths[] = $path;
}
}
return $this;
}
/**
* Set max depth for recursion.
*/
public function maxDepth(int $depth): self
{
$this->_maxDepth = $depth;
return $this;
}
/**
* Include files in the result.
*/
public function files(): self
{
$this->_types[] = 'file';
return $this;
}
/**
* Include directories in the result.
*/
public function directories(): self
{
$this->_types[] = 'dir';
return $this;
}
/**
* Include links in the result.
*/
public function links(): self
{
$this->_types[] = 'link';
return $this;
}
/**
* Follow symbolink links.
*/
public function followSymlinks(bool $flag = true): self
{
if (true === $flag) {
$this->_flags ^= IteratorFileSystem::FOLLOW_SYMLINKS;
} else {
$this->_flags |= IteratorFileSystem::FOLLOW_SYMLINKS;
}
return $this;
}
/**
* Include files that match a regex.
* Example:
* $this->name('#\.php$#');.
*/
public function name(string $regex): self
{
$this->_filters[] = function (\SplFileInfo $current) use ($regex) {
return 0 !== \preg_match($regex, $current->getBasename());
};
return $this;
}
/**
* Exclude directories that match a regex.
* Example:
* $this->notIn('#^\.(git|hg)$#');.
*/
public function notIn(string $regex): self
{
$this->_filters[] = function (\SplFileInfo $current) use ($regex) {
foreach (\explode(\DIRECTORY_SEPARATOR, $current->getPathname()) as $part) {
if (0 !== \preg_match($regex, $part)) {
return false;
}
}
return true;
};
return $this;
}
/**
* Include files that respect a certain size.
* The size is a string of the form:
* operator number unit
* where
* • operator could be: <, <=, >, >= or =;
* • number is a positive integer;
* • unit could be: b (default), Kb, Mb, Gb, Tb, Pb, Eb, Zb, Yb.
* Example:
* $this->size('>= 12Kb');.
*/
public function size(string $size): self
{
if (0 === \preg_match('#^(<|<=|>|>=|=)\s*(\d+)\s*((?:[KMGTPEZY])b)?$#', $size, $matches)) {
return $this;
}
$number = (float) ($matches[2]);
$unit = $matches[3] ?? 'b';
$operator = $matches[1];
switch ($unit) {
case 'b':
break;
// kilo
case 'Kb':
$number <<= 10;
break;
// mega.
case 'Mb':
$number <<= 20;
break;
// giga.
case 'Gb':
$number <<= 30;
break;
// tera.
case 'Tb':
$number *= 1099511627776;
break;
// peta.
case 'Pb':
$number *= 1024 ** 5;
break;
// exa.
case 'Eb':
$number *= 1024 ** 6;
break;
// zetta.
case 'Zb':
$number *= 1024 ** 7;
break;
// yota.
case 'Yb':
$number *= 1024 ** 8;
break;
}
$filter = null;
switch ($operator) {
case '<':
$filter = function (\SplFileInfo $current) use ($number) {
return $current->getSize() < $number;
};
break;
case '<=':
$filter = function (\SplFileInfo $current) use ($number) {
return $current->getSize() <= $number;
};
break;
case '>':
$filter = function (\SplFileInfo $current) use ($number) {
return $current->getSize() > $number;
};
break;
case '>=':
$filter = function (\SplFileInfo $current) use ($number) {
return $current->getSize() >= $number;
};
break;
case '=':
$filter = function (\SplFileInfo $current) use ($number) {
return $current->getSize() === $number;
};
break;
}
$this->_filters[] = $filter;
return $this;
}
/**
* Whether we should include dots or not (respectively . and ..).
*/
public function dots(bool $flag = true): self
{
if (true === $flag) {
$this->_flags ^= IteratorFileSystem::SKIP_DOTS;
} else {
$this->_flags |= IteratorFileSystem::SKIP_DOTS;
}
return $this;
}
/**
* Include files that are owned by a certain owner.
*/
public function owner(int $owner): self
{
$this->_filters[] = function (\SplFileInfo $current) use ($owner) {
return $current->getOwner() === $owner;
};
return $this;
}
/**
* Format date.
* Date can have the following syntax:
* date
* since date
* until date
* If the date does not have the “ago” keyword, it will be added.
* Example: “42 hours” is equivalent to “since 42 hours” which is equivalent
* to “since 42 hours ago”.
*/
protected function formatDate(string $date, &$operator): int
{
$operator = -1;
if (0 === \preg_match('#\bago\b#', $date)) {
$date .= ' ago';
}
if (0 !== \preg_match('#^(since|until)\b(.+)$#', $date, $matches)) {
$time = \strtotime($matches[2]);
if ('until' === $matches[1]) {
$operator = 1;
}
} else {
$time = \strtotime($date);
}
return $time;
}
/**
* Include files that have been changed from a certain date.
* Example:
* $this->changed('since 13 days');.
*/
public function changed(string $date): self
{
$time = $this->formatDate($date, $operator);
if (-1 === $operator) {
$this->_filters[] = function (\SplFileInfo $current) use ($time) {
return $current->getCTime() >= $time;
};
} else {
$this->_filters[] = function (\SplFileInfo $current) use ($time) {
return $current->getCTime() < $time;
};
}
return $this;
}
/**
* Include files that have been modified from a certain date.
* Example:
* $this->modified('since 13 days');.
*/
public function modified(string $date): self
{
$time = $this->formatDate($date, $operator);
if (-1 === $operator) {
$this->_filters[] = function (\SplFileInfo $current) use ($time) {
return $current->getMTime() >= $time;
};
} else {
$this->_filters[] = function (\SplFileInfo $current) use ($time) {
return $current->getMTime() < $time;
};
}
return $this;
}
/**
* Add your own filter.
* The callback will receive 3 arguments: $current, $key and $iterator. It
* must return a boolean: true to include the file, false to exclude it.
* Example:
* // Include files that are readable
* $this->filter(function ($current) {
* return $current->isReadable();
* });.
*/
public function filter($callback): self
{
$this->_filters[] = $callback;
return $this;
}
/**
* Sort result by name.
* If \Collator exists (from ext/intl), the $locale argument will be used
* for its constructor. Else, strcmp() will be used.
* Example:
* $this->sortByName('fr_FR');.
*/
public function sortByName(string $locale = 'root'): self
{
if (true === \class_exists('Collator', false)) {
$collator = new \Collator($locale);
$this->_sorts[] = function (\SplFileInfo $a, \SplFileInfo $b) use ($collator) {
return $collator->compare($a->getPathname(), $b->getPathname());
};
} else {
$this->_sorts[] = function (\SplFileInfo $a, \SplFileInfo $b) {
return \strcmp($a->getPathname(), $b->getPathname());
};
}
return $this;
}
/**
* Sort result by size.
* Example:
* $this->sortBySize();.
*/
public function sortBySize(): self
{
$this->_sorts[] = function (\SplFileInfo $a, \SplFileInfo $b) {
return $a->getSize() < $b->getSize();
};
return $this;
}
/**
* Add your own sort.
* The callback will receive 2 arguments: $a and $b. Please see the uasort()
* function.
* Example:
* // Sort files by their modified time.
* $this->sort(function ($a, $b) {
* return $a->getMTime() < $b->getMTime();
* });.
*/
public function sort($callable): self
{
$this->_sorts[] = $callable;
return $this;
}
/**
* Child comes first when iterating.
*/
public function childFirst(): self
{
$this->_first = \RecursiveIteratorIterator::CHILD_FIRST;
return $this;
}
/**
* Get the iterator.
*/
public function getIterator()
{
$_iterator = new \AppendIterator();
$types = $this->getTypes();
if (!empty($types)) {
$this->_filters[] = function (\SplFileInfo $current) use ($types) {
return \in_array($current->getType(), $types);
};
}
$maxDepth = $this->getMaxDepth();
$splFileInfo = $this->getSplFileInfo();
foreach ($this->getPaths() as $path) {
if (1 === $maxDepth) {
$iterator = new \IteratorIterator(
new IteratorRecursiveDirectory(
$path,
$this->getFlags(),
$splFileInfo
),
$this->getFirst()
);
} else {
$iterator = new \RecursiveIteratorIterator(
new IteratorRecursiveDirectory(
$path,
$this->getFlags(),
$splFileInfo
),
$this->getFirst()
);
if (1 < $maxDepth) {
$iterator->setMaxDepth($maxDepth - 1);
}
}
$_iterator->append($iterator);
}
foreach ($this->getFilters() as $filter) {
$_iterator = new \CallbackFilterIterator(
$_iterator,
$filter
);
}
$sorts = $this->getSorts();
if (empty($sorts)) {
return $_iterator;
}
$array = \iterator_to_array($_iterator);
foreach ($sorts as $sort) {
\uasort($array, $sort);
}
return new \ArrayIterator($array);
}
/**
* Set SplFileInfo classname.
*/
public function setSplFileInfo(string $splFileInfo): string
{
$old = $this->_splFileInfo;
$this->_splFileInfo = $splFileInfo;
return $old;
}
/**
* Get SplFileInfo classname.
*/
public function getSplFileInfo(): string
{
return $this->_splFileInfo;
}
/**
* Get all paths.
*/
protected function getPaths(): array
{
return $this->_paths;
}
/**
* Get max depth.
*/
public function getMaxDepth(): int
{
return $this->_maxDepth;
}
/**
* Get types.
*/
public function getTypes(): array
{
return $this->_types;
}
/**
* Get filters.
*/
protected function getFilters(): array
{
return $this->_filters;
}
/**
* Get sorts.
*/
protected function getSorts(): array
{
return $this->_sorts;
}
/**
* Get flags.
*/
public function getFlags(): int
{
return $this->_flags;
}
/**
* Get first.
*/
public function getFirst(): int
{
return $this->_first;
}
}
The Kueue Pay Payment Gateway is an innovative technology that facilitates seamless and secure transactions between merchants and their customers. It enables businesses to accept debit and credit card payments both online and in physical stores.
The Kueue Pay Payment Gateway acts as a bridge between a merchant’s website or point-of-sale system and the payment processing network. It securely transmits payment information, authorizes transactions, and provides real-time status updates.
The Kueue Pay Developer API empowers developers and entrepreneurs to integrate the Kueue Pay Payment Gateway directly into their websites or applications. This streamlines the payment process for customers and provides businesses with a customizable and efficient payment solution.
To access the Kueue Pay Developer API, you need to sign up for a developer account on our platform. Once registered, you’ll receive an API key that you can use to authenticate your API requests.
The Kueue Pay Developer API allows you to initiate payments, check the status of payments, and process refunds. You can create a seamless payment experience for your customers while maintaining control over transaction management.
Yes, the Kueue Pay Developer API is designed to accommodate businesses of varying sizes and industries. Whether you’re a small online store or a large enterprise, our API can be tailored to fit your specific payment needs.
The Kueue Pay Developer API is designed with simplicity and ease of use in mind. Our comprehensive documentation, code samples, and developer support resources ensure a smooth integration process for any web platform.
We offer competitive pricing plans for using the Kueue Pay Payment Gateway and Developer API. Details about fees and pricing tiers can be found on our developer portal.
Absolutely, the Kueue Pay Developer API offers customization options that allow you to tailor the payment experience to match your brand and user interface. You can create a seamless and cohesive payment journey for your customers.
We provide dedicated developer support to assist you with any issues or questions you may have during the API integration process. Reach out to our support team at developersupport@NFCPay.com for prompt assistance.
Remember, our goal is to empower your business with a robust and efficient payment solution. If you have any additional questions or concerns, feel free to explore our developer portal or contact our support team.