<?php
/**
 * File/Directory manipulation
 *
 * PHP versions 4 and 5
 *
 * @category   pear
 * @package    System
 * @author     Tomas V.V.Cox <cox@idecnet.com>
 * @copyright  1997-2009 The Authors
 * @license    http://opensource.org/licenses/bsd-license.php New BSD License
 * @version    CVS: $Id: System.php 313024 2011-07-06 19:51:24Z dufuz $
 * @link       http://pear.php.net/package/PEAR
 * @since      File available since Release 0.1
 */

/**
 * base class
 */
require_once 'PEAR.php';
require_once 'Console/Getopt.php';

$GLOBALS['_System_temp_files'] = array();

/**
* System offers cross plattform compatible system functions
*
* Static functions for different operations. Should work under
* Unix and Windows. The names and usage has been taken from its respectively
* GNU commands. The functions will return (bool) false on error and will
* trigger the error with the PHP trigger_error() function (you can silence
* the error by prefixing a '@' sign after the function call, but this
* is not recommended practice.  Instead use an error handler with
* {@link set_error_handler()}).
*
* Documentation on this class you can find in:
* http://pear.php.net/manual/
*
* Example usage:
* if (!@System::rm('-r file1 dir1')) {
*    print "could not delete file1 or dir1";
* }
*
* In case you need to to pass file names with spaces,
* pass the params as an array:
*
* System::rm(array('-r', $file1, $dir1));
*
* @category   pear
* @package    System
* @author     Tomas V.V. Cox <cox@idecnet.com>
* @copyright  1997-2006 The PHP Group
* @license    http://opensource.org/licenses/bsd-license.php New BSD License
* @version    Release: 1.9.4
* @link       http://pear.php.net/package/PEAR
* @since      Class available since Release 0.1
* @static
*/
class System
{
    /**
     * returns the commandline arguments of a function
     *
     * @param    string  $argv           the commandline
     * @param    string  $short_options  the allowed option short-tags
     * @param    string  $long_options   the allowed option long-tags
     * @return   array   the given options and there values
     * @static
     * @access private
     */
    function _parseArgs($argv, $short_options, $long_options = null)
    {
        if (!is_array($argv) && $argv !== null) {
            // Find all items, quoted or otherwise
            preg_match_all("/(?:[\"'])(.*?)(?:['\"])|([^\s]+)/", $argv, $av);
            $argv = $av[1];
            foreach ($av[2] as $k => $a) {
                if (empty($a)) {
                    continue;
                }
                $argv[$k] = trim($a) ;
            }
        }
        return Console_Getopt::getopt2($argv, $short_options, $long_options);
    }

    /**
     * Output errors with PHP trigger_error(). You can silence the errors
     * with prefixing a "@" sign to the function call: @System::mkdir(..);
     *
     * @param mixed $error a PEAR error or a string with the error message
     * @return bool false
     * @static
     * @access private
     */
    function raiseError($error)
    {
        if (PEAR::isError($error)) {
            $error = $error->getMessage();
        }
        trigger_error($error, E_USER_WARNING);
        return false;
    }

    /**
     * Creates a nested array representing the structure of a directory
     *
     * System::_dirToStruct('dir1', 0) =>
     *   Array
     *    (
     *    [dirs] => Array
     *        (
     *            [0] => dir1
     *        )
     *
     *    [files] => Array
     *        (
     *            [0] => dir1/file2
     *            [1] => dir1/file3
     *        )
     *    )
     * @param    string  $sPath      Name of the directory
     * @param    integer $maxinst    max. deep of the lookup
     * @param    integer $aktinst    starting deep of the lookup
     * @param    bool    $silent     if true, do not emit errors.
     * @return   array   the structure of the dir
     * @static
     * @access   private
     */
    function _dirToStruct($sPath, $maxinst, $aktinst = 0, $silent = false)
    {
        $struct = array('dirs' => array(), 'files' => array());
        if (($dir = @opendir($sPath)) === false) {
            if (!$silent) {
                System::raiseError("Could not open dir $sPath");
            }
            return $struct; // XXX could not open error
        }

        $struct['dirs'][] = $sPath = realpath($sPath); // XXX don't add if '.' or '..' ?
        $list = array();
        while (false !== ($file = readdir($dir))) {
            if ($file != '.' && $file != '..') {
                $list[] = $file;
            }
        }

        closedir($dir);
        natsort($list);
        if ($aktinst < $maxinst || $maxinst == 0) {
            foreach ($list as $val) {
                $path = $sPath . DIRECTORY_SEPARATOR . $val;
                if (is_dir($path) && !is_link($path)) {
                    $tmp    = System::_dirToStruct($path, $maxinst, $aktinst+1, $silent);
                    $struct = array_merge_recursive($struct, $tmp);
                } else {
                    $struct['files'][] = $path;
                }
            }
        }

        return $struct;
    }

    /**
     * Creates a nested array representing the structure of a directory and files
     *
     * @param    array $files Array listing files and dirs
     * @return   array
     * @static
     * @see System::_dirToStruct()
     */
    function _multipleToStruct($files)
    {
        $struct = array('dirs' => array(), 'files' => array());
        settype($files, 'array');
        foreach ($files as $file) {
            if (is_dir($file) && !is_link($file)) {
                $tmp    = System::_dirToStruct($file, 0);
                $struct = array_merge_recursive($tmp, $struct);
            } else {
                if (!in_array($file, $struct['files'])) {
                    $struct['files'][] = $file;
                }
            }
        }
        return $struct;
    }

    /**
     * The rm command for removing files.
     * Supports multiple files and dirs and also recursive deletes
     *
     * @param    string  $args   the arguments for rm
     * @return   mixed   PEAR_Error or true for success
     * @static
     * @access   public
     */
    function rm($args)
    {
        $opts = System::_parseArgs($args, 'rf'); // "f" does nothing but I like it :-)
        if (PEAR::isError($opts)) {
            return System::raiseError($opts);
        }
        foreach ($opts[0] as $opt) {
            if ($opt[0] == 'r') {
                $do_recursive = true;
            }
        }
        $ret = true;
        if (isset($do_recursive)) {
            $struct = System::_multipleToStruct($opts[1]);
            foreach ($struct['files'] as $file) {
                if (!@unlink($file)) {
                    $ret = false;
                }
            }

            rsort($struct['dirs']);
            foreach ($struct['dirs'] as $dir) {
                if (!@rmdir($dir)) {
                    $ret = false;
                }
            }
        } else {
            foreach ($opts[1] as $file) {
                $delete = (is_dir($file)) ? 'rmdir' : 'unlink';
                if (!@$delete($file)) {
                    $ret = false;
                }
            }
        }
        return $ret;
    }

    /**
     * Make directories.
     *
     * The -p option will create parent directories
     * @param    string  $args    the name of the director(y|ies) to create
     * @return   bool    True for success
     * @static
     * @access   public
     */
    function mkDir($args)
    {
        $opts = System::_parseArgs($args, 'pm:');
        if (PEAR::isError($opts)) {
            return System::raiseError($opts);
        }

        $mode = 0777; // default mode
        foreach ($opts[0] as $opt) {
            if ($opt[0] == 'p') {
                $create_parents = true;
            } elseif ($opt[0] == 'm') {
                // if the mode is clearly an octal number (starts with 0)
                // convert it to decimal
                if (strlen($opt[1]) && $opt[1]{0} == '0') {
                    $opt[1] = octdec($opt[1]);
                } else {
                    // convert to int
                    $opt[1] += 0;
                }
                $mode = $opt[1];
            }
        }

        $ret = true;
        if (isset($create_parents)) {
            foreach ($opts[1] as $dir) {
                $dirstack = array();
                while ((!file_exists($dir) || !is_dir($dir)) &&
                        $dir != DIRECTORY_SEPARATOR) {
                    array_unshift($dirstack, $dir);
                    $dir = dirname($dir);
                }

                while ($newdir = array_shift($dirstack)) {
                    if (!is_writeable(dirname($newdir))) {
                        $ret = false;
                        break;
                    }

                    if (!mkdir($newdir, $mode)) {
                        $ret = false;
                    }
                }
            }
        } else {
            foreach($opts[1] as $dir) {
                if ((@file_exists($dir) || !is_dir($dir)) && !mkdir($dir, $mode)) {
                    $ret = false;
                }
            }
        }

        return $ret;
    }

    /**
     * Concatenate files
     *
     * Usage:
     * 1) $var = System::cat('sample.txt test.txt');
     * 2) System::cat('sample.txt test.txt > final.txt');
     * 3) System::cat('sample.txt test.txt >> final.txt');
     *
     * Note: as the class use fopen, urls should work also (test that)
     *
     * @param    string  $args   the arguments
     * @return   boolean true on success
     * @static
     * @access   public
     */
    function &cat($args)
    {
        $ret = null;
        $files = array();
        if (!is_array($args)) {
            $args = preg_split('/\s+/', $args, -1, PREG_SPLIT_NO_EMPTY);
        }

        $count_args = count($args);
        for ($i = 0; $i < $count_args; $i++) {
            if ($args[$i] == '>') {
                $mode = 'wb';
                $outputfile = $args[$i+1];
                break;
            } elseif ($args[$i] == '>>') {
                $mode = 'ab+';
                $outputfile = $args[$i+1];
                break;
            } else {
                $files[] = $args[$i];
            }
        }
        $outputfd = false;
        if (isset($mode)) {
            if (!$outputfd = fopen($outputfile, $mode)) {
                $err = System::raiseError("Could not open $outputfile");
                return $err;
            }
            $ret = true;
        }
        foreach ($files as $file) {
            if (!$fd = fopen($file, 'r')) {
                System::raiseError("Could not open $file");
                continue;
            }
            while ($cont = fread($fd, 2048)) {
                if (is_resource($outputfd)) {
                    fwrite($outputfd, $cont);
                } else {
                    $ret .= $cont;
                }
            }
            fclose($fd);
        }
        if (is_resource($outputfd)) {
            fclose($outputfd);
        }
        return $ret;
    }

