<?php

namespace sndsgd\fs\entity;

class DirEntity extends EntityAbstract
{
    /**
     * @inheritDoc
     */
    public function test(int $opts): bool
    {
        return parent::test($opts | \sndsgd\Fs::DIR);
    }

    /**
     * @inheritDoc
     */
    public function canWrite()
    {
        $path = $this->path;
        while (file_exists($path) === false) {
            $path = dirname($path);
        }
        $dir = new self($path);
        return $dir->test(\sndsgd\Fs::WRITABLE);
    }

    /**
     * @inheritDoc
     */
    public function prepareWrite($mode = 0775)
    {
        if (file_exists($this->path)) {
            return $this->test(\sndsgd\Fs::WRITABLE);
        }
        else if (mkdir($this->path, $mode, true) === false) {
            $this->setError("failed to create directory '{$this->path}'");
            return false;
        }
        else {
            return true;
        }
    }

    /**
     * Get an instance of \sndsgd\fs\File for a file in this directory
     *
     * @param string $name The name of the file in the directory
     * @return \sndsgd\fs\entity\FileEntity
     */
    public function getFile(string $name): FileEntity
    {
        return new FileEntity($this->path.DIRECTORY_SEPARATOR.$name);
    }

    /**
     * Retrieve a subdirectory of the current directory
     *
     * @param string $name The name of the sub directory
     * @return \sndsgd\fs\entity\DirEntity
     */
    public function getDir(string $name): DirEntity
    {
        return new DirEntity($this->path.DIRECTORY_SEPARATOR.$name);
    }

    /**
     * Determine if a directory is empty
     *
     * @return bool
     * @throws \RuntimeException If the directory does not exist or is not readable
     */
    public function isEmpty()
    {
        if ($this->test(\sndsgd\Fs::EXISTS | \sndsgd\Fs::READABLE) === false) {
            throw new \RuntimeException(
                "failed to determine if a directory is empty; ".$this->getError()
            );
        }

        return count(scandir($this->path)) === 2;
    }

    /**
     * get a list of the directory children
     *
     * @param boolean $asStrings Only return the child entity names
     * @return array<string>|boolean
     */
    public function getList($asStrings = false)
    {
        $list = scandir($this->path);
        if ($asStrings === true) {
            return array_diff($list, [".", ".."]);
        }

        $ret = [];
        foreach ($list as $name) {
            if ($name === "." || $name === "..") {
                continue;
            }
            $path = $this->path.DIRECTORY_SEPARATOR.$name;
            $ret[] = (is_dir($path)) ? new static($path) : new FileEntity($path);
        }
        return $ret;
    }

    /**
     * Recursively remove the directory
     *
     * @return bool
     */
    public function remove(): bool
    {
        if ($this->test(\sndsgd\Fs::EXISTS | \sndsgd\Fs::READABLE | \sndsgd\Fs::WRITABLE) === false) {
            $this->error = "failed to remove directory; {$this->error}";
            return false;
        }

        foreach ($this->getList() as $entity) {
            if ($entity->remove() === false) {
                $this->error = $entity->getError();
                return false;
            }
        }

        if (@rmdir($this->path) === false) {
            $this->setError("failed to remove directory '{$this->path}'");
            return false;
        }

        return true;
    }
}


<?php
declare(strict_types=1);
/**
 * Caridea
 *
 * 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.
 *
 * @copyright 2015-2018 LibreWorks contributors
 * @license   Apache-2.0
 */
namespace Caridea\Http;

/**
 * Parses a query string from a URI and gets its values accurately.
 *
 * The problem here is that PHP will overwrite entries in the `$_GET`
 * superglobal if they share the same name. With PHP, a request to
 * `file.php?foobar=foo&foobar=bar` will result in `$_GET` set to
 * `['foobar' => 'bar']`.
 *
 * Other platforms allow list-like access to these parameters. This class will
 * account for both of the following cases:
 * - `param=foo&param=bar`
 * - `param[]=foo&param[]=bar`
 *
 * @copyright 2015-2018 LibreWorks contributors
 * @license   Apache-2.0
 */
class QueryParams
{
    /**
     * Parses the query string from the `QUERY_STRING` in the provided array.
     *
     * For the URL `file.php?test[]=1&test[]=2&noval&foobar=foo&foobar=bar&abc=123`,
     * the returned array will be:
     *
     * ```php
     * [
     *     'test' => ['1', '2'],
     *     'noval' => '',
     *     'foobar' => ['foo', 'bar'],
     *     'abc' => '123'
     * ];
     * ```
     *
     * @param array<string,mixed> $server The server values array
     */
    public static function get(array $server): array
    {
        $params = [];
        if (isset($server['QUERY_STRING'])) {
            $query = ltrim($server['QUERY_STRING'], '?');
            foreach (explode('&', $query) as $pair) {
                if ($pair) {
                    list($name, $value) = self::normalize(
                        array_map('urldecode', explode('=', $pair, 2))
                    );
                    $params[$name][] = $value;
                }
            }
        }
        return $params ? array_map(function ($v) {
            return count($v) === 1 ? $v[0] : $v;
        }, $params) : $params;
    }

    protected static function normalize(array $pair): array
    {
        $name = $pair[0];
        if (substr($name, -2, 2) == '[]') {
            $name = substr($name, 0, -2);
        }
        return [$name, count($pair) > 1 ? $pair[1] : ''];
    }

    /**
     * Parses the query string from the `QUERY_STRING` in the `$_SERVER` superglobal.
     *
     * For the URL `file.php?test[]=1&test[]=2&noval&foobar=foo&foobar=bar&abc=123`,
     * the returned array will be:
     *
     * ```php
     * [
     *     'test' => ['1', '2'],
     *     'noval' => '',
     *     'foobar' => ['foo', 'bar'],
     *     'abc' => '123'
     * ];
     * ```
     * @return array<string,mixed> The query string values
     */
    public static function getFromServer(): array
    {
        return self::get($_SERVER);
    }
}


<?php

/*
 * The MIT License
 *
 * Copyright 2018 Daniel Popiniuc
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

namespace danielgp\io_operations;

trait InputOutputTiming
{

    use InputOutputMemory;

    public $intTimeCounter = 0;

    /**
     * Converts a Date from ISO-8601 format into UTC Time zone SQL format
     *
     * @param string $inStrictIso8601DtTm
     * @return string
     */
    public function convertDateTimeToUtcTimeZone($inStrictIso8601DtTm)
    {
        $tmpDateTimeIn = $this->convertTimeFromFormatSafely($inStrictIso8601DtTm);
        $tmpDateTimeIn->setTimezone(new \DateTimeZone('UTC'));
        return $tmpDateTimeIn->format('Y-m-d H:i:s');
    }

    public function convertTimeFromFormatSafely($inStrictIso8601DtTm)
    {
        $tmpDateTimeIn = \DateTime::createFromFormat(\DATE_ATOM, $inStrictIso8601DtTm);
        if ($tmpDateTimeIn === false) {
            throw new \RuntimeException(''
                . sprintf('Unable to create DateTime object from %s string!', $inStrictIso8601DtTm));
        }
        return $tmpDateTimeIn;
    }

    public function convertTimeToMilliseconds($time)
    {
        $dateTime = new \DateTime($time);
        $seconds  = array_sum([
            (((int) $dateTime->format('H')) * 3600),
            (((int) $dateTime->format('i')) * 60),
            ((int) $dateTime->format('s')),
        ]);
        return floatval($seconds . '.' . $dateTime->format('u'));
    }

    public function getTimestampArray($crtTime)
    {
        return [
            'float'  => $this->getTimestampFloat($crtTime),
            'string' => $this->getTimestampString($crtTime)
        ];
    }

    public function getTimestampFloat($crtTime)
    {
        return ($crtTime['sec'] + $crtTime['usec'] / pow(10, 6));
    }

    private function getTimestampString($dateTime)
    {
        return '['
            . $dateTime->format('Y-m-d H:i:s.u') . ']';
    }

    public function getTimestampedInfo()
    {
        $dateTime = new \DateTime('now', new \DateTimeZone('UTC'));
        $sMessage = $this->getTimestampString($dateTime) . '~' . $this->getMemoryUsageString();
        $this->intTimeCounter++;
        if (PHP_SAPI === 'cli') {
            return strip_tags($sMessage);
        }
        return $sMessage;
    }
}


<?php
namespace T3v\T3vNavigations\Controller\ContentElements;

use TYPO3\CMS\Core\Utility\GeneralUtility;

use T3v\T3vContent\Controller\ContentElements\ContentElementController;

use T3v\T3vNavigations\Domain\Repository\OverviewNavigationItemRepository;

/**
 * The overview navigation content element controller class.
 *
 * @package T3v\T3vNavigations\Controller\ContentElements
 */
class OverviewNavigationContentElementController extends ContentElementController {
  /**
   * The overview navigation item repository.
   *
   * @var \T3v\T3vNavigations\Domain\Repository\OverviewNavigationItemRepository
   * @inject
   */
  protected $overviewNavigationItemRepository;

  /**
   * The index action.
   */
  public function indexAction() {
    $settings = $this->settings;

    $items     = [];
    $itemsUids = GeneralUtility::intExplode(',', $settings['items'], true);

    foreach($itemsUids as $uid) {
      $items[] = $this->overviewNavigationItemRepository->findByUid($uid);
    }

    $this->view->assign('settings', $settings);
    $this->view->assign('items', $items);
  }
}


<?php declare(strict_types=1);

namespace Identity\Events;

use Exception;
use GeneralForm\EventException;
use GeneralForm\IEvent;
use GeneralForm\IEventContainer;
use Identity\IIdentityModel;
use Nette\SmartObject;

/**
 * Class CleanUserEvent
 *
 * @author  geniv
 * @package Identity\Events
 */
class CleanUserEvent implements IEvent
{
    use SmartObject;

    /** @var string */
    private $validate;
    /** @var IIdentityModel */
    private $identityModel;

    /**
     * CleanUserEvent constructor.
     *
     * @param string         $validate
     * @param IIdentityModel $identityModel
     */
    public function __construct(string $validate, IIdentityModel $identityModel)
    {
        $this->setValidate($validate);
        $this->identityModel = $identityModel;
    }

    /**
     * Set validate.
     *
     * @param string $validate
     */
    public function setValidate(string $validate)
    {
        $this->validate = $validate;
    }

    /**
     * Update.
     *
     * @param IEventContainer $eventContainer
     * @param array           $values
     * @throws EventException
     */
    public function update(IEventContainer $eventContainer, array $values)
    {
        try {
            $result = $this->identityModel->cleanUser($this->validate);
            //TODO pridat mozne nastaveni callbacku pro vlastni notifikaci???
        } catch (Exception $e) {
            // recall exception
            throw new EventException($e->getMessage());
        }
    }
}


