<?php

declare(strict_types=1);

/*
 * This file is part of the RollerworksDatagrid package.
 *
 * (c) Sebastiaan Stok <s.stok@rollerscapes.net>
 *
 * This source file is subject to the MIT license that is bundled
 * with this source code in the file LICENSE.
 */

namespace Rollerworks\Component\Datagrid;

use Rollerworks\Component\Datagrid\Exception\InvalidArgumentException;
use Rollerworks\Component\Datagrid\Exception\UnexpectedTypeException;

/**
 * @author Sebastiaan Stok <s.stok@rollerscapes.net>
 */
class DatagridRegistry implements DatagridRegistryInterface
{
    private $configurators;

    /** @var \Closure[] */
    private $lazyConfigurators = [];

    /**
     * Constructor.
     *
     * Note you don't have to register the Configurator when it has no constructor
     * or setter dependencies. You can simple use the FQCN of the configurator class,
     * and will be initialized upon first usage.
     *
     * @param \Closure[] $configurators An array of lazy loading configurators.
     *                                  The Closure when called it expected to return
     *                                  the DatagridConfiguratorInterface object
     *
     * @throws UnexpectedTypeException
     */
    public function __construct(array $configurators = [])
    {
        /** @var string $name */
        foreach ($configurators as $name => $configurator) {
            if (!$configurator instanceof \Closure) {
                throw new UnexpectedTypeException($configurator, \Closure::class);
            }

            $this->lazyConfigurators[$name] = $configurator;
        }
    }

    /**
     * Returns a DatagridConfigurator by name.
     *
     * @param string $name The name of the datagrid configurator
     *
     * @throws InvalidArgumentException if the configurator can not be retrieved
     *
     * @return DatagridConfiguratorInterface
     */
    public function getConfigurator(string $name): DatagridConfiguratorInterface
    {
        if (!isset($this->configurators[$name])) {
            $configurator = null;

            if (isset($this->lazyConfigurators[$name])) {
                $configurator = $this->lazyConfigurators[$name]();
            }

            if (!$configurator) {
                // Support fully-qualified class names.
                if (!class_exists($name) || !in_array(DatagridConfiguratorInterface::class, class_implements($name), true)) {
                    throw new InvalidArgumentException(sprintf('Could not load datagrid configurator "%s"', $name));
                }

                $configurator = new $name();
            }

            $this->configurators[$name] = $configurator;
        }

        return $this->configurators[$name];
    }

    /**
     * Returns whether the given DatagridConfigurator is supported.
     *
     * @param string $name The name of the datagrid configurator
     *
     * @return bool
     */
    public function hasConfigurator(string $name): bool
    {
        if (isset($this->configurators[$name])) {
            return true;
        }

        if (isset($this->lazyConfigurators[$name])) {
            return true;
        }

        return class_exists($name) && in_array(DatagridConfiguratorInterface::class, class_implements($name), true);
    }
}


<?php

declare(strict_types=1);

/*
 * This file is part of the RollerworksDatagrid package.
 *
 * (c) Sebastiaan Stok <s.stok@rollerscapes.net>
 *
 * This source file is subject to the MIT license that is bundled
 * with this source code in the file LICENSE.
 */

namespace Rollerworks\Component\Datagrid\Extension\Core\Type;

use Rollerworks\Component\Datagrid\Column\AbstractType;
use Rollerworks\Component\Datagrid\Column\CellView;
use Rollerworks\Component\Datagrid\Column\ColumnInterface;
use Rollerworks\Component\Datagrid\Column\HeaderView;
use Rollerworks\Component\Datagrid\Exception\UnexpectedTypeException;

class BatchType extends AbstractType
{
    /**
     * {@inheritdoc}
     */
    public function buildCellView(CellView $view, ColumnInterface $column, array $options)
    {
        if (!is_scalar($view->value)) {
            throw new UnexpectedTypeException($view->value, 'scalar');
        }

        $id = str_replace(':', '-', sprintf('%s-%s__%s', $view->datagrid->name, $view->name, $view->value));

        // Strip leading underscores and digits. These are allowed in
        // form names, but not in HTML4 ID attributes.
        // http://www.w3.org/TR/html401/struct/global.html#adef-id
        $id = ltrim($id, '_0123456789');

        $view->vars['datagrid_name'] = $view->datagrid->name;
        $view->vars['selection_name'] = sprintf('%s[%s][]', $view->datagrid->name, $view->name);
        $view->vars['selection_id'] = $id;
    }

    /**
     * {@inheritdoc}
     */
    public function buildHeaderView(HeaderView $view, ColumnInterface $column, array $options)
    {
        $view->vars['datagrid_name'] = $view->datagrid->name;
    }
}


<?php

declare(strict_types=1);

/*
 * This file is part of the RollerworksDatagrid package.
 *
 * (c) Sebastiaan Stok <s.stok@rollerscapes.net>
 *
 * This source file is subject to the MIT license that is bundled
 * with this source code in the file LICENSE.
 */

namespace Rollerworks\Component\Datagrid\Util;

use Rollerworks\Component\Datagrid\Column\ColumnTypeExtensionInterface;
use Rollerworks\Component\Datagrid\Column\ColumnTypeInterface;
use Rollerworks\Component\Datagrid\Column\ColumnTypeRegistry;
use Rollerworks\Component\Datagrid\Column\ResolvedColumnTypeFactory;
use Rollerworks\Component\Datagrid\Column\ResolvedColumnTypeFactoryInterface;
use Rollerworks\Component\Datagrid\DatagridExtensionInterface;
use Rollerworks\Component\Datagrid\DatagridFactory;
use Rollerworks\Component\Datagrid\DatagridRegistry;
use Rollerworks\Component\Datagrid\DatagridRegistryInterface;
use Rollerworks\Component\Datagrid\PreloadedExtension;

/**
 * @author Sebastiaan Stok <s.stok@rollerscapes.net>
 */
final class DatagridFactoryBuilder
{
    private $resolvedTypeFactory;
    private $datagridRegistry;
    private $extensions = [];
    private $types = [];
    private $typeExtensions = [];

    /**
     * @param ResolvedColumnTypeFactoryInterface $resolvedTypeFactory
     *
     * @return DatagridFactoryBuilder
     */
    public function setResolvedTypeFactory(ResolvedColumnTypeFactoryInterface $resolvedTypeFactory): self
    {
        $this->resolvedTypeFactory = $resolvedTypeFactory;

        return $this;
    }

    /**
     * @param DatagridRegistryInterface $datagridRegistry
     *
     * @return DatagridFactoryBuilder
     */
    public function setDatagridRegistry(DatagridRegistryInterface $datagridRegistry): self
    {
        $this->datagridRegistry = $datagridRegistry;

        return $this;
    }

    /**
     * @param DatagridExtensionInterface $extension
     *
     * @return DatagridFactoryBuilder
     */
    public function addExtension(DatagridExtensionInterface $extension): self
    {
        $this->extensions[] = $extension;

        return $this;
    }

    /**
     * @param DatagridExtensionInterface[] $extensions
     *
     * @return DatagridFactoryBuilder
     */
    public function addExtensions($extensions): self
    {
        $this->extensions = array_merge($this->extensions, $extensions);

        return $this;
    }

    /**
     * @param ColumnTypeInterface $type
     *
     * @return DatagridFactoryBuilder
     */
    public function addType(ColumnTypeInterface $type): self
    {
        $this->types[get_class($type)] = $type;

        return $this;
    }

    /**
     * @param ColumnTypeInterface[] $types
     *
     * @return DatagridFactoryBuilder
     */
    public function addTypes(array $types): self
    {
        foreach ($types as $type) {
            $this->types[get_class($type)] = $type;
        }

        return $this;
    }

    /**
     * @param ColumnTypeExtensionInterface $typeExtension
     *
     * @return DatagridFactoryBuilder
     */
    public function addTypeExtension(ColumnTypeExtensionInterface $typeExtension): self
    {
        $this->typeExtensions[$typeExtension->getExtendedType()][] = $typeExtension;

        return $this;
    }

    /**
     * @param ColumnTypeExtensionInterface[] $typeExtensions
     *
     * @return DatagridFactoryBuilder
     */
    public function addTypeExtensions(array $typeExtensions): self
    {
        foreach ($typeExtensions as $typeExtension) {
            $this->typeExtensions[$typeExtension->getExtendedType()][] = $typeExtension;
        }

        return $this;
    }

    /**
     * @return DatagridFactory
     */
    public function getDatagridFactory(): DatagridFactory
    {
        $extensions = $this->extensions;

        if (count($this->types) > 0 || count($this->typeExtensions) > 0) {
            $extensions[] = new PreloadedExtension($this->types, $this->typeExtensions);
        }

        $typesRegistry = new ColumnTypeRegistry(
            $extensions,
            $this->resolvedTypeFactory ?: new ResolvedColumnTypeFactory()
        );

        return new DatagridFactory($typesRegistry, $this->datagridRegistry ?: new DatagridRegistry());
    }
}


<?php
/*
 * PSX is a open source PHP framework to develop RESTful APIs.
 * For the current version and informations visit <http://phpsx.org>
 *
 * Copyright 2010-2017 Christoph Kappestein <christoph.kappestein@gmail.com>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

namespace PSX\Data;

use PSX\Data\Util\PriorityQueue;
use PSX\Http\MediaType;

/**
 * WriterFactory
 *
 * @author  Christoph Kappestein <christoph.kappestein@gmail.com>
 * @license http://www.apache.org/licenses/LICENSE-2.0
 * @link    http://phpsx.org
 */
class WriterFactory
{
    protected $writers;
    protected $contentNegotiation = array();

    public function __construct()
    {
        $this->writers = new PriorityQueue();
    }

    public function addWriter(WriterInterface $writer, $priority = 0)
    {
        $this->writers->insert($writer, $priority);
    }

    public function getDefaultWriter(array $supportedWriter = null)
    {
        foreach ($this->writers as $writer) {
            $className = get_class($writer);

            if ($supportedWriter !== null && !in_array($className, $supportedWriter)) {
                continue;
            }

            return $writer;
        }

        return null;
    }

    public function getWriterByContentType($contentType, array $supportedWriter = null)
    {
        if (empty($contentType)) {
            return null;
        }

        $contentTypes = MediaType::parseList($contentType);

        // first we check all custom content negotiation rules
        if (!empty($this->contentNegotiation)) {
            foreach ($contentTypes as $contentType) {
                $writer = $this->getWriterFromContentNegotiation($contentType, $supportedWriter);

                if ($writer !== null) {
                    return $writer;
                }
            }
        }

        // then we ask every writer whether they support the content type
        foreach ($contentTypes as $contentType) {
            foreach ($this->writers as $writer) {
                if ($supportedWriter !== null && !in_array(get_class($writer), $supportedWriter)) {
                    continue;
                }

                if ($writer->isContentTypeSupported($contentType)) {
                    return $writer;
                }
            }
        }

        return null;
    }

    public function getWriterByInstance($className)
    {
        foreach ($this->writers as $writer) {
            if (get_class($writer) === $className) {
                return $writer;
            }
        }

        return null;
    }