    /**
     * Creates temporary files or directories. This function will remove
     * the created files when the scripts finish its execution.
     *
     * Usage:
     *   1) $tempfile = System::mktemp("prefix");
     *   2) $tempdir  = System::mktemp("-d prefix");
     *   3) $tempfile = System::mktemp();
     *   4) $tempfile = System::mktemp("-t /var/tmp prefix");
     *
     * prefix -> The string that will be prepended to the temp name
     *           (defaults to "tmp").
     * -d     -> A temporary dir will be created instead of a file.
     * -t     -> The target dir where the temporary (file|dir) will be created. If
     *           this param is missing by default the env vars TMP on Windows or
     *           TMPDIR in Unix will be used. If these vars are also missing
     *           c:\windows\temp or /tmp will be used.
     *
     * @param   string  $args  The arguments
     * @return  mixed   the full path of the created (file|dir) or false
     * @see System::tmpdir()
     * @static
     * @access  public
     */
    function mktemp($args = null)
    {
        static $first_time = true;
        $opts = System::_parseArgs($args, 't:d');
        if (PEAR::isError($opts)) {
            return System::raiseError($opts);
        }

        foreach ($opts[0] as $opt) {
            if ($opt[0] == 'd') {
                $tmp_is_dir = true;
            } elseif ($opt[0] == 't') {
                $tmpdir = $opt[1];
            }
        }

        $prefix = (isset($opts[1][0])) ? $opts[1][0] : 'tmp';
        if (!isset($tmpdir)) {
            $tmpdir = System::tmpdir();
        }

        if (!System::mkDir(array('-p', $tmpdir))) {
            return false;
        }

        $tmp = tempnam($tmpdir, $prefix);
        if (isset($tmp_is_dir)) {
            unlink($tmp); // be careful possible race condition here
            if (!mkdir($tmp, 0700)) {
                return System::raiseError("Unable to create temporary directory $tmpdir");
            }
        }

        $GLOBALS['_System_temp_files'][] = $tmp;
        if (isset($tmp_is_dir)) {
            //$GLOBALS['_System_temp_files'][] = dirname($tmp);
        }

        if ($first_time) {
            PEAR::registerShutdownFunc(array('System', '_removeTmpFiles'));
            $first_time = false;
        }

        return $tmp;
    }

    /**
     * Remove temporary files created my mkTemp. This function is executed
     * at script shutdown time
     *
     * @static
     * @access private
     */
    function _removeTmpFiles()
    {
        if (count($GLOBALS['_System_temp_files'])) {
            $delete = $GLOBALS['_System_temp_files'];
            array_unshift($delete, '-r');
            System::rm($delete);
            $GLOBALS['_System_temp_files'] = array();
        }
    }

    /**
     * Get the path of the temporal directory set in the system
     * by looking in its environments variables.
     * Note: php.ini-recommended removes the "E" from the variables_order setting,
     * making unavaible the $_ENV array, that s why we do tests with _ENV
     *
     * @static
     * @return string The temporary directory on the system
     */
    function tmpdir()
    {
        if (OS_WINDOWS) {
            if ($var = isset($_ENV['TMP']) ? $_ENV['TMP'] : getenv('TMP')) {
                return $var;
            }
            if ($var = isset($_ENV['TEMP']) ? $_ENV['TEMP'] : getenv('TEMP')) {
                return $var;
            }
            if ($var = isset($_ENV['USERPROFILE']) ? $_ENV['USERPROFILE'] : getenv('USERPROFILE')) {
                return $var;
            }
            if ($var = isset($_ENV['windir']) ? $_ENV['windir'] : getenv('windir')) {
                return $var;
            }
            return getenv('SystemRoot') . '\temp';
        }
        if ($var = isset($_ENV['TMPDIR']) ? $_ENV['TMPDIR'] : getenv('TMPDIR')) {
            return $var;
        }
        return realpath('/tmp');
    }

    /**
     * The "which" command (show the full path of a command)
     *
     * @param string $program The command to search for
     * @param mixed  $fallback Value to return if $program is not found
     *
     * @return mixed A string with the full path or false if not found
     * @static
     * @author Stig Bakken <ssb@php.net>
     */
    function which($program, $fallback = false)
    {
        // enforce API
        if (!is_string($program) || '' == $program) {
            return $fallback;
        }

        // full path given
        if (basename($program) != $program) {
            $path_elements[] = dirname($program);
            $program = basename($program);
        } else {
            // Honor safe mode
            if (!ini_get('safe_mode') || !$path = ini_get('safe_mode_exec_dir')) {
                $path = getenv('PATH');
                if (!$path) {
                    $path = getenv('Path'); // some OSes are just stupid enough to do this
                }
            }
            $path_elements = explode(PATH_SEPARATOR, $path);
        }

        if (OS_WINDOWS) {
            $exe_suffixes = getenv('PATHEXT')
                                ? explode(PATH_SEPARATOR, getenv('PATHEXT'))
                                : array('.exe','.bat','.cmd','.com');
            // allow passing a command.exe param
            if (strpos($program, '.') !== false) {
                array_unshift($exe_suffixes, '');
            }
            // is_executable() is not available on windows for PHP4
            $pear_is_executable = (function_exists('is_executable')) ? 'is_executable' : 'is_file';
        } else {
            $exe_suffixes = array('');
            $pear_is_executable = 'is_executable';
        }

        foreach ($exe_suffixes as $suff) {
            foreach ($path_elements as $dir) {
                $file = $dir . DIRECTORY_SEPARATOR . $program . $suff;
                if (@$pear_is_executable($file)) {
                    return $file;
                }
            }
        }
        return $fallback;
    }

    /**
     * The "find" command
     *
     * Usage:
     *
     * System::find($dir);
     * System::find("$dir -type d");
     * System::find("$dir -type f");
     * System::find("$dir -name *.php");
     * System::find("$dir -name *.php -name *.htm*");
     * System::find("$dir -maxdepth 1");
     *
     * Params implmented:
     * $dir            -> Start the search at this directory
     * -type d         -> return only directories
     * -type f         -> return only files
     * -maxdepth <n>   -> max depth of recursion
     * -name <pattern> -> search pattern (bash style). Multiple -name param allowed
     *
     * @param  mixed Either array or string with the command line
     * @return array Array of found files
     * @static
     *
     */
    function find($args)
    {
        if (!is_array($args)) {
            $args = preg_split('/\s+/', $args, -1, PREG_SPLIT_NO_EMPTY);
        }
        $dir = realpath(array_shift($args));
        if (!$dir) {
            return array();
        }
        $patterns = array();
        $depth = 0;
        $do_files = $do_dirs = true;
        $args_count = count($args);
        for ($i = 0; $i < $args_count; $i++) {
            switch ($args[$i]) {
                case '-type':
                    if (in_array($args[$i+1], array('d', 'f'))) {
                        if ($args[$i+1] == 'd') {
                            $do_files = false;
                        } else {
                            $do_dirs = false;
                        }
                    }
                    $i++;
                    break;
                case '-name':
                    $name = preg_quote($args[$i+1], '#');
                    // our magic characters ? and * have just been escaped,
                    // so now we change the escaped versions to PCRE operators
                    $name = strtr($name, array('\?' => '.', '\*' => '.*'));
                    $patterns[] = '('.$name.')';
                    $i++;
                    break;
                case '-maxdepth':
                    $depth = $args[$i+1];
                    break;
            }
        }
        $path = System::_dirToStruct($dir, $depth, 0, true);
        if ($do_files && $do_dirs) {
            $files = array_merge($path['files'], $path['dirs']);
        } elseif ($do_dirs) {
            $files = $path['dirs'];
        } else {
            $files = $path['files'];
        }
        if (count($patterns)) {
            $dsq = preg_quote(DIRECTORY_SEPARATOR, '#');
            $pattern = '#(^|'.$dsq.')'.implode('|', $patterns).'($|'.$dsq.')#';
            $ret = array();
            $files_count = count($files);
            for ($i = 0; $i < $files_count; $i++) {
                // only search in the part of the file below the current directory
                $filepart = basename($files[$i]);
                if (preg_match($pattern, $filepart)) {
                    $ret[] = $files[$i];
                }
            }
            return $ret;
        }
        return $files;
    }
}


<?php

namespace QCharts\CoreBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * ChartConfig
 *
 * @ORM\Table()
 * @ORM\Entity
 */