<?php
/*
 * Copyright (c) 2016 @trashtoy
 * https://github.com/trashtoy/
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 * this software and associated documentation files (the "Software"), to deal in
 * the Software without restriction, including without limitation the rights to use,
 * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
 * Software, and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
/**
 * PHP class file.
 * @auhtor trashtoy
 * @since  2.2.0
 */
namespace Peach\Http\Header;

use Exception;
use Peach\DT\Timestamp;
use Peach\DT\Util;

/**
 * Set-Cookie ヘッダーの expires 属性を書式化するクラスです.
 * expires 属性の書式は以下の通りです.
 * Wdy, DD-Mon-YY HH:MM:SS GMT
 *
 * このクラスは {@link CookieOptions} でのみ使用されます.
 * エンドユーザーがこのクラスを直接使う機会はありません.
 *
 * @ignore
 */
class CookieExpiresFormat
{
    /**
     * このクラスを直接インスタンス化することはできません.
     */
    private function __construct() {}

    /**
     * 唯一の CookieExpiresFormat オブジェクトを返します.
     *
     * @return CookieExpiresFormat
     * @codeCoverageIgnore
     */
    public static function getInstance()
    {
        static $instance = null;
        if ($instance === null) {
            $instance = new self();
        }
        return $instance;
    }

    /**
     * 指定された時刻を, 第 2 引数のタイムゾーンをベースとして
     * "Wdy, DD-Mon-YY HH:MM:SS GMT" 形式の文字列に変換します.
     *
     * @param  Timestamp $t      変換対象の時刻
     * @param  int       $offset タイムゾーン (分単位)
     * @return string 変換結果
     */
    public function format(Timestamp $t, $offset)
    {
        return $this->handleFormat($t->add("minute", Util::cleanTimeZoneOffset($offset)));
    }

    /**
     * format() の具体的な実装です. 引数の時刻は GMT に変換されているものとします.
     *
     * @param  Timestamp $t 変換対象の時刻 (GMT)
     * @return string 変換結果
     */
    private function handleFormat(Timestamp $t)
    {
        $wdy = $this->formatWeekday($t->getDay());
        $dd  = str_pad($t->get("date"), 2, "0", STR_PAD_LEFT);
        $mon = $this->formatMonth($t->get("month"));
        $yy  = str_pad($t->get("year"), 4, "0", STR_PAD_LEFT);
        $hms = $t->formatTime();
        return "{$wdy}, {$dd}-{$mon}-{$yy} {$hms} GMT";
    }

    /**
     * 整数の曜日と, それに対応する曜日文字列の一覧を返します.
     *
     * @return array キーに曜日, 値にその曜日の略称が対応する配列
     * @codeCoverageIgnore
     */
    private function getWeekdayMapping()
    {
        static $weekdayList = array(
            0 => "Sun",
            1 => "Mon",
            2 => "Tue",
            3 => "Wed",
            4 => "Thu",
            5 => "Fri",
            6 => "Sat",
        );
        return $weekdayList;
    }

    /**
     * 指定された曜日を
     * "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
     * のいずれかに変換します.
     *
     * @param  int $day 曜日 (0 以上 6 以下)
     * @return string   指定された曜日に対応する文字列
     */
    private function formatWeekday($day)
    {
        $weekdayList = $this->getWeekdayMapping();
        if (array_key_exists($day, $weekdayList)) {
            return $weekdayList[$day];
        }
        // @codeCoverageIgnoreStart
        throw new Exception("Invalid day: {$day}");
        // @codeCoverageIgnoreEnd
    }

    /**
     * 整数の月と, それに対応する略称のマッピングを返します.
     *
     * @return array キーに月, 値にその月の略称が対応する配列
     * @codeCoverageIgnore
     */
    private function getMonthMapping()
    {
        static $monthList = array(
            1  => "Jan",
            2  => "Feb",
            3  => "Mar",
            4  => "Apr",
            5  => "May",
            6  => "Jun",
            7  => "Jul",
            8  => "Aug",
            9  => "Sep",
            10 => "Oct",
            11 => "Nov",
            12 => "Dec",
        );
        return $monthList;
    }

    /**
     * 指定された月を
     * Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec
     * のいずれかに変換します.
     *
     * @param  int $m 月 (1 以上 12 以下)
     * @return string 指定された月に対応する文字列
     */
    private function formatMonth($m)
    {
        $monthList = $this->getMonthMapping();
        if (array_key_exists($m, $monthList)) {
            return $monthList[$m];
        }
        // @codeCoverageIgnoreStart
        throw new Exception("Invalid month: {$m}");
        // @codeCoverageIgnoreEnd
    }
}


<?php

namespace Asoc\Dadatata\Filter\Tesseract;

use Asoc\Dadatata\Exception\ProcessingFailedException;
use Asoc\Dadatata\Filter\FilterInterface;
use Asoc\Dadatata\Filter\OptionsInterface;
use Asoc\Dadatata\Model\ImageInterface;
use Asoc\Dadatata\Model\ThingInterface;
use Asoc\Dadatata\Tool\Tesseract;
use Asoc\Dadatata\ToolInterface;
use Neutron\TemporaryFilesystem\TemporaryFilesystemInterface;

class ExtractText implements FilterInterface
{
    /**
     * @var \Asoc\Dadatata\ToolInterface|Tesseract
     */
    private $tesseract;
    /**
     * @var \Neutron\TemporaryFilesystem\TemporaryFilesystemInterface
     */
    private $tmpFs;
    /**
     * @var OcrOptions
     */
    private $defaults;

    public function __construct(ToolInterface $tesseract, TemporaryFilesystemInterface $tmpFs)
    {
        $this->tesseract = $tesseract;
        $this->tmpFs     = $tmpFs;
    }

    /**
     * @param ThingInterface   $thing
     * @param string           $sourcePath
     * @param OptionsInterface $options
     *
     * @throws \Asoc\Dadatata\Exception\ProcessingFailedException
     * @return array Paths to generated files
     */
    public function process(ThingInterface $thing, $sourcePath, OptionsInterface $options = null)
    {
        $tmpDir  = $this->tmpFs->createTemporaryDirectory();
        $tmpFile = $tmpDir.DIRECTORY_SEPARATOR.$thing->getKey();

        /** @var OcrOptions $options */
        $options = $this->defaults->merge($options);

        $pb = $this->tesseract->getProcessBuilder()
            ->language($options->getLanguage())
            ->source($sourcePath)
            ->output($tmpFile);

        $process = $pb->getProcess();

        $code = $process->run();
        if ($code !== 0) {
            throw ProcessingFailedException::create(
                'Failed to convert image to text',
                $code,
                $process->getOutput(),
                $process->getErrorOutput()
            );
        }

        return [$tmpFile];
    }

    /**
     * @param ThingInterface $thing
     *
     * @return boolean
     */
    public function canHandle(ThingInterface $thing)
    {
        return $thing instanceof ImageInterface;
    }

    /**
     * @param OptionsInterface $options
     */
    public function setOptions(OptionsInterface $options)
    {
        if (!($options instanceof OcrOptions)) {
            $options = new OcrOptions($options->all());
        }
        $this->defaults = $options;
    }
}


<?php
/*
This is part of Wedeto, the WEb DEvelopment TOolkit.
It is published under the MIT Open Source License.

Copyright 2017, Egbert van der Wal

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

namespace Wedeto\Application\Dispatch;

use Wedeto\DB\Model;
use Wedeto\DB\Exception\DAOException;

use Wedeto\Util\Functions as WF;
use Wedeto\Util\Dictionary;
use Wedeto\Util\Validation\Type;
use Wedeto\Util\LoggerAwareStaticTrait;
use Wedeto\Util\DI\DI;

use Wedeto\Log\Logger;

use Wedeto\HTTP\Response\Response;
use Wedeto\HTTP\Response\Error as HTTPError;
use Wedeto\HTTP\StatusCode;

use ReflectionMethod;
use Throwable;
use RuntimeException;

/**
 * Run / include an application and make sure it produces response.
 * All output if buffered and will be logged to the logger at the end, to
 * avoid sending garbage to the client.
 */
class AppRunner
{
    use LoggerAwareStaticTrait;

    /** The variables to make available in the app */
    protected $variables = [];

    /** The instances to make available in the app */
    protected $instances = [];

    /** The arguments to the script */
    protected $arguments;

    /** The application to execute */
    protected $app;

    /** The initial output buffer level */
    protected $output_buffer_level;

    /**
     * Create the AppRunner with the request and the app path
     * @param string $app The path to the appplication to run
     * @param Dictionary $arguments The arguments to the app
     */
    public function __construct(string $app, $arguments = null)
    {
        self::getLogger();
        $this->app = $app;

        if (!empty($arguments))
        {
            if (!($arguments instanceof Dictionary))
                $arguments = new Dictionary($arguments);
            $this->arguments = $arguments;
        }
        else
            $this->arguments = new Dictionary;
    }

    /**
     * Assign a variable to make available to the app.
     *
     * Depending on the type of controller, the variables are assigned in
     * various ways.  For a plain script, the variables are available directly
     * as their name. When the script contains a class, the variables may be
     * assigned to public properties of that class with the same name.
     *
     * Additionally, they may be assigned to parameters to the controller
     * method. When $as_instance is set to true, an equal class name
     * is sufficient to perform the matching. When $as_instance is set to false,
     * class and name must be equal. This only works for objects.
     *
     * @param string $name The name of the variable
     * @param string $value The value to assign
     * @param bool $as_instance To allow referencing this variable by class
     * @return AppRunner Provides fluent interface
     */
    public function setVariable(string $name, $value, bool $as_instance = true)
    {
        $this->variables[$name] = $value;
        if (is_object($value))
            $this->instances[get_class($value)] = $value;
        return $this;
    }

    /**
     * Set multiple variables. A wrapper around AppRunner#setVariable to loop
     * over an array.
     * @param array|Traversable $variables The variables to set
     * @param bool $as_instance To allow referincing this variable by class
     * @return AppRunner Provides fluent interface
     */
    public function setVariables($variables, bool $as_instance = true)
    {
        foreach ($variables as $key => $var)
            $this->setVariable($key, $var, $as_instance);
        return $this;
    }

    /**
     * @return mixed A set variable, or null if it isn't set
     */
    public function getVariable(string $name)
    {
        return $this->variables[$name] ?? null;
    }

    /**
     * Set the argument Dictionary. Parameters for controller methods
     * may be filled using these values, in which case they will be removed
     * from the dictionary. The remaining contents will be assigned to
     * a variable called $arguments, automatically. This takes precedence
     * over AppRunner#setVariable.
     *
     * @param Dictionary $arguments The arguments to set
     * @return AppRunner Provides fluent interface
     */
    public function setArguments(Dictionary $arguments)
    {
        $this->arguments = $arguments;
        return $this;
    }

