diff --git a/htdocs/api/class/api_login.class.php b/htdocs/api/class/api_login.class.php index 9b965e24c3362609c73a2df5f72499634d255ab0..c6b71e8b25c693e70f6f394fb039931c96cefb26 100644 --- a/htdocs/api/class/api_login.class.php +++ b/htdocs/api/class/api_login.class.php @@ -34,25 +34,25 @@ class Login /** * Login * - * Request the API token for a couple username / password. + * Request the API token for a couple username / password. * Using method POST is recommanded for security reasons (method GET is often logged by default by web servers with parameters so with login and pass into server log file). - * Both methods are provided for developer conveniance. Best is to not use at all the login API method and enter directly the "api_key" into field at the top right of page (Note: "api_key" can be found/set on the user page). - * + * Both methods are provided for developer conveniance. Best is to not use at all the login API method and enter directly the "api_key" into field at the top right of page (Note: "api_key" can be found/set on the user page). + * * @param string $login User login * @param string $password User password - * @param int $entity Entity (when multicompany module is used). Empty means 1=first company. + * @param string $entity Entity (when multicompany module is used). '' means 1=first company. * @param int $reset Reset token (0=get current token, 1=ask a new token and canceled old token. This means access using current existing API token of user will fails: new token will be required for new access) * @return array Response status and user token * * @throws RestException - * + * * @url GET / * @url POST / */ - public function index($login, $password, $entity=0, $reset=0) { + public function index($login, $password, $entity='', $reset=0) { global $conf, $dolibarr_main_authentication, $dolibarr_auto_user; - + // Authentication mode if (empty($dolibarr_main_authentication)) $dolibarr_main_authentication = 'http,dolibarr'; @@ -62,6 +62,8 @@ class Login // Set authmode $authmode = explode(',', $dolibarr_main_authentication); + if ($entity == '') $entity=1; + include_once DOL_DOCUMENT_ROOT . '/core/lib/security2.lib.php'; $login = checkLoginPassEntity($login, $password, $entity, $authmode); if (empty($login)) @@ -70,21 +72,21 @@ class Login } $token = 'failedtogenerateorgettoken'; - + $tmpuser=new User($this->db); - $tmpuser->fetch(0, $login); - + $tmpuser->fetch(0, $login, 0, 0, $entity); + // Renew the hash if (empty($tmpuser->api_key) || $reset) { // Generate token for user $token = dol_hash($login.uniqid().$conf->global->MAIN_API_KEY,1); - + // We store API token into database $sql = "UPDATE ".MAIN_DB_PREFIX."user"; $sql.= " SET api_key = '".$this->db->escape($token)."'"; $sql.= " WHERE login = '".$this->db->escape($login)."'"; - + dol_syslog(get_class($this)."::login", LOG_DEBUG); // No log $result = $this->db->query($sql); if (!$result) @@ -96,13 +98,14 @@ class Login { $token = $tmpuser->api_key; } - + //return token return array( 'success' => array( 'code' => 200, 'token' => $token, - 'message' => 'Welcome ' . $login.($reset?' - Token is new':' - This is your token (generated by a previous call). You can use it to make any REST API call, or enter it into the DOLAPIKEY field to use the Dolibarr API explorer.') + 'entity' => $tmpuser->entity, + 'message' => 'Welcome ' . $login.($reset?' - Token is new':' - This is your token (generated by a previous call). You can use it to make any REST API call, or enter it into the DOLAPIKEY field to use the Dolibarr API explorer.') ) ); } diff --git a/htdocs/api/index.php b/htdocs/api/index.php index 1e04590da14ce1f12c396def9cb3dbe6910799c9..7a99490a48fadca234360d401092df8b66ed7fdd 100644 --- a/htdocs/api/index.php +++ b/htdocs/api/index.php @@ -21,9 +21,7 @@ * \defgroup api Module DolibarrApi * \brief API loader * Search files htdocs/<module>/class/api_<module>.class.php - * \file htdocs/api/indexphp - * - * @todo User authentication with api_key + * \file htdocs/api/index.php */ if (! defined("NOLOGIN")) define("NOLOGIN",'1'); @@ -79,110 +77,94 @@ $api->r->addAuthenticationClass('DolibarrApiAccess',''); // Define accepted mime types UploadFormat::$allowedMimeTypes = array('image/jpeg', 'image/png', 'text/plain', 'application/octet-stream'); -$listofapis = array(); -$modulesdir = dolGetModulesDirs(); -foreach ($modulesdir as $dir) +// Analyze URLs +// index.php/explorer do a redirect to index.php/explorer/ +// index.php/explorer/ called by swagger to build explorer page +// index.php/explorer/.../....png|.css|.js called by swagger for resources to build explorer page +// index.php/explorer/resources.json called by swagger to get list of all services +// index.php/explorer/resources.json/xxx called by swagger to get detail of services xxx +// index.php/xxx called by any REST client to run API + + +preg_match('/index\.php\/([^\/]+)(.*)$/', $_SERVER["PHP_SELF"], $reg); +// .../index.php/categories?sortfield=t.rowid&sortorder=ASC + + +// Call Explorer file for all APIs definitions +if (! empty($reg[1]) && $reg[1] == 'explorer' && ($reg[2] == '/resources.json' || $reg[2] == '/resources.json/root')) { - /* - * Search available module - */ - //dol_syslog("Scan directory ".$dir." for API modules"); + // Scan all API files to load them + + $listofapis = array(); - $handle=@opendir(dol_osencode($dir)); - if (is_resource($handle)) + $modulesdir = dolGetModulesDirs(); + foreach ($modulesdir as $dir) { - while (($file = readdir($handle))!==false) + // Search available module + dol_syslog("Scan directory ".$dir." for module descriptor to after search for API files"); + + $handle=@opendir(dol_osencode($dir)); + if (is_resource($handle)) { - if (is_readable($dir.$file) && preg_match("/^mod(.*)\.class\.php$/i",$file,$reg)) + while (($file = readdir($handle))!==false) { - $module = strtolower($reg[1]); - $moduledirforclass = $module; - $moduleforperm = $module; + if (is_readable($dir.$file) && preg_match("/^mod(.*)\.class\.php$/i",$file,$reg)) + { + $module = strtolower($reg[1]); + $moduledirforclass = getModuleDirForApiClass($module); + $moduleforperm = $module; + if ($module == 'propale') { $moduleforperm='propal'; } - if ($module == 'propale') { - $moduledirforclass = 'comm/propal'; - $moduleforperm='propal'; - } - elseif ($module == 'agenda') { - $moduledirforclass = 'comm/action'; - } - elseif ($module == 'adherent') { - $moduledirforclass = 'adherents'; - } - elseif ($module == 'banque') { - $moduledirforclass = 'compta/bank'; - } - elseif ($module == 'categorie') { - $moduledirforclass = 'categories'; - } - elseif ($module == 'facture') { - $moduledirforclass = 'compta/facture'; - } - elseif ($module == 'project') { - $moduledirforclass = 'projet'; - } - elseif ($module == 'task') { - $moduledirforclass = 'projet'; - } - elseif ($module == 'stock') { - $moduledirforclass = 'product/stock'; - } - elseif ($module == 'fournisseur') { - $moduledirforclass = 'fourn'; - } - //dol_syslog("Found module file ".$file." - module=".$module." - moduledirforclass=".$moduledirforclass); + //dol_syslog("Found module file ".$file." - module=".$module." - moduledirforclass=".$moduledirforclass); - // Defined if module is enabled - $enabled=true; - if (empty($conf->$moduleforperm->enabled)) $enabled=false; + // Defined if module is enabled + $enabled=true; + if (empty($conf->$moduleforperm->enabled)) $enabled=false; - if ($enabled) - { - /* - * If exists, load the API class for enable module - * - * Search files named api_<object>.class.php into /htdocs/<module>/class directory - * - * @todo : use getElementProperties() function ? - */ - $dir_part = dol_buildpath('/'.$moduledirforclass.'/class/'); - - $handle_part=@opendir(dol_osencode($dir_part)); - if (is_resource($handle_part)) + if ($enabled) { - while (($file_searched = readdir($handle_part))!==false) - { - if ($file_searched == 'api_access.class.php') continue; + // If exists, load the API class for enable module + // Search files named api_<object>.class.php into /htdocs/<module>/class directory + // @todo : use getElementProperties() function ? + $dir_part = dol_buildpath('/'.$moduledirforclass.'/class/'); - // Support of the deprecated API. - if (is_readable($dir_part.$file_searched) && preg_match("/^api_deprecated_(.*)\.class\.php$/i",$file_searched,$reg)) - { - $classname = ucwords($reg[1]).'Api'; - require_once $dir_part.$file_searched; - if (class_exists($classname)) - { - //dol_syslog("Found deprecated API by index.php: classname=".$classname." for module ".$dir." into ".$dir_part.$file_searched); - $api->r->addAPIClass($classname, '/'); - } - else - { - dol_syslog("We found an api_xxx file (".$file_searched.") but class ".$classname." does not exists after loading file", LOG_WARNING); - } - } - elseif (is_readable($dir_part.$file_searched) && preg_match("/^api_(.*)\.class\.php$/i",$file_searched,$reg)) + $handle_part=@opendir(dol_osencode($dir_part)); + if (is_resource($handle_part)) + { + while (($file_searched = readdir($handle_part))!==false) { - $classname = ucwords($reg[1]); - $classname = str_replace('_', '', $classname); - require_once $dir_part.$file_searched; - if (class_exists($classname)) + if ($file_searched == 'api_access.class.php') continue; + + // Support of the deprecated API. + if (is_readable($dir_part.$file_searched) && preg_match("/^api_deprecated_(.*)\.class\.php$/i",$file_searched,$reg)) { - //dol_syslog("Found API by index.php: classname=".$classname." for module ".$dir." into ".$dir_part.$file_searched); - $listofapis[] = $classname; + $classname = ucwords($reg[1]).'Api'; + require_once $dir_part.$file_searched; + if (class_exists($classname)) + { + //dol_syslog("Found deprecated API by index.php: classname=".$classname." for module ".$dir." into ".$dir_part.$file_searched); + $api->r->addAPIClass($classname, '/'); + } + else + { + dol_syslog("We found an api_xxx file (".$file_searched.") but class ".$classname." does not exists after loading file", LOG_WARNING); + } } - else + elseif (is_readable($dir_part.$file_searched) && preg_match("/^api_(.*)\.class\.php$/i",$file_searched,$reg)) { - dol_syslog("We found an api_xxx file (".$file_searched.") but class ".$classname." does not exists after loading file", LOG_WARNING); + $classname = ucwords($reg[1]); + $classname = str_replace('_', '', $classname); + require_once $dir_part.$file_searched; + if (class_exists($classname)) + { + //dol_syslog("Found API by index.php: classname=".$classname." for module ".$dir." into ".$dir_part.$file_searched); + $listofapis[] = $classname; + } + else + { + dol_syslog("We found an api_xxx file (".$file_searched.") but class ".$classname." does not exists after loading file", LOG_WARNING); + } } } } @@ -191,20 +173,61 @@ foreach ($modulesdir as $dir) } } } + + // Sort the classes before adding them to Restler. The Restler API Explorer + // shows the classes in the order they are added and it's a mess if they are not sorted. + sort($listofapis); + //var_dump($listofapis); + foreach ($listofapis as $classname) + { + $api->r->addAPIClass($classname); + } } -// Sort the classes before adding them to Restler. The Restler API Explorer -// shows the classes in the order they are added and it's a mess if they are -// not sorted. -sort($listofapis); -//var_dump($listofapis); -foreach ($listofapis as $classname) +// Call one APIs or one definition of an API +if (! empty($reg[1]) && ($reg[1] != 'explorer' || ($reg[2] != '/resources.json' && preg_match('/^\/resources.json\/(.+)$/', $reg[2], $regbis)))) { - $api->r->addAPIClass($classname); + $module = $reg[1]; + if ($module == 'explorer') // If we call page to explore details of a service + { + $module = $regbis[1]; + } + + // Load a dedicated API file + dol_syslog("Load a dedicated API file"); + + $module=strtolower($module); + $moduledirforclass = getModuleDirForApiClass($module); + + if (in_array($module, array('category','contact','customer','invoice','order','product','thirdparty','user'))) // Old Apis + { + $classfile = $module; + if ($module == 'customer') { $classfile = 'thirdparty'; } + if ($module == 'order') { $classfile = 'commande'; } + $dir_part_file = dol_buildpath('/'.$moduledirforclass.'/class/api_deprecated_'.$classfile.'.class.php'); + $classname=ucwords($module); + if ($module == 'customer') { $classname='Thirdparty'; } + if ($module == 'order') { $classname='Commande'; } + //var_dump($classfile);var_dump($classname);exit; + + require_once $dir_part_file; + if (class_exists($classname.'Api')) $api->r->addAPIClass($classname.'Api', '/'); + } + else + { + $classfile = str_replace('_', '', $module); + if ($module == 'supplierinvoices') $classfile = 'supplier_invoices'; + $dir_part_file = dol_buildpath('/'.$moduledirforclass.'/class/api_'.$classfile.'.class.php'); + $classname=ucwords($module); + + require_once $dir_part_file; + if (class_exists($classname)) $api->r->addAPIClass($classname); + } } // TODO If not found, redirect to explorer //var_dump($api); +//exit; // Call API (we suppose we found it) $api->r->handle(); diff --git a/htdocs/core/lib/functions2.lib.php b/htdocs/core/lib/functions2.lib.php index b68d7706e433915707814a96bf22133f73a6beec..72f27a16602a274f73b05077265771d2781457a9 100755 --- a/htdocs/core/lib/functions2.lib.php +++ b/htdocs/core/lib/functions2.lib.php @@ -2121,8 +2121,8 @@ function colorStringToArray($stringcolor,$colorifnotfound=array(88,88,88)) * Applies the Cartesian product algorithm to an array * Source: http://stackoverflow.com/a/15973172 * - * @param array $input Array of products - * @return array Array of combinations + * @param array $input Array of products + * @return array Array of combinations */ function cartesianArray(array $input) { // filter out empty values @@ -2145,3 +2145,70 @@ function cartesianArray(array $input) { return $result; } + + +/** + * Get name of directory where the api_...class.php file is stored + * + * @param string $module Module name + * @return string Directory name + */ +function getModuleDirForApiClass($module) +{ + $moduledirforclass=$module; + + if (in_array($module, array('login', 'access', 'status', 'documents'))) { + $moduledirforclass = 'api'; + } + if (preg_match('/^dictionary/', $module)) { + $moduledirforclass = 'api'; + } + + if ($module == 'contact' || $module == 'contacts' || $module == 'customer' || $module == 'thirdparty' || $module == 'thirdparties') { + $moduledirforclass = 'societe'; + } + if ($module == 'propale' || $module == 'proposals') { + $moduledirforclass = 'comm/propal'; + } + elseif ($module == 'agenda' || $module == 'agendaevents') { + $moduledirforclass = 'comm/action'; + } + elseif ($module == 'adherent' || $module == 'members' || $module == 'memberstypes' || $module == 'subscriptions') { + $moduledirforclass = 'adherents'; + } + elseif ($module == 'banque' || $module == 'bankaccounts') { + $moduledirforclass = 'compta/bank'; + } + elseif ($module == 'category' || $module == 'categorie') { + $moduledirforclass = 'categories'; + } + elseif ($module == 'order' || $module == 'orders') { + $moduledirforclass = 'commande'; + } + elseif ($module == 'facture' || $module == 'invoice' || $module == 'invoices') { + $moduledirforclass = 'compta/facture'; + } + elseif ($module == 'products') { + $moduledirforclass = 'product'; + } + elseif ($module == 'project' || $module == 'projects' || $module == 'tasks') { + $moduledirforclass = 'projet'; + } + elseif ($module == 'task') { + $moduledirforclass = 'projet'; + } + elseif ($module == 'stock' || $module == 'stockmovements' || $module == 'warehouses') { + $moduledirforclass = 'product/stock'; + } + elseif ($module == 'fournisseur' || $module == 'supplierinvoices') { + $moduledirforclass = 'fourn'; + } + elseif ($module == 'expensereports') { + $moduledirforclass = 'expensereport'; + } + elseif ($module == 'users') { + $moduledirforclass = 'user'; + } + + return $moduledirforclass; +} diff --git a/htdocs/societe/class/api_contacts.class.php b/htdocs/societe/class/api_contacts.class.php index f136d6895b231102eb6b5d1602ed921c13c56598..fcfdf4ad0840e85a3c46ca77268312b97e74c782 100644 --- a/htdocs/societe/class/api_contacts.class.php +++ b/htdocs/societe/class/api_contacts.class.php @@ -47,6 +47,9 @@ class Contacts extends DolibarrApi { global $db, $conf; $this->db = $db; + + include_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php'; + $this->contact = new Contact($this->db); } diff --git a/htdocs/societe/class/api_deprecated_thirdparty.class.php b/htdocs/societe/class/api_deprecated_thirdparty.class.php index bca74ba8ae28f427b02c650648bdc7716640e365..b335fb3518340519a0a797748cecc4a6ee3ac9c2 100644 --- a/htdocs/societe/class/api_deprecated_thirdparty.class.php +++ b/htdocs/societe/class/api_deprecated_thirdparty.class.php @@ -22,7 +22,7 @@ * API class for thirdparty object * * @smart-auto-routing false - * @access protected + * @access protected * @class DolibarrApiAccess {@requires user,external} * @deprecated Use Thirdparties instead (defined in api_thirdparties.class.php) */ @@ -30,7 +30,7 @@ class ThirdpartyApi extends DolibarrApi { /** * - * @var array $FIELDS Mandatory fields, checked when create and update object + * @var array $FIELDS Mandatory fields, checked when create and update object */ static $FIELDS = array( 'name' @@ -49,15 +49,17 @@ class ThirdpartyApi extends DolibarrApi * Constructor <b>Warning: Deprecated</b> * * @url thirdparty/ - * + * */ function __construct() { + include_once DOL_DOCUMENT_ROOT.'/societe/class/client.class.php'; + global $db, $conf; $this->db = $db; $this->company = new Societe($this->db); $this->customer = new Client($this->db); - + if (! empty($conf->global->SOCIETE_MAIL_REQUIRED)) { static::$FIELDS[] = 'email'; } @@ -70,21 +72,21 @@ class ThirdpartyApi extends DolibarrApi * * @param int $id ID of customer * @return array|mixed data without useless information - * + * * @url GET customer/{id} * @throws RestException */ function getCustomer($id) - { + { if(! DolibarrApiAccess::$user->rights->societe->lire) { throw new RestException(401); } - + $result = $this->customer->fetch($id); if( ! $result ) { throw new RestException(404, 'Customer not found'); } - + if( ! DolibarrApi::_checkAccessToResource('societe',$this->customer->id)) { throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } @@ -94,11 +96,11 @@ class ThirdpartyApi extends DolibarrApi /** * Search customer by email <b>Warning: Deprecated</b> - * + * * @param string $email email id * * @return object client with given email - * + * * @url GET customer/byemail/{email} */ function getByEmail($email) { @@ -117,21 +119,21 @@ class ThirdpartyApi extends DolibarrApi * * @param int $id ID of thirdparty * @return array|mixed data without useless information - * + * * @url GET thirdparty/{id} * @throws RestException */ function get($id) - { + { if(! DolibarrApiAccess::$user->rights->societe->lire) { throw new RestException(401); } - + $result = $this->company->fetch($id); if( ! $result ) { throw new RestException(404, 'Thirdparty not found'); } - + if( ! DolibarrApi::_checkAccessToResource('societe',$this->company->id)) { throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } @@ -141,10 +143,10 @@ class ThirdpartyApi extends DolibarrApi /** * List thirdparties <b>Warning: Deprecated</b> - * + * * Get a list of thirdparties - * - * @param int $mode Set to 1 to show only customers + * + * @param int $mode Set to 1 to show only customers * Set to 2 to show only prospects * Set to 3 to show only those are not customer neither prospect * @param Text $email Search by email filter @@ -153,17 +155,17 @@ class ThirdpartyApi extends DolibarrApi * @param int $limit Limit for list * @param int $page Page number * @return array Array of thirdparty objects - * + * * @url GET /thirdparty/list * */ function getList($mode=0, $email=NULL, $sortfield = "s.rowid", $sortorder = 'ASC', $limit = 0, $page = 0) { global $db, $conf; - + $obj_ret = array(); - + $socid = DolibarrApiAccess::$user->societe_id ? DolibarrApiAccess::$user->societe_id : ''; - + // If the internal user must only see his customers, force searching by him $search_sale = 0; if (! DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) $search_sale = DolibarrApiAccess::$user->id; @@ -171,7 +173,7 @@ class ThirdpartyApi extends DolibarrApi $sql = "SELECT s.rowid"; if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) || $search_sale > 0) $sql .= ", sc.fk_soc, sc.fk_user"; // We need these fields in order to filter by sale (including the case where the user can only see his prospects) $sql.= " FROM ".MAIN_DB_PREFIX."societe as s"; - + if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) || $search_sale > 0) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; // We need this table joined to the select in order to filter by sale $sql.= ", ".MAIN_DB_PREFIX."c_stcomm as st"; $sql.= " WHERE s.fk_stcomm = st.id"; @@ -183,13 +185,13 @@ class ThirdpartyApi extends DolibarrApi if ($email != NULL) $sql.= " AND s.email = \"".$email."\""; if ($socid) $sql.= " AND s.rowid = ".$socid; if ($search_sale > 0) $sql.= " AND s.rowid = sc.fk_soc"; // Join for the needed table to filter by sale - + // Insert sale filter if ($search_sale > 0) { $sql .= " AND sc.fk_user = ".$search_sale; } - + $nbtotalofrecords = ''; if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) { @@ -233,47 +235,47 @@ class ThirdpartyApi extends DolibarrApi } return $obj_ret; } - + /** * Show customers <b>Warning: Deprecated</b> - * + * * @return array List of customers - * + * * @url GET /thirdparty/list/customers * @url GET /customer/list */ function getListCustomers() { return $this->getList(1); } - + /** * Show prospects <b>Warning: Deprecated</b> - * + * * @return array List of prospects - * + * * @url GET /thirdparty/list/prospects */ function getListProspects() { return $this->getList(2); } - + /** * Show other <b>Warning: Deprecated</b> - * + * * @return array List of thirpdparties who are not customer neither prospect - * + * * @url GET /thirdparty/list/others */ function getListOthers() { return $this->getList(3); } - + /** * Create thirdparty object <b>Warning: Deprecated</b> * * @param array $request_data Request datas * @return int ID of thirdparty - * + * * @url POST thirdparty/ */ function post($request_data = NULL) @@ -283,7 +285,7 @@ class ThirdpartyApi extends DolibarrApi } // Check mandatory fields $result = $this->_validate($request_data); - + foreach($request_data as $field => $value) { $this->company->$field = $value; } @@ -296,7 +298,7 @@ class ThirdpartyApi extends DolibarrApi * * @param array $request_data Request datas * @return int ID of thirdparty - * + * * @url POST customer/ */ function postCustomer($request_data) { @@ -309,9 +311,9 @@ class ThirdpartyApi extends DolibarrApi * Update thirdparty <b>Warning: Deprecated</b> * * @param int $id Id of thirdparty to update - * @param array $request_data Datas - * @return int - * + * @param array $request_data Datas + * @return int + * * @url PUT thirdparty/{id} */ function put($id, $request_data = NULL) @@ -319,12 +321,12 @@ class ThirdpartyApi extends DolibarrApi if(! DolibarrApiAccess::$user->rights->societe->creer) { throw new RestException(401); } - + $result = $this->company->fetch($id); if( ! $result ) { throw new RestException(404, 'Thirdparty not found'); } - + if( ! DolibarrApi::_checkAccessToResource('societe',$this->company->id)) { throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } @@ -333,19 +335,19 @@ class ThirdpartyApi extends DolibarrApi if ($field == 'id') continue; $this->company->$field = $value; } - + if($this->company->update($id, DolibarrApiAccess::$user,1,'','','update')) return $this->get ($id); - + return false; } /** * Update customer <b>Warning: Deprecated</b> * * @param int $id Id of thirdparty to update - * @param array $request_data Datas - * @return int - * + * @param array $request_data Datas + * @return int + * * @url PUT customer/{id} */ function putClient($id, $request_data = NULL) { @@ -363,19 +365,19 @@ class ThirdpartyApi extends DolibarrApi foreach($request_data as $field => $value) { $this->customer->$field = $value; } - + if($this->customer->update($id, DolibarrApiAccess::$user,1,'','','update')) return $this->get ($id); - + return false; } - + /** * Delete thirdparty <b>Warning: Deprecated</b> * * @param int $id Thirparty ID * @return integer - * + * * @url DELETE thirdparty/{id} * @url DELETE customer/{id} */ @@ -393,13 +395,13 @@ class ThirdpartyApi extends DolibarrApi } return $this->company->delete($id); } - + /** * Validate fields before create or update object - * + * * @param array $data Datas to validate * @return array - * + * * @throws RestException */ function _validate($data) diff --git a/htdocs/user/class/user.class.php b/htdocs/user/class/user.class.php index 6b39158a87bcf6ae6252428cd67ffb09a031cbf7..577a6389b6fe93b1bc45eb38dae914a5c4893c3f 100644 --- a/htdocs/user/class/user.class.php +++ b/htdocs/user/class/user.class.php @@ -221,7 +221,7 @@ class User extends CommonObject if (!empty($conf->multicompany->enabled) && !empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) $sql.= " WHERE u.entity IS NOT NULL"; // multicompany is on in transverse mode or user making fetch is on entity 0, so user is allowed to fetch anywhere into database else - $sql.= " WHERE u.entity IN (0, ".$conf->entity.")"; + $sql.= " WHERE u.entity IN (0, ".($entity!=''?$entity:$conf->entity).")"; // search in entity provided in parameter } if ($sid) // permet une recherche du user par son SID ActiveDirectory ou Samba @@ -236,6 +236,7 @@ class User extends CommonObject { $sql.= " AND u.rowid = ".$id; } + $sql.= " ORDER BY u.entity ASC"; // Avoid random result when there is 2 login in 2 different entities $result = $this->db->query($sql); if ($result) @@ -310,8 +311,8 @@ class User extends CommonObject $this->fk_member = $obj->fk_member; $this->fk_user = $obj->fk_user; - // Protection when module multicompany was set, admin was set to first entity and the module disabled, - // then this admin user must be admin for all entities. + // Protection when module multicompany was set, admin was set to first entity and then, the module was disabled, + // in such case, this admin user must be admin for ALL entities. if (empty($conf->multicompany->enabled) && $this->admin && $this->entity == 1) $this->entity = 0; // Retreive all extrafield for thirdparty