    /**
     * Returns a writer class by the class short name
     *
     * @param string $format
     * @return string|null
     */
    public function getWriterClassNameByFormat($format)
    {
        $format = strtolower($format);
        foreach ($this->writers as $writer) {
            $class = get_class($writer);
            $name  = strtolower(substr($class, strrpos($class, '\\') + 1));

            if ($name == $format) {
                return $class;
            }
        }

        return null;
    }

    /**
     * With this method you can set which writer should be used for an specific
     * content type. The content type can be i.e. text/plain or image/*
     *
     * @param string $contentType
     * @param string $writerClass
     */
    public function setContentNegotiation($contentType, $writerClass)
    {
        $this->contentNegotiation[$contentType] = $writerClass;
    }

    /**
     * Returns the fitting writer according to the content negotiation. If no
     * fitting writer could be found null gets returned
     *
     * @param \PSX\Http\MediaType $contentType
     * @param array $supportedWriter
     * @return \PSX\Data\WriterInterface
     */
    protected function getWriterFromContentNegotiation(MediaType $contentType, array $supportedWriter = null)
    {
        if (empty($this->contentNegotiation)) {
            return null;
        }

        foreach ($this->contentNegotiation as $acceptedContentType => $writerClass) {
            if ($supportedWriter !== null && !in_array($writerClass, $supportedWriter)) {
                continue;
            }

            $acceptedContentType = new MediaType($acceptedContentType);

            if ($acceptedContentType->match($contentType)) {
                $writer = $this->getWriterByInstance($writerClass);

                if ($writer !== null) {
                    return $writer;
                }
            }
        }

        return null;
    }
}


<?php

declare(strict_types=1);

/*
 * This file is part of the RollerworksDatagrid package.
 *
 * (c) Sebastiaan Stok <s.stok@rollerscapes.net>
 *
 * This source file is subject to the MIT license that is bundled
 * with this source code in the file LICENSE.
 */

namespace Rollerworks\Component\Datagrid\Extension\Core;

use Rollerworks\Component\Datagrid\AbstractDatagridExtension;
use Symfony\Component\PropertyAccess\PropertyAccess;

/**
 * @author Sebastiaan Stok <s.stok@rollerscapes.net>
 */
class CoreExtension extends AbstractDatagridExtension
{
    /**
     * {@inheritdoc}
     */
    protected function loadTypes(): array
    {
        $propertyAccessor = PropertyAccess::createPropertyAccessor();

        return [
            new Type\ColumnType($propertyAccessor),
            new Type\CompoundColumnType(),

            new Type\ActionType(),
            new Type\BatchType(),
            new Type\BooleanType(),
            new Type\DateTimeType(),
            new Type\MoneyType(),
            new Type\NumberType(),
            new Type\TextType(),
        ];
    }
}


<?php

declare(strict_types=1);

/*
 * This file is part of the RollerworksDatagrid package.
 *
 * (c) Sebastiaan Stok <s.stok@rollerscapes.net>
 *
 * This source file is subject to the MIT license that is bundled
 * with this source code in the file LICENSE.
 */

namespace Rollerworks\Component\Datagrid\Extension\Core\DataTransformer;

use Rollerworks\Component\Datagrid\Exception\TransformationFailedException;
use Rollerworks\Component\Datagrid\Exception\UnexpectedTypeException;

/**
 * Transforms between a normalized time and a localized time string.
 *
 * @author Bernhard Schussek <bschussek@gmail.com>
 * @author Florian Eckerstorfer <florian@eckerstorfer.org>
 */
class DateTimeToLocalizedStringTransformer extends BaseDateTimeTransformer
{
    private $dateFormat;
    private $timeFormat;
    private $pattern;
    private $calendar;

    /**
     * Constructor.
     *
     * @see BaseDateTimeTransformer::formats for available format options
     *
     * @param string $inputTimezone  The name of the input timezone
     * @param string $outputTimezone The name of the output timezone
     * @param int    $dateFormat     The date format
     * @param int    $timeFormat     The time format
     * @param int    $calendar       One of the \IntlDateFormatter calendar constants
     * @param string $pattern        A pattern to pass to \IntlDateFormatter
     *
     * @throws UnexpectedTypeException If a format is not supported or if a timezone is not a string
     */
    public function __construct(
        string $inputTimezone = null,
        string $outputTimezone = null,
        int $dateFormat = null,
        int $timeFormat = null,
        int $calendar = \IntlDateFormatter::GREGORIAN,
        string $pattern = null
    ) {
        parent::__construct($inputTimezone, $outputTimezone);

        if (null === $dateFormat) {
            $dateFormat = \IntlDateFormatter::MEDIUM;
        }

        if (null === $timeFormat) {
            $timeFormat = \IntlDateFormatter::SHORT;
        }

        if (!in_array($dateFormat, self::$formats, true)) {
            throw new UnexpectedTypeException($dateFormat, self::$formats);
        }

        if (!in_array($timeFormat, self::$formats, true)) {
            throw new UnexpectedTypeException($timeFormat, self::$formats);
        }

        $this->dateFormat = $dateFormat;
        $this->timeFormat = $timeFormat;
        $this->calendar = $calendar;
        $this->pattern = $pattern ?? '';
    }

    /**
     * Transforms a normalized date into a localized date string.
     *
     * @param \DateTime $dateTime Normalized date
     *
     * @throws TransformationFailedException If the given value is not an instance
     *                                       of \DateTime or if the date could not
     *                                       be transformed
     *
     * @return string|array Localized date string/array
     */
    public function transform($dateTime)
    {
        if (null === $dateTime) {
            return '';
        }

        if (!$dateTime instanceof \DateTime) {
            throw new TransformationFailedException('Expected a \DateTime.');
        }

        // convert time to UTC before passing it to the formatter
        $dateTime = clone $dateTime;

        if ('UTC' !== $this->inputTimezone) {
            $dateTime->setTimezone(new \DateTimeZone('UTC'));
        }

        $value = $this->getIntlDateFormatter()->format((int) $dateTime->format('U'));

        if (intl_get_error_code() != 0) {
            throw new TransformationFailedException(intl_get_error_message());
        }

        return $value;
    }

    protected function getIntlDateFormatter(): \IntlDateFormatter
    {
        $intlDateFormatter = new \IntlDateFormatter(
            \Locale::getDefault(),
            $this->dateFormat,
            $this->timeFormat,
            $this->outputTimezone,
            $this->calendar,
            $this->pattern
        );

        $intlDateFormatter->setLenient(false);

        // Ensure the year is always four digits when no pattern is set
        if ('' === $this->pattern) {
            $intlDateFormatter->setPattern(str_replace(['yy', 'yyyyyyyy'], 'yyyy', $intlDateFormatter->getPattern()));
        }

        return $intlDateFormatter;
    }
}


<?php

declare(strict_types=1);

/*
 * This file is part of the RollerworksDatagrid package.
 *
 * (c) Sebastiaan Stok <s.stok@rollerscapes.net>
 *
 * This source file is subject to the MIT license that is bundled
 * with this source code in the file LICENSE.
 */

namespace Rollerworks\Component\Datagrid;

use Rollerworks\Component\Datagrid\Column\HeaderView;
use Rollerworks\Component\Datagrid\Exception\InvalidArgumentException;

/**
 * DatagridView provides all the information to render a Datagrid.
 *
 * This class should only be initialized be directly.
 *
 * @author Sebastiaan Stok <s.stok@rollerscapes.net>
 */
class DatagridView extends BaseView implements \IteratorAggregate, \Countable
{
    /**
     * READ-ONLY: The Datagrid name.
     *
     * @var string
     */
    public $name;

    /**
     * READ-ONLY: The Datagrid Header views.
     *
     * @var HeaderView[]
     */
    public $columns = [];

    /**
     * READ-ONLY: The Datagrid rows.
     *
     * @var DatagridRowView[]
     */
    public $rows = [];

    public function __construct(DatagridInterface $datagrid)
    {
        $this->name = $datagrid->getName();
    }

    /**
     * Initialize the datagrid view.
     */
    public function init(DatagridInterface $datagrid)
    {
        if (null === $data = $datagrid->getData()) {
            throw new InvalidArgumentException('No data provided for the view.');
        }

        $columns = $datagrid->getColumns();

        foreach ($columns as $column) {
            $this->columns[$column->getName()] = $column->createHeaderView($this);
        }

        if (!isset($this->vars['row_vars'])) {
            $this->vars['row_vars'] = [];
        }

        foreach ($data as $id => $value) {
            $this->rows[$id] = $row = new DatagridRowView($this, $columns, $value, $id);
            $row->vars = $this->vars['row_vars'];
        }
    }

    public function hasColumn(string $name): bool
    {
        return isset($this->columns[$name]);
    }

    public function getColumn(string $name): HeaderView
    {
        if (isset($this->columns[$name])) {
            return $this->columns[$name];
        }

        throw new InvalidArgumentException(sprintf('Column "%s" does not exist in datagrid.', $name));
    }

    /**
     * Returns the number of elements in the collection.
     *
     * @return int
     */
    public function count()
    {
        return count($this->rows);
    }

    /**
     * Returns an iterator to iterate over rows (implements \IteratorAggregate).
     *
     * @return \ArrayIterator The iterator
     */
    public function getIterator()
    {
        return new \ArrayIterator($this->rows);
    }
}


<?php
/*
 * PSX is a open source PHP framework to develop RESTful APIs.
 * For the current version and informations visit <http://phpsx.org>
 *
 * Copyright 2010-2015 Christoph Kappestein <christoph.kappestein@gmail.com>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

namespace PSX\Data;

use PSX\Http\Exception as StatusCode;
use PSX\Http\MediaType;
use PSX\Schema\Parser;
use PSX\Schema\SchemaInterface;
use PSX\Schema\SchemaTraverser;
use PSX\Schema\Visitor\TypeVisitor;
use PSX\Schema\VisitorInterface as SchemaVisitorInterface;

/**
 * Main entry point of the data library. Through the processor it is possible to
 * reade and write arbitrary data in conformance to a specific schema.
 *
 * <code>
 * $config    = Configuration::createDefault();
 * $processor = new Processor($config);
 *
 * // reads the json data into a custom model class
 * $model = $processor->read(Some\Model::class, Payload::json('{"foo": "bar"}'));
 *
 * // writes the model back into json
 * $response = $processor->write($model);
 * </code>
 *
 * @author  Christoph Kappestein <christoph.kappestein@gmail.com>
 * @license http://www.apache.org/licenses/LICENSE-2.0
 * @link    http://phpsx.org
 */
class Processor
{
    /**
     * @var \PSX\Data\Configuration
     */
    protected $config;

    /**
     * @var \PSX\Schema\ParserInterface
     */
    protected $parser;

    /**
     * @var \PSX\Data\ExporterInterface
     */
    protected $exporter;

    /**
     * @var \PSX\Schema\SchemaTraverser
     */
    protected $traverser;

    public function __construct(Configuration $config)
    {
        $this->config    = $config;
        $this->parser    = new Parser\Popo($this->config->getAnnotationReader());
        $this->exporter  = new Exporter\Popo($this->config->getAnnotationReader());
        $this->traverser = new SchemaTraverser();
    }

    public function getConfiguration()
    {
        return $this->config;
    }