    /**
     * Run the app and make produce a response.
     * @throws Wedeto\HTTP\Response\Response or another exception thrown by the controller
     */
    public function execute()
    {
        try
        {
            // No output should be produced by apps directly, so buffer
            // everything, and log afterwards
            $this->output_buffer_level = ob_get_level();

            ob_start();
            $response = $this->doExecute();

            if (
                (is_object($response) && !($response instanceof Response)) ||
                (is_string($response) && class_exists($response))
            )
            {
                $response = $this->reflect($response);
            }

            if ($response instanceof Response)
                throw $response;

            throw new HTTPError(500, "App did not produce any response");
        }
        catch (Response $response)
        {
            self::$logger->debug("Response type {0} returned from controller: {1}", [get_class($response), $this->app]);
            throw $response;
        }
        catch (Throwable $e)
        {
            self::$logger->debug("While executing controller: {0}", [$this->app]);
            self::$logger->notice(
                "Unexpected exception of type {0} thrown while processing request: {1}",
                [get_class($e), $e]
            );

            throw $e;
        }
        finally
        {
            $this->logScriptOutput();
        }
    }

    /**
     * A wrapper to execute / include the selected route.  It puts the
     * app in a private scope, which access to a set of predefined variables.
     *
     * @param string $path The file to execute
     * @return mixed The response produced by the script, if any
     */
    protected function doExecute()
    {
        // Prepare some variables that come in handy in apps
        extract($this->variables);

        // Set the arguments
        $arguments = $this->arguments;

        // Get the app to execute
        $path = $this->app;

        self::$logger->debug("Including {0}", [$path]);
        $resp = include $path;

        return $resp;
    }

    /**
     * Get a list of public variables of the object, and set them to any variable assigned
     * using AppRunner#setVariable. A variable called 'logger' will be filled with a logger
     * instance of the class. If a method called 'setLogger' exists it will also be called
     * with this instance.
     *
     * @param object $object The object to fill
     */
    protected function injectVariables($object)
    {
        // Inject some properties when they're public
        $vars = array_keys(get_object_vars($object));

        foreach ($this->variables as $name => $value)
        {
            if (in_array($name, $vars))
                $object->$name = $value;
        }

        if (in_array('arguments', $vars))
            $object->arguments = $this->arguments;

        if (in_array('logger', $vars))
            $object->logger = Logger::getLogger(get_class($object));

        if (method_exists($object, 'setLogger'))
            $object->setLogger(Logger::getLogger(get_class($object)));
    }

    /**
     * Find the correct method in a controller to execute for the current request.
     * The route led to this controller, so the method is the first following URL argument.
     * Any suffix is stripped - method names may not contain dots anyway.
     * @param object $object The object from which to find a method to call.
     * @return callable A callable method in this object
     */
    protected function findController($object)
    {
        // Get the next URL argument
        $urlargs = $this->arguments;
        $arg = $urlargs->shift();

        // Store it as controller name
        $controller = $arg;

        // Strip any suffix
        if (($pos = strpos($controller, '.')) !== false)
            $controller = substr($controller, 0, $pos);

        // Check if the method exists
        if (!method_exists($object, $controller))
        {
            // Fall back to an index method
            if (method_exists($object, "index"))
            {
                if ($controller !== null)
                    $urlargs->unshift($arg);
                $controller = "index";
            }
            else
                throw new HTTPError(404, "Unknown controller: " . $controller);
        }
        return $controller;
    }

    /**
     * If you prefer to encapsulate your controllers in classes, you can
     * have your app files return an object instead of a response.
     *
     * Create a class and add methods to this class with names corresponding to
     * the first unmatched part of the route. E.g., if your controller is
     * /image and the called route is /image/edit/3, your class should contain
     * a method called 'edit' that accepts one argument of int-type.
     *
     * The parameters of your methods are extracted using reflection and
     * matched to the request. You can use string or int types, or subclasses
     * of Wedeto\DB\Model. In the latter case, the object will be instantiated
     * using the parameter as identifier, that will be passed to the
     * DAO::get method.
     *
     * It is also possible to set variables, using AppRunner#setVariable.
     * Variables set this way will be assigned to corresponding parameters of the
     * method. These parameters must match in type and name.
     *
     * Finally, all remaining arguments can be passed to a parameter called
     * $arguments with type Dictionary, or, a Dictionary parameter that is the
     * last parameter.
     */
    protected function reflect($object)
    {
        // Instantiate an object when a classname is specified
        if (is_string($object) && class_exists($object))
            $object = DI::getInjector()->newInstance($object, $this->variables);

        // Find the correct method in the object
        $controller = $this->findController($object);

        // Fill public member variables of controller
        $this->injectVariables($object);

        $method = new ReflectionMethod($object, $controller);
        $parameters = $method->getParameters();

        // No required parameters, call the method!
        if (count($parameters) === 0)
            return call_user_func(array($object, $controller));

        // Iterate over the parameters and assign a value to them
        $args = array();
        $arg_cnt = 0;
        $urlargs = $this->arguments;
        $vars = $this->variables;
        $vars['arguments'] = $this->variables;

        foreach ($parameters as $cnt => $param)
        {
            $tp = $param->getType();
            if ($tp === null)
            {
                ++$arg_cnt;
                if (!$urlargs->has(0))
                    throw new HTTPError(400, "Invalid arguments - expecting argument $arg_cnt");

                $args[] = $urlargs->shift();
                continue;
            }

            $tp = (string)$tp;

            // Check if a variable by the correct name was set
            $name = $param->getName();
            if (isset($vars[$name]))
            {
                $val = $vars[$name];
                if ((is_object($val) && is_a($val, $tp)) || (gettype($val) === $tp))
                {
                    $args[] = $val;
                    continue;
                }
            }

            // Arguments may be passed in by having a Dictionary parameter as the last parameter
            if ($tp === Dictionary::class)
            {
                if ($cnt !== (count($parameters) - 1))
                    throw new HTTPError(500, "Dictionary must be last parameter");

                $args[] = $urlargs;
                break;
            }

            if (class_exists($tp) && isset($this->instances[$tp]))
            {
                $args[] = $this->instances[$tp];
                continue;
            }

            ++$arg_cnt;
            if ($tp === "int")
            {
                if (!$urlargs->has(0, Type::INT))
                    throw new HTTPError(400, "Invalid arguments - missing integer as argument $cnt");
                $args[] = (int)$urlargs->shift();
                continue;
            }

            if ($tp === "string")
            {
                if (!$urlargs->has(0, Type::STRING))
                    throw new HTTPError(400, "Invalid arguments - missing string as argument $cnt");
                $args[]  = (string)$urlargs->shift();
                continue;
            }

            if (class_exists($tp) && is_subclass_of($tp, Model::class))
            {
                if (!$urlargs->has(0))
                    throw new HTTPError(400, "Invalid arguments - missing identifier as argument $cnt");
                $object_id = $urlargs->shift();
                $dao = $tp::getDAO();
                try
                {
                    $obj = $dao->getByID($object_id);
                }
                catch (DAOException $e)
                {
                    $namespace_parts = explode("\\", $tp);
                    $base_class_name = end($namespace_parts);
                    throw new HTTPError(404, "Unable to load {$base_class_name} with ID $object_id", "Invalid entity");
                }
                $args[] = $obj;
                continue;
            }

            throw new HTTPError(500, "Invalid parameter type: " . $tp);
        }

        return call_user_func_array([$object, $controller], $args);
    }

    /**
     * Log all output of the script to the logger.
     */
    private function logScriptOutput()
    {
        $output_buffers = array();
        $ob_cnt = 0;
        while (ob_get_level() > $this->output_buffer_level)
        {
            $output = trim(ob_get_contents());
            ++$ob_cnt;
            ob_end_clean();
            if (!empty($output))
            {
                $lines = explode("\n", $output);
                foreach ($lines as $n => $line)
                    self::$logger->debug("Script output: {0}/{1}: {2}", [$ob_cnt, $n + 1, $line]);
            }
        }
    }
}


<?php

namespace Asoc\Dadatata\Filter;

use Asoc\Dadatata\Model\AudioInterface;
use Asoc\Dadatata\Model\DocumentInterface;
use Asoc\Dadatata\Model\ImageInterface;
use Asoc\Dadatata\Model\TextInterface;
use Asoc\Dadatata\Model\ThingInterface;
use Asoc\Dadatata\Model\VideoInterface;

class PassFilter implements FilterInterface
{
    /**
     * @var PassOptions
     */
    private $defaults;

    /**
     * @param OptionsInterface $options
     */
    public function setOptions(OptionsInterface $options)
    {
        if (!($options instanceof PassOptions)) {
            $options = new PassOptions($options);
        }

        $this->defaults = $options;
    }

    /**
     * @param ThingInterface                              $thing
     * @param string                                      $sourcePath
     * @param \Asoc\Dadatata\Filter\OptionsInterface|null $options
     *
     * @return array Paths to generated files
     */
    public function process(ThingInterface $thing, $sourcePath, OptionsInterface $options = null)
    {
        return [$sourcePath];
    }

    /**
     * @param ThingInterface $thing
     *
     * @return boolean
     */
    public function canHandle(ThingInterface $thing)
    {
        $ok = false;

        if ($this->defaults->passIfCategory()) {
            $category = $this->defaults->getCategory();
            if ($category === 'image' && $thing instanceof ImageInterface
                || $category === 'document' && $thing instanceof DocumentInterface
                || $category === 'audio' && $thing instanceof AudioInterface
                || $category === 'video' && $thing instanceof VideoInterface
                || $category === 'text' && $thing instanceof TextInterface
            ) {
                $ok = true;
            }
        }
        if ($this->defaults->passIfMime()) {
            $mime = $this->defaults->getMime();
            $ok   = $mime === $thing->getMime();
        }

        return $ok;
    }
}


<?php

/**
 * Melis Technology (http://www.melistechnology.com)
 *
 * @copyright Copyright (c) 2016 Melis Technology (http://www.melistechnology.com)
 *
 */

namespace MelisCmsPageHistoric\Controller\DashboardPlugins;

use MelisCore\Controller\DashboardPlugins\MelisCoreDashboardTemplatingPlugin;
use Zend\View\Model\ViewModel;
use Zend\Session\Container;
use MelisCms\Service\MelisCmsRightsService;

class MelisCmsPageHistoricRecentUserActivityPlugin extends MelisCoreDashboardTemplatingPlugin
{
    public function __construct()
    {
        $this->pluginModule = 'meliscmspagehistoric';
        parent::__construct();
    }

