Add bank account support
[dolibarr-api.git] / index.php
1 <?php
2
3 /*** DOLIBARR ***/
4 require("dolibarr/master.inc.php");
5 require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php';
6 require_once(DOL_DOCUMENT_ROOT."/adherents/class/adherent.class.php");
7 require_once(DOL_DOCUMENT_ROOT."/adherents/class/adherent_type.class.php");
8 require_once(DOL_DOCUMENT_ROOT."/societe/class/societe.class.php");
9 require_once(DOL_DOCUMENT_ROOT."/societe/class/companybankaccount.class.php");
10 require_once(DOL_DOCUMENT_ROOT."/core/class/cpays.class.php");
11 /****************/
12
13
14 require 'Array2XML.php';
15 require 'Slim/Slim.php';
16 \Slim\Slim::registerAutoloader();
17 require 'mediatypehandler.php';
18
19 $app = new \Slim\Slim();
20
21 $app->config('debug', true);
22
23 $log = $app->getLog();
24 $log->setEnabled(true);
25 $log->setLevel(\Slim\Log::WARN);
26
27 // automatically negociate content-type and decode data and encode response
28 $app->add(new MediaTypeMiddleware());
29
30 $app->notFound(function () use ($app) {
31     echo marsh_response(array('errors' => array(new APIError('Path not found', 'dolibarr.api.InvalidPath', 1001))));
32 });
33
34 $return405=function() use ($app) {
35     halt_error(405, new APIError('Method not allowed', 'dolibarr.api.MethodNotAllowed', 1002));
36 };
37
38 function add_allow() {
39     $methods=func_get_args();
40     if(count($methods) == 1 && is_array($methods[0])) {
41         $methods=$methods[0];
42     }
43     return function (\Slim\Route $route) use ($methods) {
44         $app = \Slim\Slim::getInstance();
45         $app->response()['Allow'] = implode(', ', $methods);
46     };
47 };
48
49 /**
50  * Exception class to wrap API errors
51  */
52 class APIException extends Exception implements JsonSerializable {
53     private $errors;
54     private $status;
55
56     public function __construct($status, $errors) {
57         $this->status=$status;
58         $this->errors=$errors;
59     }
60
61     public function addError($err) {
62         $this->errors[]=$err;
63     }
64
65     public function getErrors() {
66         return $this->errors;
67     }
68
69     public function getStatus() {
70         return $this->status;
71     }
72
73     public function hasErrors() {
74         return (bool)count($this->errors);
75     }
76
77     public function __toString() {
78         return __CLASS__;
79     }
80
81     public function jsonSerialize() {
82         return array('errors' => $this->errors);
83     }
84 }
85
86 class APIError implements JsonSerializable, IteratorAggregate {
87     protected $error;
88     protected $error_code;
89     protected $message;
90
91     public function __construct($message, $error='cafai.api.GenericError', $errcode=1000) {
92         $this->error      = $error;
93         $this->error_code = $errcode;
94         $this->message    = $message;
95     }
96
97     public function jsonSerialize() {
98         return array('error' => $this->error, 
99                      'error_code' => $this->error_code,
100                      'message' => $this->message);
101     }
102
103     public function getIterator() {
104         return new ArrayIterator($this->jsonSerialize());
105
106     }
107 }
108
109 class APISimpleError extends APIError {
110     public function __construct($message) {
111         parent::__construct($message, static::error, static::error_code);
112     }
113 }
114
115 class APIObjectNotFoundError extends APISimpleError {
116     const error='dolibarr.api.ObjectNotFound';
117     const error_code=1003;
118 }
119
120 class APIInputError extends APISimpleError {
121     const error='dolibarr.api.InputError';
122     const error_code=1010;
123 }
124
125 class APIMissingParamError extends APIError {
126     const error_base='dolibarr.api.MissingParam';
127     const error_code=1011;
128     public function __construct($target, $message) {
129         $error=self::error_base.".$target";
130         parent::__construct($message, $error, self::error_code);
131     }
132 }
133
134 class APIInvalidParamError extends APIError {
135     const error_base='dolibarr.api.InvalidParam';
136     const error_code=1012;
137     public function __construct($target, $message) {
138         $error=self::error_base.".$target";
139         parent::__construct($message, $error, self::error_code);
140     }
141 }
142
143 class APIInternalError extends APISimpleError {
144     const error='dolibarr.api.InternalError';
145     const error_code=1020;
146 }
147
148 class APIDatabaseError extends APIError {
149     const error='dolibarr.api.DatabaseError';
150     const error_code=1021;
151     public function __construct($message, $db, $error='', $code=0) {
152         global $log, $app;
153         $debug_mode=$app->config('debug');
154
155         $trace=(new Exception)->getTraceAsString();
156         $log->error("Database Error:\n".
157                     "\tclient: ".$app->request()->getIp()."\n".
158                     "\tpath: ".$app->request()->getPath()."\n".
159                     "\tdata: ".@json_encode($app->request()->getBody())."\n".
160                     "\terr msg: ".$message."\n".
161                     "\tinfo: error=\"".$error."\" code=".$code."\n".
162                     "\tsql error: ".$db->lasterrno.'; '.$db->lasterror."\n".
163                     "\tquery: ".$db->lastqueryerror."\n".
164                     "\ttrace:\n".preg_replace("/^#0 .*?\n/", '', $trace)."\n");
165
166         if($debug_mode)
167             parent::__construct($message, self::error, self::error_code);
168         else
169             /* Mask database errors on production... */
170             parent::__construct("", APIInternalError::error, APIInternalError::error_code);
171     }
172
173 }
174
175
176 function halt_error($status, $rest_error) {
177     $app = \Slim\Slim::getInstance();
178     $app->halt($status, marsh_response(array('errors' => array(
179         $rest_error
180     ))));
181 }
182
183 /**
184  * Check keys of an array for a constraint ($cb)
185  * returns the key that fail
186  */
187 function check_keys($data, $keys, $cb) {
188     $ret=array();
189     foreach($keys as &$v) {
190         if(!$cb($data, $v)) {
191             $ret[]=$v;
192         }
193     }
194     return $ret;
195 }
196
197 function buildPath($path) {
198     return \Slim\Slim::getInstance()->request()->getScriptName().$path;
199 }
200
201 function check_unmodified_since($unix_timestamp, $error_on_missing=true) {
202     global $app;
203     $h=$app->request()->headers('IF_UNMODIFIED_SINCE');
204     if($h === null && $error_on_missing) {
205         halt_error(403, new APIError('You must supply the If-Unmodified-Since header '.
206                                      'in order to call this method'));
207     }
208     $unmodified_since = strtotime($h);
209     return $unix_timestamp == $unmodified_since;
210 }
211
212 require 'adherents.php';
213 require 'misc.php';
214
215 $app->run();