/**
  * Instantiate the Redis class.
  *
  * Instantiates the Redis class.
  *
  * @param null $persistent_id To create an instance that persists between requests, use persistent_id to specify a unique ID for the instance.
  */
 public function __construct()
 {
     global $blog_id, $table_prefix;
     $redis = array('scheme' => 'tcp', 'host' => '127.0.0.1', 'port' => 6379);
     if (defined('WP_REDIS_SCHEME')) {
         $redis['scheme'] = WP_REDIS_SCHEME;
     }
     if (defined('WP_REDIS_HOST')) {
         $redis['host'] = WP_REDIS_HOST;
     }
     if (defined('WP_REDIS_PORT')) {
         $redis['port'] = WP_REDIS_PORT;
     }
     if (defined('WP_REDIS_PATH')) {
         $redis['path'] = WP_REDIS_PATH;
     }
     if (defined('WP_REDIS_PASSWORD')) {
         $redis['password'] = WP_REDIS_PASSWORD;
     }
     if (defined('WP_REDIS_DATABASE')) {
         $redis['database'] = WP_REDIS_DATABASE;
     }
     $redis_client = defined('WP_REDIS_CLIENT') ? WP_REDIS_CLIENT : null;
     if (class_exists('Redis') && strcasecmp('predis', $redis_client) !== 0) {
         $redis_client = defined('HHVM_VERSION') ? 'hhvm' : 'pecl';
     } else {
         $redis_client = 'predis';
     }
     try {
         if (strcasecmp('hhvm', $redis_client) === 0) {
             $this->redis_client = sprintf('HHVM %s Extension', HHVM_VERSION);
             $this->redis = new Redis();
             // adjust host and port, if the scheme is `unix`
             if (strcasecmp('unix', $redis['scheme']) === 0) {
                 $redis['host'] = 'unix://' . $redis['path'];
                 $redis['port'] = 0;
             }
             if (!$this->redis->connect($redis['host'], $redis['port'])) {
                 throw new Exception();
             }
             if (isset($redis['password'])) {
                 $this->redis->auth($redis['password']);
             }
             if (isset($redis['database'])) {
                 $this->redis->select($redis['database']);
             }
             $this->redis_connected = true;
         } elseif (strcasecmp('pecl', $redis_client) === 0) {
             $this->redis_client = 'PCEL Extension';
             $this->redis = new Redis();
             if (strcasecmp('unix', $redis['scheme']) === 0) {
                 $this->redis->connect($redis['path']);
             } else {
                 $this->redis->connect($redis['host'], $redis['port']);
             }
             if (isset($redis['password'])) {
                 $this->redis->auth($redis['password']);
             }
             if (isset($redis['database'])) {
                 $this->redis->select($redis['database']);
             }
             $this->redis_connected = true;
         } else {
             $this->redis_client = 'Predis';
             // require PHP 5.4 or greater
             if (version_compare(PHP_VERSION, '5.4.0', '<')) {
                 throw new Exception();
             }
             // check if bundled Predis library exists
             if (!realpath(dirname(__FILE__) . '/plugins/redis-cache/includes/predis.php')) {
                 throw new Exception();
             }
             require_once dirname(__FILE__) . '/plugins/redis-cache/includes/predis.php';
             Predis\Autoloader::register();
             $this->redis = new Predis\Client($redis);
             $this->redis->connect();
             $this->redis_connected = true;
             $this->redis_client .= ' v' . Predis\Client::VERSION;
         }
     } catch (Exception $exception) {
         // When Redis is unavailable, fall back to the internal back by forcing all groups to be "no redis" groups
         $this->no_redis_groups = array_unique(array_merge($this->no_redis_groups, $this->global_groups));
         $this->redis_connected = false;
     }
     /**
      * This approach is borrowed from Sivel and Boren. Use the salt for easy cache invalidation and for
      * multi single WP installs on the same server.
      */
     if (!defined('WP_CACHE_KEY_SALT')) {
         define('WP_CACHE_KEY_SALT', '');
     }
     // Assign global and blog prefixes for use with keys
     if (function_exists('is_multisite')) {
         $this->global_prefix = is_multisite() || defined('CUSTOM_USER_TABLE') && defined('CUSTOM_USER_META_TABLE') ? '' : $table_prefix;
         $this->blog_prefix = (is_multisite() ? $blog_id : $table_prefix) . ':';
     }
 }