class ChartConfig
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(name="typeOfChart", type="string", length=255)
     */
    private $typeOfChart;

    /**
     * @var integer
     * @ORM\Column(name="queryLimit", type="integer")
     */
    private $queryLimit;

    /**
     * @var float
     * @ORM\Column(name="executionLimit", type="float")
     */
    private $executionLimit;

    /**
     * @var integer
     * @ORM\Column(name="offset", type="integer")
     */
    private $offset;

    /**
     * @var string
     * @ORM\Column(name="connection", type="string", length=255)
     */
    private $databaseConnection;

    /**
     * @var integer
     * @ORM\Column(name="cached", type="smallint")
     */
    private $isCached;

    /**
     * @var \DateTime
     * @ORM\Column(name="fetched_on", type="datetimetz", nullable=true)
     */
    private $fetchedOn;

    /**
     * ChartConfig constructor.
     */
    public function __construct()
    {
        $this->fetchedOn = new \DateTime('now');
    }

    /**
     * Get id
     *
     * @return integer
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set typeOfChart
     *
     * @param string $typeOfChart
     *
     * @return ChartConfig
     */
    public function setTypeOfChart($typeOfChart)
    {
        $this->typeOfChart = $typeOfChart;

        return $this;
    }

    /**
     * Get typeOfChart
     *
     * @return string
     */
    public function getTypeOfChart()
    {
        return $this->typeOfChart;
    }

    /**
     * Set queryLimit
     *
     * @param integer $queryLimit
     *
     * @return ChartConfig
     */
    public function setQueryLimit($queryLimit)
    {
        $this->queryLimit = $queryLimit;

        return $this;
    }

    /**
     * Get queryLimit
     *
     * @return integer
     */
    public function getQueryLimit()
    {
        return $this->queryLimit;
    }

    /**
     * Set executionLimit
     *
     * @param float $executionLimit
     *
     * @return ChartConfig
     */
    public function setExecutionLimit($executionLimit)
    {
        $this->executionLimit = $executionLimit;

        return $this;
    }

    /**
     * Get executionLimit
     *
     * @return float
     */
    public function getExecutionLimit()
    {
        return $this->executionLimit;
    }

    /**
     * Set offset
     *
     * @param integer $offset
     *
     * @return ChartConfig
     */
    public function setOffset($offset)
    {
        $this->offset = $offset;

        return $this;
    }

    /**
     * Get offset
     *
     * @return integer
     */
    public function getOffset()
    {
        return $this->offset;
    }

    /**
     * Set databaseConnection
     *
     * @param string $databaseConnection
     *
     * @return ChartConfig
     */
    public function setDatabaseConnection($databaseConnection)
    {
        $this->databaseConnection = $databaseConnection;

        return $this;
    }

    /**
     * Get databaseConnection
     *
     * @return string
     */
    public function getDatabaseConnection()
    {
        return $this->databaseConnection;
    }

    /**
     * Set isCached
     *
     * @param integer $isCached
     *
     * @return ChartConfig
     */
    public function setIsCached($isCached = false)
    {
        $this->isCached = $isCached;

        return $this;
    }

    /**
     * Get isCached
     *
     * @return integer
     */
    public function getIsCached()
    {
        return $this->isCached;
    }

    /**
     * Set fetchedOn
     *
     * @param \DateTime $fetchedOn
     *
     * @return ChartConfig
     */
    public function setFetchedOn($fetchedOn = null)
    {
        if (!is_null($fetchedOn))
        {
            $this->fetchedOn = $fetchedOn;
            return $this;
        }
        $this->fetchedOn = new \DateTime('now');
        return $this;
    }

    /**
     * Get fetchedOn
     *
     * @return \DateTime
     */
    public function getFetchedOn()
    {
        return $this->fetchedOn;
    }
}


<?php

namespace Bavix\Lumper;

use Bavix\Slice\Slice;

class Lumper
{

    /**
     * @var []
     */
    protected $instances = [];

    /**
     * @param callable $callback
     *
     * @return string
     */
    protected function _string(callable $callback)
    {
        return new Reflection\Func($callback);
    }

    /**
     * @param callable $callback
     * @param string   $hash
     *
     * @return string
     */
    protected function _unique(callable $callback, $hash)
    {
        if (null === $hash || $hash instanceof Slice)
        {
            $hash .= $this->_string($callback);
        }

        return $hash;
    }

    /**
     * @param callable $callback
     * @param string   $unique
     *
     * @return mixed
     */
    public function once(callable $callback, $unique = null)
    {
        $_ = (string)$this->_unique($callback, $unique);

        if (empty($this->instances[$_]))
        {
            $this->instances[$_] =
                $unique instanceof Slice ?
                    $callback($unique) :
                    $callback();
        }

        return $this->instances[$_];
    }

}


<?php

namespace Reaction\Widgets\Bootstrap;

use Reaction\Helpers\Html;
use Reaction\Exceptions\InvalidConfigException;
use Reaction\Helpers\ArrayHelper;

/**
 * Carousel renders a carousel bootstrap javascript component.
 *
 * For example:
 *
 * ```php
 * echo Carousel::widget([
 *     'app' => $this->app,
 *     'items' => [
 *         // the item contains only the image
 *         '<img src="http://twitter.github.io/bootstrap/assets/img/bootstrap-mdo-sfmoma-01.jpg"/>',
 *         // equivalent to the above
 *         ['content' => '<img src="http://twitter.github.io/bootstrap/assets/img/bootstrap-mdo-sfmoma-02.jpg"/>'],
 *         // the item contains both the image and the caption
 *         [
 *             'content' => '<img src="http://twitter.github.io/bootstrap/assets/img/bootstrap-mdo-sfmoma-03.jpg"/>',
 *             'caption' => '<h4>This is title</h4><p>This is the caption text</p>',
 *             'options' => [...],
 *         ],
 *     ]
 * ]);
 * ```
 */
class Carousel extends Widget
{
    /**
     * @var array|boolean the labels for the previous and the next control buttons.
     * If false, it means the previous and the next control buttons should not be displayed.
     */
    public $controls = [];
    /**
     * @var array the text labels for the previous and the next control buttons.
     */
    public $controlsLabels = ['Previous', 'Next'];
    /**
     * @var boolean
     * If false carousel indicators (<ol> tag with anchors to items) should not be displayed.
     */
    public $showIndicators = true;
    /**
     * @var array list of slides in the carousel. Each array element represents a single
     * slide with the following structure:
     *
     * ```php
     * [
     *     // required, slide content (HTML), such as an image tag
     *     'content' => '<img src="http://twitter.github.io/bootstrap/assets/img/bootstrap-mdo-sfmoma-01.jpg"/>',
     *     // optional, the caption (HTML) of the slide
     *     'caption' => '<h4>This is title</h4><p>This is the caption text</p>',
     *     // optional the HTML attributes of the slide container
     *     'options' => [],
     * ]
     * ```
     */
    public $items = [];

    /**
     * Initializes the widget.
     */
    public function init()
    {
        parent::init();
        Html::addCssClass($this->options, ['widget' => 'carousel slide']);
        if (isset($this->controls) && empty($this->controls)) {
            $this->controls[] = Html::tag('span', '', ['class' => 'carousel-control-prev-icon'])
                . $this->htmlHlp->tag('span', $this->controlsLabels[0], ['class' => 'sr-only']);
            $this->controls[] = Html::tag('span', '', ['class' => 'carousel-control-next-icon'])
                . $this->htmlHlp->tag('span', $this->controlsLabels[1], ['class' => 'sr-only']);
        }
    }

    /**
     * Renders the widget.
     */
    public function run()
    {
        $this->registerPlugin('carousel');
        return implode("\n", [
            $this->htmlHlp->beginTag('div', $this->options),
            $this->renderIndicators(),
            $this->renderItems(),
            $this->renderControls(),
            $this->htmlHlp->endTag('div')
        ]) . "\n";
    }

    /**
     * Renders carousel indicators.
     * @return string the rendering result
     */
    public function renderIndicators()
    {
        if ($this->showIndicators === false) {
            return '';
        }
        $indicators = [];
        for ($i = 0, $count = count($this->items); $i < $count; $i++) {
            $options = ['data-target' => '#' . $this->options['id'], 'data-slide-to' => $i];
            if ($i === 0) {
                Html::addCssClass($options, 'active');
            }
            $indicators[] = $this->htmlHlp->tag('li', '', $options);
        }

        return $this->htmlHlp->tag('ol', implode("\n", $indicators), ['class' => 'carousel-indicators']);
    }

    /**
     * Renders carousel items as specified on [[items]].
     * @return string the rendering result
     */
    public function renderItems()
    {
        $items = [];
        for ($i = 0, $count = count($this->items); $i < $count; $i++) {
            $items[] = $this->renderItem($this->items[$i], $i);
        }

        return $this->htmlHlp->tag('div', implode("\n", $items), ['class' => 'carousel-inner']);
    }

    /**
     * Renders a single carousel item
     * @param string|array $item a single item from [[items]]
     * @param int $index the item index as the first item should be set to `active`
     * @return string the rendering result
     * @throws InvalidConfigException if the item is invalid
     */
    public function renderItem($item, $index)
    {
        if (is_string($item)) {
            $content = $item;
            $caption = null;
            $options = [];
        } elseif (isset($item['content'])) {
            $content = $item['content'];
            $caption = ArrayHelper::getValue($item, 'caption');
            if ($caption !== null) {
                $captionOptions = ArrayHelper::getValue($item, 'captionOptions', []);
                Html::addCssClass($captionOptions, ['widget' => 'carousel-caption']);
                $caption = $this->htmlHlp->tag('div', $caption, ['class' => $captionOptions]);
            }
            $options = ArrayHelper::getValue($item, 'options', []);
        } else {
            throw new InvalidConfigException('The "content" option is required.');
        }

        Html::addCssClass($options, ['widget' => 'carousel-item']);
        if ($index === 0) {
            Html::addCssClass($options, 'active');
        }

        return $this->htmlHlp->tag('div', $content . "\n" . $caption, $options);
    }

    /**
     * Renders previous and next control buttons.
     * @throws InvalidConfigException if [[controls]] is invalid.
     */
    public function renderControls()
    {
        if (isset($this->controls[0], $this->controls[1])) {
            return $this->htmlHlp->a($this->controls[0], '#' . $this->options['id'], [
                'class' => 'carousel-control-prev',
                'data-slide' => 'prev',
            ]) . "\n"
            . $this->htmlHlp->a($this->controls[1], '#' . $this->options['id'], [
                'class' => 'carousel-control-next',
                'data-slide' => 'next',
            ]);
        } elseif ($this->controls === false) {
            return '';
        } else {
            throw new InvalidConfigException('The "controls" property must be either false or an array of two elements.');
        }
    }
}


<?php
/**
 * Zend Framework
 *
 * LICENSE
 *
 * This source file is subject to the new BSD license that is bundled
 * with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://framework.zend.com/license/new-bsd
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@zend.com so we can send you a copy immediately.
 *
 * @category   Zend
 * @package    Zend_Config
 * @copyright  Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 * @version    $Id: Ini.php 24593 2012-01-05 20:35:02Z matthew $
 */

/**
 * @see Zend_Config_Writer
 */

/**
 * @category   Zend
 * @package    Zend_Config
 * @copyright  Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 */
class Zend_Config_Writer_Ini extends Zend_Config_Writer_FileAbstract
{
    /**
     * String that separates nesting levels of configuration data identifiers
     *
     * @var string
     */
    protected $_nestSeparator = '.';

    /**
     * If true the ini string is rendered in the global namespace without sections.
     *
     * @var bool
     */
    protected $_renderWithoutSections = false;

    /**
     * Set the nest separator
     *
     * @param  string $filename
     * @return Zend_Config_Writer_Ini
     */
    public function setNestSeparator($separator)
    {
        $this->_nestSeparator = $separator;

        return $this;
    }