    /**
     * Tries to read the provided payload with a fitting reader. The reader
     * depends on the content type of the payload or on the reader type if
     * explicit specified. Then we validate the data according to the provided
     * schema
     *
     * @param string $schema
     * @param \PSX\Data\Payload $payload
     * @param \PSX\Schema\VisitorInterface $visitor
     * @return mixed
     * @throws \PSX\Data\InvalidDataException
     * @throws \PSX\Http\Exception\UnsupportedMediaTypeException
     */
    public function read($schema, Payload $payload, SchemaVisitorInterface $visitor = null)
    {
        $data   = $this->parse($payload);
        $schema = $this->getSchema($schema);

        if ($visitor === null) {
            $visitor = new TypeVisitor();
        }

        return $this->traverser->traverse(
            $data,
            $schema,
            $visitor
        );
    }

    /**
     * Parses the payload and returns the data in a normalized format
     *
     * @param \PSX\Data\Payload $payload
     * @return \stdClass
     * @throws StatusCode\UnsupportedMediaTypeException
     */
    public function parse(Payload $payload)
    {
        $reader = $this->getReader($payload->getContentType(), $payload->getRwType(), $payload->getRwSupported());
        $data   = $reader->read($payload->getData());

        $transformer = $payload->getTransformer();

        if ($transformer === null) {
            $transformer = $this->getDefaultTransformer($payload->getContentType());
        }

        if ($transformer instanceof TransformerInterface) {
            $data = $transformer->transform($data);
        }

        return $data;
    }

    /**
     * Writes the payload with a fitting writer and returns the result as
     * string. The writer depends on the content type of the payload or on the
     * writer type if explicit specified
     *
     * @param \PSX\Data\Payload $payload
     * @return string
     * @throws \PSX\Data\InvalidDataException
     * @throws \PSX\Http\Exception\NotAcceptableException
     */
    public function write(Payload $payload)
    {
        $data   = $payload->getData();
        $data   = $this->transform($data);
        $writer = $this->getWriter($payload->getContentType(), $payload->getRwType(), $payload->getRwSupported());

        return $writer->write($data);
    }

    /**
     * Returns the data of the payload in a normalized format
     *
     * @param mixed $payload
     * @return \stdClass
     */
    public function transform($data)
    {
        return $this->exporter->export($data);
    }

    /**
     * Returns a fitting reader for the given content type or throws an
     * unsupported media exception. It is also possible to explicit select a
     * reader by providing the class name as reader type.
     *
     * @param string $contentType
     * @param string $readerType
     * @param array $supportedReader
     * @return \PSX\Data\ReaderInterface
     */
    public function getReader($contentType, $readerType = null, array $supportedReader = null)
    {
        if ($readerType === null) {
            $reader = $this->config->getReaderFactory()->getReaderByContentType($contentType, $supportedReader);
        } else {
            $reader = $this->config->getReaderFactory()->getReaderByInstance($readerType);
        }

        if ($reader === null) {
            $reader = $this->config->getReaderFactory()->getDefaultReader($supportedReader);
        }

        if (!$reader instanceof ReaderInterface) {
            throw new StatusCode\UnsupportedMediaTypeException('Could not find fitting data reader');
        }

        return $reader;
    }

    /**
     * Returns a fitting writer for the given content type or throws an not
     * acceptable exception. It is also possible to explicit select a writer by
     * providing the class name as writer type.
     *
     * @param string $contentType
     * @param string $writerType
     * @param array $supportedWriter
     * @return \PSX\Data\WriterInterface
     */
    public function getWriter($contentType, $writerType = null, array $supportedWriter = null)
    {
        if ($writerType === null) {
            $writer = $this->config->getWriterFactory()->getWriterByContentType($contentType, $supportedWriter);
        } else {
            $writer = $this->config->getWriterFactory()->getWriterByInstance($writerType);
        }

        if ($writer === null) {
            $writer = $this->config->getWriterFactory()->getDefaultWriter($supportedWriter);
        }

        if (!$writer instanceof WriterInterface) {
            throw new StatusCode\NotAcceptableException('Could not find fitting data writer');
        }

        return $writer;
    }

    protected function getDefaultTransformer($contentType)
    {
        $mime = new MediaType($contentType);

        if ($mime->getName() == 'application/atom+xml') {
            return new Transformer\Atom();
        } elseif ($mime->getName() == 'application/jsonx+xml') {
            return new Transformer\Jsonx();
        } elseif ($mime->getName() == 'application/rss+xml') {
            return new Transformer\Rss();
        } elseif ($mime->getName() == 'application/soap+xml') {
            return new Transformer\Soap($this->config->getNamespace());
        } elseif (in_array($mime->getName(), MediaType\Xml::getMediaTypes()) ||
            substr($mime->getSubType(), -4) == '+xml' ||
            substr($mime->getSubType(), -4) == '/xml') {
            return new Transformer\XmlArray();
        }

        return null;
    }

    protected function getSchema($schema)
    {
        if (is_string($schema)) {
            return $this->config->getSchemaManager()->getSchema($schema);
        } elseif ($schema instanceof SchemaInterface) {
            return $schema;
        } else {
            throw new InvalidDataException('Schema must be either a string or \PSX\Schema\SchemaInterface');
        }
    }
}


<?php

declare(strict_types=1);

/*
 * This file is part of the RollerworksDatagrid package.
 *
 * (c) Sebastiaan Stok <s.stok@rollerscapes.net>
 *
 * This source file is subject to the MIT license that is bundled
 * with this source code in the file LICENSE.
 */

namespace Rollerworks\Component\Datagrid\Extension\Core\DataTransformer;

use Rollerworks\Component\Datagrid\DataTransformerInterface;
use Rollerworks\Component\Datagrid\Exception\TransformationFailedException;

/**
 * @author Sebastiaan Stok <s.stok@rollerscapes.net>
 */
class ValueFormatTransformer implements DataTransformerInterface
{
    /**
     * @var null|string
     */
    private $glue;

    /**
     * @var callback|null|string
     */
    private $format;

    /**
     * @param null|string          $glue
     * @param null|string|callback $format
     */
    public function __construct($glue = null, $format = null)
    {
        $this->glue = $glue;
        $this->format = $format;
    }

    /**
     * {@inheritdoc}
     */
    public function transform($value)
    {
        if (is_array($value) && null === $this->glue && null === $this->format) {
            throw new TransformationFailedException(
                sprintf('At least "glue" or "format" option must be set when the end value is an array.')
            );
        }

        if (null === $this->format) {
            // Glue is required to be set at this point, so no need for further checking.
            if (is_array($value)) {
                return implode($this->glue, $value);
            }

            return (string) $value;
        }

        if (!is_array($value)) {
            $format = $this->format;

            if (is_callable($format)) {
                return $format($value);
            }

            return sprintf($format, $value);
        }

        return $this->formatValue($value, $this->format, $this->glue);
    }

    private function formatValue($value, $format, $glue): string
    {
        $formatCallable = is_callable($format);

        if (null === $glue) {
            if ($formatCallable) {
                return $format($value);
            }

            return vsprintf($format, $value);
        }

        $formattedValues = [];

        foreach ($value as $field => $val) {
            if ($formatCallable) {
                $formattedValues[] = $format($val, $field);
            } else {
                $formattedValues[] = sprintf($format, $val);
            }
        }

        return implode($glue, $formattedValues);
    }
}


<?php

declare(strict_types=1);

/*
 * This file is part of the RollerworksDatagrid package.
 *
 * (c) Sebastiaan Stok <s.stok@rollerscapes.net>
 *
 * This source file is subject to the MIT license that is bundled
 * with this source code in the file LICENSE.
 */

namespace Rollerworks\Component\Datagrid;

use Rollerworks\Component\Datagrid\Column\ColumnInterface;
use Rollerworks\Component\Datagrid\Exception\BadMethodCallException;
use Rollerworks\Component\Datagrid\Exception\InvalidArgumentException;
use Rollerworks\Component\Datagrid\Exception\UnexpectedTypeException;
use Rollerworks\Component\Datagrid\Exception\UnknownColumnException;

/**
 * Default Datagrid implementation.
 *
 * This class should not be construct directly.
 * Use DatagridFactory::createDatagrid() DatagridFactory::createDatagridBuilder()
 * to create a new Datagrid.
 *
 * @author Sebastiaan Stok <s.stok@rollerscapes.net>
 */
class Datagrid implements DatagridInterface
{
    /**
     * Unique datagrid name.
     *
     * @var string
     */
    private $name;

    /**
     * @var array|\Traversable|null
     */
    private $data;

    /**
     * Datagrid columns.
     *
     * @var ColumnInterface[]
     */
    private $columns = [];

    /**
     * @var callable
     */
    private $viewBuilder;

    /**
     * Constructor.
     *
     * @param string            $name        Name of the datagrid
     * @param ColumnInterface[] $columns     Columns of the datagrid
     * @param callable|null     $viewBuilder A callable view builder.
     *                                       Use the decorator pattern to chain multiple
     */
    public function __construct($name, array $columns, callable $viewBuilder = null)
    {
        $this->name = $name;
        $this->viewBuilder = $viewBuilder;

        foreach ($columns as $column) {
            if (!$column instanceof ColumnInterface) {
                throw new InvalidArgumentException(
                    sprintf(
                        'All columns passed to Datagrid::__construct() must of instances of %s.',
                        ColumnInterface::class
                    )
                );
            }

            $this->columns[$column->getName()] = $column;
        }
    }

    /**
     * {@inheritdoc}
     */
    public function getName(): string
    {
        return $this->name;
    }

    /**
     * {@inheritdoc}
     */
    public function getColumn(string $name): ColumnInterface
    {
        if (!isset($this->columns[$name])) {
            throw new UnknownColumnException($name, $this);
        }

        return $this->columns[$name];
    }

    /**
     * {@inheritdoc}
     */
    public function getColumns(): array
    {
        return $this->columns;
    }

    /**
     * {@inheritdoc}
     */
    public function hasColumn(string $name): bool
    {
        return isset($this->columns[$name]);
    }

    /**
     * {@inheritdoc}
     */
    public function hasColumnType(string $type): bool
    {
        foreach ($this->columns as $column) {
            if ($column->getType()->getInnerType() instanceof $type) {
                return true;
            }
        }

        return false;
    }

    /**
     * {@inheritdoc}
     */
    public function setData($data)
    {
        if (null !== $this->data) {
            throw new BadMethodCallException('Datagrid::setData() can only be called once.');
        }

        if (!is_array($data) && !$data instanceof \Traversable) {
            throw new UnexpectedTypeException($data, ['array', 'Traversable']);
        }

        $this->data = $data;

        return $this;
    }

    /**
     * {@inheritdoc}
     */
    public function getData()
    {
        return $this->data;
    }