Beispiel #2
1
 /**
  * 保存记录至redis
  * @access private
  * @param  string $value 保存值
  * @return boolean       成功返回true,失败返回false
  */
 private function save_item_in_redis($value = '')
 {
     require './include/Predis/Autoloader.php';
     Predis\Autoloader::register();
     try {
         $r = new Predis\Client();
         $r->connect('127.0.0.1', 6379);
         $my_log_len = $r->llen($this->config->item('encryption_key'));
         if ($my_log_len < 21) {
             $r->rpush($this->config->item('encryption_key'), $value);
         } else {
             $r->lpop($this->config->item('encryption_key'));
             $r->rpush($this->config->item('encryption_key'), $value);
         }
         return TRUE;
     } catch (Exception $e) {
         echo $e->getMessage();
         return FALSE;
     }
 }
Beispiel #3
0
 public static function createConnection(array $additional = array())
 {
     $serverProfile = Predis\Profiles\ServerProfile::get(self::SERVER_VERSION);
     $connection = new Predis\Client(RC::getConnectionArguments($additional), $serverProfile);
     $connection->connect();
     $connection->select(RC::DEFAULT_DATABASE);
     return $connection;
 }
Beispiel #4
0
 private static function createConnection()
 {
     $serverProfile = Predis\RedisServerProfile::get('dev');
     $connection = new Predis\Client(RC::getConnectionArguments(), $serverProfile);
     $connection->connect();
     $connection->select(RC::DEFAULT_DATABASE);
     return $connection;
 }
Beispiel #5
0
 private static function createConnection()
 {
     $serverProfile = Predis\RedisServerProfile::get('dev');
     $connection = new Predis\Client(array('host' => RC::SERVER_HOST, 'port' => RC::SERVER_PORT), $serverProfile);
     $connection->connect();
     $connection->selectDatabase(RC::DEFAULT_DATABASE);
     return $connection;
 }
Beispiel #6
0
 /**
  * 获取动态出入金、转账记录
  * @return mixed 成功返回对应记录,失败返回false
  */
 private function get_my_log()
 {
     require_once './include/Predis/Autoloader.php';
     Predis\Autoloader::register();
     try {
         $r = new Predis\Client();
         $r->connect('127.0.0.1', 6379);
         $my_log_len = $r->llen($this->config->item('encryption_key'));
         return $my_log_len == 0 ? false : $r->lrange($this->config->item('encryption_key'), 0, $my_log_len - 1);
     } catch (Exception $e) {
         return false;
     }
 }
Beispiel #7
0
 private function buildRedisObject($client, $host, $port, $database = 0)
 {
     if ($client == 'phpredis') {
         $redis = new Redis();
         $redis->connect($host, $port);
     } elseif ($client == 'predis') {
         $redis = new Predis\Client(array('scheme' => 'tcp', 'host' => $host, 'port' => $port));
         $redis->connect();
     }
     if ($database) {
         $redis->select($database);
     }
     return $redis;
 }
Beispiel #8
0
 /**
  * auto-connect to the available cache-system on the server
  *
  * @return iAdapter
  */
 protected function autoConnectToAvailableCacheSystem()
 {
     static $adapterCache;
     if (is_object($adapterCache) && $adapterCache instanceof iAdapter) {
         return $adapterCache;
     } else {
         $memcached = null;
         $isMemcachedAvailable = false;
         if (extension_loaded('memcached')) {
             $memcached = new \Memcached();
             $isMemcachedAvailable = $memcached->addServer('127.0.0.1', '11211');
         }
         if ($isMemcachedAvailable === false) {
             $memcached = null;
         }
         $adapterMemcached = new AdapterMemcached($memcached);
         if ($adapterMemcached->installed() === true) {
             // fallback to Memcached
             $adapter = $adapterMemcached;
         } else {
             $memcache = null;
             $isMemcacheAvailable = false;
             if (class_exists('\\Memcache')) {
                 $memcache = new \Memcache();
                 /** @noinspection PhpUsageOfSilenceOperatorInspection */
                 $isMemcacheAvailable = @$memcache->connect('127.0.0.1', 11211);
             }
             if ($isMemcacheAvailable === false) {
                 $memcache = null;
             }
             $adapterMemcache = new AdapterMemcache($memcache);
             if ($adapterMemcache->installed() === true) {
                 // fallback to Memcache
                 $adapter = $adapterMemcache;
             } else {
                 $redis = null;
                 $isRedisAvailable = false;
                 if (extension_loaded('redis')) {
                     if (class_exists('\\Predis\\Client')) {
                         $redis = new \Predis\Client(array('scheme' => 'tcp', 'host' => '127.0.0.1', 'port' => 6379, 'timeout' => '2.0'));
                         try {
                             $redis->connect();
                             $isRedisAvailable = $redis->getConnection()->isConnected();
                         } catch (\Exception $e) {
                             // nothing
                         }
                     }
                 }
                 if ($isRedisAvailable === false) {
                     $redis = null;
                 }
                 $adapterRedis = new AdapterPredis($redis);
                 if ($adapterRedis->installed() === true) {
                     // fallback to Redis
                     $adapter = $adapterRedis;
                 } else {
                     $adapterXcache = new AdapterXcache();
                     if ($adapterXcache->installed() === true) {
                         // fallback to Xcache
                         $adapter = $adapterXcache;
                     } else {
                         $adapterApc = new AdapterApc();
                         if ($adapterApc->installed() === true) {
                             // fallback to APC || APCu
                             $adapter = $adapterApc;
                         } else {
                             // no cache-adapter available -> use a array
                             $adapter = new AdapterArray();
                         }
                     }
                 }
             }
         }
         // save to static cache
         $adapterCache = $adapter;
     }
     return $adapter;
 }