    /**
     * Set if rendering should occour without sections or not.
     *
     * If set to true, the INI file is rendered without sections completely
     * into the global namespace of the INI file.
     *
     * @param  bool $withoutSections
     * @return Zend_Config_Writer_Ini
     */
    public function setRenderWithoutSections($withoutSections=true)
    {
        $this->_renderWithoutSections = (bool)$withoutSections;
        return $this;
    }

    /**
     * Render a Zend_Config into a INI config string.
     *
     * @since 1.10
     * @return string
     */
    public function render()
    {
        $iniString   = '';
        $extends     = $this->_config->getExtends();
        $sectionName = $this->_config->getSectionName();

        if($this->_renderWithoutSections == true) {
            $iniString .= $this->_addBranch($this->_config);
        } else if (is_string($sectionName)) {
            $iniString .= '[' . $sectionName . ']' . "\n"
                       .  $this->_addBranch($this->_config)
                       .  "\n";
        } else {
            $config = $this->_sortRootElements($this->_config);
            foreach ($config as $sectionName => $data) {
                if (!($data instanceof Zend_Config)) {
                    $iniString .= $sectionName
                               .  ' = '
                               .  $this->_prepareValue($data)
                               .  "\n";
                } else {
                    if (isset($extends[$sectionName])) {
                        $sectionName .= ' : ' . $extends[$sectionName];
                    }

                    $iniString .= '[' . $sectionName . ']' . "\n"
                               .  $this->_addBranch($data)
                               .  "\n";
                }
            }
        }

        return $iniString;
    }

    /**
     * Add a branch to an INI string recursively
     *
     * @param  Zend_Config $config
     * @return void
     */
    protected function _addBranch(Zend_Config $config, $parents = array())
    {
        $iniString = '';

        foreach ($config as $key => $value) {
            $group = array_merge($parents, array($key));

            if ($value instanceof Zend_Config) {
                $iniString .= $this->_addBranch($value, $group);
            } else {
                $iniString .= implode($this->_nestSeparator, $group)
                           .  ' = '
                           .  $this->_prepareValue($value)
                           .  "\n";
            }
        }

        return $iniString;
    }

    /**
     * Prepare a value for INI
     *
     * @param  mixed $value
     * @return string
     */
    protected function _prepareValue($value)
    {
        if (is_integer($value) || is_float($value)) {
            return $value;
        } elseif (is_bool($value)) {
            return ($value ? 'true' : 'false');
        } elseif (strpos($value, '"') === false) {
            return '"' . $value .  '"';
        } else {
            /** @see Zend_Config_Exception */

            throw new Zend_Config_Exception('Value can not contain double quotes "');
        }
    }

    /**
     * Root elements that are not assigned to any section needs to be
     * on the top of config.
     *
     * @see    http://framework.zend.com/issues/browse/ZF-6289
     * @param  Zend_Config
     * @return Zend_Config
     */
    protected function _sortRootElements(Zend_Config $config)
    {
        $configArray = $config->toArray();
        $sections = array();

        // remove sections from config array
        foreach ($configArray as $key => $value) {
            if (is_array($value)) {
                $sections[$key] = $value;
                unset($configArray[$key]);
            }
        }

        // readd sections to the end
        foreach ($sections as $key => $value) {
            $configArray[$key] = $value;
        }

        return new Zend_Config($configArray);
    }
}


<?php
/**
 * Class representing a HTTP request message
 *
 * PHP version 5
 *
 * LICENSE
 *
 * This source file is subject to BSD 3-Clause License that is bundled
 * with this package in the file LICENSE and available at the URL
 * https://raw.github.com/pear/HTTP_Request2/trunk/docs/LICENSE
 *
 * @category  HTTP
 * @package   HTTP_Request2
 * @author    Alexey Borzov <avb@php.net>
 * @copyright 2008-2014 Alexey Borzov <avb@php.net>
 * @license   http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
 * @link      http://pear.php.net/package/HTTP_Request2
 */

/**
 * A class representing an URL as per RFC 3986.
 */
require_once 'Net/URL2.php';

/**
 * Exception class for HTTP_Request2 package
 */
require_once 'HTTP/Request2/Exception.php';

/**
 * Class representing a HTTP request message
 *
 * @category HTTP
 * @package  HTTP_Request2
 * @author   Alexey Borzov <avb@php.net>
 * @license  http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
 * @version  Release: 2.2.1
 * @link     http://pear.php.net/package/HTTP_Request2
 * @link     http://tools.ietf.org/html/rfc2616#section-5
 */
class HTTP_Request2 implements SplSubject
{
    /**#@+
     * Constants for HTTP request methods
     *
     * @link http://tools.ietf.org/html/rfc2616#section-5.1.1
     */
    const METHOD_OPTIONS = 'OPTIONS';
    const METHOD_GET     = 'GET';
    const METHOD_HEAD    = 'HEAD';
    const METHOD_POST    = 'POST';
    const METHOD_PUT     = 'PUT';
    const METHOD_DELETE  = 'DELETE';
    const METHOD_TRACE   = 'TRACE';
    const METHOD_CONNECT = 'CONNECT';
    /**#@-*/

    /**#@+
     * Constants for HTTP authentication schemes
     *
     * @link http://tools.ietf.org/html/rfc2617
     */
    const AUTH_BASIC  = 'basic';
    const AUTH_DIGEST = 'digest';
    /**#@-*/

    /**
     * Regular expression used to check for invalid symbols in RFC 2616 tokens
     * @link http://pear.php.net/bugs/bug.php?id=15630
     */
    const REGEXP_INVALID_TOKEN = '![\x00-\x1f\x7f-\xff()<>@,;:\\\\"/\[\]?={}\s]!';

    /**
     * Regular expression used to check for invalid symbols in cookie strings
     * @link http://pear.php.net/bugs/bug.php?id=15630
     * @link http://web.archive.org/web/20080331104521/http://cgi.netscape.com/newsref/std/cookie_spec.html
     */
    const REGEXP_INVALID_COOKIE = '/[\s,;]/';

    /**
     * Fileinfo magic database resource
     * @var  resource
     * @see  detectMimeType()
     */
    private static $_fileinfoDb;

    /**
     * Observers attached to the request (instances of SplObserver)
     * @var  array
     */
    protected $observers = array();

    /**
     * Request URL
     * @var  Net_URL2
     */
    protected $url;

    /**
     * Request method
     * @var  string
     */
    protected $method = self::METHOD_GET;

    /**
     * Authentication data
     * @var  array
     * @see  getAuth()
     */
    protected $auth;

    /**
     * Request headers
     * @var  array
     */
    protected $headers = array();

    /**
     * Configuration parameters
     * @var  array
     * @see  setConfig()
     */
    protected $config = array(
        'adapter'           => 'HTTP_Request2_Adapter_Socket',
        'connect_timeout'   => 10,
        'timeout'           => 0,
        'use_brackets'      => true,
        'protocol_version'  => '1.1',
        'buffer_size'       => 16384,
        'store_body'        => true,
        'local_ip'          => null,

        'proxy_host'        => '',
        'proxy_port'        => '',
        'proxy_user'        => '',
        'proxy_password'    => '',
        'proxy_auth_scheme' => self::AUTH_BASIC,
        'proxy_type'        => 'http',

        'ssl_verify_peer'   => true,
        'ssl_verify_host'   => true,
        'ssl_cafile'        => null,
        'ssl_capath'        => null,
        'ssl_local_cert'    => null,
        'ssl_passphrase'    => null,

        'digest_compat_ie'  => false,

        'follow_redirects'  => false,
        'max_redirects'     => 5,
        'strict_redirects'  => false
    );

    /**
     * Last event in request / response handling, intended for observers
     * @var  array
     * @see  getLastEvent()
     */
    protected $lastEvent = array(
        'name' => 'start',
        'data' => null
    );

    /**
     * Request body
     * @var  string|resource
     * @see  setBody()
     */
    protected $body = '';

    /**
     * Array of POST parameters
     * @var  array
     */
    protected $postParams = array();

    /**
     * Array of file uploads (for multipart/form-data POST requests)
     * @var  array
     */
    protected $uploads = array();

    /**
     * Adapter used to perform actual HTTP request
     * @var  HTTP_Request2_Adapter
     */
    protected $adapter;

    /**
     * Cookie jar to persist cookies between requests
     * @var HTTP_Request2_CookieJar
     */
    protected $cookieJar = null;

    /**
     * Constructor. Can set request URL, method and configuration array.
     *
     * Also sets a default value for User-Agent header.
     *
     * @param string|Net_Url2 $url    Request URL
     * @param string          $method Request method
     * @param array           $config Configuration for this Request instance
     */
    public function __construct(
        $url = null, $method = self::METHOD_GET, array $config = array()
    ) {
        $this->setConfig($config);
        if (!empty($url)) {
            $this->setUrl($url);
        }
        if (!empty($method)) {
            $this->setMethod($method);
        }
        $this->setHeader(
            'user-agent', 'HTTP_Request2/2.2.1 ' .
            '(http://pear.php.net/package/http_request2) PHP/' . phpversion()
        );
    }

    /**
     * Sets the URL for this request
     *
     * If the URL has userinfo part (username & password) these will be removed
     * and converted to auth data. If the URL does not have a path component,
     * that will be set to '/'.
     *
     * @param string|Net_URL2 $url Request URL
     *
     * @return   HTTP_Request2
     * @throws   HTTP_Request2_LogicException
     */
    public function setUrl($url)
    {
        if (is_string($url)) {
            $url = new Net_URL2(
                $url, array(Net_URL2::OPTION_USE_BRACKETS => $this->config['use_brackets'])
            );
        }
        if (!$url instanceof Net_URL2) {
            throw new HTTP_Request2_LogicException(
                'Parameter is not a valid HTTP URL',
                HTTP_Request2_Exception::INVALID_ARGUMENT
            );
        }
        // URL contains username / password?
        if ($url->getUserinfo()) {
            $username = $url->getUser();
            $password = $url->getPassword();
            $this->setAuth(rawurldecode($username), $password? rawurldecode($password): '');
            $url->setUserinfo('');
        }
        if ('' == $url->getPath()) {
            $url->setPath('/');
        }
        $this->url = $url;

        return $this;
    }