    /**
     * {@inheritdoc}
     */
    public function createView(): DatagridView
    {
        if (!isset($this->data)) {
            throw new BadMethodCallException(
                'setDate() must be called before before you can create a view from the Datagrid.'
            );
        }

        $blockName = $this->getName();
        $uniqueBlockPrefix = '_'.$blockName;

        $view = new DatagridView($this);
        $view->vars = [
            'cache_key' => $uniqueBlockPrefix.'_datagrid',
            'unique_block_prefix' => $uniqueBlockPrefix,
            'block_prefixes' => ['datagrid', $uniqueBlockPrefix],
            // Vars for the row-view
            'row_vars' => [
                'unique_block_prefix' => $uniqueBlockPrefix.'_row',
                'block_prefixes' => ['datagrid_row', $uniqueBlockPrefix.'_row'],
            ],
        ];

        if (null !== $this->viewBuilder) {
            $builder = $this->viewBuilder;
            $builder($view);
        }

        $view->init($this);

        return $view;
    }
}


<?php
namespace Codeception\Module;

use Codeception\Exception\ModuleConfig;
use Codeception\Lib\Connector\Laravel5 as LaravelConnector;
use Codeception\Lib\Framework;
use Codeception\Lib\Interfaces\ActiveRecord;
use Codeception\Subscriber\ErrorHandler;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Http\Request;

/**
 *
 * This module allows you to run functional tests for Laravel 5.
 * Please try it and leave your feedback.
 * The module is based on the Laravel 4 module by Davert.
 *
 * ## Demo project
 * <https://github.com/janhenkgerritsen/codeception-laravel5-sample>
 *
 * ## Status
 *
 * * Maintainer: **Jan-Henk Gerritsen**
 * * Stability: **dev**
 * * Contact: janhenkgerritsen@gmail.com
 *
 * ## Config
 *
 * * cleanup: `boolean`, default `true` - all db queries will be run in transaction, which will be rolled back at the end of test.
 * * environment_file: `string`, default `.env` - The .env file to load for the tests.
 * * bootstrap: `string`, default `bootstrap/app.php` - Relative path to app.php config file.
 * * root: `string`, default `` - Root path of our application.
 * * packages: `string`, default `workbench` - Root path of application packages (if any).
 *
 * ## API
 *
 * * app - `Illuminate\Foundation\Application` instance
 * * client - `BrowserKit` client
 *
 */
class Laravel5 extends Framework implements ActiveRecord
{

    /**
     * @var \Illuminate\Foundation\Application
     */
    public $app;

    /**
     * @var array
     */
    protected $config = [];

    /**
     * Constructor.
     *
     * @param $config
     */
    public function __construct($config = null)
    {
        $this->config = array_merge(
            array(
                'cleanup' => true,
                'environment_file' => '.env',
                'bootstrap' => 'bootstrap' . DIRECTORY_SEPARATOR . 'app.php',
                'root' => '',
                'packages' => 'workbench',
            ),
            (array) $config
        );

        parent::__construct();
    }

    /**
     * Initialize hook.
     */
    public function _initialize()
    {
        $this->revertErrorHandler();
        $this->initializeLaravel();
    }

    /**
     * Before hook.
     *
     * @param \Codeception\TestCase $test
     * @throws ModuleConfig
     */
    public function _before(\Codeception\TestCase $test)
    {
        $this->initializeLaravel();

        if ($this->app['db'] && $this->config['cleanup']) {
            $this->app['db']->beginTransaction();
        }
    }

    /**
     * After hook.
     *
     * @param \Codeception\TestCase $test
     */
    public function _after(\Codeception\TestCase $test)
    {
        if ($this->app['db'] && $this->config['cleanup']) {
            $this->app['db']->rollback();
        }

        if ($this->app['auth']) {
            $this->app['auth']->logout();
        }

        if ($this->app['cache']) {
            $this->app['cache']->flush();
        }

        if ($this->app['session']) {
            $this->app['session']->flush();
        }

        // disconnect from DB to prevent "Too many connections" issue
        if ($this->app['db']) {
            $this->app['db']->disconnect();
        }
    }

    /**
     * After step hook.
     *
     * @param \Codeception\Step $step
     */
    public function _afterStep(\Codeception\Step $step)
    {
        \Illuminate\Support\Facades\Facade::clearResolvedInstances();

        parent::_afterStep($step);
    }

    /**
     * Revert back to the Codeception error handler,
     * becauses Laravel registers it's own error handler.
     */
    protected function revertErrorHandler()
    {
        $handler = new ErrorHandler();
        set_error_handler(array($handler, 'errorHandler'));
    }

    /**
     * Initialize the Laravel framework.
     *
     * @throws ModuleConfig
     */
    protected function initializeLaravel()
    {
        $this->app = $this->bootApplication();
        $this->app->instance('request', new Request());
        $this->client = new LaravelConnector($this->app);
        $this->client->followRedirects(true);
    }

    /**
     * Boot the Laravel application object.
     *
     * @return \Illuminate\Foundation\Application
     * @throws \Codeception\Exception\ModuleConfig
     */
    protected function bootApplication()
    {
        $projectDir = explode($this->config['packages'], \Codeception\Configuration::projectDir())[0];
        $projectDir .= $this->config['root'];
        require $projectDir . 'vendor' . DIRECTORY_SEPARATOR . 'autoload.php';

        \Illuminate\Support\ClassLoader::register();

        $bootstrapFile = $projectDir . $this->config['bootstrap'];

        if (! file_exists($bootstrapFile)) {
            throw new ModuleConfig(
                $this, "Laravel bootstrap file not found in $bootstrapFile.\nPlease provide a valid path to it using 'bootstrap' config param. "
            );
        }

        $app = require $bootstrapFile;
        $app->loadEnvironmentFrom($this->config['environment_file']);

        return $app;
    }

   /**
     * Provides access the Laravel application object.
     *
     * @return \Illuminate\Foundation\Application
     */
    public function getApplication()
    {
        return $this->app;
    }

    /**
     * Opens web page using route name and parameters.
     *
     * ```php
     * <?php
     * $I->amOnRoute('posts.create');
     * ?>
     * ```
     *
     * @param $route
     * @param array $params
     */
    public function amOnRoute($route, $params = [])
    {
        $domain = $this->app['routes']->getByName($route)->domain();
        $absolute = ! is_null($domain);

        $url = $this->app['url']->route($route, $params, $absolute);
        $this->amOnPage($url);
    }

    /**
     * Opens web page by action name
     *
     * ```php
     * <?php
     * $I->amOnAction('PostsController@index');
     * ?>
     * ```
     *
     * @param $action
     * @param array $params
     */
    public function amOnAction($action, $params = [])
    {
        $namespacedAction = $this->actionWithNamespace($action);

        $domain = $this->app['routes']->getByAction($namespacedAction)->domain();
        $absolute = ! is_null($domain);

        $url = $this->app['url']->action($action, $params, $absolute);
        $this->amOnPage($url);
    }

    /**
     * Normalize an action to full namespaced action.
     *
     * @param string $action
     * @return string
     */
    protected function actionWithNamespace($action)
    {
        $rootNamespace = $this->getRootControllerNamespace();

        if ($rootNamespace && ! (strpos($action, '\\') === 0)) {
            return $rootNamespace . '\\' . $action;
        } else {
            return trim($action, '\\');
        }
    }

    /**
     * Get the root controller namespace for the application.
     *
     * @return string
     */
    protected function getRootControllerNamespace()
    {
        $urlGenerator = $this->app['url'];
        $reflection = new \ReflectionClass($urlGenerator);

        $property = $reflection->getProperty('rootNamespace');
        $property->setAccessible(true);

        return $property->getValue($urlGenerator);
    }

    /**
     * Checks that current url matches route
     *
     * ```php
     * <?php
     * $I->seeCurrentRouteIs('posts.index');
     * ?>
     * ```
     * @param $route
     * @param array $params
     */
    public function seeCurrentRouteIs($route, $params = array())
    {
        $this->seeCurrentUrlEquals($this->app['url']->route($route, $params, false));
    }

    /**
     * Checks that current url matches action
     *
     * ```php
     * <?php
     * $I->seeCurrentActionIs('PostsController@index');
     * ?>
     * ```
     *
     * @param $action
     * @param array $params
     */
    public function seeCurrentActionIs($action, $params = array())
    {
        $this->seeCurrentUrlEquals($this->app['url']->action($action, $params, false));
    }

    /**
     * Assert that the session has a given list of values.
     *
     * @param  string|array $key
     * @param  mixed $value
     * @return void
     */
    public function seeInSession($key, $value = null)
    {
        if (is_array($key)) {
            $this->seeSessionHasValues($key);
            return;
        }

        if (is_null($value)) {
            $this->assertTrue($this->app['session']->has($key));
        } else {
            $this->assertEquals($value, $this->app['session']->get($key));
        }
    }

    /**
     * Assert that the session has a given list of values.
     *
     * @param  array $bindings
     * @return void
     */
    public function seeSessionHasValues(array $bindings)
    {
        foreach ($bindings as $key => $value) {
            if (is_int($key)) {
                $this->seeInSession($value);
            } else {
                $this->seeInSession($key, $value);
            }
        }
    }

    /**
     * Assert that the form errors are bound to the View.
     *
     * @return bool
     */
    public function seeFormHasErrors()
    {
        $viewErrorBag = $this->app->make('view')->shared('errors');
        $this->assertTrue(count($viewErrorBag) > 0);
    }

    /**
     * Assert that specific form error messages are set in the view.
     *
     * Useful for validation messages and generally messages array
     *  e.g.
     *  return `Redirect::to('register')->withErrors($validator);`
     *
     * Example of Usage
     *
     * ``` php
     * <?php
     * $I->seeFormErrorMessages(array('username'=>'Invalid Username'));
     * ?>
     * ```
     * @param array $bindings
     */
    public function seeFormErrorMessages(array $bindings)
    {
        foreach ($bindings as $key => $value) {
            $this->seeFormErrorMessage($key, $value);
        }
    }

    /**
     * Assert that specific form error message is set in the view.
     *
     * Useful for validation messages and generally messages array
     *  e.g.
     *  return `Redirect::to('register')->withErrors($validator);`
     *
     * Example of Usage
     *
     * ``` php
     * <?php
     * $I->seeFormErrorMessage('username', 'Invalid Username');
     * ?>
     * ```
     * @param string $key
     * @param string $errorMessage
     */
    public function seeFormErrorMessage($key, $errorMessage)
    {
        $viewErrorBag = $this->app['view']->shared('errors');

        $this->assertEquals($errorMessage, $viewErrorBag->first($key));
    }

    /**
     * Set the currently logged in user for the application.
     * Takes either an object that implements the User interface or
     * an array of credentials.
     *
     * @param  \Illuminate\Contracts\Auth\User|array $user
     * @param  string $driver
     * @return void
     */
    public function amLoggedAs($user, $driver = null)
    {
        if ($user instanceof Authenticatable) {
            $this->app['auth']->driver($driver)->setUser($user);
        } else {
            $this->app['auth']->driver($driver)->attempt($user);
        }
    }

    /**
     * Logs user out
     */
    public function logout()
    {
        $this->app['auth']->logout();
    }

    /**
     * Checks that user is authenticated
     */
    public function seeAuthentication()
    {
        $this->assertTrue($this->app['auth']->check(), 'User is not logged in');
    }

    /**
     * Check that user is not authenticated
     */
    public function dontSeeAuthentication()
    {
        $this->assertFalse($this->app['auth']->check(), 'User is logged in');
    }