Beispiel #9
0
 switch ($handler_config['type']) {
     case 'hipchat':
         $handler = new \Monolog\Handler\HipChatHandler($handler_config['token'], $handler_config['room']);
         break;
     case 'file':
         $handler = new \Monolog\Handler\StreamHandler(__DIR__ . '/web/' . $handler_config['path']);
         break;
     case 'socketioemitter':
         $redisConfig = isset($handler_config['redis']) ? $handler_config['redis'] : array();
         $redisConfig += array('host' => '127.0.0.1', 'port' => 6379);
         if (extension_loaded('redis')) {
             $redis = new \Redis();
             $redis->connect($redisConfig['host'], $redisConfig['port']);
         } else {
             $redis = new Predis\Client(['host' => $redisConfig['host'], 'port' => $redisConfig['port']]);
             $redis->connect();
         }
         $emitter = new \SocketIO\Emitter($redis);
         if (isset($handler_config['namespace'])) {
             $emitter->of($handler_config['namespace']);
         }
         if (isset($handler_config['room'])) {
             $emitter->in($handler_config['room']);
         }
         $handler = new \CultuurNet\UDB3\Monolog\SocketIOEmitterHandler($emitter);
         break;
     default:
         continue 2;
 }
 $handler->setLevel($handler_config['level']);
 $logger->pushHandler($handler);
Beispiel #10
0
 /**
  * Performs the test.
  *
  * @return \Jyxo\Beholder\Result
  */
 public function run()
 {
     // The redis extension or Predis library is required
     if (!extension_loaded('redis') && !class_exists('\\Predis\\Client')) {
         return new \Jyxo\Beholder\Result(\Jyxo\Beholder\Result::NOT_APPLICABLE, 'Extension redis or Predis library required');
     }
     $random = md5(uniqid(time(), true));
     $key = 'beholder-' . $random;
     $value = $random;
     // Status label
     $description = (false !== filter_var($this->host, FILTER_VALIDATE_IP) ? gethostbyaddr($this->host) : $this->host) . ':' . $this->port . '?database=' . $this->database;
     // Connection
     if (extension_loaded('redis')) {
         $redis = new \Redis();
         if (false === $redis->connect($this->host, $this->port, 2)) {
             return new \Jyxo\Beholder\Result(\Jyxo\Beholder\Result::FAILURE, sprintf('Connection error %s', $description));
         }
     } else {
         $redis = new \Predis\Client(array('host' => $this->host, 'port' => $this->port));
         if (false === $redis->connect()) {
             return new \Jyxo\Beholder\Result(\Jyxo\Beholder\Result::FAILURE, sprintf('Connection error %s', $description));
         }
     }
     // Select database
     if (false === $redis->select($this->database)) {
         return new \Jyxo\Beholder\Result(\Jyxo\Beholder\Result::FAILURE, sprintf('Database error %s', $description));
     }
     // Saving
     if (false === $redis->set($key, $value)) {
         if ($redis instanceof \Redis) {
             $redis->close();
         } else {
             $redis->quit();
         }
         return new \Jyxo\Beholder\Result(\Jyxo\Beholder\Result::FAILURE, sprintf('Write error %s', $description));
     }
     // Check
     $check = $redis->get($key);
     if (false === $check || $check !== $value) {
         if ($redis instanceof \Redis) {
             $redis->close();
         } else {
             $redis->quit();
         }
         return new \Jyxo\Beholder\Result(\Jyxo\Beholder\Result::FAILURE, sprintf('Read error %s', $description));
     }
     // Deleting
     if (false === $redis->del($key)) {
         if ($redis instanceof \Redis) {
             $redis->close();
         } else {
             $redis->quit();
         }
         return new \Jyxo\Beholder\Result(\Jyxo\Beholder\Result::FAILURE, sprintf('Delete error %s', $description));
     }
     // Disconnect
     if ($redis instanceof \Redis) {
         $redis->close();
     } else {
         $redis->quit();
     }
     // OK
     return new \Jyxo\Beholder\Result(\Jyxo\Beholder\Result::SUCCESS, $description);
 }