    /**
     * Returns the request URL
     *
     * @return   Net_URL2
     */
    public function getUrl()
    {
        return $this->url;
    }

    /**
     * Sets the request method
     *
     * @param string $method one of the methods defined in RFC 2616
     *
     * @return   HTTP_Request2
     * @throws   HTTP_Request2_LogicException if the method name is invalid
     */
    public function setMethod($method)
    {
        // Method name should be a token: http://tools.ietf.org/html/rfc2616#section-5.1.1
        if (preg_match(self::REGEXP_INVALID_TOKEN, $method)) {
            throw new HTTP_Request2_LogicException(
                "Invalid request method '{$method}'",
                HTTP_Request2_Exception::INVALID_ARGUMENT
            );
        }
        $this->method = $method;

        return $this;
    }

    /**
     * Returns the request method
     *
     * @return   string
     */
    public function getMethod()
    {
        return $this->method;
    }

    /**
     * Sets the configuration parameter(s)
     *
     * The following parameters are available:
     *

     *
 'adapter'           - adapter to use (string)

     *
 'connect_timeout'   - Connection timeout in seconds (integer)

     *
 'timeout'           - Total number of seconds a request can take.
     *                              Use 0 for no limit, should be greater than
     *                              'connect_timeout' if set (integer)

     *
 'use_brackets'      - Whether to append [] to array variable names (bool)

     *
 'protocol_version'  - HTTP Version to use, '1.0' or '1.1' (string)

     *
 'buffer_size'       - Buffer size to use for reading and writing (int)

     *
 'store_body'        - Whether to store response body in response object.
     *                              Set to false if receiving a huge response and
     *                              using an Observer to save it (boolean)

     *
 'local_ip'          - Specifies the IP address that will be used for accessing
     *                              the network (string)

     *
 'proxy_type'        - Proxy type, 'http' or 'socks5' (string)

     *
 'proxy_host'        - Proxy server host (string)

     *
 'proxy_port'        - Proxy server port (integer)

     *
 'proxy_user'        - Proxy auth username (string)

     *
 'proxy_password'    - Proxy auth password (string)

     *
 'proxy_auth_scheme' - Proxy auth scheme, one of HTTP_Request2::AUTH_* constants (string)

     *
 'proxy'             - Shorthand for proxy_* parameters, proxy given as URL,
     *                              e.g. 'socks5://localhost:1080/' (string)

     *
 'ssl_verify_peer'   - Whether to verify peer's SSL certificate (bool)

     *
 'ssl_verify_host'   - Whether to check that Common Name in SSL
     *                              certificate matches host name (bool)

     *
 'ssl_cafile'        - Cerificate Authority file to verify the peer
     *                              with (use with 'ssl_verify_peer') (string)

     *
 'ssl_capath'        - Directory holding multiple Certificate
     *                              Authority files (string)

     *
 'ssl_local_cert'    - Name of a file containing local cerificate (string)

     *
 'ssl_passphrase'    - Passphrase with which local certificate
     *                              was encoded (string)

     *
 'digest_compat_ie'  - Whether to imitate behaviour of MSIE 5 and 6
     *                              in using URL without query string in digest
     *                              authentication (boolean)

     *
 'follow_redirects'  - Whether to automatically follow HTTP Redirects (boolean)

     *
 'max_redirects'     - Maximum number of redirects to follow (integer)

     *
 'strict_redirects'  - Whether to keep request method on redirects via status 301 and
     *                              302 (true, needed for compatibility with RFC 2616)
     *                              or switch to GET (false, needed for compatibility with most
     *                              browsers) (boolean)

     *

     *
     * @param string|array $nameOrConfig configuration parameter name or array
     *                                   ('parameter name' => 'parameter value')
     * @param mixed        $value        parameter value if $nameOrConfig is not an array
     *
     * @return   HTTP_Request2
     * @throws   HTTP_Request2_LogicException If the parameter is unknown
     */
    public function setConfig($nameOrConfig, $value = null)
    {
        if (is_array($nameOrConfig)) {
            foreach ($nameOrConfig as $name => $value) {
                $this->setConfig($name, $value);
            }

        } elseif ('proxy' == $nameOrConfig) {
            $url = new Net_URL2($value);
            $this->setConfig(array(
                'proxy_type'     => $url->getScheme(),
                'proxy_host'     => $url->getHost(),
                'proxy_port'     => $url->getPort(),
                'proxy_user'     => rawurldecode($url->getUser()),
                'proxy_password' => rawurldecode($url->getPassword())
            ));

        } else {
            if (!array_key_exists($nameOrConfig, $this->config)) {
                throw new HTTP_Request2_LogicException(
                    "Unknown configuration parameter '{$nameOrConfig}'",
                    HTTP_Request2_Exception::INVALID_ARGUMENT
                );
            }
            $this->config[$nameOrConfig] = $value;
        }

        return $this;
    }

    /**
     * Returns the value(s) of the configuration parameter(s)
     *
     * @param string $name parameter name
     *
     * @return   mixed   value of $name parameter, array of all configuration
     *                   parameters if $name is not given
     * @throws   HTTP_Request2_LogicException If the parameter is unknown
     */
    public function getConfig($name = null)
    {
        if (null === $name) {
            return $this->config;
        } elseif (!array_key_exists($name, $this->config)) {
            throw new HTTP_Request2_LogicException(
                "Unknown configuration parameter '{$name}'",
                HTTP_Request2_Exception::INVALID_ARGUMENT
            );
        }
        return $this->config[$name];
    }

    /**
     * Sets the autentification data
     *
     * @param string $user     user name
     * @param string $password password
     * @param string $scheme   authentication scheme
     *
     * @return   HTTP_Request2
     */
    public function setAuth($user, $password = '', $scheme = self::AUTH_BASIC)
    {
        if (empty($user)) {
            $this->auth = null;
        } else {
            $this->auth = array(
                'user'     => (string)$user,
                'password' => (string)$password,
                'scheme'   => $scheme
            );
        }

        return $this;
    }

    /**
     * Returns the authentication data
     *
     * The array has the keys 'user', 'password' and 'scheme', where 'scheme'
     * is one of the HTTP_Request2::AUTH_* constants.
     *
     * @return   array
     */
    public function getAuth()
    {
        return $this->auth;
    }

    /**
     * Sets request header(s)
     *
     * The first parameter may be either a full header string 'header: value' or
     * header name. In the former case $value parameter is ignored, in the latter
     * the header's value will either be set to $value or the header will be
     * removed if $value is null. The first parameter can also be an array of
     * headers, in that case method will be called recursively.
     *
     * Note that headers are treated case insensitively as per RFC 2616.
     *
     *
     * $req->setHeader('Foo: Bar'); // sets the value of 'Foo' header to 'Bar'
     * $req->setHeader('FoO', 'Baz'); // sets the value of 'Foo' header to 'Baz'
     * $req->setHeader(array('foo' => 'Quux')); // sets the value of 'Foo' header to 'Quux'
     * $req->setHeader('FOO'); // removes 'Foo' header from request
     *
     *
     * @param string|array      $name    header name, header string ('Header: value')
     *                                   or an array of headers
     * @param string|array|null $value   header value if $name is not an array,
     *                                   header will be removed if value is null
     * @param bool              $replace whether to replace previous header with the
     *                                   same name or append to its value
     *
     * @return   HTTP_Request2
     * @throws   HTTP_Request2_LogicException
     */
    public function setHeader($name, $value = null, $replace = true)
    {
        if (is_array($name)) {
            foreach ($name as $k => $v) {
                if (is_string($k)) {
                    $this->setHeader($k, $v, $replace);
                } else {
                    $this->setHeader($v, null, $replace);
                }
            }
        } else {
            if (null === $value && strpos($name, ':')) {
                list($name, $value) = array_map('trim', explode(':', $name, 2));
            }
            // Header name should be a token: http://tools.ietf.org/html/rfc2616#section-4.2
            if (preg_match(self::REGEXP_INVALID_TOKEN, $name)) {
                throw new HTTP_Request2_LogicException(
                    "Invalid header name '{$name}'",
                    HTTP_Request2_Exception::INVALID_ARGUMENT
                );
            }
            // Header names are case insensitive anyway
            $name = strtolower($name);
            if (null === $value) {
                unset($this->headers[$name]);

            } else {
                if (is_array($value)) {
                    $value = implode(', ', array_map('trim', $value));
                } elseif (is_string($value)) {
                    $value = trim($value);
                }
                if (!isset($this->headers[$name]) || $replace) {
                    $this->headers[$name] = $value;
                } else {
                    $this->headers[$name] .= ', ' . $value;
                }
            }
        }

        return $this;
    }

    /**
     * Returns the request headers
     *
     * The array is of the form ('header name' => 'header value'), header names
     * are lowercased
     *
     * @return   array
     */
    public function getHeaders()
    {
        return $this->headers;
    }

    /**
     * Adds a cookie to the request
     *
     * If the request does not have a CookieJar object set, this method simply
     * appends a cookie to "Cookie:" header.
     *
     * If a CookieJar object is available, the cookie is stored in that object.
     * Data from request URL will be used for setting its 'domain' and 'path'
     * parameters, 'expires' and 'secure' will be set to null and false,
     * respectively. If you need further control, use CookieJar's methods.
     *
     * @param string $name  cookie name
     * @param string $value cookie value
     *
     * @return   HTTP_Request2
     * @throws   HTTP_Request2_LogicException
     * @see      setCookieJar()
     */
    public function addCookie($name, $value)
    {
        if (!empty($this->cookieJar)) {
            $this->cookieJar->store(
                array('name' => $name, 'value' => $value), $this->url
            );

        } else {
            $cookie = $name . '=' . $value;
            if (preg_match(self::REGEXP_INVALID_COOKIE, $cookie)) {
                throw new HTTP_Request2_LogicException(
                    "Invalid cookie: '{$cookie}'",
                    HTTP_Request2_Exception::INVALID_ARGUMENT
                );
            }
            $cookies = empty($this->headers['cookie'])? '': $this->headers['cookie'] . '; ';
            $this->setHeader('cookie', $cookies . $cookie);
        }

        return $this;
    }