    /**
     * Return an instance of a class from the IoC Container.
     * (http://laravel.com/docs/ioc)
     *
     * Example
     * ``` php
     * <?php
     * // In Laravel
     * App::bind('foo', function($app)
     * {
     *     return new FooBar;
     * });
     *
     * // Then in test
     * $service = $I->grabService('foo');
     *
     * // Will return an instance of FooBar, also works for singletons.
     * ?>
     * ```
     *
     * @param  string $class
     * @return mixed
     */
    public function grabService($class)
    {
        return $this->app[$class];
    }

    /**
     * Inserts record into the database.
     *
     * ``` php
     * <?php
     * $user_id = $I->haveRecord('users', array('name' => 'Davert'));
     * ?>
     * ```
     *
     * @param $model
     * @param array $attributes
     * @return mixed
     */
    public function haveRecord($model, $attributes = array())
    {
        $id = $this->app['db']->table($model)->insertGetId($attributes);
        if (!$id) {
            $this->fail("Couldn't insert record into table $model");
        }
        return $id;
    }

    /**
     * Checks that record exists in database.
     *
     * ``` php
     * $I->seeRecord('users', array('name' => 'davert'));
     * ```
     *
     * @param $model
     * @param array $attributes
     */
    public function seeRecord($model, $attributes = array())
    {
        $record = $this->findRecord($model, $attributes);
        if (!$record) {
            $this->fail("Couldn't find $model with " . json_encode($attributes));
        }
        $this->debugSection($model, json_encode($record));
    }

    /**
     * Checks that record does not exist in database.
     *
     * ``` php
     * <?php
     * $I->dontSeeRecord('users', array('name' => 'davert'));
     * ?>
     * ```
     *
     * @param $model
     * @param array $attributes
     */
    public function dontSeeRecord($model, $attributes = array())
    {
        $record = $this->findRecord($model, $attributes);
        $this->debugSection($model, json_encode($record));
        if ($record) {
            $this->fail("Unexpectedly managed to find $model with " . json_encode($attributes));
        }
    }

    /**
     * Retrieves record from database
     *
     * ``` php
     * <?php
     * $category = $I->grabRecord('users', array('name' => 'davert'));
     * ?>
     * ```
     *
     * @param $model
     * @param array $attributes
     * @return mixed
     */
    public function grabRecord($model, $attributes = array())
    {
        return $this->findRecord($model, $attributes);
    }

    /**
     * @param $model
     * @param array $attributes
     * @return mixed
     */
    protected function findRecord($model, $attributes = array())
    {
        $query = $this->app['db']->table($model);
        foreach ($attributes as $key => $value) {
            $query->where($key, $value);
        }
        return $query->first();
    }

}


<?php
/**
 * Spiral Framework.
 *
 * @license   MIT
 * @author    Anton Titov (Wolfy-J)
 */

namespace Spiral\Toolkit;

use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\UriInterface;
use Spiral\Http\Routing\RouteInterface;
use Spiral\Pagination\PaginatorInterface;

/**
 * Helps to generate uris for paginator. Must be created INSIDE request scope.
 */
class PaginationHelper
{
    /**
     * @var RouteInterface
     */
    private $route;

    /**
     * @var ServerRequestInterface
     */
    private $request;

    /**
     * @param RouteInterface         $route
     * @param ServerRequestInterface $request
     */
    public function __construct(RouteInterface $route, ServerRequestInterface $request)
    {
        $this->route = $route;
        $this->request = $request;
    }

    /**
     * @param PaginatorInterface $paginator
     * @param int                $pageNumber
     *
     * @return UriInterface
     */
    public function uri(PaginatorInterface $paginator, int $pageNumber): UriInterface
    {
        return $this->route->uri([$paginator->getParameter() => $pageNumber]);
    }
}


<?php

declare(strict_types=1);

/*
 * This file is part of the RollerworksDatagrid package.
 *
 * (c) Sebastiaan Stok <s.stok@rollerscapes.net>
 *
 * This source file is subject to the MIT license that is bundled
 * with this source code in the file LICENSE.
 */

namespace Rollerworks\Component\Datagrid\Extension\Core\DataTransformer;

use Rollerworks\Component\Datagrid\DataTransformerInterface;
use Rollerworks\Component\Datagrid\Exception\TransformationFailedException;

/**
 * Transforms between a number type and a localized number with grouping
 * (each thousand) and comma separators.
 *
 * @author Bernhard Schussek <bschussek@gmail.com>
 * @author Florian Eckerstorfer <florian@eckerstorfer.org>
 */
class NumberToLocalizedStringTransformer implements DataTransformerInterface
{
    /**
     * Rounds a number towards positive infinity.
     *
     * Rounds 1.4 to 2 and -1.4 to -1.
     */
    const ROUND_CEILING = \NumberFormatter::ROUND_CEILING;

    /**
     * Rounds a number towards negative infinity.
     *
     * Rounds 1.4 to 1 and -1.4 to -2.
     */
    const ROUND_FLOOR = \NumberFormatter::ROUND_FLOOR;

    /**
     * Rounds a number away from zero.
     *
     * Rounds 1.4 to 2 and -1.4 to -2.
     */
    const ROUND_UP = \NumberFormatter::ROUND_UP;

    /**
     * Rounds a number towards zero.
     *
     * Rounds 1.4 to 1 and -1.4 to -1.
     */
    const ROUND_DOWN = \NumberFormatter::ROUND_DOWN;

    /**
     * Rounds to the nearest number and halves to the next even number.
     *
     * Rounds 2.5, 1.6 and 1.5 to 2 and 1.4 to 1.
     */
    const ROUND_HALF_EVEN = \NumberFormatter::ROUND_HALFEVEN;

    /**
     * Rounds to the nearest number and halves away from zero.
     *
     * Rounds 2.5 to 3, 1.6 and 1.5 to 2 and 1.4 to 1.
     */
    const ROUND_HALF_UP = \NumberFormatter::ROUND_HALFUP;

    /**
     * Rounds to the nearest number and halves towards zero.
     *
     * Rounds 2.5 and 1.6 to 2, 1.5 and 1.4 to 1.
     */
    const ROUND_HALF_DOWN = \NumberFormatter::ROUND_HALFDOWN;

    /**
     * @var int|null
     */
    protected $precision;

    /**
     * @var bool|null
     */
    protected $grouping;

    /**
     * @var int|null
     */
    protected $roundingMode;

    /**
     * @var int
     */
    protected $type;

    /**
     * @param int  $precision
     * @param bool $grouping
     * @param int  $roundingMode
     * @param int  $type
     */
    public function __construct($precision = null, $grouping = null, $roundingMode = null, $type = \NumberFormatter::TYPE_DOUBLE)
    {
        if (null === $grouping) {
            $grouping = false;
        }

        if (null === $roundingMode) {
            $roundingMode = self::ROUND_HALF_UP;
        }

        $this->precision = $precision;
        $this->grouping = $grouping;
        $this->roundingMode = $roundingMode;
        $this->type = $type;
    }

    /**
     * Transforms a number type into localized number.
     *
     * @param int|float $value Number value
     *
     * @throws TransformationFailedException If the given value is not numeric
     *                                       or if the value can not be transformed
     *
     * @return string Localized value
     */
    public function transform($value)
    {
        if (null === $value) {
            return '';
        }

        if (!is_numeric($value)) {
            throw new TransformationFailedException('Expected a numeric.');
        }

        $formatter = $this->getNumberFormatter();
        $value = $formatter->format($value);

        if (intl_is_failure($formatter->getErrorCode())) {
            throw new TransformationFailedException($formatter->getErrorMessage());
        }

        // Convert fixed spaces to normal ones
        $value = str_replace("\xc2\xa0", ' ', $value);

        return $value;
    }

    /**
     * Returns a preconfigured \NumberFormatter instance.
     *
     * @param int $type
     *
     * @return \NumberFormatter
     */
    protected function getNumberFormatter($type = \NumberFormatter::DECIMAL)
    {
        $formatter = new \NumberFormatter(\Locale::getDefault(), $type);

        if (null !== $this->precision) {
            $formatter->setAttribute(\NumberFormatter::FRACTION_DIGITS, $this->precision);
            $formatter->setAttribute(\NumberFormatter::ROUNDING_MODE, $this->roundingMode);
        }

        $formatter->setAttribute(\NumberFormatter::GROUPING_USED, $this->grouping);

        return $formatter;
    }
}


<?php
namespace Codeception\Lib\Connector;
use Illuminate\Foundation\Application;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Request as DomRequest;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Client;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\HttpKernel\TerminableInterface;
class Laravel5 extends Client implements HttpKernelInterface, TerminableInterface
{
    /**
     * @var Application
     */
    private $app;
    /**
     * @var HttpKernelInterface
     */
    private $httpKernel;
    /**
     * Constructor.
     *
     * @param Application $app
     */
    public function __construct(Application $app)
    {
        $this->app = $app;
        $this->httpKernel = $this->app->make('Illuminate\Contracts\Http\Kernel');
        $this->httpKernel->bootstrap();
        $this->app->boot();
        parent::__construct($this);
    }
    /**
     * Handle a request.
     *
     * @param DomRequest $request
     * @param int $type
     * @param bool $catch
     * @return Response
     */
    public function handle(DomRequest $request, $type = self::MASTER_REQUEST, $catch = true)
    {
        $request = Request::createFromBase($request);
        $request->enableHttpMethodParameterOverride();
        $this->app->bind('request', $request);
        return $this->httpKernel->handle($request);
    }
	/**
	 * Terminates a request/response cycle.
	 *
	 * @param DomRequest $request A Request instance
	 * @param Response $response A Response instance
	 *
	 * @api
	 */
	public function terminate(DomRequest $request, Response $response)
	{
		$this->httpKernel->terminate(Request::createFromBase($request), $response);
	}
}


<?php
/*
 * PSX is a open source PHP framework to develop RESTful APIs.
 * For the current version and informations visit <http://phpsx.org>
 *
 * Copyright 2010-2017 Christoph Kappestein <christoph.kappestein@gmail.com>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

namespace PSX\Data\Util;

use InvalidArgumentException;

/**
 * CurveArray
 *
 * @author  Christoph Kappestein <christoph.kappestein@gmail.com>
 * @license http://www.apache.org/licenses/LICENSE-2.0
 * @link    http://phpsx.org
 */
class CurveArray
{
    /**
     * Converts a flat array into a nested object using a seperator
     *
     * @param array $data
     * @param string $seperator
     * @return \stdClass
     */
    public static function nest(array $data, $seperator = '_')
    {
        if (self::isAssoc($data)) {
            $result = new \stdClass();

            foreach ($data as $key => $value) {
                if (($pos = strpos($key, $seperator)) !== false) {
                    $subKey = substr($key, 0, $pos);
                    $name   = substr($key, $pos + 1);

                    if (!isset($result->{$subKey})) {
                        $result->{$subKey} = self::nest(self::getParts($data, $subKey . $seperator), $seperator);
                    }
                } else {
                    $result->{$key} = $value;
                }
            }

            return $result;
        } else {
            $result = [];

            foreach ($data as $value) {
                $result[] = self::nest($value, $seperator);
            }

            return $result;
        }
    }