Beispiel #11
0
function redisConnect($host, $port)
{
    $server = array('host' => is_null($_GET["host"]) ? $host : $_GET["host"], 'port' => is_null($_GET["port"]) ? $port : $_GET["port"]);
    $client = new Predis\Client($server);
    try {
        $client->connect();
    } catch (Exception $e) {
        exit($server . " error: " . $e);
    }
    if (is_null($client) || is_null($client->ping())) {
        echo "cannot reach server" . $host . ":" . $port;
        return;
    }
    return $client;
}
Beispiel #12
0
        $redis_api = 'php-redis';
    } catch (Exception $e) {
        if (isset($rt_wp_nginx_purger) && !empty($rt_wp_nginx_purger)) {
            $rt_wp_nginx_purger->log($e->getMessage(), 'ERROR');
        }
    }
} else {
    if (!class_exists('Predis\\Autoloader')) {
        require_once 'predis.php';
    }
    Predis\Autoloader::register();
    //redis server parameter
    $myredis = new Predis\Client(['host' => $host, 'port' => $port]);
    //connect
    try {
        $myredis->connect();
        $redis_api = 'predis';
    } catch (Exception $e) {
        if (isset($rt_wp_nginx_purger) && !empty($rt_wp_nginx_purger)) {
            $rt_wp_nginx_purger->log($e->getMessage(), 'ERROR');
        }
    }
}
//Lua Script
$lua = <<<LUA
local k =  0
for i, name in ipairs(redis.call('KEYS', KEYS[1]))
do
    redis.call('DEL', name)
    k = k+1
end
 /**
  * Instantiate the Redis class.
  *
  * Instantiates the Redis class.
  *
  * @param   null $persistent_id      To create an instance that persists between requests, use persistent_id to specify a unique ID for the instance.
  */
 public function __construct()
 {
     global $blog_id, $table_prefix;
     // General Redis settings
     $redis = array('host' => '127.0.0.1', 'port' => 6379);
     if (defined('WP_REDIS_BACKEND_HOST') && WP_REDIS_BACKEND_HOST) {
         $redis['host'] = WP_REDIS_BACKEND_HOST;
     }
     if (defined('WP_REDIS_BACKEND_PORT') && WP_REDIS_BACKEND_PORT) {
         $redis['port'] = WP_REDIS_BACKEND_PORT;
     }
     if (defined('WP_REDIS_BACKEND_AUTH') && WP_REDIS_BACKEND_AUTH) {
         $redis['auth'] = WP_REDIS_BACKEND_AUTH;
     }
     if (defined('WP_REDIS_BACKEND_DB') && WP_REDIS_BACKEND_DB) {
         $redis['database'] = WP_REDIS_BACKEND_DB;
     }
     if (defined('WP_REDIS_SERIALIZER')) {
         $redis['serializer'] = WP_REDIS_SERIALIZER;
     } else {
         $redis['serializer'] = Redis::SERIALIZER_PHP;
     }
     // Use Redis PECL library.
     try {
         $this->redis = new Redis();
         $this->redis->connect($redis['host'], $redis['port']);
         $this->redis->setOption(Redis::OPT_SERIALIZER, $redis['serializer']);
         if (isset($redis['auth'])) {
             $this->redis->auth($redis['auth']);
         }
         if (isset($redis['database'])) {
             $this->redis->select($redis['database']);
         }
         $this->redis_connected = true;
     } catch (RedisException $e) {
         // When Redis is unavailable, fall back to the internal back by forcing all groups to be "no redis" groups
         $this->no_redis_groups = array_unique(array_merge($this->no_redis_groups, $this->global_groups));
         $this->redis_connected = false;
     }
     /**
      * This approach is borrowed from Sivel and Boren. Use the salt for easy cache invalidation and for
      * multi single WP installs on the same server.
      */
     if (!defined('WP_CACHE_KEY_SALT')) {
         define('WP_CACHE_KEY_SALT', '');
     }
     // Assign global and blog prefixes for use with keys
     if (function_exists('is_multisite')) {
         $this->global_prefix = is_multisite() || defined('CUSTOM_USER_TABLE') && defined('CUSTOM_USER_META_TABLE') ? '' : $table_prefix;
         $this->blog_prefix = (is_multisite() ? $blog_id : $table_prefix) . ':';
     }
 }
