Skip to content

Commit

Permalink
Fixed #56, #55, #54
Browse files Browse the repository at this point in the history
  • Loading branch information
Pieter Colpaert committed Dec 17, 2015
1 parent 6c7a2ee commit 9072f77
Show file tree
Hide file tree
Showing 15 changed files with 433 additions and 500 deletions.
28 changes: 0 additions & 28 deletions .env.example

This file was deleted.

4 changes: 1 addition & 3 deletions .gitignore
@@ -1,11 +1,9 @@
includes/dbConfig.php
storage
nbproject/
api/stats/.htpasswd
googlea35442edef93c3d8.html
push.php
api/push.php
.vagrant
.idea/
/vendor/
.env
composer.lock
36 changes: 0 additions & 36 deletions .htaccess

This file was deleted.

File renamed without changes.
25 changes: 12 additions & 13 deletions README.md
Expand Up @@ -10,26 +10,25 @@ Native applications using the iRail API and created or supported by the iRail te

All information can be found on [our blog at hello.iRail.be](http://hello.irail.be/).

## Configuration ##
## Installation for development purposes ##

For the configuration we used a package named dotenv.
There is a `.env example` located in the base folder from the project.
`composer install` wil write a nex .env file for your confiration.
The only thing you need to do is change the variables so it fits to your credentails.
_note: you'll also need to have [nodejs](https://nodejs.org) and [composer](http://getcomposer.org) installed on your system_

* Step 1: clone this repo
* Step 2: `composer install`
* Step 3: Run your test server: `php -S localhost:8008 -t api`
* Step 4: Enjoy your own iRail API at http://localhost:8008/connections.php?from=Gent%20Sint%20Pieters&to=Antwerp
* Step 3: make sure storage is writable: `chmod 777 storage`
* Step 4: Run your test server: `php -S localhost:8008 -t api`
* Step 5: Enjoy your own iRail API at http://localhost:8008/connections.php?from=Gent%20Sint%20Pieters&to=Antwerp

## Update stations list ##

Stations are updated through the irail/stations composer package. Just perform a `composer update` in the root of the project

## Some interesting links: ##
## More links ##

* Source: <http://github.com/iRail/iRail>
* Mailing: <http://list.irail.be/>
* Issue tracking: <https://github.com/iRail/iRail/issues>
* API: <http://api.irail.be/>
* BeTrains code: <https://github.com/iRail/BeTrains-for-Android>
* Our mailing list: http://list.irail.be/
* Our GTFS data dumps: http://gtfs.irail.be/
* Issue tracker: https://github.com/iRail/iRail/issues
* Just use our HTTP API: http://api.irail.be/
* BeTrains for Android app source code: https://github.com/iRail/BeTrains-for-Android
* Other repositories: https://github.com/iRail
142 changes: 53 additions & 89 deletions api/APICall.php
@@ -1,12 +1,16 @@
<?php
/* Copyright (C) 2011 by iRail vzw/asbl
* © 2015 by Open Knowledge Belgium vzw/asbl
*
* This class foresees in basic REST functionality. It will get all the GET vars and put it in a request. This requestobject will be given as a parameter to the DataRoot object, which will fetch the data and will give us a printer to print the header and body of the HTTP response.
* This class foresees in basic HTTP functionality. It will get all the GET vars and put it in a request.
* This requestobject will be given as a parameter to the DataRoot object, which will fetch the data and will give us a printer to print the header and body of the HTTP response.
*
* @author Pieter Colpaert
*/

use Dotenv\Dotenv;
use Monolog\Logger;
use Monolog\Handler\StreamHandler;
use Monolog\Formatter\LineFormatter;

ini_set('include_path', '.:data');
include_once 'data/DataRoot.php';
Expand All @@ -17,34 +21,44 @@ class APICall

protected $request;
protected $dataRoot;

//Hooks
private $logging = false;

protected $log;
/**
* @param $functionname
*/
public function __construct($functionname)
public function __construct($resourcename)
{
//When the HTTP request didn't set a User Agent, set it to a blank
if (! isset($_SERVER['HTTP_USER_AGENT'])) {
$_SERVER['HTTP_USER_AGENT'] = '';
}
//Default timezone is Brussels
date_default_timezone_set('Europe/Brussels');
//This is the current resource that's handled. E.g., stations, connections, vehicleinfo or liveboard
$this->resourcename = $resourcename;
try {
$requestname = ucfirst(strtolower($functionname)).'Request';
$this->log = new Logger('irapi');
//Create a formatter for the logs
$logFormatter = new LineFormatter("%datetime% | %message% | %context%\n", 'Y-m-d\TH:i:s');
$streamHandler = new StreamHandler(__DIR__ . '/../storage/irapi.log', Logger::INFO);
$streamHandler->setFormatter($logFormatter);
$this->log->pushHandler($streamHandler);
$requestname = ucfirst(strtolower($resourcename)).'Request';
include_once "requests/$requestname.php";
$this->request = new $requestname();
$this->dataRoot = new DataRoot($functionname, $this->VERSION, $this->request->getFormat());
$this->dataRoot = new DataRoot($resourcename, $this->VERSION, $this->request->getFormat());
} catch (Exception $e) {
$this->buildError($functionname, $e);
$this->buildError($e);
}
}

/**
* @param $fn
* @param $e
*/
private function buildError($fn, $e)
private function buildError($e)
{
$this->logError($fn, $e);
//get the right format - This is some duplicated code and I hate to write it
$format = '';
$this->logError($e);
//Build a nice output
$format = '';
if (isset($_GET['format'])) {
$format = $_GET['format'];
}
Expand All @@ -69,97 +83,47 @@ public function executeCall()
try {
$this->dataRoot->fetchData($this->request, $this->request->getSystem());
$this->dataRoot->printAll();
$this->logRequest();
$this->writeLog();
} catch (Exception $e) {
$this->buildError($this->dataRoot->getRootname(), $e);
$this->buildError($e);
}
}

public function disableLogging()
{
$this->logging = false;
}

/**
* @param $functionname
* @param Exception $e
*/
protected function logError($functionname, Exception $e)
protected function logError(Exception $e)
{
if (! isset($_SERVER['HTTP_USER_AGENT'])) {
$_SERVER['HTTP_USER_AGENT'] = 'unknown';
}
if ($this->logging) {
$this->writeLog($_SERVER['HTTP_USER_AGENT'], '', '', "Error in $functionname ".$e->getMessage(), $_SERVER['REMOTE_ADDR']);
if ($e->getCode() >= 500) {
$this->log->addCritical($this->resourcename . ',,,' . '"' . $e->getMessage() . '"');
} else {
$this->log->addError($this->resourcename . ',,,' . '"' . $e->getMessage() . '"');
}
}

//to be overriden

protected function logRequest()
{
if (! isset($_SERVER['HTTP_USER_AGENT'])) {
$_SERVER['HTTP_USER_AGENT'] = 'unknown';
}
if ($this->logging) {
$functionname = $this->dataRoot->getRootname();
$this->writeLog($_SERVER['HTTP_USER_AGENT'], '', '', "none ($functionname)", $_SERVER['REMOTE_ADDR']);
}
}

/**
* @param $ua
* @param $from
* @param $to
* @param $err
* @param $ip
* @throws Exception
*/
protected function writeLog($ua, $from, $to, $err, $ip)
{
// get time + date in rfc2822 format
date_default_timezone_set('Europe/Brussels');
$now = date('D, d M Y H:i:s');
if ($from == '') {
$from = 'EMPTY';
}
if ($to == '') {
$to = 'EMPTY';
}
if ($ua == '') {
$ua = '-';
}
self::connectToDB();
$from = mysql_real_escape_string($from);
$to = mysql_real_escape_string($to);
$err = mysql_real_escape_string($err);
$ip = mysql_real_escape_string($ip);
$ua = mysql_real_escape_string($ua);
// insert in db
try {
$dotenv = new Dotenv(dirname(__DIR__));
$dotenv->load();

$query = "
INSERT INTO $api_table ($api_c2, $api_c3, $api_c4, $api_c5, $api_c6, $api_c7, $api_c8)
VALUES('$now', '$ua', '$from', '$to', '$err', '$ip', '".$_ENV['apiServerName']."')";

$result = mysql_query($query);
} catch (Exception $e) {
echo 'Error writing to the database.';
}
}

public static function connectToDB()
{
try {
$dotenv = new Dotenv(dirname(__DIR__));
$dotenv->load();

mysql_pconnect($_ENV['apiHost'], $_ENV['apiUser'], $_ENV['apiPassword']);
mysql_select_db($_ENV['apiDatabase']);
} catch (Exception $e) {
throw new Exception('Error connecting to the database.', 3);
protected function writeLog($err)
{
$query = [];
if ($this->resourcename === 'connections') {
$query['departureStop'] = $this->request->getFrom();
$query['arrivalStop'] = $this->request->getTo();
} else if ($this->resourcename === 'liveboard') {
$query['departureStop'] = $this->request->getStation();
} else if ($this->resourcename === 'vehicle') {
$query['vehicle'] = $this->request->getVehicleId();
}

$this->log->addInfo($this->resourcename, [
'query' => $query,
'user_agent' => $_SERVER['HTTP_USER_AGENT'],
'error' => $err
]);

}
}
12 changes: 1 addition & 11 deletions api/connections.php
Expand Up @@ -28,15 +28,5 @@
include_once '../vendor/autoload.php';
include_once 'APICall.php';
date_default_timezone_set('Europe/Brussels');

class ConnectionsCall extends APICall
{
protected function logRequest()
{
$r = $this->request;
parent::writeLog($_SERVER['HTTP_USER_AGENT'], $r->getFrom(), $r->getTo(), 'none (connections)', $_SERVER['REMOTE_ADDR']);
}
}

$call = new ConnectionsCall('connections');
$call = new APICall('connections');
$call->executeCall();
14 changes: 7 additions & 7 deletions api/data/DataRoot.php
Expand Up @@ -23,13 +23,13 @@ class DataRoot
* @internal param format $string the format of the document: json, json or XML
*/
public function __construct($rootname, $version, $format, $error = '')
{
{
//We're making this in the class form: Json or Xml or Jsonp
$format = ucfirst(strtolower($format));
//fallback for when callback is set but not the format= Jsonp
if (isset($_GET['callback']) && $format == 'Json') {
$format = 'Jsonp';
}
$format = ucfirst(strtolower($format));
//fallback for when callback is set but not the format= Jsonp
if (isset($_GET['callback']) && $format == 'Json') {
$format = 'Jsonp';
}
if (! file_exists("output/$format.php")) {
throw new Exception('Incorrect format specified. Please correct this and try again', 402);
}
Expand Down Expand Up @@ -81,7 +81,7 @@ public function fetchData($request, $SYSTEM)
} elseif ($e->getCode() == '300') {
throw new Exception($e->getMessage(), 300);
} else {
throw new Exception('Could not get data. Please report this problem to iRail@list.iRail.be.', 502);
throw new Exception('Could not get data. Please report this problem to iRail@list.iRail.be.', 500);
}
}
}
Expand Down

0 comments on commit 9072f77

Please sign in to comment.