    /**
     * Converts a nested array into a flat using a seperator. The prefix and
     * result parameter are used internally for performance reason and should
     * not be used
     *
     * @param array $data
     * @param string $seperator
     * @param string $prefix
     * @param array $result
     * @return array
     */
    public static function flatten($data, $seperator = '_', $prefix = null, array &$result = null)
    {
        if ($result === null) {
            $result = array();
        }

        if ($data instanceof \stdClass) {
            $data = (array) $data;
        } elseif (!is_array($data)) {
            throw new InvalidArgumentException('Data must be either an stdClass or array');
        }

        foreach ($data as $key => $value) {
            if ($value instanceof \stdClass || is_array($value)) {
                self::flatten($value, $seperator, $prefix . $key . $seperator, $result);
            } else {
                $result[$prefix . $key] = $value;
            }
        }

        return $result;
    }

    /**
     * Replaces all associative arrays with stdClass in an arbitrary array
     * structure
     *
     * @param array $data
     * @return \stdClass|array
     */
    public static function objectify(array $data)
    {
        if (self::isAssoc($data)) {
            $result = new \stdClass();
            foreach ($data as $key => $value) {
                $result->{$key} = is_array($value) ? self::objectify($value) : $value;
            }

            return $result;
        } else {
            $result = [];
            foreach ($data as $value) {
                $result[] = is_array($value) ? self::objectify($value) : $value;
            }

            return $result;
        }
    }

    /**
     * Returns whether an array is index based or associative
     *
     * @param array $array
     * @return boolean
     */
    public static function isAssoc(array $array)
    {
        if (empty($array)) {
            return false;
        }

        if (isset($array[0])) {
            $n = count($array) - 1;

            return array_sum(array_keys($array)) != ($n * ($n + 1)) / 2;
        } else {
            return true;
        }
    }

    protected static function getParts(array $data, $prefix)
    {
        $result = array();

        foreach ($data as $key => $value) {
            if (substr($key, 0, strlen($prefix)) == $prefix) {
                $name = substr($key, strlen($prefix));

                if (!empty($name)) {
                    $result[$name] = $value;
                }
            }
        }

        return $result;
    }
}


<?php

declare(strict_types=1);

/*
 * This file is part of the RollerworksDatagrid package.
 *
 * (c) Sebastiaan Stok <s.stok@rollerscapes.net>
 *
 * This source file is subject to the MIT license that is bundled
 * with this source code in the file LICENSE.
 */

namespace Rollerworks\Component\Datagrid\Column;

use Rollerworks\Component\Datagrid\DatagridView;
use Rollerworks\Component\Datagrid\Exception\UnexpectedTypeException;
use Rollerworks\Component\Datagrid\Extension\Core\Type\CompoundColumnType;
use Symfony\Component\OptionsResolver\OptionsResolver;

/**
 * @author Sebastiaan Stok <s.stok@rollerscapes.net>
 */
class ResolvedColumnType implements ResolvedColumnTypeInterface
{
    /**
     * @var ColumnTypeInterface
     */
    protected $innerType;

    /**
     * @var ResolvedColumnType
     */
    protected $parent;

    /**
     * @var bool
     */
    protected $compound = null;

    /**
     * @var ColumnTypeExtensionInterface[]
     */
    private $typeExtensions;

    /**
     * @var OptionsResolver
     */
    private $optionsResolver;

    /**
     * Constructor.
     *
     * @param ColumnTypeInterface            $innerType
     * @param ColumnTypeExtensionInterface[] $typeExtensions
     * @param ResolvedColumnTypeInterface    $parent
     *
     * @throws UnexpectedTypeException When one of the given extensions is not an ColumnTypeExtensionInterface
     */
    public function __construct(ColumnTypeInterface $innerType, array $typeExtensions = [], ResolvedColumnTypeInterface $parent = null)
    {
        foreach ($typeExtensions as $extension) {
            if (!$extension instanceof ColumnTypeExtensionInterface) {
                throw new UnexpectedTypeException($extension, 'Rollerworks\Component\Datagrid\Column\ColumnTypeExtensionInterface');
            }
        }

        $this->innerType = $innerType;
        $this->typeExtensions = $typeExtensions;
        $this->parent = $parent;
    }

    /**
     * {@inheritdoc}
     */
    public function getBlockPrefix(): string
    {
        return $this->innerType->getBlockPrefix();
    }

    /**
     * Returns the parent type.
     *
     * @return ResolvedColumnTypeInterface|null The parent type or null
     */
    public function getParent()
    {
        return $this->parent;
    }

    /**
     * Returns the wrapped column type.
     *
     * @return ColumnTypeInterface The wrapped column type
     */
    public function getInnerType(): ColumnTypeInterface
    {
        return $this->innerType;
    }

    /**
     * Returns the extensions of the wrapped column type.
     *
     * @return ColumnTypeExtensionInterface[] An array of {@link ColumnTypeExtensionInterface} instances
     */
    public function getTypeExtensions(): array
    {
        return $this->typeExtensions;
    }

    /**
     * This configures the {@link ColumnInterface}.
     *
     * This method is called for each type in the hierarchy starting from the
     * top most type. Type extensions can further modify the column.
     *
     * @param ColumnInterface $config
     * @param array           $options
     */
    public function buildType(ColumnInterface $config, array $options)
    {
        if (null !== $this->parent) {
            $this->parent->buildType($config, $options);
        }

        $this->innerType->buildColumn($config, $options);

        foreach ($this->typeExtensions as $extension) {
            $extension->buildColumn($config, $options);
        }
    }

    /**
     * Returns a new ColumnInterface instance.
     *
     * @param string $name
     * @param array  $options
     *
     * @return ColumnInterface
     */
    public function createColumn(string $name, array $options = []): ColumnInterface
    {
        $options = $this->getOptionsResolver()->resolve($options);

        return $this->newColumn($name, $options);
    }

    /**
     * {@inheritdoc}.
     */
    public function createHeaderView(ColumnInterface $column, DatagridView $datagrid): HeaderView
    {
        return new HeaderView($column, $datagrid, $column->getOption('label'));
    }

    /**
     * {@inheritdoc}.
     *
     * @param ColumnInterface $column
     * @param HeaderView      $header
     *
     * @return CellView
     */
    public function createCellView(ColumnInterface $column, HeaderView $header): CellView
    {
        return new CellView($header, $header->datagrid);
    }

    /**
     * Configures a header view for the type hierarchy.
     *
     * @param HeaderView      $view
     * @param ColumnInterface $column
     * @param array           $options
     */
    public function buildHeaderView(HeaderView $view, ColumnInterface $column, array $options)
    {
        if (null !== $this->parent) {
            $this->parent->buildHeaderView($view, $column, $options);
        }

        $this->innerType->buildHeaderView($view, $column, $options);

        foreach ($this->typeExtensions as $extension) {
            $extension->buildHeaderView($view, $column, $options);
        }
    }

    /**
     * Configures a cell view for the type hierarchy.
     *
     * @param CellView        $view
     * @param ColumnInterface $column
     * @param array           $options
     */
    public function buildCellView(CellView $view, ColumnInterface $column, array $options)
    {
        if (null !== $this->parent) {
            $this->parent->buildCellView($view, $column, $options);
        }

        $this->innerType->buildCellView($view, $column, $options);

        foreach ($this->typeExtensions as $extension) {
            $extension->buildCellView($view, $column, $options);
        }
    }

    /**
     * {@inheritdoc}
     */
    public function getValue(ColumnInterface $column, $object)
    {
        $dataProvider = $column->getDataProvider();
        $value = $dataProvider($object);

        if (null !== ($transformer = $column->getViewTransformer())) {
            $value = $transformer->transform($value);
        }

        return $value;
    }

    /**
     * Returns the configured options resolver used for this type.
     *
     * @return OptionsResolver The options resolver
     */
    public function getOptionsResolver(): OptionsResolver
    {
        if (null === $this->optionsResolver) {
            if (null !== $this->parent) {
                $this->optionsResolver = clone $this->parent->getOptionsResolver();
            } else {
                $this->optionsResolver = new OptionsResolver();
            }

            $this->innerType->configureOptions($this->optionsResolver);

            foreach ($this->typeExtensions as $extension) {
                $extension->configureOptions($this->optionsResolver);
            }
        }

        return $this->optionsResolver;
    }

    /**
     * Creates a new Column instance.
     *
     * Override this method if you want to customize the Column class.
     *
     * @param string $name    The name of the column
     * @param array  $options The builder options
     *
     * @return ColumnInterface The new column instance
     */
    protected function newColumn($name, array $options): ColumnInterface
    {
        // Special case of CompoundColumnType which requires that child columns
        // are set afterwards. Whenever you extend this class, make sure to honor this
        // special use-case.
        if (null === $this->compound) {
            $this->compound = $this->isCompound();
        }

        if ($this->compound) {
            return new CompoundColumn($name, $this, $options);
        }

        return new Column($name, $this, $options);
    }

    /**
     * Determines whether this type is a compound.
     *
     * @return bool
     */
    protected function isCompound(): bool
    {
        if ($this->innerType instanceof CompoundColumnType) {
            return true;
        }

        for ($type = $this->parent; null !== $type; $type = $type->getParent()) {
            if ($type->getInnerType() instanceof CompoundColumnType) {
                return true;
            }
        }

        return false;
    }
}


<?php

declare(strict_types=1);

/*
 * This file is part of the RollerworksDatagrid package.
 *
 * (c) Sebastiaan Stok <s.stok@rollerscapes.net>
 *
 * This source file is subject to the MIT license that is bundled
 * with this source code in the file LICENSE.
 */

namespace Rollerworks\Component\Datagrid\Extension\Core\Type;

use Rollerworks\Component\Datagrid\Column\AbstractType;
use Rollerworks\Component\Datagrid\Column\ColumnInterface;
use Rollerworks\Component\Datagrid\Extension\Core\DataTransformer\ChainTransformer;
use Rollerworks\Component\Datagrid\Extension\Core\DataTransformer\DateTimeToLocalizedStringTransformer;
use Rollerworks\Component\Datagrid\Extension\Core\DataTransformer\StringToDateTimeTransformer;
use Rollerworks\Component\Datagrid\Extension\Core\DataTransformer\TimestampToDateTimeTransformer;
use Symfony\Component\OptionsResolver\OptionsResolver;

/**
 * DateTimeType.
 *
 * @author Sebastiaan Stok <s.stok@rollerscapes.net>
 */
class DateTimeType extends AbstractType
{
    /**
     * @var array
     */
    private static $acceptedFormats = [
        \IntlDateFormatter::FULL,
        \IntlDateFormatter::LONG,
        \IntlDateFormatter::MEDIUM,
        \IntlDateFormatter::SHORT,
        \IntlDateFormatter::NONE,
    ];

    /**
     * {@inheritdoc}
     */
    public function buildColumn(ColumnInterface $column, array $options)
    {
        $transformer = new ChainTransformer();

        if ('string' === $options['input']) {
            $transformer->append(
                new StringToDateTimeTransformer($options['model_timezone'], $options['model_timezone'])
            );
        } elseif ('timestamp' === $options['input']) {
            $transformer->append(
                new TimestampToDateTimeTransformer($options['model_timezone'], $options['model_timezone'])
            );
        }

        $transformer->append(new DateTimeToLocalizedStringTransformer(
            $options['model_timezone'],
            $options['view_timezone'],
            $options['date_format'],
            $options['time_format'],
            $options['calendar'],
            $options['format']
        ));

        $column->setViewTransformer($transformer);
    }