    /**
     * Adds page's recent activity on the dashboard
     */
    public function recentActivityPages()
    {
        $finalPages = [];
        $pageId     = null;
        $pageMelisKey = null;

        if($this->isCmsActive())
        {
            $melisTranslation = $this->getServiceLocator()->get('MelisCoreTranslation');
            $melisAppConfig = $this->getServiceLocator()->get('MelisCoreConfig');
            $melisCoreAuth = $this->getServiceLocator()->get('MelisCoreAuth');
            $melisCmsRights = $this->getServiceLocator()->get('MelisCmsRights');

            $translator = $this->getServiceLocator()->get('translator');

            $melisKeys = $melisAppConfig->getMelisKeys();
            $fullKeyPage = $melisKeys['meliscms_page'];

            $xmlRights = $melisCoreAuth->getAuthRights();

            $pageId = '';
            $pageMelisKey = '';
            $itemConfigPage = $melisAppConfig->getItem($fullKeyPage);
            if ($itemConfigPage)
            {
                $pageId = $itemConfigPage['conf']['id'];
                $pageMelisKey = $itemConfigPage['conf']['melisKey'];
            }

            $container = new Container('meliscore');
            $locale = $container['melis-lang-locale'];

            $maxLines = 8;
            if (!empty($this->pluginConfig['max_lines']))
                $maxLines = $this->pluginConfig['max_lines'];

            $melisPageHistoricTable = $this->getServiceLocator()->get('MelisPagehistoricTable');
            $melisPage = $this->getServiceLocator()->get('MelisPagehistoricTable');
            $userTable = $this->getServiceLocator()->get('MelisCoreTableUser');

            $pages = $melisPageHistoricTable->getPagesHistoricForDashboard((int)$maxLines);

            $finalPages = array();
            if ($pages)
            {
                $pages = $pages->toArray();

                foreach ($pages as $keyPage => $page)
                {
                    $melisPage = $this->getServiceLocator()->get('MelisEnginePage');
                    $datasPage = $melisPage->getDatasPage($page['pageId'], 'saved');
                    if (!empty($datasPage))
                        $datasPage = $datasPage->getMelisPageTree();

                    $datasPageHistoric = $melisPageHistoricTable->getDescendingHistoric($page['pageId'], 1);
                    $datasPageHistoric = $datasPageHistoric->toArray();
                    $datasPageHistoric = $datasPageHistoric[0];
                    $datasUser = $userTable->getEntryById($datasPageHistoric['hist_user_id']);
                    $name = '#' . $datasPageHistoric['hist_user_id'];
                    if ($datasUser)
                    {
                        $datasUser = $datasUser->toArray();
                        if ($datasUser)
                        {
                            $datasUser = $datasUser[0];
                            $name = $datasUser['usr_firstname'] . ' ' . $datasUser['usr_lastname'];
                        }
                    }

                    $date = strftime($melisTranslation->getDateFormatByLocate($locale), strtotime($datasPageHistoric['hist_date']));

                    $data_icon = 'fa fa-file-o';
                    if (!empty($datasPage))
                    {
                        if ($datasPage->page_type == 'PAGE')
                            $data_icon = 'fa fa-file-o';
                        if ($datasPage->page_type == 'SITE')
                            $data_icon = 'fa fa-home';
                        if ($datasPage->page_type == 'FOLDER')
                            $data_icon = 'fa fa-folder-open-o';
                    }

                    $actionIcon = '';
                    if ($datasPageHistoric['hist_action'] == 'Publish')
                        $actionIcon = 'fa fa-circle fa-color-green';
                    if ($datasPageHistoric['hist_action'] == 'Unpublish')
                        $actionIcon = 'fa fa-circle fa-color-red';
                    if ($datasPageHistoric['hist_action'] == 'Save')
                        $actionIcon = 'fa fa-save';
                    if ($datasPageHistoric['hist_action'] == 'Delete')
                        $actionIcon = 'fa fa-times fa-color-red';

                    $isAccessible = $melisCmsRights->isAccessible($xmlRights, MelisCmsRightsService::MELISCMS_PREFIX_PAGES, $page['pageId']);

                    $pageName = $translator->translate('tr_meliscms_page_Page');
                    if (!empty($datasPage->page_name))
                        $pageName = $datasPage->page_name;

                    $pageFinal = array(
                        'page_id' => $page['pageId'],
                        'page_name' => $pageName,
                        'hist_action' => $translator->translate('tr_melispagehistoric_action_text_'.$datasPageHistoric['hist_action']),
                        'hist_date' => $date,
                        'hist_user_id' => $datasPageHistoric['hist_user_id'],
                        'hist_user_name' => $name,
                        'page_icon' => $data_icon,
                        'hist_action_icon' => $actionIcon,
                        'page_accessible' => (string)$isAccessible,
                    );

                    $finalPages[] = $pageFinal;
                }
            }
        }
        else
        {
            $config = $this->getServiceLocator()->get('config');
            unset($config['plugins']['meliscore_dashboard']['interface']['meliscore_dashboard_recent_activity']);
        }

        $view = new ViewModel();
        $view->setTemplate('melis-cms-page-historic/dashboard-plugin/recent-user-activity');
        $view->pages = $finalPages;

        $view->pageId = $pageId;
        $view->pageMelisKey = $pageMelisKey;
        $view->isCmsActive = $this->isCmsActive();
        return $view;
    }

    /**
     * Checking if MelisCms modul is activated
     *
     * @return boolean
     */
    private function isCmsActive()
    {
        $melisCms  = 'MelisCms';
        $moduleSvc = $this->getServiceLocator()->get('ModulesService');
        $modules   = $moduleSvc->getActiveModules();

        if(in_array($melisCms, $modules)) {
            return true;
        }

        return false;
    }
}


<?php

declare(strict_types=1);

namespace Rancoud\Database;

use Exception;
use PDO;
use PDOException;
use PDOStatement;

/**
 * Class Database.
 */
class Database
{
    /**
     * @var Configurator
     */
    protected $configurator = null;

    /**
     * @var PDO
     */
    protected $pdo = null;

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

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

    /**
     * @var Database
     */
    protected static $instance;

    /**
     * Database constructor.
     *
     * @param Configurator $configurator
     */
    public function __construct(Configurator $configurator)
    {
        $this->configurator = $configurator;
    }

    /**
     * @param Configurator|null $configurator
     *
     * @throws DatabaseException
     *
     * @return Database
     */
    public static function getInstance(Configurator $configurator = null): self
    {
        if (self::$instance === null) {
            if ($configurator === null) {
                throw new DatabaseException('Configurator Missing');
            }
            self::$instance = new self($configurator);
        } elseif ($configurator !== null) {
            throw new DatabaseException('Configurator Already Setup');
        }

        return self::$instance;
    }

    /**
     * @throws DatabaseException
     */
    public function connect()
    {
        try {
            $startTime = \microtime(true);

            $this->pdo = $this->configurator->createPDOConnection();

            $endTime = \microtime(true);

            if ($this->configurator->hasSaveQueries()) {
                $this->savedQueries[] = ['Connection' => $this->getTime($startTime, $endTime)];
            }
        } catch (Exception $e) {
            $this->addErrorConnection($e);

            if ($this->configurator->hasThrowException()) {
                throw new DatabaseException('Error Connecting Database');
            }
        }
    }

    /**
     * @param string $sql
     * @param array  $parameters
     *
     * @throws DatabaseException
     *
     * @return PDOStatement
     */
    protected function prepareBind(string $sql, array $parameters = []): ?PDOStatement
    {
        if ($this->pdo === null) {
            $this->connect();
        }

        $statement = null;

        try {
            $statement = $this->pdo->prepare($sql);
            if ($statement === false) {
                throw new Exception('Error Prepare Statement');
            }
        } catch (Exception $e) {
            $this->addErrorPrepare($sql, $parameters);
            if ($this->configurator->hasThrowException()) {
                throw new DatabaseException('Error Prepare Statement');
            }
        }

        if ($statement === false) {
            return null;
        }

        foreach ($parameters as $key => $value) {
            $param = $this->getPdoParamType($value);
            if (\is_float($value)) {
                $value = (string) $value;
            }

            if ($param === false) {
                throw new DatabaseException('Error Bind Value');
            }

            try {
                $statement->bindValue(":$key", $value, $param);
            } catch (PDOException $e) {
                throw new DatabaseException($e->getMessage());
            }
        }

        return $statement;
    }

    /**
     * @param mixed $value
     *
     * @return bool|int
     */
    protected function getPdoParamType($value)
    {
        if (\is_int($value)) {
            return PDO::PARAM_INT;
        } elseif (\is_bool($value)) {
            return PDO::PARAM_BOOL;
        } elseif (null === $value) {
            return PDO::PARAM_NULL;
        } elseif (\is_string($value)) {
            return PDO::PARAM_STR;
        } elseif (\is_float($value)) {
            return PDO::PARAM_STR;
        } elseif (\is_resource($value)) {
            return PDO::PARAM_LOB;
        }

        return false;
    }

    /**
     * @param PDOStatement $statement
     */
    protected function addErrorStatement(PDOStatement $statement): void
    {
        $this->errors[] = [
            'query'       => $statement->queryString,
            'query_error' => $statement->errorInfo(),
            'pdo_error'   => $this->pdo->errorInfo(),
            'dump_params' => $this->getDumpParams($statement)
        ];
    }

    /**
     * @param Exception $exception
     */
    protected function addErrorConnection(Exception $exception): void
    {
        $this->errors[] = [
            'query'       => $this->configurator->getDsn(),
            'query_error' => null,
            'pdo_error'   => $exception->getMessage(),
            'dump_params' => $this->configurator->getParametersForPDO()
        ];
    }

    /**
     * @param string $sql
     * @param array  $parameters
     */
    protected function addErrorPrepare(string $sql, array $parameters): void
    {
        $this->errors[] = [
            'query'       => $sql,
            'query_error' => null,
            'pdo_error'   => $this->pdo->errorInfo(),
            'dump_params' => $parameters
        ];
    }

    /**
     * @param PDOStatement $statement
     * @param array        $parameters
     * @param float        $time
     */
    protected function addQuery(PDOStatement $statement, array $parameters, float $time): void
    {
        if ($this->configurator->hasSaveQueries()) {
            $this->savedQueries[] = [
                'query'      => $statement->queryString,
                'parameters' => $parameters,
                'time'       => $time
            ];
        }
    }

    /**
     * @param PDOStatement $statement
     *
     * @return string
     */
    protected function getDumpParams(PDOStatement $statement): string
    {
        \ob_start();
        $statement->debugDumpParams();
        $result = \ob_get_contents();
        \ob_end_clean();

        return $result;
    }

    /**
     * @param string $sql
     * @param array  $parameters
     *
     * @throws DatabaseException
     *
     * @return PDOStatement|null
     */
    public function select(string $sql, array $parameters = []): ?PDOStatement
    {
        $statement = $this->prepareBind($sql, $parameters);

        if ($statement === null) {
            return null;
        }

        $startTime = \microtime(true);

        $this->executeStatement($statement);

        $endTime = \microtime(true);

        $this->addQuery($statement, $parameters, $this->getTime($startTime, $endTime));

        return $statement;
    }

    /**
     * @param PDOStatement $statement
     *
     * @throws DatabaseException
     *
     * @return bool
     */
    protected function executeStatement(PDOStatement $statement): bool
    {
        $success = false;

        try {
            $success = $statement->execute();
            if ($success === false) {
                throw new Exception('Error Execute');
            }
        } catch (Exception $e) {
            $this->addErrorStatement($statement);
            if ($this->configurator->hasThrowException()) {
                throw new DatabaseException('Error Execute');
            }
        }

        return $success;
    }