    /**
     * Sets the request body
     *
     * If you provide file pointer rather than file name, it should support
     * fstat() and rewind() operations.
     *
     * @param string|resource|HTTP_Request2_MultipartBody $body       Either a
     *               string with the body or filename containing body or
     *               pointer to an open file or object with multipart body data
     * @param bool                                        $isFilename Whether
     *               first parameter is a filename
     *
     * @return   HTTP_Request2
     * @throws   HTTP_Request2_LogicException
     */
    public function setBody($body, $isFilename = false)
    {
        if (!$isFilename && !is_resource($body)) {
            if (!$body instanceof HTTP_Request2_MultipartBody) {
                $this->body = (string)$body;
            } else {
                $this->body = $body;
            }
        } else {
            $fileData = $this->fopenWrapper($body, empty($this->headers['content-type']));
            $this->body = $fileData['fp'];
            if (empty($this->headers['content-type'])) {
                $this->setHeader('content-type', $fileData['type']);
            }
        }
        $this->postParams = $this->uploads = array();

        return $this;
    }

    /**
     * Returns the request body
     *
     * @return   string|resource|HTTP_Request2_MultipartBody
     */
    public function getBody()
    {
        if (self::METHOD_POST == $this->method
            && (!empty($this->postParams) || !empty($this->uploads))
        ) {
            if (0 === strpos($this->headers['content-type'], 'application/x-www-form-urlencoded')) {
                $body = http_build_query($this->postParams, '', '&');
                if (!$this->getConfig('use_brackets')) {
                    $body = preg_replace('/%5B\d+%5D=/', '=', $body);
                }
                // support RFC 3986 by not encoding '~' symbol (request #15368)
                return str_replace('%7E', '~', $body);

            } elseif (0 === strpos($this->headers['content-type'], 'multipart/form-data')) {
                require_once 'HTTP/Request2/MultipartBody.php';
                return new HTTP_Request2_MultipartBody(
                    $this->postParams, $this->uploads, $this->getConfig('use_brackets')
                );
            }
        }
        return $this->body;
    }

    /**
     * Adds a file to form-based file upload
     *
     * Used to emulate file upload via a HTML form. The method also sets
     * Content-Type of HTTP request to 'multipart/form-data'.
     *
     * If you just want to send the contents of a file as the body of HTTP
     * request you should use setBody() method.
     *
     * If you provide file pointers rather than file names, they should support
     * fstat() and rewind() operations.
     *
     * @param string                $fieldName    name of file-upload field
     * @param string|resource|array $filename     full name of local file,
     *               pointer to open file or an array of files
     * @param string                $sendFilename filename to send in the request
     * @param string                $contentType  content-type of file being uploaded
     *
     * @return   HTTP_Request2
     * @throws   HTTP_Request2_LogicException
     */
    public function addUpload(
        $fieldName, $filename, $sendFilename = null, $contentType = null
    ) {
        if (!is_array($filename)) {
            $fileData = $this->fopenWrapper($filename, empty($contentType));
            $this->uploads[$fieldName] = array(
                'fp'        => $fileData['fp'],
                'filename'  => !empty($sendFilename)? $sendFilename
                                :(is_string($filename)? basename($filename): 'anonymous.blob') ,
                'size'      => $fileData['size'],
                'type'      => empty($contentType)? $fileData['type']: $contentType
            );
        } else {
            $fps = $names = $sizes = $types = array();
            foreach ($filename as $f) {
                if (!is_array($f)) {
                    $f = array($f);
                }
                $fileData = $this->fopenWrapper($f[0], empty($f[2]));
                $fps[]   = $fileData['fp'];
                $names[] = !empty($f[1])? $f[1]
                            :(is_string($f[0])? basename($f[0]): 'anonymous.blob');
                $sizes[] = $fileData['size'];
                $types[] = empty($f[2])? $fileData['type']: $f[2];
            }
            $this->uploads[$fieldName] = array(
                'fp' => $fps, 'filename' => $names, 'size' => $sizes, 'type' => $types
            );
        }
        if (empty($this->headers['content-type'])
            || 'application/x-www-form-urlencoded' == $this->headers['content-type']
        ) {
            $this->setHeader('content-type', 'multipart/form-data');
        }

        return $this;
    }

    /**
     * Adds POST parameter(s) to the request.
     *
     * @param string|array $name  parameter name or array ('name' => 'value')
     * @param mixed        $value parameter value (can be an array)
     *
     * @return   HTTP_Request2
     */
    public function addPostParameter($name, $value = null)
    {
        if (!is_array($name)) {
            $this->postParams[$name] = $value;
        } else {
            foreach ($name as $k => $v) {
                $this->addPostParameter($k, $v);
            }
        }
        if (empty($this->headers['content-type'])) {
            $this->setHeader('content-type', 'application/x-www-form-urlencoded');
        }

        return $this;
    }

    /**
     * Attaches a new observer
     *
     * @param SplObserver $observer any object implementing SplObserver
     */
    public function attach(SplObserver $observer)
    {
        foreach ($this->observers as $attached) {
            if ($attached === $observer) {
                return;
            }
        }
        $this->observers[] = $observer;
    }

    /**
     * Detaches an existing observer
     *
     * @param SplObserver $observer any object implementing SplObserver
     */
    public function detach(SplObserver $observer)
    {
        foreach ($this->observers as $key => $attached) {
            if ($attached === $observer) {
                unset($this->observers[$key]);
                return;
            }
        }
    }

    /**
     * Notifies all observers
     */
    public function notify()
    {
        foreach ($this->observers as $observer) {
            $observer->update($this);
        }
    }

    /**
     * Sets the last event
     *
     * Adapters should use this method to set the current state of the request
     * and notify the observers.
     *
     * @param string $name event name
     * @param mixed  $data event data
     */
    public function setLastEvent($name, $data = null)
    {
        $this->lastEvent = array(
            'name' => $name,
            'data' => $data
        );
        $this->notify();
    }

    /**
     * Returns the last event
     *
     * Observers should use this method to access the last change in request.
     * The following event names are possible:
     *

     *
'connect'                 - after connection to remote server,
     *                                   data is the destination (string)

     *
'disconnect'              - after disconnection from server

     *
'sentHeaders'             - after sending the request headers,
     *                                   data is the headers sent (string)

     *
'sentBodyPart'            - after sending a part of the request body,
     *                                   data is the length of that part (int)

     *
'sentBody'                - after sending the whole request body,
     *                                   data is request body length (int)

     *
'receivedHeaders'         - after receiving the response headers,
     *                                   data is HTTP_Request2_Response object

     *
'receivedBodyPart'        - after receiving a part of the response
     *                                   body, data is that part (string)

     *
'receivedEncodedBodyPart' - as 'receivedBodyPart', but data is still
     *                                   encoded by Content-Encoding

     *
'receivedBody'            - after receiving the complete response
     *                                   body, data is HTTP_Request2_Response object

     *

     * Different adapters may not send all the event types. Mock adapter does
     * not send any events to the observers.
     *
     * @return   array   The array has two keys: 'name' and 'data'
     */
    public function getLastEvent()
    {
        return $this->lastEvent;
    }

    /**
     * Sets the adapter used to actually perform the request
     *
     * You can pass either an instance of a class implementing HTTP_Request2_Adapter
     * or a class name. The method will only try to include a file if the class
     * name starts with HTTP_Request2_Adapter_, it will also try to prepend this
     * prefix to the class name if it doesn't contain any underscores, so that
     *
     * $request->setAdapter('curl');
     *
     * will work.
     *
     * @param string|HTTP_Request2_Adapter $adapter Adapter to use
     *
     * @return   HTTP_Request2
     * @throws   HTTP_Request2_LogicException
     */
    public function setAdapter($adapter)
    {
        if (is_string($adapter)) {
            if (!class_exists($adapter, false)) {
                if (false === strpos($adapter, '_')) {
                    $adapter = 'HTTP_Request2_Adapter_' . ucfirst($adapter);
                }
                if (!class_exists($adapter, false)
                    && preg_match('/^HTTP_Request2_Adapter_([a-zA-Z0-9]+)$/', $adapter)
                ) {
                    include_once str_replace('_', DIRECTORY_SEPARATOR, $adapter) . '.php';
                }
                if (!class_exists($adapter, false)) {
                    throw new HTTP_Request2_LogicException(
                        "Class {$adapter} not found",
                        HTTP_Request2_Exception::MISSING_VALUE
                    );
                }
            }
            $adapter = new $adapter;
        }
        if (!$adapter instanceof HTTP_Request2_Adapter) {
            throw new HTTP_Request2_LogicException(
                'Parameter is not a HTTP request adapter',
                HTTP_Request2_Exception::INVALID_ARGUMENT
            );
        }
        $this->adapter = $adapter;

        return $this;
    }

    /**
     * Sets the cookie jar
     *
     * A cookie jar is used to maintain cookies across HTTP requests and
     * responses. Cookies from jar will be automatically added to the request
     * headers based on request URL.
     *
     * @param HTTP_Request2_CookieJar|bool $jar Existing CookieJar object, true to
     *                                          create a new one, false to remove
     *
     * @return HTTP_Request2
     * @throws HTTP_Request2_LogicException
     */
    public function setCookieJar($jar = true)
    {
        if (!class_exists('HTTP_Request2_CookieJar', false)) {
            require_once 'HTTP/Request2/CookieJar.php';
        }

        if ($jar instanceof HTTP_Request2_CookieJar) {
            $this->cookieJar = $jar;
        } elseif (true === $jar) {
            $this->cookieJar = new HTTP_Request2_CookieJar();
        } elseif (!$jar) {
            $this->cookieJar = null;
        } else {
            throw new HTTP_Request2_LogicException(
                'Invalid parameter passed to setCookieJar()',
                HTTP_Request2_Exception::INVALID_ARGUMENT
            );
        }

        return $this;
    }

    /**
     * Returns current CookieJar object or null if none
     *
     * @return HTTP_Request2_CookieJar|null
     */
    public function getCookieJar()
    {
        return $this->cookieJar;
    }