    /**
     * {@inheritdoc}
     */
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'input' => 'datetime',
            'model_timezone' => null,
            'view_timezone' => null,
            'date_format' => \IntlDateFormatter::MEDIUM,
            'time_format' => \IntlDateFormatter::MEDIUM,
            'calendar' => \IntlDateFormatter::GREGORIAN,
            'format' => null,
        ]);

        $resolver->setAllowedValues('date_format', self::$acceptedFormats);
        $resolver->setAllowedValues('time_format', self::$acceptedFormats);

        $resolver->setAllowedTypes('model_timezone', ['null', 'string']);
        $resolver->setAllowedTypes('view_timezone', ['null', 'string']);
        $resolver->setAllowedTypes('format', ['null', 'string']);
        $resolver->setAllowedTypes('calendar', ['int', 'IntlCalendar']);
        $resolver->setAllowedValues('input', ['string', 'timestamp', 'datetime']);
    }
}


<?php

/**
 * Agms Abstract Request
 */
namespace Omnipay\Agms\Message;

/**
 * Agms Abstract Request
 *
 * This is the parent class for all Agms requests.
 */
abstract class AbstractRequest extends \Omnipay\Common\Message\AbstractRequest
{
    /**
     * Endpoint URL
     *
     * @var string URL
     */
    protected $endpoint = 'https://gateway.agms.com/roxapi/agms.asmx';

    /**
     * Payment type
     *
     * @var string URL
     */
    protected $paymentType = 'creditcard';

    /**
     * Get the gateway endpoint
     *
     * @return string
     */
    public function getEndpoint()
    {
        return $this->endpoint;
    }

    /**
     * Get the gateway username
     *
     * @return string
     */
    public function getUsername()
    {
        return $this->getParameter('username');
    }

    /**
     * Set the gateway username
     *
     * @return AbstractRequest
     */
    public function setUsername($value)
    {
        return $this->setParameter('username', $value);
    }

    /**
     * Get the gateway password
     *
     * @return string
     */
    public function getPassword()
    {
        return $this->getParameter('password');
    }

    /**
     * Set the gateway password
     *
     * @return AbstractRequest
     */
    public function setPassword($value)
    {
        return $this->setParameter('password', $value);
    }

    /**
     * Get the gateway api key
     *
     * @return string
     */
    public function getApiKey()
    {
        return $this->getParameter('apiKey');
    }

    /**
     * Set the gateway api key
     *
     * @return AbstractRequest
     */
    public function setApiKey($value)
    {
        return $this->setParameter('apiKey', $value);
    }

    /**
     * Get the gateway account number
     *
     * @return string
     */
    public function getAccountNumber()
    {
        return $this->getParameter('accountNumber');
    }

    /**
     * Set the gateway account number
     *
     * @return AbstractRequest
     */
    public function setAccountNumber($value)
    {
        return $this->setParameter('accountNumber', $value);
    }

    /**
     * Get the developer mode
     *
     * @return string
     */
    public function getDeveloperMode()
    {
        return false;
    }

    /**
     * Set the gateway developer mode
     *
     * @return AbstractRequest
     */
    public function setDeveloperMode($value)
    {
        return $this->setParameter('developerMode', false);
    }

    /**
     * Get the gateway base data
     *
     * @return array
     */
    protected function getBaseData()
    {
        $data = array();
        $data['GatewayUserName'] = $this->getUsername();
        $data['GatewayPassword'] = $this->getPassword();
        $data['PaymentType'] = $this->paymentType;

        if (isset($this->transactionType)) {
            $data['TransactionType'] = $this->transactionType;
        }
        if (isset($this->safeAction)) {
            $data['SAFE_Action'] = $this->safeAction;
        }
        return $data;
    }

    /**
     * Get the billing data
     *
     * @return array
     */
    protected function getBillingData()
    {
        $data = array();
        if ($card = $this->getCard()) {
            // Customer billing details
            $data['FirstName'] = $card->getBillingFirstName();
            $data['LastName'] = $card->getBillingLastName();
            $data['Company'] = $card->getBillingCompany();
            $data['Address1'] = $card->getBillingAddress1();
            if ($card->getBillingAddress2()) {
                $data['Address2'] = $card->getBillingAddress2();
            }

            $data['City'] = $card->getBillingCity();
            $data['State'] = $card->getBillingState();
            $data['Zip'] = $card->getBillingPostcode();
            $data['Country'] = $card->getBillingCountry();
            $data['Phone'] = $card->getBillingPhone();
            $data['Email'] = $card->getEmail();
        }
        return $data;
    }

    /**
     * Get the shipping data
     *
     * @return array
     */
    protected function getShippingData()
    {
        $data = array();
        // Customer shipping details
        if ($card = $this->getCard()) {
            // Customer shipping details
            if ($card->getShippingFirstName()) {
                $data['ShippingFirstName'] = $card->getShippingFirstName();
            }
            if ($card->getShippingLastName()) {
                $data['ShippingLastName'] = $card->getShippingLastName();
            }
            if ($card->getShippingCompany()) {
                $data['ShippingCompany'] = $card->getShippingCompany();
            }
            if ($card->getShippingAddress1()) {
                $data['ShippingAddress1'] = $card->getShippingAddress1();
            }
            if ($card->getShippingAddress2()) {
                $data['ShippingAddress2'] = $card->getShippingAddress2();
            }
            if ($card->getShippingCity()) {
                $data['ShippingCity'] = $card->getShippingCity();
            }
            if ($card->getShippingState()) {
                $data['ShippingState'] = $card->getShippingState();
            }
            if ($card->getShippingPostcode()) {
                $data['ShippingZip'] = $card->getShippingPostcode();
            }
            if ($card->getShippingCountry()) {
                $data['ShippingCountry'] = $card->getShippingCountry();
            }
        }
        return $data;
    }

    /**
     * Get the invoice data
     *
     * @return array
     */
    protected function getInvoiceData()
    {
        $data = array();
        $data['Amount'] = $this->getAmount();
        if ($this->getDescription()) {
            $data['OrderDescription'] = $this->getDescription();
        }
        return $data;
    }

    /**
     * Get the authorization data
     *
     * @return array
     */
    protected function getAuthData()
    {
        $data = array();
        if ($this->getTransactionId()) {
            $data['TransactionID'] = $this->getTransactionId();
        }
        return $data;
    }

    /**
     * Send the request
     *
     * @return AbstractResponse
     */
    public function sendData($data)
    {
        $xml = $this->buildRequest($data);

        $headers = array(
            'content-type' => 'text/xml; charset=utf-8',
            'SOAPAction' => 'https://gateway.agms.com/roxapi/ProcessTransaction'
        );

        $httpResponse =  $this->httpClient->post($this->getEndpoint(), $headers, $xml)->send();
        return $this->response = new Response($this, $httpResponse->getBody());
    }

    /**
     * Build xml for the gateway
     *
     * @return xml string
     */
    protected function buildRequest($data)
    {
        $xmlHeader = '<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
    <ProcessTransaction xmlns="https://gateway.agms.com/roxapi/">
      <objparameters>';
        $xmlFooter = '</objparameters>
    </ProcessTransaction>
  </soap:Body>
</soap:Envelope>';
        $xmlBody = '';
        foreach ($data as $key => $value) {
            $xmlBody = $xmlBody . "<$key>$value</$key>";
        }
        return $xmlHeader . $xmlBody . $xmlFooter;
    }

    /**
     * Build xml for the gateway
     * @return xml string
     */
    protected function buildTokenRequest($data, $op)
    {
        $xmlHeader = '<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
    <' . $op . ' xmlns="https://gateway.agms.com/roxapi/">
      <vParameter>';
        $xmlFooter = '</vParameter>
    </' . $op . '>
  </soap:Body>
</soap:Envelope>';
        $xmlBody = '';
        foreach ($data as $key => $value) {
            $xmlBody = $xmlBody . "<$key>$value</$key>";
        }
        return $xmlHeader . $xmlBody . $xmlFooter;
    }
}


<?php

declare(strict_types=1);

/*
 * This file is part of the RollerworksDatagrid package.
 *
 * (c) Sebastiaan Stok <s.stok@rollerscapes.net>
 *
 * This source file is subject to the MIT license that is bundled
 * with this source code in the file LICENSE.
 */

namespace Rollerworks\Component\Datagrid\Util;

/**
 * @author Issei Murasawa <issei.m7@gmail.com>
 * @author Bernhard Schussek <bschussek@gmail.com>
 */
final class StringUtil
{
    /**
     * This class should not be instantiated.
     */
    private function __construct()
    {
    }

    /**
     * Returns the trimmed data.
     *
     * @param string $string
     *
     * @return string
     */
    public static function trim(string $string): string
    {
        if (null !== $result = @preg_replace('/^[\pZ\p{Cc}]+|[\pZ\p{Cc}]+$/u', '', $string)) {
            return $result;
        }

        return trim($string);
    }

    /**
     * Converts a fully-qualified class name to a block prefix.
     *
     * @param string $fqcn The fully-qualified class name
     *
     * @return string|null The block prefix or null if not a valid FQCN
     */
    public static function fqcnToBlockPrefix(string $fqcn): string
    {
        // Non-greedy ("+?") to match "type" suffix, if present
        if (preg_match('~([^\\\\]+?)(type)?$~i', $fqcn, $matches)) {
            return strtolower(
                preg_replace(['/([A-Z]+)([A-Z][a-z])/', '/([a-z\d])([A-Z])/'], ['\\1_\\2', '\\1_\\2'], $matches[1])
            );
        }
    }
}


<?php

declare(strict_types=1);

/*
 * This file is part of the RollerworksDatagrid package.
 *
 * (c) Sebastiaan Stok <s.stok@rollerscapes.net>
 *
 * This source file is subject to the MIT license that is bundled
 * with this source code in the file LICENSE.
 */

namespace Rollerworks\Component\Datagrid\Extension\Core\DataTransformer;

use Rollerworks\Component\Datagrid\Exception\TransformationFailedException;

/**
 * Transforms between a normalized format and a localized money string.
 *
 * @author Sebastiaan Stok <s.stok@rollerscapes.net>
 * @author Bernhard Schussek <bschussek@gmail.com>
 * @author Florian Eckerstorfer <florian@eckerstorfer.org>
 */
class MoneyToLocalizedStringTransformer extends NumberToLocalizedStringTransformer
{
    /**
     * @var int
     */
    private $divisor = 1;

    /**
     * @var string
     */
    private $defaultCurrency;

    /**
     * Constructor.
     *
     * @param int    $precision
     * @param bool   $grouping
     * @param int    $roundingMode
     * @param int    $divisor
     * @param string $defaultCurrency
     */
    public function __construct(
        int $precision = 2,
        bool $grouping = true,
        int $roundingMode = self::ROUND_HALF_UP,
        int $divisor = 1,
        string $defaultCurrency = 'EUR'
    ) {
        parent::__construct($precision, $grouping, $roundingMode);

        $this->divisor = $divisor;
        $this->defaultCurrency = $defaultCurrency;
    }