    /**
     * @param PDOStatement $statement
     * @param int          $fetchType
     *
     * @return mixed
     */
    public function read(PDOStatement $statement, $fetchType = PDO::FETCH_ASSOC)
    {
        return $statement->fetch($fetchType);
    }

    /**
     * @param PDOStatement $statement
     * @param int          $fetchType
     *
     * @return array
     */
    public function readAll(PDOStatement $statement, $fetchType = PDO::FETCH_ASSOC): array
    {
        return $statement->fetchAll($fetchType);
    }

    /**
     * @param string $sql
     * @param array  $parameters
     * @param bool   $getLastInsertId
     *
     * @throws DatabaseException
     *
     * @return int|bool
     */
    public function insert(string $sql, array $parameters = [], bool $getLastInsertId = false)
    {
        $statement = $this->prepareBind($sql, $parameters);

        if ($statement === null) {
            return false;
        }

        $startTime = \microtime(true);

        $success = $this->executeStatement($statement);
        if ($success === false) {
            return false;
        }

        $endTime = \microtime(true);

        $this->addQuery($statement, $parameters, $this->getTime($startTime, $endTime));

        $lastInsertId = true;
        if ($getLastInsertId === true) {
            $lastInsertId = (int) $this->pdo->lastInsertId();
        }

        $statement->closeCursor();
        $statement = null;

        return $lastInsertId;
    }

    /**
     * @param string $sql
     * @param array  $parameters
     * @param bool   $getCountRowsAffected
     *
     * @throws DatabaseException
     *
     * @return int|bool
     */
    public function update(string $sql, array $parameters = [], bool $getCountRowsAffected = false)
    {
        $statement = $this->prepareBind($sql, $parameters);

        if ($statement === null) {
            return false;
        }

        $startTime = \microtime(true);

        $success = $this->executeStatement($statement);
        if ($success === false) {
            return false;
        }

        $endTime = \microtime(true);

        $this->addQuery($statement, $parameters, $this->getTime($startTime, $endTime));

        $countRowAffected = true;
        if ($getCountRowsAffected) {
            $countRowAffected = (int) $statement->rowCount();
        }

        $statement->closeCursor();
        $statement = null;

        return $countRowAffected;
    }

    /**
     * @param string $sql
     * @param array  $parameters
     * @param bool   $getCountRowsAffected
     *
     * @throws DatabaseException
     *
     * @return int|bool
     */
    public function delete(string $sql, array $parameters = [], bool $getCountRowsAffected = false)
    {
        $statement = $this->prepareBind($sql, $parameters);

        if ($statement === null) {
            return false;
        }

        $startTime = \microtime(true);

        $success = $this->executeStatement($statement);
        if ($success === false) {
            return false;
        }

        $endTime = \microtime(true);

        $this->addQuery($statement, $parameters, $this->getTime($startTime, $endTime));

        $countRowAffected = true;
        if ($getCountRowsAffected) {
            $countRowAffected = (int) $statement->rowCount();
        }

        $statement->closeCursor();
        $statement = null;

        return $countRowAffected;
    }

    /**
     * @param string $sql
     * @param array  $parameters
     *
     * @throws DatabaseException
     *
     * @return int|bool
     */
    public function count(string $sql, array $parameters = [])
    {
        $statement = $this->select($sql, $parameters);

        if ($statement === null) {
            return false;
        }

        $cursor = $statement->fetch(PDO::FETCH_ASSOC);

        $count = (int) \current($cursor);

        $statement->closeCursor();
        $statement = null;

        return $count;
    }

    /**
     * @param string $sql
     * @param array  $parameters
     *
     * @throws DatabaseException
     *
     * @return bool
     */
    public function exec(string $sql, array $parameters = []): bool
    {
        $statement = $this->prepareBind($sql, $parameters);

        if ($statement === null) {
            return false;
        }

        $startTime = \microtime(true);

        $success = $this->executeStatement($statement);

        $endTime = \microtime(true);

        $this->addQuery($statement, $parameters, $this->getTime($startTime, $endTime));

        $statement->closeCursor();
        $statement = null;

        return $success;
    }

    /**
     * @return PDO|null
     */
    public function getPdo(): ?PDO
    {
        return $this->pdo;
    }

    /**
     * @param string $sql
     * @param array  $parameters
     *
     * @throws DatabaseException
     *
     * @return array|bool
     */
    public function selectAll(string $sql, array $parameters = [])
    {
        $statement = $this->select($sql, $parameters);

        if ($statement === null) {
            return false;
        }

        $results = $this->readAll($statement);

        $statement->closeCursor();
        $statement = null;

        return $results;
    }

    /**
     * @param string $sql
     * @param array  $parameters
     *
     * @throws DatabaseException
     *
     * @return array|bool
     */
    public function selectRow($sql, array $parameters = [])
    {
        $statement = $this->select($sql, $parameters);

        if ($statement === null) {
            return false;
        }

        $row = $this->read($statement);
        if ($row === false) {
            $row = [];
        }

        $statement->closeCursor();
        $statement = null;

        return $row;
    }

    /**
     * @param string $sql
     * @param array  $parameters
     *
     * @throws DatabaseException
     *
     * @return array|bool
     */
    public function selectCol(string $sql, array $parameters = [])
    {
        $statement = $this->select($sql, $parameters);

        if ($statement === null) {
            return false;
        }

        $datas = $this->readAll($statement);
        $col = [];
        foreach ($datas as $data) {
            $col[] = \current($data);
        }

        $statement->closeCursor();
        $statement = null;

        return $col;
    }

    /**
     * @param string $sql
     * @param array  $parameters
     *
     * @throws DatabaseException
     *
     * @return mixed|bool
     */
    public function selectVar(string $sql, array $parameters = [])
    {
        $var = false;

        $statement = $this->select($sql, $parameters);

        if ($statement === null) {
            return false;
        }

        $row = $this->read($statement);
        if ($row !== false) {
            $var = \current($row);
        }

        $statement->closeCursor();
        $statement = null;

        return $var;
    }

    /**
     * @throws DatabaseException
     * @throws PDOException
     *
     * @return bool
     */
    public function startTransaction(): bool
    {
        if ($this->pdo === null) {
            $this->connect();
        }

        return $this->pdo->beginTransaction();
    }

    /**
     * @throws DatabaseException
     *
     * @return bool
     */
    public function completeTransaction(): bool
    {
        if ($this->pdo === null) {
            $this->connect();
        }

        if ($this->pdo->inTransaction() === false) {
            return false;
        }

        if ($this->hasErrors()) {
            $this->pdo->rollBack();

            return false;
        }

        $this->pdo->commit();

        return true;
    }

    /**
     * @throws DatabaseException
     *
     * @return bool
     */
    public function commitTransaction(): bool
    {
        if ($this->pdo === null) {
            $this->connect();
        }

        if ($this->pdo->inTransaction() === false) {
            return false;
        }

        return $this->pdo->commit();
    }

    /**
     * @throws DatabaseException
     *
     * @return bool
     */
    public function rollbackTransaction(): bool
    {
        if ($this->pdo === null) {
            $this->connect();
        }

        if ($this->pdo->inTransaction() === false) {
            return false;
        }

        return $this->pdo->rollBack();
    }

    /**
     * @return bool
     */
    public function hasErrors(): bool
    {
        return !empty($this->errors);
    }

    /**
     * @return array
     */
    public function getErrors(): array
    {
        return $this->errors;
    }

    /**
     * @return array|null
     */
    public function getLastError(): ?array
    {
        $countErrors = \count($this->errors);
        if ($countErrors === 0) {
            return null;
        }

        return $this->errors[$countErrors - 1];
    }

    public function cleanErrors(): void
    {
        $this->errors = [];
    }

    /**
     * @return bool
     */
    public function hasSaveQueries(): bool
    {
        return $this->configurator->hasSaveQueries();
    }

    public function enableSaveQueries(): void
    {
        $this->configurator->enableSaveQueries();
    }

    public function disableSaveQueries(): void
    {
        $this->configurator->disableSaveQueries();
    }

    public function cleanSavedQueries(): void
    {
        $this->savedQueries = [];
    }

    /**
     * @return array
     */
    public function getSavedQueries(): array
    {
        return $this->savedQueries;
    }

    /**
     * @param string $table
     *
     * @throws DatabaseException
     *
     * @return bool
     */
    public function truncateTable(string $table): bool
    {
        $sql = 'TRUNCATE TABLE ' . $table;
        if ($this->configurator->getEngine() === 'sqlite') {
            $sql = 'DELETE FROM ' . $table;
        }

        return $this->exec($sql);
    }

    /**
     * @param array $tables
     *
     * @throws DatabaseException
     *
     * @return bool
     */
    public function truncateTables(array $tables): bool
    {
        $success = true;

        foreach ($tables as $table) {
            if ($this->truncateTable($table) === false) {
                $success = false;
            }
        }

        return $success;
    }

    /**
     * @param string $table
     *
     * @throws DatabaseException
     *
     * @return bool
     */
    public function dropTable(string $table): bool
    {
        return $this->dropTables([$table]);
    }

    /**
     * @param array $tables
     *
     * @throws DatabaseException
     *
     * @return bool
     */
    public function dropTables(array $tables): bool
    {
        $success = true;

        if ($this->configurator->getEngine() === 'sqlite') {
            foreach ($tables as $table) {
                $sql = 'DROP TABLE IF EXISTS ' . $table;
                if ($this->exec($sql) === false) {
                    $success = false;
                }
            }

            return $success;
        }

        $tables = \implode(',', $tables);

        $sql = 'DROP TABLE IF EXISTS ' . $tables;
        $success = $this->exec($sql);

        return $success;
    }

    /**
     * @param string $filepath
     *
     * @throws DatabaseException
     *
     * @return bool
     */
    public function useSqlFile(string $filepath): bool
    {
        if (!\file_exists($filepath)) {
            throw new DatabaseException('File missing for useSqlFile method: ' . $filepath);
        }

        $sqlFile = \file_get_contents($filepath);

        return $this->exec($sqlFile);
    }

    /**
     * @param float $startTime
     * @param float $endTime
     *
     * @return float
     */
    protected function getTime(float $startTime, float $endTime): float
    {
        return \round(($endTime - $startTime) * 1000000) / 1000000;
    }

    public function disconnect(): void
    {
        $this->pdo = null;
    }
}


<?php
/*
 * Copyright (c) 2014 @trashtoy
 * https://github.com/trashtoy/
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 * this software and associated documentation files (the "Software"), to deal in
 * the Software without restriction, including without limitation the rights to use,
 * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
 * Software, and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
/**
 * PHP class file.
 * @auhtor trashtoy
 * @since  2.0.0
 */
namespace Peach\DT;

