dolibarr  7.0.0-beta
index.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (C) 2015 Jean-Fran├žois Ferry <jfefe@aternatik.fr>
3  * Copyright (C) 2016 Laurent Destailleur <eldy@users.sourceforge.net>
4  * Copyright (C) 2017 Regis Houssin <regis.houssin@capnetworks.com>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program. If not, see <http://www.gnu.org/licenses/>.
18  */
19 
27 //if (! defined('NOREQUIREUSER')) define('NOREQUIREUSER','1');
28 //if (! defined('NOREQUIREDB')) define('NOREQUIREDB','1');
29 //if (! defined('NOREQUIRESOC')) define('NOREQUIRESOC','1');
30 //if (! defined('NOREQUIRETRAN')) define('NOREQUIRETRAN','1');
31 if (! defined('NOCSRFCHECK')) define('NOCSRFCHECK','1'); // Do not check anti CSRF attack test
32 //if (! defined('NOSTYLECHECK')) define('NOSTYLECHECK','1'); // Do not check style html tag into posted data
33 if (! defined('NOTOKENRENEWAL')) define('NOTOKENRENEWAL','1'); // Do not check anti POST attack test
34 if (! defined('NOREQUIREMENU')) define('NOREQUIREMENU','1'); // If there is no need to load and show top and left menu
35 if (! defined('NOREQUIREHTML')) define('NOREQUIREHTML','1'); // If we don't need to load the html.form.class.php
36 if (! defined('NOREQUIREAJAX')) define('NOREQUIREAJAX','1'); // Do not load ajax.lib.php library
37 if (! defined("NOLOGIN")) define("NOLOGIN",'1'); // If this page is public (can be called outside logged session)
38 
39 
40 // Force entity if a value is provided into HTTP header. Otherwise, will use the entity of user of token used.
41 if (! empty($_SERVER['HTTP_DOLAPIENTITY'])) define("DOLENTITY", (int) $_SERVER['HTTP_DOLAPIENTITY']);
42 
43 
44 $res=0;
45 if (! $res && file_exists("../main.inc.php")) $res=include '../main.inc.php';
46 if (! $res) die("Include of main fails");
47 
48 require_once DOL_DOCUMENT_ROOT.'/includes/restler/framework/Luracast/Restler/AutoLoader.php';
49 
50 call_user_func(function () {
51  $loader = Luracast\Restler\AutoLoader::instance();
52  spl_autoload_register($loader);
53  return $loader;
54 });
55 
56 require_once DOL_DOCUMENT_ROOT.'/api/class/api.class.php';
57 require_once DOL_DOCUMENT_ROOT.'/api/class/api_access.class.php';
58 require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
59 
60 
61 
62 // Enable and test if module Api is enabled
63 if (empty($conf->global->MAIN_MODULE_API))
64 {
65  $langs->load("admin");
66  dol_syslog("Call Dolibarr API interfaces with module REST disabled");
67  print $langs->trans("WarningModuleNotActive",'Api').'.<br><br>';
68  print $langs->trans("ToActivateModule");
69  exit;
70 }
71 
72 // Test if explorer is not disabled
73 if (preg_match('/api\/index\.php\/explorer/', $_SERVER["PHP_SELF"]) && ! empty($conf->global->API_EXPLORER_DISABLED))
74 {
75  $langs->load("admin");
76  dol_syslog("Call Dolibarr API interfaces with module REST disabled");
77  print $langs->trans("WarningAPIExplorerDisabled").'.<br><br>';
78  exit;
79 }
80 
81 
82 // This 2 lines are usefull only if we want to exclude some Urls from the explorer
83 //use Luracast\Restler\Explorer;
84 //Explorer::$excludedPaths = array('/categories');
85 
86 
87 // Analyze URLs
88 // index.php/explorer do a redirect to index.php/explorer/
89 // index.php/explorer/ called by swagger to build explorer page
90 // index.php/explorer/.../....png|.css|.js called by swagger for resources to build explorer page
91 // index.php/explorer/resources.json called by swagger to get list of all services
92 // index.php/explorer/resources.json/xxx called by swagger to get detail of services xxx
93 // index.php/xxx called by any REST client to run API
94 
95 
96 preg_match('/index\.php\/([^\/]+)(.*)$/', $_SERVER["PHP_SELF"], $reg);
97 // .../index.php/categories?sortfield=t.rowid&sortorder=ASC
98 
99 
100 // Set the flag to say to refresh (when we reload the explorer, production must be for API call only)
101 $refreshcache=false;
102 if (! empty($reg[1]) && $reg[1] == 'explorer' && ($reg[2] == '/swagger.json' || $reg[2] == '/swagger.json/root' || $reg[2] == '/resources.json' || $reg[2] == '/resources.json/root'))
103 {
104  $refreshcache=true;
105 }
106 
107 
108 $api = new DolibarrApi($db, '', $refreshcache);
109 //var_dump($api->r->apiVersionMap);
110 
111 // Enable the Restler API Explorer.
112 // See https://github.com/Luracast/Restler-API-Explorer for more info.
113 $api->r->addAPIClass('Luracast\\Restler\\Explorer');
114 
115 $api->r->setSupportedFormats('JsonFormat', 'XmlFormat', 'UploadFormat'); // 'YamlFormat'
116 $api->r->addAuthenticationClass('DolibarrApiAccess','');
117 
118 // Define accepted mime types
119 UploadFormat::$allowedMimeTypes = array('image/jpeg', 'image/png', 'text/plain', 'application/octet-stream');
120 
121 
122 
123 // Call Explorer file for all APIs definitions
124 if (! empty($reg[1]) && $reg[1] == 'explorer' && ($reg[2] == '/swagger.json' || $reg[2] == '/swagger.json/root' || $reg[2] == '/resources.json' || $reg[2] == '/resources.json/root'))
125 {
126  // Scan all API files to load them
127 
128  $listofapis = array();
129 
130  $modulesdir = dolGetModulesDirs();
131  foreach ($modulesdir as $dir)
132  {
133  // Search available module
134  dol_syslog("Scan directory ".$dir." for module descriptor files, then search for API files");
135 
136  $handle=@opendir(dol_osencode($dir));
137  if (is_resource($handle))
138  {
139  while (($file = readdir($handle))!==false)
140  {
141  if (is_readable($dir.$file) && preg_match("/^mod(.*)\.class\.php$/i",$file,$regmod))
142  {
143  $module = strtolower($regmod[1]);
144  $moduledirforclass = getModuleDirForApiClass($module);
145  $modulenameforenabled = $module;
146  if ($module == 'propale') { $modulenameforenabled='propal'; }
147  if ($module == 'supplierproposal') { $modulenameforenabled='supplier_proposal'; }
148 
149  dol_syslog("Found module file ".$file." - module=".$module." - modulenameforenabled=".$modulenameforenabled." - moduledirforclass=".$moduledirforclass);
150 
151  // Defined if module is enabled
152  $enabled=true;
153  if (empty($conf->$modulenameforenabled->enabled)) $enabled=false;
154 
155  if ($enabled)
156  {
157  // If exists, load the API class for enable module
158  // Search files named api_<object>.class.php into /htdocs/<module>/class directory
159  // @todo : use getElementProperties() function ?
160  $dir_part = dol_buildpath('/'.$moduledirforclass.'/class/');
161 
162  $handle_part=@opendir(dol_osencode($dir_part));
163  if (is_resource($handle_part))
164  {
165  while (($file_searched = readdir($handle_part))!==false)
166  {
167  if ($file_searched == 'api_access.class.php') continue;
168 
169  if (is_readable($dir_part.$file_searched) && preg_match("/^api_(.*)\.class\.php$/i",$file_searched,$regapi))
170  {
171  $classname = ucwords($regapi[1]);
172  $classname = str_replace('_', '', $classname);
173  require_once $dir_part.$file_searched;
174  if (class_exists($classname.'Api'))
175  {
176  //dol_syslog("Found API by index.php: classname=".$classname."Api for module ".$dir." into ".$dir_part.$file_searched);
177  $listofapis[strtolower($classname.'Api')] = $classname.'Api';
178  }
179  elseif (class_exists($classname))
180  {
181  //dol_syslog("Found API by index.php: classname=".$classname." for module ".$dir." into ".$dir_part.$file_searched);
182  $listofapis[strtolower($classname)] = $classname;
183  }
184  else
185  {
186  dol_syslog("We found an api_xxx file (".$file_searched.") but class ".$classname." does not exists after loading file", LOG_WARNING);
187  }
188  }
189  }
190  }
191  }
192  }
193  }
194  }
195  }
196 
197  // Sort the classes before adding them to Restler.
198  // The Restler API Explorer shows the classes in the order they are added and it's a mess if they are not sorted.
199  asort($listofapis);
200  foreach ($listofapis as $apiname => $classname)
201  {
202  $api->r->addAPIClass($classname, $apiname);
203  }
204  //var_dump($api->r);
205 }
206 
207 // Call one APIs or one definition of an API
208 if (! empty($reg[1]) && ($reg[1] != 'explorer' || ($reg[2] != '/swagger.json' && $reg[2] != '/resources.json' && preg_match('/^\/(swagger|resources)\.json\/(.+)$/', $reg[2], $regbis) && $regbis[2] != 'root')))
209 {
210  $module = $reg[1];
211  if ($module == 'explorer') // If we call page to explore details of a service
212  {
213  $module = $regbis[2];
214  }
215 
216  $module=strtolower($module);
217  $moduledirforclass = getModuleDirForApiClass($module);
218 
219  // Load a dedicated API file
220  dol_syslog("Load a dedicated API file moduledirforclass=".$moduledirforclass);
221 
222  $tmpmodule = $module;
223  if ($tmpmodule != 'api')
224  $tmpmodule = preg_replace('/api$/i', '', $tmpmodule);
225  $classfile = str_replace('_', '', $tmpmodule);
226  if ($module == 'supplierproposals')
227  $classfile = 'supplier_proposals';
228  if ($module == 'supplierorders')
229  $classfile = 'supplier_orders';
230  if ($module == 'supplierinvoices')
231  $classfile = 'supplier_invoices';
232  $dir_part_file = dol_buildpath('/' . $moduledirforclass . '/class/api_' . $classfile . '.class.php', 0, 2);
233 
234  $classname = ucwords($module);
235 
236  dol_syslog('Search /' . $moduledirforclass . '/class/api_' . $classfile . '.class.php => dir_part_file=' . $dir_part_file . ' classname=' . $classname);
237 
238  $res = false;
239  if ($dir_part_file)
240  $res = include_once $dir_part_file;
241  if (! $res) {
242  print 'API not found (failed to include API file)';
243  header('HTTP/1.1 501 API not found (failed to include API file)');
244  exit(0);
245  }
246 
247  if (class_exists($classname))
248  $api->r->addAPIClass($classname);
249 }
250 
251 // TODO If not found, redirect to explorer
252 //var_dump($api->r->apiVersionMap);
253 //exit;
254 
255 // Call API (we suppose we found it)
256 $api->r->handle();
dol_osencode($str)
Return a string encoded into OS filesystem encoding.
getModuleDirForApiClass($module)
Get name of directory where the api_...class.php file is stored.
dolGetModulesDirs($subdir='')
Return list of modules directories.
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
Class for API REST v1.
Definition: api.class.php:29
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='')
Write log message into outputs.
print
Draft customers invoices.
Definition: index.php:91