Beispiel #14
0
 public function __construct()
 {
     parent::__construct();
     $app = $this;
     // default config
     $app['debug'] = true;
     $app['http_cache'] = false;
     $app['buzz.client'] = null;
     $app['monolog.level'] = \Monolog\Logger::ERROR;
     $app['redis.config'] = false;
     // array('host' => 'localhost', 'port' => 6379);
     $app['stats.config'] = ['enabled' => false];
     $app['rate_limiting.config'] = ['enabled' => false, 'limit' => 3];
     $app['proxy'] = false;
     $app['proxy_server.address'] = null;
     /// load config
     $config = __DIR__ . '/../../config.php';
     if (stream_resolve_include_path($config)) {
         include $config;
     }
     // New Relic
     $app->register(new \Ekino\Bundle\NewRelicBundle\Silex\EkinoNewRelicServiceProvider(), ['new_relic.application_name' => false, 'new_relic.log_exceptions' => true]);
     // HTTP cache
     if ($app['http_cache']) {
         $app->register(new \Silex\Provider\HttpCacheServiceProvider(), ['http_cache.cache_dir' => __DIR__ . '/../../var/cache/', 'http_cache.options' => ['debug' => $app['debug']]]);
     }
     // Exception handler
     $app->error(function (\Exception $e, $code) use($app) {
         if ($app['debug']) {
             return;
         }
         if ($e instanceof HttpException && $e->getStatusCode() == 429) {
             // don't log rate limiting
         } else {
             $app['stats']->error($e);
         }
         $errors = [['message' => $e->getMessage()]];
         $result = ['errors' => $errors];
         return $app->json($result, $code);
     });
     // Monolog
     $app->register(new \Silex\Provider\MonologServiceProvider(), ['monolog.logfile' => __DIR__ . '/../../var/logs/transport.log', 'monolog.level' => $app['monolog.level'], 'monolog.name' => 'transport']);
     $app->before(function (Request $request) use($app) {
         $app['monolog']->addInfo('- ' . $request->getClientIp() . ' ' . $request->headers->get('referer') . ' ' . $request->server->get('HTTP_USER_AGENT'));
     });
     // if hosted behind a reverse proxy
     if ($app['proxy']) {
         $proxies = [$_SERVER['REMOTE_ADDR']];
         if (is_array($app['proxy'])) {
             $proxies = $app['proxy'];
         }
         Request::setTrustedProxies($proxies);
     }
     // Initialize buzz client
     $client = $app['buzz.client'] ?: new \Buzz\Client\FileGetContents();
     if ($app['proxy_server.address']) {
         $client->setProxy($app['proxy_server.address']);
     }
     // create Transport API
     $app['api'] = new \Transport\API(new \Buzz\Browser($client));
     // allow cross-domain requests, enable cache
     $app->after(function (Request $request, Response $response) use($app) {
         $response->headers->set('Access-Control-Allow-Origin', '*');
         if ($app['http_cache']) {
             $response->headers->set('Cache-Control', 's-maxage=30, public');
         }
     });
     // Serializer
     $app['serializer'] = $app->share(function () use($app) {
         $fields = $app['request']->get('fields') ?: [];
         return new Serializer([new FieldsNormalizer($fields)], ['json' => new JsonEncoder()]);
     });
     // Redis
     $redis = null;
     try {
         if ($app['redis.config']) {
             $redis = new \Predis\Client($app['redis.config']);
             $redis->connect();
         }
     } catch (\Exception $e) {
         $app['monolog']->addError($e->getMessage());
         $redis = null;
     }
     // statistics
     $app['stats'] = new \Transport\Statistics($redis, $app['stats.config']['enabled']);
     $app->after(function (Request $request, Response $response) use($app) {
         if ($response->getStatusCode() !== 429) {
             $app['stats']->call();
             $app['stats']->resource($request->getPathInfo());
         }
     });
     // rate limiting
     $app['rate_limiting'] = new \Transport\RateLimiting($redis, $app['rate_limiting.config']['enabled'], $app['rate_limiting.config']['limit']);
     $app->before(function (Request $request) use($app) {
         if ($app['rate_limiting']->isEnabled()) {
             $ip = $request->getClientIp();
             if ($app['rate_limiting']->hasReachedLimit($ip)) {
                 throw new HttpException(429, 'Rate limit of ' . $app['rate_limiting']->getLimit() . ' requests per second exceeded');
             }
             $app['rate_limiting']->increment($ip);
         }
     });
     $app->after(function (Request $request, Response $response) use($app) {
         if ($app['rate_limiting']->isEnabled()) {
             $ip = $request->getClientIp();
             $response->headers->set('X-Rate-Limit-Limit', $app['rate_limiting']->getLimit());
             $response->headers->set('X-Rate-Limit-Remaining', $app['rate_limiting']->getRemaining($ip));
             $response->headers->set('X-Rate-Limit-Reset', $app['rate_limiting']->getReset());
         }
     });
     // home
     $app->get('/', function () use($app) {
         return file_get_contents('index.html');
     })->bind('home');
     // api
     $app->get('/v1/', function () use($app) {
         return $app->json(['date' => date('c'), 'author' => 'Opendata.ch', 'version' => '1.0']);
     })->bind('api');
     /**
      * Search locations.
      *
      * Returns the matching locations for the given parameters. Either query or ( x and y ) are required.
      *
      * The locations in the response are scored to determine which is the most exact location.
      *
      * This method can return a refine response, what means that the request has to be redone.
      *
      * @SWG\Get(
      *     path="/locations",
      *     tags={"locations"},
      *     @SWG\Parameter(
      *         name="query",
      *         in="query",
      *         description="Specifies the location name to search for (e.g. Basel)",
      *         type="string"
      *     ),
      *     @SWG\Parameter(
      *         name="x",
      *         in="query",
      *         description="Latitude (e.g. 47.476001)",
      *         type="number"
      *     ),
      *     @SWG\Parameter(
      *         name="y",
      *         in="query",
      *         description="Longitude (e.g. 8.306130)",
      *         type="number"
      *     ),
      *     @SWG\Parameter(
      *         name="type",
      *         in="query",
      *         description="Only with `query` parameter. Specifies the location type, possible types are:<ul><li>`all` (default): Looks up for all types of locations</li><li>`station`: Looks up for stations (train station, bus station)</li><li>`poi`: Looks up for points of interest (Clock tower, China garden)</li><li>`address`: Looks up for an address (Zurich Bahnhofstrasse 33)</li></ul>",
      *         type="string"
      *     ),
      *     @SWG\Parameter(
      *         name="transportations[]",
      *         in="query",
      *         description="Only with `x` and `y` parameter. Transportation means; one or more of `ice_tgv_rj`, `ec_ic`, `ir`, `re_d`, `ship`, `s_sn_r`, `bus`, `cableway`, `arz_ext`, `tramway_underground` (e.g. transportations[]=ec_ic&transportations[]=bus)",
      *         type="string"
      *     ),
      *     @SWG\Response(
      *         response="200",
      *         description="List of locations",
      *         @SWG\Schema(
      *             type="object",
      *             @SWG\Property(
      *                  property="stations",
      *                  type="array",
      *                  @SWG\Items(ref="#/definitions/Location")
      *             ),
      *         ),
      *     ),
      * )
      */
     $app->get('/v1/locations', function (Request $request) use($app) {
         $stations = [];
         $x = $request->get('x') ?: null;
         $y = $request->get('y') ?: null;
         $transportations = $request->get('transportations');
         if ($x && $y) {
             $query = new NearbyQuery($x, $y);
             if ($transportations) {
                 $query->transportations = (array) $transportations;
             }
             $stations = $app['api']->findNearbyLocations($query);
         }
         $query = $request->get('query');
         if ($query) {
             $query = new LocationQuery($query, $request->get('type'));
             $stations = $app['api']->findLocations($query);
         }
         $result = ['stations' => $stations];
         $json = $app['serializer']->serialize((object) $result, 'json');
         return new Response($json, 200, ['Content-Type' => 'application/json']);
     })->bind('locations');
     /**
      * Search connections.
      *
      * Returns the next connections from a location to another.
      *
      * @SWG\Get(
      *     path="/connections",
      *     tags={"connections"},
      *     @SWG\Parameter(
      *         name="from",
      *         in="query",
      *         description="Specifies the departure location of the connection (e.g. Lausanne)",
      *         type="string",
      *         required=true
      *     ),
      *     @SWG\Parameter(
      *         name="to",
      *         in="query",
      *         description="Specifies the arrival location of the connection (e.g. Genève)",
      *         type="string",
      *         required=true
      *     ),
      *     @SWG\Parameter(
      *         name="via[]",
      *         in="query",
      *         description="Specifies up to five via locations. When specifying several vias, array notation (via[]=Bern&via[]=Fribourg) is required",
      *         type="string"
      *     ),
      *     @SWG\Parameter(
      *         name="date",
      *         in="query",
      *         description="Date of the connection, in the format YYYY-MM-DD (e.g. 2012-03-25)",
      *         type="string"
      *     ),
      *     @SWG\Parameter(
      *         name="time",
      *         in="query",
      *         description="Time of the connection, in the format hh:mm (e.g. 17:30)",
      *         type="string"
      *     ),
      *     @SWG\Parameter(
      *         name="isArrivalTime",
      *         in="query",
      *         description="defaults to `0`, if set to `1` the passed `date` and `time` is the arrival time",
      *         type="integer"
      *     ),
      *     @SWG\Parameter(
      *         name="transportations[]",
      *         in="query",
      *         description="Transportation means; one or more of `ice_tgv_rj`, `ec_ic`, `ir`, `re_d`, `ship`, `s_sn_r`, `bus`, `cableway`, `arz_ext`, `tramway_underground` (e.g. transportations[]=ec_ic&transportations[]=bus)",
      *         type="string"
      *     ),
      *     @SWG\Parameter(
      *         name="limit",
      *         in="query",
      *         description="1 - 6. Specifies the number of connections to return. If several connections depart at the same time they are counted as 1.",
      *         type="integer"
      *     ),
      *     @SWG\Parameter(
      *         name="page",
      *         in="query",
      *         description="0 - 10. Allows pagination of connections. Zero-based, so first page is 0, second is 1, third is 2 and so on.",
      *         type="integer"
      *     ),
      *     @SWG\Parameter(
      *         name="direct",
      *         in="query",
      *         description="defaults to `0`, if set to `1` only direct connections are allowed",
      *         type="integer"
      *     ),
      *     @SWG\Parameter(
      *         name="sleeper",
      *         in="query",
      *         description="defaults to `0`, if set to `1` only night trains containing beds are allowed, implies `direct=1`",
      *         type="integer"
      *     ),
      *     @SWG\Parameter(
      *         name="couchette",
      *         in="query",
      *         description="defaults to `0`, if set to `1` only night trains containing couchettes are allowed, implies `direct=1`",
      *         type="integer"
      *     ),
      *     @SWG\Parameter(
      *         name="bike",
      *         in="query",
      *         description="defaults to `0`, if set to `1` only trains allowing the transport of bicycles are allowed",
      *         type="integer"
      *     ),
      *     @SWG\Parameter(
      *         name="accessibility",
      *         in="query",
      *         description="Possible values are `independent_boarding`, `assisted_boarding`, and `advanced_notice`",
      *         type="string"
      *     ),
      *     @SWG\Response(
      *         response="200",
      *         description="A list of connections",
      *         @SWG\Schema(
      *             type="object",
      *             @SWG\Property(
      *                  property="connections",
      *                  type="array",
      *                  description="Found connections",
      *                  @SWG\Items(ref="#/definitions/Connection")
      *             ),
      *             @SWG\Property(
      *                  property="from",
      *                  description="Departure station of search",
      *                  ref="#/definitions/Station"
      *             ),
      *             @SWG\Property(
      *                  property="to",
      *                  description="Arrival station of search",
      *                  ref="#/definitions/Station"
      *             ),
      *             @SWG\Property(
      *                  property="stations",
      *                  type="array",
      *                  description="All stations from query",
      *                  @SWG\Items(ref="#/definitions/Station")
      *             ),
      *         ),
      *     ),
      * )
      */
     $app->get('/v1/connections', function (Request $request) use($app) {
         $query = LocationQueryParser::create($request);
         // get stations
         $stations = $app['api']->findLocations($query);
         // get connections
         $connections = [];
         $from = reset($stations['from']) ?: null;
         $to = reset($stations['to']) ?: null;
         $via = [];
         foreach ($stations as $k => $v) {
             if (preg_match('/^via[0-9]+$/', $k) && $v) {
                 $via[] = reset($v);
             }
         }
         if ($from && $to) {
             $app['stats']->station($from);
             $app['stats']->station($to);
             $query = ConnectionQueryParser::create($request, $from, $to, $via);
             $errors = ConnectionQueryParser::validate($query);
             if ($errors) {
                 return $app->json(['errors' => $errors], 400);
             }
             $connections = $app['api']->findConnections($query);
         }
         $result = ['connections' => $connections, 'from' => $from, 'to' => $to, 'stations' => $stations];
         $json = $app['serializer']->serialize((object) $result, 'json');
         return new Response($json, 200, ['Content-Type' => 'application/json']);
     })->bind('connections');
     /**
      * Get station board.
      *
      * Returns the next connections leaving from a specific location.
      *
      * @SWG\Get(
      *     path="/stationboard",
      *     tags={"stationboard"},
      *     @SWG\Parameter(
      *         name="station",
      *         in="query",
      *         description="Specifies the location of which a stationboard should be returned (e.g. Aarau)",
      *         type="string",
      *         required=true
      *     ),
      *     @SWG\Parameter(
      *         name="id",
      *         in="query",
      *         description="The id of the station whose stationboard should be returned. Alternative to the station parameter; one of these two is required. If both an id and a station are specified the id has precedence. e.g. 8503059 (for Zurich Stadelhofen)",
      *         type="string"
      *     ),
      *     @SWG\Parameter(
      *         name="limit",
      *         in="query",
      *         description="Number of departing connections to return. This is not a hard limit - if multiple connections leave at the same time it'll return any connections that leave at the same time as the last connection within the limit. For example: `limit=4` will return connections leaving at: 19:30, 19:32, 19:32, 19:35, 19:35. Because one of the connections leaving at 19:35 is within the limit, all connections leaving at 19:35 are shown.",
      *         type="integer"
      *     ),
      *     @SWG\Parameter(
      *         name="transportations[]",
      *         in="query",
      *         description="Transportation means; one or more of `ice_tgv_rj`, `ec_ic`, `ir`, `re_d`, `ship`, `s_sn_r`, `bus`, `cableway`, `arz_ext`, `tramway_underground` (e.g. transportations[]=ec_ic&transportations[]=bus)",
      *         type="string"
      *     ),
      *     @SWG\Parameter(
      *         name="datetime",
      *         in="query",
      *         description="Date and time of departing connections, in the format `YYYY-MM-DD hh:mm` (e.g. 2012-03-25 17:30)",
      *         type="string"
      *     ),
      *     @SWG\Parameter(
      *         name="type",
      *         in="query",
      *         description="`departure` (default) or `arrival`",
      *         type="string"
      *     ),
      *     @SWG\Response(
      *         response="200",
      *         description="Stationboard",
      *         @SWG\Schema(
      *             type="object",
      *             @SWG\Property(
      *                  property="station",
      *                  description="The first matched location based on the query. The stationboard will be displayed if this is a station.",
      *                  ref="#/definitions/Station"
      *             ),
      *             @SWG\Property(
      *                  property="stationboard",
      *                  description="A list of journeys with the stop of the line leaving from that station.",
      *                  type="array",
      *                  @SWG\Items(ref="#/definitions/Journey")
      *             ),
      *         ),
      *     ),
      * )
      */
     $app->get('/v1/stationboard', function (Request $request) use($app) {
         $stationboard = [];
         $limit = $request->get('limit', 40);
         if ($limit > 420) {
             return new Response('Invalid value for Parameter `limit`.', 400);
         }
         $date = $request->get('date');
         if (!$date) {
             $date = $request->get('datetime');
         }
         if ($date) {
             $date = new \DateTime($date, new \DateTimeZone('Europe/Zurich'));
         }
         $transportations = $request->get('transportations');
         $station = $request->get('station') ?: $request->get('id');
         $boardType = $request->get('type');
         $query = new LocationQuery($station, 'station');
         $stations = $app['api']->findLocations($query);
         $station = reset($stations);
         if ($station instanceof Station) {
             $app['stats']->station($station);
             $query = new StationBoardQuery($station, $date);
             if ($transportations) {
                 $query->transportations = (array) $transportations;
             }
             if ($boardType) {
                 $query->boardType = $boardType;
             }
             $query->maxJourneys = $limit;
             $stationboard = $app['api']->getStationBoard($query);
         }
         $result = ['station' => $station, 'stationboard' => $stationboard];
         $json = $app['serializer']->serialize((object) $result, 'json');
         return new Response($json, 200, ['Content-Type' => 'application/json']);
     })->bind('stationboard');
     // Swagger
     $app->get('/swagger.json', function () use($app) {
         $swagger = \Swagger\scan(__DIR__);
         return new Response($swagger, 200, ['Content-Type' => 'application/json']);
     })->bind('swagger');
 }
 /**
  * @return null|\Predis\Client The Redis client, or null.
  */
 private static function getPRedisClient()
 {
     // just once
     if (self::$sPRedisClient == null) {
         $client = new Predis\Client(array('scheme' => 'tcp', 'host' => '127.0.0.1', 'port' => 6379));
         try {
             $client->connect();
         } catch (Exception $e) {
             // connection unsuccessful... do nothing
             return null;
         }
         self::$sPRedisClient = $client;
     }
     return self::$sPRedisClient;
 }