/**
 * Unix time ({@link http://www.php.net/manual/function.time.php time()} の返り値や
 * {@link http://www.php.net/manual/function.date.php date()} の引数として使用される整数)
 * と時間オブジェクトの相互変換を行うクラスです.
 *
 * このクラスはシングルトンです. {@link UnixTimeFormat::getInstance()}
 * からオブジェクトを取得してください.
 */
class UnixTimeFormat implements Format
{
    /**
     * このクラスは getInstance() からインスタンス化します.
     */
    private function __construct() {}

    /**
     * このクラスのインスタンスを取得します.
     * @return UnixTimeFormat
     * @codeCoverageIgnore
     */
    public static function getInstance()
    {
        static $instance = null;
        if (!isset($instance)) {
            $instance = new self();
        }
        return $instance;
    }

    /**
     * 指定されたタイムスタンプを Date に変換します.
     *
     * @param  string $format タイムスタンプ
     * @return Date           変換結果
     */
    public function parseDate($format)
    {
        $time  = intval($format);
        $year  = date("Y", $time);
        $month = date("n", $time);
        $date  = date("d", $time);
        return new Date($year, $month, $date);
    }

    /**
     * 指定されたタイムスタンプを Datetime に変換します.
     *
     * @param  string $format タイムスタンプ
     * @return Datetime       変換結果
     */
    public function parseDatetime($format)
    {
        $time  = intval($format);
        $year  = date("Y", $time);
        $month = date("n", $time);
        $date  = date("d", $time);
        $hour  = date("H", $time);
        $min   = date("i", $time);
        return new Datetime($year, $month, $date, $hour, $min);
    }

    /**
     * 指定されたタイムスタンプを Timestamp に変換します.
     * @param  string $format タイムスタンプ
     * @return Timestamp      変換結果
     */
    public function parseTimestamp($format)
    {
        $time  = intval($format);
        $year  = date("Y", $time);
        $month = date("n", $time);
        $date  = date("d", $time);
        $hour  = date("H", $time);
        $min   = date("i", $time);
        $sec   = date("s", $time);
        return new Timestamp($year, $month, $date, $hour, $min, $sec);
    }

    /**
     * 指定されたオブジェクトを Timestamp 型にキャストして
     * {@link UnixTimeFormat::formatTimestamp()}
     * を実行した結果を返します.
     *
     * @param  Date $d 書式化する時間オブジェクト
     * @return string  指定された日付の 0 時 0 分 0 秒のタイムスタンプ
     */
    public function formatDate(Date $d)
    {
        return $this->formatTimestamp($d->toTimestamp());
    }

    /**
     * 指定されたオブジェクトを Timestamp 型にキャストして
     * {@link UnixTimeFormat::formatTimestamp()}
     * を実行した結果を返します.
     *
     * @param  Datetime $d 書式化する時間オブジェクト
     * @return string      指定された時刻の 0 秒のタイムスタンプ
     */
    public function formatDatetime(Datetime $d)
    {
        return $this->formatTimestamp($d->toTimestamp());
    }

    /**
     * 指定された時刻をタイムスタンプに変換します.
     *
     * このメソッドは、引数の Timestamp オブジェクトが持つ各フィールド
     * (年月日・時分秒) の値から {@link http://www.php.net/manual/function.mktime.php mktime()}
     * を行い, その結果を返り値とします.
     *
     * ただし, 返り値が string 型となることに注意してください.
     *
     * @param  Timestamp $d 書式化対象の時間オブジェクト
     * @return string       指定された時刻のタイムスタンプ
     */
    public function formatTimestamp(Timestamp $d)
    {
        $hour  = $d->get('hour');
        $min   = $d->get('minute');
        $sec   = $d->get('second');
        $month = $d->get('month');
        $date  = $d->get('date');
        $year  = $d->get('year');
        return strval(mktime($hour, $min, $sec, $month, $date, $year));
    }
}


<?php

/**
 * Client object
 *
 * @package    RpkUtils\Sysinfo
 * @author     Repkit <repkit@gmail.com>
 * @copyright  2015 Repkit
 * @license    MIT <http://opensource.org/licenses/MIT>
 * @since      2015-11-12
 */

 namespace RpkUtils\Sysinfo;

 class Client
 {
    /**
     * Client ip
     * @return string
     */
    public static function ip()
    {

        if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
          // check ip from share internet
          $ip = $_SERVER['HTTP_CLIENT_IP'];

        } elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
          // to check ip is pass from proxy
          $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];

        } elseif (!empty($_SERVER['REMOTE_ADDR'])) {

          $ip = $_SERVER['REMOTE_ADDR'];

        } else {

            $ip = '0.0.0.0';
        }

        return $ip;
    }
 }


<?php

namespace futuretek\shared;

/**
 * Class StopWords
 *
 * @package futuretek\shared
 * @author  Lukas Cerny <lukas.cerny@futuretek.cz>
 * @license Apache-2.0
 * @link    http://www.futuretek.cz
 */
class StopWords
{
    /**
     * Get stop-words list in array format
     *
     * @param string $language Language code (en, es, cs)
     * @return array
     */
    public static function getArray($language)
    {
        $fileName = __DIR__ . '/stop-words/' . $language . '.txt';
        if (file_exists($fileName)) {
            return array_map('trim', file($fileName));
        }

        return [];
    }

    /**
     * Get stop-words list in string format - separated by defined separator
     *
     * @param string $language Language code (en, es, cs)
     * @param string $separator word separator
     * @return string
     */
    public static function getString($language, $separator = ',')
    {
        $fileName = __DIR__ . '/stop-words/' . $language . '.txt';
        if (file_exists($fileName)) {
            return implode($separator, array_map('trim', file($fileName)));
        }

        return '';
    }
}


<?php
/**
 * Created by PhpStorm.
 * User: sicmouse
 * Date: 2018/9/3
 * Time: 下午7:55
 */

namespace DdvPhp\DdvRestfulApi\Lib;

use DdvPhp\DdvRestfulApi\Interfaces\AuthSign;
use DdvPhp\DdvRestfulApi\Interfaces\RequestSignInfo;
use DdvPhp\DdvRestfulApi\Interfaces\Auth as AuthInterface;
use DdvPhp\DdvRestfulApi\Exception\AuthError as AuthErrorException;

class Auth implements AuthInterface
{
    protected $authDataDriver = 'file';
    protected $authDataDriverConfig = array();
    /**
     * 授权前面类目录
     * @var array
     */
    protected $authSignClassNamespaces = array();
    /**
     * @var RequestSignInfo|null
     */
    protected $signInfo = null;
    /**
     * 授权版本
     * @var string|null
     */
    protected $version = null;
    /**
     * 授权内容
     * @var string|null
     */
    protected $authorization = null;
    /**
     * 授权具体版本的签名对象
     * @var AuthSign|null
     */
    protected $authSign = null;

    /**
     * 设置请求信息
     * @param RequestInfo $requestInfo
     * @return $this
     * @throws RJsonError
     */
    public function setRequestSignInfo(RequestSignInfo $signInfo)
    {
        if (isset($signInfo) && $signInfo instanceof RequestSignInfo) {
            $this->signInfo = $signInfo;
        } else {
            throw new RJsonError('requestInfo is wrong');
        }
        return $this;
    }

    /**
     * 获取授权数据
     * @param $sessionId
     * @return array
     */
    public function getAuthData($sessionId)
    {
        return $this->getAuthSign()->getAuthData($sessionId);
    }

    /**
     * 设置授权数据的存储
     * @param $sessionId
     * @param null $data
     * @return null
     */
    public function saveAuthData($sessionId, $data = null)
    {
        return $this->getAuthSign()->saveAuthData($sessionId, $data);
    }

    /**
     * 获取签名后的url
     * @param null $sessionId
     * @param string $path
     * @param array $query
     * @param array $noSignQuery
     * @param string $method
     * @param array $headers
     * @param null $authClassName
     * @return string
     */
    public function getSignUrl($sessionId = null, $path = '/', $query = array(), $noSignQuery = array(), $method = 'GET', $headers = array(), $authClassName = null)
    {
        return $this->getAuthSign()->getSignUrl($sessionId, $path, $query, $noSignQuery, $method, $headers, $authClassName);
    }

    /**
     * 对url进行签名
     * @param null $sessionId
     * @param string $url
     * @param array $noSignQuery
     * @param string $method
     * @param array $query
     * @param array $headers
     * @param null $authClassName
     * @return string
     */
    public function getSignUrlByUrl($sessionId = null, $url = '/', $noSignQuery = array(), $method = 'GET', $query = array(), $headers = array(), $authClassName = null)
    {
        return $this->getAuthSign()->getSignUrlByUrl($sessionId, $url, $noSignQuery, $method, $query, $headers, $authClassName);
    }

    public function sign()
    {
        $signInfo = $this->getRequestSignInfo();
        /**
         * 获取授权信息
         * 通过 authorization 头
         */
        $authorization = trim($signInfo->getAuthorization());
        /**
         * 试图查找/，判断是否是合法的授权信息
         */
        $start = strpos($authorization, '/');
        //没有找到就不合法
        if ($start === false) {
            throw new AuthErrorException('Authentication Format Error', 'AUTHENTICATION_FORMAT_ERROR', '403');
        }
        //提取版本
        $this->version = substr($authorization, 0, $start);
        //提取授权信息
        $this->authorization = substr($authorization, ($start + 1));
        if (empty($this->version)) {
            throw new AuthErrorException('Authentication Version Error', 'AUTHENTICATION_VERSION_ERROR', '403');
        } elseif (empty($this->authorization)) {
            throw new AuthErrorException('Authentication Info Error', 'AUTHENTICATION_INFO_ERROR', '403');
        }
        /**
         * 设置授权版本
         */
        // 中杠转驼峰
        $className = 'AuthSign' . ucfirst(preg_replace_callback(
                '(\-\w)',
                function ($matches) {
                    return strtoupper(substr($matches[0], 1));
                },
                $this->version
            ));
        /**
         * 强制是一个数组
         */
        if (!is_array($this->authSignClassNamespaces)) {
            $this->authSignClassDirs = array();
        }
        /**
         * 压入一个类前缀
         */
        $this->authSignClassNamespaces[] = '\\DdvPhp\\DdvRestfulApi\\Auth\\';
        /**
         * 循环查找存在的类
         */
        foreach ($this->authSignClassNamespaces as $namespace) {
            if (class_exists($namespace . $className)) {
                // 加入命名空间
                $className = $namespace . $className;
            }
        }
        /**
         * 判断这个是否找到
         */
        if (!class_exists($className)) {
            throw new AuthErrorException('Authentication Version Class Not Find', 'AUTHENTICATION_VERSION_CLASS_NOT_FIND', '403');
        }
        /**
         * 实例化该文件
         * @var $a2 授权信息
         * @var  授权信息
         * @var AuthSign $this ->authSign
         */
        $this->authSign = new $className($this);

        /**
         * 签名
         */
        $this->getAuthSign()->sign();
        //卸载
        unset($start, $authorization, $signInfo, $className, $authObj);
    }