    /**
     * Sends the request and returns the response
     *
     * @throws   HTTP_Request2_Exception
     * @return   HTTP_Request2_Response
     */
    public function send()
    {
        // Sanity check for URL
        if (!$this->url instanceof Net_URL2
            || !$this->url->isAbsolute()
            || !in_array(strtolower($this->url->getScheme()), array('https', 'http'))
        ) {
            throw new HTTP_Request2_LogicException(
                'HTTP_Request2 needs an absolute HTTP(S) request URL, '
                . ($this->url instanceof Net_URL2
                   ? "'" . $this->url->__toString() . "'" : 'none')
                . ' given',
                HTTP_Request2_Exception::INVALID_ARGUMENT
            );
        }
        if (empty($this->adapter)) {
            $this->setAdapter($this->getConfig('adapter'));
        }
        // magic_quotes_runtime may break file uploads and chunked response
        // processing; see bug #4543. Don't use ini_get() here; see bug #16440.
        if ($magicQuotes = get_magic_quotes_runtime()) {
            set_magic_quotes_runtime(false);
        }
        // force using single byte encoding if mbstring extension overloads
        // strlen() and substr(); see bug #1781, bug #10605
        if (extension_loaded('mbstring') && (2 & ini_get('mbstring.func_overload'))) {
            $oldEncoding = mb_internal_encoding();
            mb_internal_encoding('8bit');
        }

        try {
            $response = $this->adapter->sendRequest($this);
        } catch (Exception $e) {
        }
        // cleanup in either case (poor man's "finally" clause)
        if ($magicQuotes) {
            set_magic_quotes_runtime(true);
        }
        if (!empty($oldEncoding)) {
            mb_internal_encoding($oldEncoding);
        }
        // rethrow the exception
        if (!empty($e)) {
            throw $e;
        }
        return $response;
    }

    /**
     * Wrapper around fopen()/fstat() used by setBody() and addUpload()
     *
     * @param string|resource $file       file name or pointer to open file
     * @param bool            $detectType whether to try autodetecting MIME
     *                        type of file, will only work if $file is a
     *                        filename, not pointer
     *
     * @return array array('fp' => file pointer, 'size' => file size, 'type' => MIME type)
     * @throws HTTP_Request2_LogicException
     */
    protected function fopenWrapper($file, $detectType = false)
    {
        if (!is_string($file) && !is_resource($file)) {
            throw new HTTP_Request2_LogicException(
                "Filename or file pointer resource expected",
                HTTP_Request2_Exception::INVALID_ARGUMENT
            );
        }
        $fileData = array(
            'fp'   => is_string($file)? null: $file,
            'type' => 'application/octet-stream',
            'size' => 0
        );
        if (is_string($file)) {
            if (!($fileData['fp'] = @fopen($file, 'rb'))) {
                $error = error_get_last();
                throw new HTTP_Request2_LogicException(
                    $error['message'], HTTP_Request2_Exception::READ_ERROR
                );
            }
            if ($detectType) {
                $fileData['type'] = self::detectMimeType($file);
            }
        }
        if (!($stat = fstat($fileData['fp']))) {
            throw new HTTP_Request2_LogicException(
                "fstat() call failed", HTTP_Request2_Exception::READ_ERROR
            );
        }
        $fileData['size'] = $stat['size'];

        return $fileData;
    }

    /**
     * Tries to detect MIME type of a file
     *
     * The method will try to use fileinfo extension if it is available,
     * deprecated mime_content_type() function in the other case. If neither
     * works, default 'application/octet-stream' MIME type is returned
     *
     * @param string $filename file name
     *
     * @return   string  file MIME type
     */
    protected static function detectMimeType($filename)
    {
        // finfo extension from PECL available
        if (function_exists('finfo_open')) {
            if (!isset(self::$_fileinfoDb)) {
                self::$_fileinfoDb = @finfo_open(FILEINFO_MIME);
            }
            if (self::$_fileinfoDb) {
                $info = finfo_file(self::$_fileinfoDb, $filename);
            }
        }
        // (deprecated) mime_content_type function available
        if (empty($info) && function_exists('mime_content_type')) {
            return mime_content_type($filename);
        }
        return empty($info)? 'application/octet-stream': $info;
    }
}
?>


<?php

namespace Jjanvier\Library\Crowdin\Synchronizer;

use Crowdin\Api\UpdateFile;
use Crowdin\Client as CrowdinClient;
use Jjanvier\Library\Crowdin\Translation\TranslationFinder;
use Jjanvier\Library\Crowdin\Translation\TranslationMapper;

/**
 * Class UpSynchronizer
 *
 * Send translations of the default locale to Crowdin
 */
class UpSynchronizer implements SynchronizerInterface
{
    /**
     * @var CrowdinClient
     */
    protected $crowdinClient;

    /**
     * @var TranslationFinder
     */
    protected $finder;

    /**
     * @var TranslationMapper
     */
    protected $mapper;

    /**
     * @var GitHandler
     */
    protected $gitHandler;

    /**
     * @param CrowdinClient     $client
     * @param GitHandler        $gitHandler
     * @param TranslationFinder $finder
     * @param TranslationMapper $mapper
     */
    public function __construct(
        CrowdinClient $client,
        GitHandler $gitHandler,
        TranslationFinder $finder,
        TranslationMapper $mapper
    ) {
        $this->crowdinClient = $client;
        $this->gitHandler = $gitHandler;
        $this->finder = $finder;
        $this->mapper = $mapper;
    }

    /**
     * {@inheritdoc}
     */
    public function synchronize()
    {
        // init project
        $projectDir = $this->createProjectDirectory();
        $this->finder->setPath($projectDir);
        $this->gitHandler->setProjectPath($projectDir);
        $this->gitHandler->cloneProject();

        /** @var UpdateFile $api */
        $api = $this->crowdinClient->api('update-file');

        foreach ($this->finder->getDefaultLocaleTranslations() as $localPath) {
            $crowdinPath = $this->mapper->local2crowdin($localPath);
            $api->addTranslation($localPath, $crowdinPath);
        }

        return $api->execute();
    }

    /**
     * Create the project directory
     * TODO: use the config parameter
     *
     * @return string
     */
    protected function createProjectDirectory()
    {
        $dir = sprintf('/tmp/crowdin/project/%s/', uniqid());
        exec(sprintf('mkdir -p %s', $dir));

        return $dir;
    }
}


<?php

namespace Flowcode\DashboardBundle\Controller;

use Symfony\Component\HttpFoundation\Request;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use Flowcode\DashboardBundle\Entity\Setting;
use Flowcode\DashboardBundle\Form\Type\SettingType;
use Doctrine\ORM\QueryBuilder;

/**
 * Setting controller.
 *
 * @Route("/admin/amulen/setting")
 */
class SettingController extends Controller
{
    /**
     * Lists all Setting entities.
     *
     * @Route("/", name="admin_amulen_setting")
     * @Method("GET")
     * @Template()
     */
    public function indexAction()
    {
        $em = $this->getDoctrine()->getManager();
        $entities = $em->getRepository('FlowcodeDashboardBundle:Setting')->findAll();

        return array(
            'entities' => $entities,
        );
    }

    /**
     * Finds and displays a Setting entity.
     *
     * @Route("/{id}/show", name="admin_amulen_setting_show", requirements={"id"="\d+"})
     * @Method("GET")
     * @Template()
     */
    public function showAction(Setting $setting)
    {
        $editForm = $this->createForm($this->get('amulen.dashboard.form.setting'), $setting, array(
            'action' => $this->generateUrl('admin_amulen_setting_update', array('id' => $setting->getid())),
            'method' => 'PUT',
        ));
        $deleteForm = $this->createDeleteForm($setting->getId(), 'admin_amulen_setting_delete');

        return array(

            'setting' => $setting, 'edit_form' => $editForm->createView(),
            'delete_form' => $deleteForm->createView(),

        );
    }

    /**
     * Displays a form to create a new Setting entity.
     *
     * @Route("/new", name="admin_amulen_setting_new")
     * @Method("GET")
     * @Template()
     */
    public function newAction()
    {
        $setting = new Setting();
        $form = $this->createForm($this->get('amulen.dashboard.form.setting'), $setting);

        return array(
            'setting' => $setting,
            'form' => $form->createView(),
        );
    }

    /**
     * Creates a new Setting entity.
     *
     * @Route("/create", name="admin_amulen_setting_create")
     * @Method("POST")
     * @Template("FlowcodeDashboardBundle:Setting:new.html.twig")
     */
    public function createAction(Request $request)
    {
        $setting = new Setting();
        $form = $this->createForm($this->get('amulen.dashboard.form.setting'), $setting);
        if ($form->handleRequest($request)->isValid()) {
            $em = $this->getDoctrine()->getManager();
            $em->persist($setting);
            $em->flush();

            return $this->redirect($this->generateUrl('admin_amulen_setting_show', array('id' => $setting->getId())));
        }

        return array(
            'setting' => $setting,
            'form' => $form->createView(),
        );
    }

    /**
     * Edits an existing Setting entity.
     *
     * @Route("/{id}/update", name="admin_amulen_setting_update", requirements={"id"="\d+"})
     * @Method("PUT")
     * @Template("FlowcodeDashboardBundle:Setting:edit.html.twig")
     */
    public function updateAction(Setting $setting, Request $request)
    {
        $editForm = $this->createForm($this->get('amulen.dashboard.form.setting'), $setting, array(
            'action' => $this->generateUrl('admin_amulen_setting_update', array('id' => $setting->getid())),
            'method' => 'PUT',
        ));
        if ($editForm->handleRequest($request)->isValid()) {
            $this->getDoctrine()->getManager()->flush();

            return $this->redirect($this->generateUrl('admin_amulen_setting_show', array('id' => $setting->getId())));
        }
        $deleteForm = $this->createDeleteForm($setting->getId(), 'admin_amulen_setting_delete');

        return array(
            'setting' => $setting,
            'edit_form' => $editForm->createView(),
            'delete_form' => $deleteForm->createView(),
        );
    }