    /**
     * Transforms a normalized format into a localized money string.
     *
     * @param string|int|float|array $value
     *
     * @throws TransformationFailedException If the given value is not numeric or
     *                                       if the value can not be transformed
     *
     * @return string Localized money string
     */
    public function transform($value)
    {
        if (null === $value) {
            return '';
        }

        if (is_array($value)) {
            return $this->doTransformation($value['currency'] ?: $this->defaultCurrency, (string) $value['amount']);
        }

        // Convert fixed spaces to normal ones.
        $value = str_replace("\xc2\xa0", ' ', (string) $value);

        if (false !== strpos($value, ' ')) {
            return $this->transformStringWithCurrencyToLocalized($value);
        }

        return $this->doTransformation($this->defaultCurrency, $value);
    }

    private function transformStringWithCurrencyToLocalized(string $value)
    {
        list($currency, $amount) = explode(' ', $value);

        if (mb_strlen($currency) != 3) {
            throw new TransformationFailedException(
                sprintf(
                    'Currency "%s" extracted from "%s" is not accepted. Only three character format is supported.',
                    $currency,
                    $value
                )
            );
        }

        return $this->doTransformation($currency, $amount);
    }

    private function doTransformation(string $currency, string $amount)
    {
        if (!is_numeric($amount)) {
            throw new TransformationFailedException('Expected a numeric value.');
        }

        $amount /= $this->divisor;
        $formatter = $this->getNumberFormatter(\NumberFormatter::CURRENCY);

        $value = $formatter->formatCurrency($amount, $currency);

        if (intl_is_failure($formatter->getErrorCode())) {
            throw new TransformationFailedException($formatter->getErrorMessage());
        }

        // Convert fixed spaces to normal ones
        return str_replace("\xc2\xa0", ' ', $value);
    }
}


<?php

declare(strict_types=1);

/*
 * This file is part of the RollerworksDatagrid package.
 *
 * (c) Sebastiaan Stok <s.stok@rollerscapes.net>
 *
 * This source file is subject to the MIT license that is bundled
 * with this source code in the file LICENSE.
 */

namespace Rollerworks\Component\Datagrid\Column;

use Rollerworks\Component\Datagrid\DatagridView;
use Rollerworks\Component\Datagrid\DataTransformerInterface;
use Rollerworks\Component\Datagrid\Exception\BadMethodCallException;

/**
 * @author Sebastiaan Stok <s.stok@rollerscapes.net>
 */
class Column implements ColumnInterface
{
    /**
     * @var string
     */
    private $name;

    /**
     * @var ResolvedColumnTypeInterface
     */
    private $type;

    /**
     * @var array
     */
    protected $options;

    /**
     * @var bool
     */
    protected $locked = false;

    /**
     * @var DataTransformerInterface|null
     */
    private $viewTransformer;

    /**
     * @var callable
     */
    private $dataProvider;

    /**
     * Constructor.
     *
     * @param string                      $name
     * @param ResolvedColumnTypeInterface $type
     * @param array                       $options
     *
     * @throws \InvalidArgumentException when the name is invalid
     */
    public function __construct(
        $name,
        ResolvedColumnTypeInterface $type,
        array $options = []
    ) {
        if ('' === $name) {
            throw new \InvalidArgumentException(
                sprintf(
                    'The name "%s" contains illegal characters. Names should start with a letter, digit or underscore '.
                    'and only contain letters, digits, numbers, underscores ("_"), hyphens ("-") and colons (":").',
                    $name
                )
            );
        }

        $this->name = $name;
        $this->type = $type;
        $this->options = $options;
        $this->locked = false;
    }

    /**
     * {@inheritdoc}
     */
    public function getName(): string
    {
        return $this->name;
    }

    /**
     * {@inheritdoc}
     */
    public function getType(): ResolvedColumnTypeInterface
    {
        return $this->type;
    }

    /**
     * {@inheritdoc}
     */
    public function setViewTransformer(DataTransformerInterface $viewTransformer = null)
    {
        if ($this->locked) {
            throw new BadMethodCallException('Column setter methods cannot be accessed anymore once the data is locked.');
        }

        $this->viewTransformer = $viewTransformer;
    }

    /**
     * {@inheritdoc}
     */
    public function getViewTransformer()
    {
        return $this->viewTransformer;
    }

    /**
     * {@inheritdoc}
     */
    public function getOptions(): array
    {
        return $this->options;
    }

    /**
     * {@inheritdoc}
     */
    public function getOption(string $name, $default = null)
    {
        if (array_key_exists($name, $this->options)) {
            return $this->options[$name];
        }

        return $default;
    }

    /**
     * {@inheritdoc}
     */
    public function hasOption(string $name): bool
    {
        return array_key_exists($name, $this->options);
    }

    /**
     * {@inheritdoc}
     */
    public function createHeaderView(DatagridView $datagrid): HeaderView
    {
        // The methods createHeaderView(), buildHeaderView() are called
        // explicitly here in order to be able to override either of them
        // in a custom resolved column type.

        $view = $this->type->createHeaderView($this, $datagrid);
        $this->type->buildHeaderView($view, $this, $this->options);

        return $view;
    }

    /**
     * {@inheritdoc}
     */
    public function createCellView(HeaderView $header, $object, $index): CellView
    {
        // The methods createCellView(), buildCellView() are called
        // explicitly here in order to be able to override either of them
        // in a custom resolved column type.

        $view = $this->type->createCellView($this, $header);

        $view->vars['row'] = $index;
        $view->value = $this->type->getValue($this, $object);
        $view->source = $object;

        $this->type->buildCellView($view, $this, $this->options);

        return $view;
    }

    /**
     * Set the data-provider for the column.
     *
     * @param callable $dataProvider
     */
    public function setDataProvider(callable $dataProvider)
    {
        $this->dataProvider = $dataProvider;
    }

    /**
     * Get data-provider for this column.
     *
     * @return callable
     */
    public function getDataProvider(): callable
    {
        return $this->dataProvider;
    }
}


<?php

declare(strict_types=1);

/*
 * This file is part of the RollerworksDatagrid package.
 *
 * (c) Sebastiaan Stok <s.stok@rollerscapes.net>
 *
 * This source file is subject to the MIT license that is bundled
 * with this source code in the file LICENSE.
 */

namespace Rollerworks\Component\Datagrid\Column;

class ResolvedColumnTypeFactory implements ResolvedColumnTypeFactoryInterface
{
    /**
     * {@inheritdoc}
     */
    public function createResolvedType(ColumnTypeInterface $type, array $typeExtensions, ResolvedColumnTypeInterface $parent = null): ResolvedColumnTypeInterface
    {
        return new ResolvedColumnType($type, $typeExtensions, $parent);
    }
}


<?php

namespace Omnipay\Agms\Message;

/**
 * Agms Authorize Request
 */
class AuthorizeRequest extends AbstractRequest
{
    /**
     * Transaction type
     *
     * @return string
     */
    protected $transactionType = 'auth';

    /**
     * Get the request data
     *
     * @return array
     */
    public function getData()
    {
        $this->validate('amount', 'card');

        $this->getCard()->validate();
        $data = $this->getBaseData();
        $data['CCNumber'] = $this->getCard()->getNumber();
        $data['CCExpDate'] = $this->getCard()->getExpiryDate('my');
        $data['CVV'] = $this->getCard()->getCvv();

        // Add invoice data
        $data = array_merge($data, $this->getInvoiceData());
        // Add billing data
        $data = array_merge($data, $this->getBillingData());
        // Add shipping data
        $data = array_merge($data, $this->getShippingData());

        return $data;
    }
}


<?php

declare(strict_types=1);

/*
 * This file is part of the RollerworksDatagrid package.
 *
 * (c) Sebastiaan Stok <s.stok@rollerscapes.net>
 *
 * This source file is subject to the MIT license that is bundled
 * with this source code in the file LICENSE.
 */

namespace Rollerworks\Component\Datagrid\Column;

use Rollerworks\Component\Datagrid\DatagridExtensionInterface;
use Rollerworks\Component\Datagrid\Exception\ExceptionInterface;
use Rollerworks\Component\Datagrid\Exception\InvalidArgumentException;
use Rollerworks\Component\Datagrid\Exception\UnexpectedTypeException;

/**
 * @author Sebastiaan Stok <s.stok@rollerscapes.net>
 */
class ColumnTypeRegistry implements ColumnTypeRegistryInterface
{
    /**
     * Extensions.
     *
     * @var DatagridExtensionInterface[]
     */
    private $extensions = [];

    /**
     * @var array
     */
    private $types = [];

    /**
     * @var ResolvedColumnTypeFactoryInterface
     */
    private $resolvedTypeFactory;

    /**
     * Constructor.
     *
     * @param DatagridExtensionInterface[]       $extensions          An array of DatagridExtensionInterface
     * @param ResolvedColumnTypeFactoryInterface $resolvedTypeFactory The factory for resolved column types
     *
     * @throws UnexpectedTypeException if an extension does not implement DatagridExtensionInterface
     */
    public function __construct(array $extensions, ResolvedColumnTypeFactoryInterface $resolvedTypeFactory)
    {
        foreach ($extensions as $extension) {
            if (!$extension instanceof DatagridExtensionInterface) {
                throw new UnexpectedTypeException($extension, DatagridExtensionInterface::class);
            }
        }

        $this->extensions = $extensions;
        $this->resolvedTypeFactory = $resolvedTypeFactory;
    }

    /**
     * {@inheritdoc}
     */
    public function getType(string $name): ResolvedColumnTypeInterface
    {
        if (!isset($this->types[$name])) {
            $type = null;

            foreach ($this->extensions as $extension) {
                if ($extension->hasType($name)) {
                    $type = $extension->getType($name);

                    break;
                }
            }

            if (!$type) {
                // Support fully-qualified class names.
                if (!class_exists($name) || !in_array(ColumnTypeInterface::class, class_implements($name), true)) {
                    throw new InvalidArgumentException(sprintf('Could not load type "%s"', $name));
                }

                $type = new $name();
            }

            $this->types[$name] = $this->resolveType($type);
        }

        return $this->types[$name];
    }

    /**
     * {@inheritdoc}
     */
    public function hasType(string $name): bool
    {
        if (isset($this->types[$name])) {
            return true;
        }

        try {
            $this->getType($name);
        } catch (ExceptionInterface $e) {
            return false;
        }

        return true;
    }

    /**
     * {@inheritdoc}
     */
    public function getExtensions(): array
    {
        return $this->extensions;
    }

    private function resolveType(ColumnTypeInterface $type): ResolvedColumnTypeInterface
    {
        $parentType = $type->getParent();
        $fqcn = get_class($type);

        $typeExtensions = [];

        foreach ($this->extensions as $extension) {
            $typeExtensions = array_merge(
                $typeExtensions,
                $extension->getTypeExtensions($fqcn)
            );
        }

        return $this->resolvedTypeFactory->createResolvedType(
            $type,
            $typeExtensions,
            $parentType ? $this->getType($parentType) : null
        );
    }
}