    public function setConfig($config = array())
    {
        if (!empty($config['authDataDriver'])) {
            $this->authDataDriver = $config['authDataDriver'];
        }
        if (!empty($config['authDataDriverConfig'])) {
            $this->authDataDriverConfig = $config['authDataDriverConfig'];
        }
        if (empty($this->authDataDriverConfig)) {
            $this->authDataDriverConfig = array();
        }
    }

    /**
     * @return authSign
     * @throws AuthErrorException
     */
    public function getAuthSign()
    {
        if (isset($this->authSign) && $this->authSign instanceof AuthSign) {
            return $this->authSign;
        } else {
            throw new AuthErrorException('Auth authentication must be performed first', 'MUST_RUN_AUTH_VERIFICATION', 500);
        }
    }

    /**
     * 获取会话id
     * @return string
     * @throws AuthErrorException
     */
    public function getAccessKeyId()
    {
        return $this->getAuthSign()->getAccessKeyId();
    }
    /**
     * 获取会话id
     * @return string
     * @throws AuthErrorException
     */
    public function getSessionId()
    {
        return $this->getAccessKeyId();
    }

    /**
     * @return string
     */
    public function getAuthDataDriver()
    {
        return $this->authDataDriver;
    }

    /**
     * @return array
     */
    public function getAuthDataDriverConfig()
    {
        return $this->authDataDriverConfig;
    }

    /**
     * @return RequestSignInfo
     */
    public function getRequestSignInfo()
    {
        if ($this->signInfo instanceof RequestSignInfo) {
            return $this->signInfo;
        } else {
            throw new AuthErrorException('No RequestSignInfo instance', 'NO_REQUEST_SIGN_INFO_INSTANCE', 500);
        }
    }

    /**
     * 获取授权签名信息
     * @return null|string
     */
    public function getAuthorization()
    {
        if (empty($this->authorization)) {
            throw new AuthErrorException('Authentication Info Length Error', 'AUTHORIZATION_ERROR_INFO_LENGTH', 403);
        }
        return is_string($this->authorization) ? $this->authorization : '';
    }

    /**
     * 获取授权版本
     * @return null|string
     */
    public function getVersion()
    {
        return $this->version;
    }
}


<?php

namespace Miky\Bundle\UserBundle\Controller\Frontend;

use Miky\Bundle\AdBundle\Entity\Ad;
use Miky\Bundle\UserBundle\Entity\Customer;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;

class FavoriteController extends Controller
{
    /**
     * @return Response|RedirectResponse
     *
     * @throws AccessDeniedException
     */
    public function listFavoriteAdsAction()
    {
        $customer = $this->getUser();
        if (!is_object($customer) || !$customer instanceof Customer) {
            return $this->redirectToRoute("miky_app_home_index");
        }

        return $this->render('MikyUserBundle:Frontend/Favorite:list.html.twig', array(
            'ads' => $customer->getFavoriteAds(),
        ));
    }

    /**
     * @return Response|RedirectResponse
     *
     * @throws AccessDeniedException
     */
    public function removeFavoriteAdAction(Ad $ad)
    {
        $customer = $this->getUser();
        if (!is_object($customer) || !$customer instanceof Customer) {
            return $this->redirectToRoute("miky_app_home_index");
        }
        $customer->removeFavoriteAd($ad);
        $this->get("miky_customer_manager")->updateUser($customer);
        return $this->redirectToRoute("miky_app_favorite_ads_list");
    }

}


<?php
declare(strict_types=1);

namespace WyriHaximus\ApiClient\Tools;

use Aura\Cli\Context;
use Aura\Cli\Stdio;
use Doctrine\Common\Inflector\Inflector;
use Exception;
use PhpParser\Builder\Method;
use PhpParser\Builder\Property;
use PhpParser\BuilderFactory;
use PhpParser\PrettyPrinter;
use PhpParser\Node;
use Symfony\Component\Yaml\Yaml;
use Symfony\CS\Config\Config;
use Symfony\CS\ConfigAwareInterface;
use Symfony\CS\ConfigInterface;
use Symfony\CS\FileCacheManager;
use Symfony\CS\Fixer;
use Symfony\CS\FixerInterface;
use WyriHaximus\ApiClient\Annotations\Collection;
use WyriHaximus\ApiClient\Annotations\Nested;
use WyriHaximus\ApiClient\Annotations\Rename;
use WyriHaximus\ApiClient\Resource\ResourceInterface;

class ResourceGenerator
{
    /**
     * @var Context
     */
    protected $context;

    /**
     * @var Stdio
     */
    protected $stdio;

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

    /**
     * @var string
     */
    protected $path;

    /**
     * @var Fixer
     */
    protected $fixer;

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

    public function __construct(Context $context, Stdio $stdio)
    {
        $this->context = $context;
        $this->stdio = $stdio;

        $this->setUpArguments();
        $this->setUpFixers();
    }

    protected function setUpArguments()
    {
        $getOpt = $this->context->getopt([]);
        $i = 0;
        do {
            $i++;
            $opt = $getOpt->get($i);
            if ($opt === null) {
                break;
            }
            $this->definitions[] = $opt;
        } while (true);
        $this->path = array_pop($this->definitions);
    }

    protected function setUpFixers()
    {
        $this->fixer = new Fixer();
        $this->fixer->registerCustomFixers([
            new Fixer\Symfony\ExtraEmptyLinesFixer(),
            new Fixer\Symfony\SingleBlankLineBeforeNamespaceFixer(),
            new Fixer\PSR0\Psr0Fixer(),
            new Fixer\PSR1\EncodingFixer(),
            new Fixer\PSR1\ShortTagFixer(),
            new Fixer\PSR2\BracesFixer(),
            new Fixer\PSR2\ElseifFixer(),
            new Fixer\PSR2\EofEndingFixer(),
            new Fixer\PSR2\FunctionCallSpaceFixer(),
            new Fixer\PSR2\FunctionDeclarationFixer(),
            new Fixer\PSR2\IndentationFixer(),
            new Fixer\PSR2\LineAfterNamespaceFixer(),
            new Fixer\PSR2\LinefeedFixer(),
            new Fixer\PSR2\LowercaseConstantsFixer(),
            new Fixer\PSR2\LowercaseKeywordsFixer(),
            new Fixer\PSR2\MethodArgumentSpaceFixer(),
            new Fixer\PSR2\MultipleUseFixer(),
            new Fixer\PSR2\ParenthesisFixer(),
            new Fixer\PSR2\PhpClosingTagFixer(),
            new Fixer\PSR2\SingleLineAfterImportsFixer(),
            new Fixer\PSR2\TrailingSpacesFixer(),
            new Fixer\PSR2\VisibilityFixer(),
            new Fixer\Contrib\NewlineAfterOpenTagFixer(),
            new EmptyLineAboveDocblocksFixer(),
        ]);
        $config = Config::create()->
        fixers($this->fixer->getFixers())
        ;
        $this->fixer->addConfig($config);
        $this->fixers = $this->prepareFixers($config);
    }

    public function run()
    {
        $this->checkValidity();

        foreach ($this->definitions as $definition) {
            $this->stdio->outln('-----');
            $this->stdio->outln('- Definition: ' . $definition);
            $this->stdio->outln('-----');
            $this->generateFromDefinition($definition);
            $this->stdio->outln('-----');
        }
    }

    public function checkValidity()
    {
        if (count($this->definitions) < 1) {
            throw new \InvalidArgumentException('Not enough arguments');
        }

        if ($this->path === null) {
            throw new \InvalidArgumentException('No path set');
        }

        if (!file_exists($this->path)) {
            throw new \InvalidArgumentException('Path "' . $this->path . '" doesn\'t exist');
        }

        if (!is_dir($this->path)) {
            throw new \InvalidArgumentException('Path "' . $this->path . '" isn\'t a directory');
        }

        foreach ($this->definitions as $definition) {
            if (!file_exists($definition)) {
                throw new \InvalidArgumentException('Definition "' . $definition . '" doesn\'t exist');
            }
        }
    }

    public function generateFromDefinition(string $definition)
    {
        $yaml = $this->readYaml($definition);

        $namespacePadding = explode('\\', $yaml['class']);
        $namespace = explode('\\', $yaml['namespace']);

        $yaml['class'] = array_pop($namespacePadding);
        $yaml['namespace'] = implode('\\', array_merge($namespace, $namespacePadding));

        $namespacePathPadding = implode(DIRECTORY_SEPARATOR, $namespacePadding);
        $baseClass = implode(
            '\\',
            array_merge(
                $namespace,
                $namespacePadding,
                [
                    $yaml['class']
                ]
            )
        );

        if (isset($yaml['rename'])) {
            foreach ($yaml['rename'] as $key => $resource) {
                $yaml['properties'][$resource] = $yaml['properties'][$key];
                unset($yaml['properties'][$key]);
            }
        }

        $this->stdio->out('Interface: generating');
        $this->save(
            $this->path .
                DIRECTORY_SEPARATOR .
                $namespacePathPadding .
                DIRECTORY_SEPARATOR,
            $yaml['class'] .
                'Interface.php',
            $this->createInterface($yaml)
        );

        $this->stdio->out('Base class: generating');
        $this->save(
            $this->path .
                DIRECTORY_SEPARATOR .
                $namespacePathPadding .
                DIRECTORY_SEPARATOR,
            $yaml['class'] .
                '.php',
            $this->createBaseClass($yaml)
        );

        $this->stdio->out('Async class: generating');
        $this->save(
            $this->path .
                DIRECTORY_SEPARATOR .
                'Async' .
                DIRECTORY_SEPARATOR .
                $namespacePathPadding .
                DIRECTORY_SEPARATOR,
            $yaml['class'] .
                '.php',
            $this->createExtendingClass(
                implode(
                    '\\',
                    array_merge(
                        $namespace,
                        [
                            'Async',
                        ],
                        $namespacePadding
                    )
                ),
                $yaml['class'],
                $baseClass
            )
        );

        $this->stdio->out('Sync class: generating');
        $this->save(
            $this->path .
                DIRECTORY_SEPARATOR .
                'Sync' .
                DIRECTORY_SEPARATOR .
                $namespacePathPadding .
                DIRECTORY_SEPARATOR,
            $yaml['class'] .
                '.php',
            $this->createExtendingClass(
                implode(
                    '\\',
                    array_merge(
                        $namespace,
                        [
                            'Sync',
                        ],
                        $namespacePadding
                    )
                ),
                $yaml['class'],
                $baseClass
            )
        );
    }

    protected function readYaml(string $filename): array
    {
        return Yaml::parse(file_get_contents($filename));
    }