    /**
     * Deletes a Setting entity.
     *
     * @Route("/{id}/delete", name="admin_amulen_setting_delete", requirements={"id"="\d+"})
     * @Method("DELETE")
     */
    public function deleteAction(Setting $setting, Request $request)
    {
        $form = $this->createDeleteForm($setting->getId(), 'admin_amulen_setting_delete');
        if ($form->handleRequest($request)->isValid()) {
            $em = $this->getDoctrine()->getManager();
            $em->remove($setting);
            $em->flush();
        }

        return $this->redirect($this->generateUrl('admin_amulen_setting'));
    }

    /**
     * Create Delete form
     *
     * @param integer $id
     * @param string $route
     * @return \Symfony\Component\Form\Form
     */
    protected function createDeleteForm($id, $route)
    {
        return $this->createFormBuilder(null, array('attr' => array('id' => 'delete')))
            ->setAction($this->generateUrl($route, array('id' => $id)))
            ->setMethod('DELETE')
            ->getForm();
    }

}


<?php

namespace Colorium\Orm\Mapper;

use Colorium\Orm\Contract\QueryInterface;
use Colorium\Orm\SafePDO;
use Colorium\Orm\SQL;

class Query extends SafePDO implements QueryInterface
{

    /** @var Entity */
    protected $entity;

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

    /** @var array */
    protected $simpleOperators = ['=', '>', '>=', '<', '<=', '<>', 'like', 'not like'];

    /** @var array */
    protected $complexOperators = ['in', 'not in'];

    /** @var array */
    protected $tupleOperators = ['between', 'not between'];

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

    /** @var string */
    protected $limit = [];

    /**
     * Query constructor
     *
     * @param Entity $entity
     * @param \PDO $pdo
     */
    public function __construct(Entity $entity, \PDO $pdo)
    {
        parent::__construct($pdo);
        $this->entity = $entity;
    }

    /**
     * Filter by conditions
     *
     * @param string $expression
     * @param mixed $value
     * @return $this
     */
    public function where($expression, $value = null)
    {
        // shortcut : id
        if(is_int($expression) and !$value) {
            $expression = ['id' => $expression];
        }
        // force array
        elseif(!is_array($expression)) {
            $expression = [$expression => $value];
        }

        // parse each expression
        foreach($expression as $condition => $input) {

            // parse condition
            if(!preg_match('/^(?P<field>[a-zA-Z_0-9]+)( (?P<operator>.+))?$/', $condition, $extract)) {
                throw new \PDOException('Invalid expression "' . $condition . '"');
            }

            // clean condition
            $field = trim($extract['field']);
            $operator = isset($extract['operator'])
                ? strtolower(trim($extract['operator'], ' ?'))
                : null;

            // implicit '=' or 'in'
            if(!$operator) {
                $operator = is_array($input)
                    ? reset($this->complexOperators)
                    : reset($this->simpleOperators);
            }

            // simple operators
            if(in_array($operator, $this->simpleOperators)) {
                if(is_array($input)) {
                    throw new \PDOException('Operator "' . $operator . '" needs only one input value, in "' . $condition . '"');
                }

                $condition = '`' . $field . '` ' . $operator . ' ?';
            }
            // complex operators
            elseif(in_array($operator, $this->complexOperators)) {
                if(!is_array($input) or empty($input)) {
                    throw new \PDOException('Operator "' . $operator . '" needs multiple input values, in "' . $condition . '"');
                }

                $placeholders = array_fill(0, count($input), '?');
                $condition = '`' . $field . '` ' . $operator . ' (' . implode(', ', $placeholders) . ')';
            }
            // tuple operators
            elseif(in_array($operator, $this->tupleOperators)) {
                if(!is_array($input) or count($input) != 2) {
                    throw new \PDOException('Operator "' . $operator . '" needs exactly two input value, in "' . $condition . '"');
                }

                $condition = '`' . $field . '` ' . $operator . ' ? and ?';
            }
            // unknown operator
            else {
                throw new \PDOException('Invalid operator in "' . $condition . '"');
            }

            $this->where[$condition] = $input;
        }

        return $this;
    }

    /**
     * Sort by field
     *
     * @param string $field
     * @param int $sort
     * @return $this
     */
    public function sort($field, $sort = SORT_ASC)
    {
        $this->sort[$field] = $sort;
        return $this;
    }

    /**
     * Limit results
     *
     * @param int $i
     * @param int $offset
     * @return $this
     */
    public function limit($i, $offset = 0)
    {
        $this->limit = [$offset, $i];
        return $this;
    }

    /**
     * Fetch many result
     *
     * @param string $fields
     * @return object[]
     */
    public function fetch(...$fields)
    {
        if(!$fields) {
            $fields = array_keys($this->entity->fields) ?: ['*'];
        }

        list($sql, $values) = SQL::select($this->entity->name, $fields, $this->where, $this->sort, $this->limit);

        return $this->execute($sql, $values, function(\PDOStatement $statement) {
            return $this->entity->class
                ? $statement->fetchAll(\PDO::FETCH_CLASS | \PDO::FETCH_PROPS_LATE, $this->entity->class)
                : $statement->fetchAll(\PDO::FETCH_OBJ);
        });
    }

    /**
     * Fetch one result
     *
     * @param string $fields
     * @return object
     */
    public function one(...$fields)
    {
        if($this->limit) {
            $this->limit[1] = 1; // keep offset
        }
        else {
            $this->limit(1);
        }

        $items = $this->fetch(...$fields);
        return reset($items);
    }

    /**
     * Add record
     *
     * @param mixed $values
     * @return int
     */
    public function add($values)
    {
        if(is_object($values)) {
            $values = get_object_vars($values);
        }
        elseif(!is_array($values)) {
            $values = (array)$values;
        }

        list($sql, $values) = SQL::insert($this->entity->name, $values);

        return $this->execute($sql, $values, function() {
            return $this->pdo->lastInsertId();
        });
    }

    /**
     * Edit record
     *
     * @param mixed $values
     * @return int
     */
    public function edit($values)
    {
        if(is_object($values)) {
            $values = get_object_vars($values);
        }
        elseif(!is_array($values)) {
            $values = (array)$values;
        }

        list($sql, $values) = SQL::update($this->entity->name, $values, $this->where);

        return $this->execute($sql, $values, function(\PDOStatement $statement) {
            return $statement->rowCount();
        });
    }

    /**
     * Erase record
     *
     * @return int
     */
    public function drop()
    {
        list($sql, $values) = SQL::delete($this->entity->name, $this->where);

        return $this->execute($sql, $values, function(\PDOStatement $statement) {
            return $statement->rowCount();
        });
    }
}


<?php
/**
 * @author Serhii Nekhaienko <sergey.nekhaenko@gmail.com>
 * @license GPL
 * @copyright Serhii Nekhaienko &copy 2018
 * @version 4.0.0
 * @project endorphin-studio/browser-detector
 */

namespace EndorphinStudio\Detector\Detection;

use EndorphinStudio\Detector\Tools;

/**
 * Class OsDetector
 * Detection class for OS
 * @package EndorphinStudio\Detector\Detection
 */
class OsDetector extends AbstractDetection
{
    /**
     * @var string Key for abstract detector
     */
    protected $configKey = 'os';

    /**
     * Setup result object
     */
    protected function setupResultObject()
    {
        $osData = $this->detectByKey('family');
        foreach ($osData as $key => $value) {
            if ($key === 'originalInfo') {
                $this->setAttributes($value);
                continue;
            }
            Tools::runSetter($this->resultObject, $key, $value);
        }
        $this->additionalInfo = $osData;
    }
}


<?php

namespace Reaction\Base;

use Reaction\DI\BaseInjectionPossibleTrait;
use Reaction\DI\InjectionPossibleInterface;
use Reaction\Events\EventEmitterWildcardInterface;
use Reaction\Events\EventEmitterWildcardTrait;
use Reaction\Exceptions\InvalidCallException;
use Reaction\Exceptions\UnknownPropertyException;

/**
 * Class Component
 * @package Reaction\Base
 */
class Component extends BaseObject implements EventEmitterWildcardInterface, InjectionPossibleInterface
{
    use EventEmitterWildcardTrait;
    use BaseInjectionPossibleTrait;

    /** @var string Base path of component */
    protected $_basePath;

    /**
     * Returns the root directory of the component.
     * It defaults to the directory containing the component class file.
     * @return string the root directory of the component.
     */
    public function getBasePath()
    {
        if ($this->_basePath === null) {
            $class = new \ReflectionClass($this);
            $this->_basePath = dirname($class->getFileName());
        }

        return $this->_basePath;
    }

    /**
     * Check attached event listeners for particular event
     * @param string $event
     * @return bool
     */
    public function hasEventListeners($event) {
        return !empty($this->listeners[$event]) || !empty($this->onceListeners[$event]);
    }

    /**
     * Sets value of an object property.
     *
     * Do not call this method directly as it is a PHP magic method that
     * will be implicitly called when executing `$object->property = $value;`.
     * @param string $name the property name or the event name
     * @param mixed $value the property value
     * @throws UnknownPropertyException if the property is not defined
     * @throws InvalidCallException if the property is read-only
     * @see __get()
     */
    public function __set($name, $value)
    {
        $setter = static::_SETTER_PREFIX . $name;
        $getter = static::_GETTER_PREFIX . $name;
        if (method_exists($this, $setter)) {
            // set property
            $this->$setter($value);

            return;
        } elseif (strncmp($name, 'on ', 3) === 0) {
            // on event: attach event handler
            $this->on(trim(substr($name, 3)), $value);

            return;
        }

        if (method_exists($this, $getter)) {
            throw new InvalidCallException('Setting read-only property: ' . get_class($this) . '::' . $name);
        }

        throw new UnknownPropertyException('Setting unknown property: ' . get_class($this) . '::' . $name);
    }

    /**
     * This method is called after the object is created by cloning an existing one.
     * It removes all listeners because they are attached to the old object.
     */
    public function __clone()
    {
        $this->listeners = [];
        $this->onceListeners = [];
        $this->listenersWildcard = [];
    }
}