    protected function createBaseClass(array $yaml): string
    {
        $factory = new BuilderFactory;

        $class = $factory->class($yaml['class'])
            ->implement($yaml['class'] . 'Interface')
            ->makeAbstract();

        $docBlock = [];

        if (isset($yaml['collection'])) {
            $nestedResources = [];
            foreach ($yaml['collection'] as $key => $resource) {
                $nestedResources[] = $key . '="' . $resource . '"';
            }
            $docBlock[] = '@Collection(' . implode(', ', $nestedResources) . ')';
        }

        if (isset($yaml['nested'])) {
            $nestedResources = [];
            foreach ($yaml['nested'] as $key => $resource) {
                $nestedResources[] = $key . '="' . $resource . '"';
            }
            $docBlock[] = '@Nested(' . implode(', ', $nestedResources) . ')';
        }

        if (isset($yaml['rename'])) {
            $nestedResources = [];
            foreach ($yaml['rename'] as $key => $resource) {
                $nestedResources[] = $resource . '="' . $key . '"';
            }
            $docBlock[] = '@Rename(' . implode(', ', $nestedResources) . ')';
        }

        if (count($docBlock) > 0) {
            $class->setDocComment("/**\r\n * " . implode("\r\n * ", $docBlock) . "\r\n */");
        }

        $class->addStmt(
            new Node\Stmt\TraitUse([
                new Node\Name('TransportAwareTrait')
            ])
        );

        foreach ($yaml['properties'] as $name => $details) {
            $type = $details;
            if (is_array($details)) {
                $type = $details['type'];
            }
            $class->addStmt($this->createProperty($factory, $type, $name, $details));
            $class->addStmt($this->createMethod($factory, $type, $name, $details));
        }

        $stmt = $factory->namespace($yaml['namespace']);
        if (isset($yaml['collection'])) {
            $stmt = $stmt->addStmt(
                $factory->use(Collection::class)
            );
        }
        if (isset($yaml['nested'])) {
            $stmt = $stmt->addStmt(
                $factory->use(Nested::class)
            );
        }
        if (isset($yaml['rename'])) {
            $stmt = $stmt->addStmt(
                $factory->use(Rename::class)
            );
        }
        $stmt
            ->addStmt($factory->use('WyriHaximus\ApiClient\Resource\TransportAwareTrait'))
            ->addStmt($class)
        ;

        $node = $stmt->getNode();

        $prettyPrinter = new PrettyPrinter\Standard();
        return $prettyPrinter->prettyPrintFile([
            $node
        ]) . PHP_EOL;
    }

    protected function createInterface(array $yaml): string
    {
        $factory = new BuilderFactory;

        $class = $factory->interface($yaml['class'] . 'Interface')
            ->extend('ResourceInterface');

        foreach ($yaml['properties'] as $name => $details) {
            $type = $details;
            if (is_array($details)) {
                $type = $details['type'];
            }
            $class->addStmt($this->createMethod($factory, $type, $name, $details));
        }

        $node = $factory->namespace($yaml['namespace'])
            ->addStmt($factory->use(ResourceInterface::class))
            ->addStmt($class)
            ->getNode()
        ;

        $prettyPrinter = new PrettyPrinter\Standard();
        return $prettyPrinter->prettyPrintFile([
            $node
        ]) . PHP_EOL;
    }

    protected function createProperty(BuilderFactory $factory, string $type, string $name, $details): Property
    {
        $property = $factory->property($name)
            ->makeProtected()
            ->setDocComment('/**
                              * @var ' . $type . '
                              */');
        if (isset($details['default'])) {
            $property->setDefault($details['default']);
        }

        return $property;
    }

    protected function createMethod(BuilderFactory $factory, string $type, string $name, $details): Method
    {
        return $factory->method(Inflector::camelize($name))
            ->makePublic()
            ->setReturnType($type)
            ->setDocComment('/**
                              * @return ' . $type . '
                              */')
            ->addStmt(
                new Node\Stmt\Return_(
                    new Node\Expr\PropertyFetch(
                        new Node\Expr\Variable('this'),
                        $name
                    )
                )
            );
    }

    protected function createExtendingClass(string $namespace, string $className, string $baseClass): string
    {
        $factory = new BuilderFactory;

        $class = $factory->class($className)
            ->extend('Base' . $className);

        $class->addStmt($factory->method('refresh')
            ->makePublic()
            ->setReturnType($className)
            ->addStmt(
                new Node\Stmt\Return_(
                    new Node\Expr\MethodCall(
                        new Node\Expr\Variable('this'),
                        'wait',
                        [
                            new Node\Expr\MethodCall(
                                new Node\Expr\Variable('this'),
                                'callAsync',
                                [
                                    new Node\Scalar\String_('refresh'),
                                ]
                            ),
                        ]
                    )
                )
            ));

        $node = $factory->namespace($namespace)
            ->addStmt($factory->use($baseClass)->as('Base' . $className))
            ->addStmt($class)

            ->getNode()
        ;

        $prettyPrinter = new PrettyPrinter\Standard();
        return $prettyPrinter->prettyPrintFile([
            $node
        ]) . PHP_EOL;
    }

    protected function save(string $directory, string $fileName, string $fileContents)
    {
        $fileName = str_replace('\\', DIRECTORY_SEPARATOR, $fileName);
        if (file_exists($directory . $fileName)) {
            $this->stdio->outln(', exists!');
            return;
        }

        $path = $directory . $fileName;
        $pathChunks = explode(DIRECTORY_SEPARATOR, $path);
        array_pop($pathChunks);
        $path = implode(DIRECTORY_SEPARATOR, $pathChunks);
        if (!file_exists($path)) {
            mkdir($path, 0777, true);
        }

        if (!file_exists($path)) {
            throw new Exception('Unable to create: ' . $path);
        }

        $this->stdio->out(', writing');
        file_put_contents($directory . $fileName, $fileContents);

        do {
            usleep(500);
        } while (!file_exists($directory . $fileName));

        $this->stdio->out(', applying PSR-2');
        $this->applyPsr2($directory . $fileName);
        $this->stdio->outln(', done!');
    }

    /**
     * @param string $fileName
     */
    protected function applyPsr2($fileName)
    {
        $file = new \SplFileInfo($fileName);
        $this->fixer->fixFile(
            $file,
            $this->fixers,
            false,
            false,
            new FileCacheManager(
                false,
                '',
                $this->fixers
            )
        );

        file_put_contents(
            $fileName,
            str_replace(
                '<?php',
                '<?php declare(strict_types=1);',
                file_get_contents(
                    $fileName
                )
            )
        );
    }

    /**
     * @param ConfigInterface $config
     *
     * @return FixerInterface[]
     */
    private function prepareFixers(ConfigInterface $config): array
    {
        $fixers = $config->getFixers();

        foreach ($fixers as $fixer) {
            if ($fixer instanceof ConfigAwareInterface) {
                $fixer->setConfig($config);
            }
        }

        return $fixers;
    }
}


<?php

namespace CoRex\Support\System\Console;

use CoRex\Support\Str;

class Table
{
    private $headers;
    private $columns;
    private $widths;
    private $rows;

    private $charCross = '+';
    private $charHorizontal = '-';
    private $charVertical = '|';

    /**
     * Table constructor.
     */
    public function __construct()
    {
        $this->headers = [];
        $this->columns = [];
        $this->widths = [];
        $this->rows = [];
    }

    /**
     * Set headers.
     *
     * @param array $headers
     */
    public function setHeaders(array $headers)
    {
        $columnNumber = 0;
        foreach ($headers as $header) {
            $this->updateWidth($columnNumber, $this->length($header));
            if (!in_array($header, $this->headers)) {
                $this->headers[] = $header;
            }
            $columnNumber++;
        }
    }

    /**
     * Set rows.
     *
     * @param array $rows
     */
    public function setRows(array $rows)
    {
        foreach ($rows as $row) {
            $columnNumber = 0;
            if (!is_array($row)) {
                $row = [$row];
            }
            foreach ($row as $column => $value) {
                $this->updateWidth($columnNumber, $this->length($column));
                $this->updateWidth($columnNumber, $this->length($value));
                if (!in_array($column, $this->columns)) {
                    $this->columns[] = $column;
                }
                $columnNumber++;
            }
            $this->rows[] = $row;
        }
    }

    /**
     * Render table.
     *
     * @return string
     */
    public function render()
    {
        $output = [];

        // Top.
        if (count($this->rows) > 0) {
            $output[] = $this->renderLine();
        }

        // Headers.
        if (count($this->columns) > 0) {
            $line = [];
            $line[] = $this->charVertical;
            $columnNumber = 0;
            foreach ($this->columns as $index => $column) {
                $title = $column;
                if (isset($this->headers[$index])) {
                    $title = $this->headers[$index];
                }
                $line[] = $this->renderCell($columnNumber, $title, ' ', 'info');
                $line[] = $this->charVertical;
                $columnNumber++;
            }
            $output[] = implode('', $line);
        }

        // Body.
        if (count($this->rows) > 0) {

            // Middle.
            $output[] = $this->renderLine();

            // Rows.
            foreach ($this->rows as $row) {
                $output[] = $this->renderRow($row);
            }

            // Footer
            $output[] = $this->renderLine();
        }

        return implode("\n", $output);
    }

    /**
     * Render line.
     *
     * @return string
     */
    private function renderLine()
    {
        $output = [];
        $output[] = $this->charCross;
        if (count($this->columns) > 0) {
            for ($columnNumber = 0; $columnNumber < count($this->columns); $columnNumber++) {
                $output[] = $this->renderCell($columnNumber, $this->charHorizontal, $this->charHorizontal);
                $output[] = $this->charCross;
            }
        }
        return implode('', $output);
    }

    /**
     * Render row.
     *
     * @param array $row
     * @return string
     */
    private function renderRow(array $row)
    {
        $output = [];
        $output[] = $this->charVertical;
        $columnNumber = 0;
        foreach ($row as $column => $value) {
            $output[] = $this->renderCell($columnNumber, $value, ' ');
            $output[] = $this->charVertical;
            $columnNumber++;
        }
        return implode('', $output);
    }

    /**
     * Render cell.
     *
     * @param integer $columnNumber
     * @param string $value
     * @param string $filler
     * @param string $style Default ''.
     * @return string
     */
    private function renderCell($columnNumber, $value, $filler, $style = '')
    {
        $output = [];
        $width = $this->getWidth($columnNumber);
        $output[] = $filler;
        while ($this->length($value) < $width) {
            $value .= $filler;
        }
        $output[] = Style::applyStyle($value, $style);
        $output[] = $filler;
        return implode('', $output);
    }

    /**
     * Get width of column.
     *
     * @param integer $columnNumber
     * @return integer
     */
    private function getWidth($columnNumber)
    {
        if (isset($this->widths[$columnNumber])) {
            return $this->widths[$columnNumber];
        }
        return 0;
    }

    /**
     * Update width.
     *
     * @param integer $columnNumber
     * @param integer $width
     */
    private function updateWidth($columnNumber, $width)
    {
        if ($width > $this->getWidth($columnNumber)) {
            $this->widths[$columnNumber] = $width;
        }
    }

    /**
     * Length.
     *
     * @param string $string
     * @return integer
     */
    private function length($string)
    {
        $string = preg_replace("/\033\[[^m]*m/", '', $string);
        return Str::length($string);
    }
}