diff --git a/dev/examples/zapier/authentication.js b/dev/examples/zapier/authentication.js index 1c95c76f9c2..fceedd4ab5f 100644 --- a/dev/examples/zapier/authentication.js +++ b/dev/examples/zapier/authentication.js @@ -1,6 +1,6 @@ /*jshint esversion: 6 */ -const testAuth = (z , bundle) => { - const url = bundle.authData.url+'/api/index.php/login'; +const test = (z , bundle) => { + const url = bundle.authData.url+'/api/index.php/status'; // Normally you want to make a request to an endpoint that is either specifically designed to test auth, or one that // every user will have access to, such as an account or profile endpoint like /me. // In this example, we'll hit httpbin, which validates the Authorization Header against the arguments passed in the URL path @@ -11,67 +11,92 @@ const testAuth = (z , bundle) => { // This method can return any truthy value to indicate the credentials are valid. // Raise an error to show return promise.then((response) => { - if (response.status === 401) { - throw new Error('The Session Key you supplied is invalid'); + if (response.status === 400) { + throw new Error('400 -The Session Key you supplied is invalid'); + } + if (response.status === 403) { + throw new Error('403 -The Session Key you supplied is invalid'); } return response; }); }; -const getSessionKey = (z, bundle) => { +// To include the session key header on all outbound requests, simply define a function here. +// It runs runs before each request is sent out, allowing you to make tweaks to the request in a centralized spot +const includeSessionKeyHeader = (request, z, bundle) => { + if (bundle.authData.sessionKey) { + request.headers = request.headers || {}; + request.headers['DOLAPIKEY'] = bundle.authData.sessionKey; + } + return request; +}; + +// If we get a response and it is a 401, we can raise a special error telling Zapier to retry this after another exchange. +const sessionRefreshIf401 = (response, z, bundle) => { + if (bundle.authData.sessionKey) { + if (response.status === 401) { + throw new z.errors.RefreshAuthError('Session apikey needs refreshing.'); + } + } + return response; +}; + +const getSessionKey = async (z, bundle) => { const url = bundle.authData.url + '/api/index.php/login'; - const promise = z.request({ - method: 'POST', + const response = await z.request({ url: url, + method: 'POST', body: { login: bundle.authData.login, password: bundle.authData.password, - } + }, }); - return promise.then((response) => { - if (response.status === 401) { - throw new Error('The login/password you supplied is invalid'); - } - const json = JSON.parse(response.content); - return { - sessionKey: json.success.token || 'secret' - }; - }); + // if (response.status === 401) { + // throw new Error('The login/password you supplied is invalid'); + // } + const json = JSON.parse(response.content); + return { + sessionKey: json.success.token || '', + }; }; module.exports = { - type: 'session', - // Define any auth fields your app requires here. The user will be prompted to enter this info when - // they connect their account. - fields: [ - { - key: 'url', - label: 'Url of service', - required: true, - type: 'string' + config: { + type: 'session', + sessionConfig: { + perform: getSessionKey }, - { - key: 'login', - label: 'Login', - required: true, - type: 'string' - }, - { - key: 'password', - label: 'Password', - required: true, - type: 'password' - } - ], - // The test method allows Zapier to verify that the credentials a user provides are valid. We'll execute this - // method whenever a user connects their account for the first time. - test: testAuth, - // The method that will exchange the fields provided by the user for session credentials. - sessionConfig: { - perform: getSessionKey + // Define any auth fields your app requires here. The user will be prompted to enter this info when + // they connect their account. + fields: [ + { + key: 'url', + label: 'Url of service without trailing-slash', + required: true, + type: 'string' + }, + { + key: 'login', + label: 'Login', + required: true, + type: 'string' + }, + { + key: 'password', + label: 'Password', + required: true, + type: 'password' + } + ], + // The test method allows Zapier to verify that the credentials a user provides are valid. We'll execute this + // method whenever a user connects their account for the first time. + test, + // The method that will exchange the fields provided by the user for session credentials. + // assuming "login" is a key returned from the test + connectionLabel: '{{login}}' }, - // assuming "login" is a key returned from the test - connectionLabel: '{{login}}' + befores: [includeSessionKeyHeader], + afters: [sessionRefreshIf401], }; diff --git a/dev/examples/zapier/creates/thirdparty.js b/dev/examples/zapier/creates/thirdparty.js index 82cc39f8fab..3e20fd10e41 100644 --- a/dev/examples/zapier/creates/thirdparty.js +++ b/dev/examples/zapier/creates/thirdparty.js @@ -72,7 +72,7 @@ module.exports = { }, outputFields: [ - {key: 'id', label: 'ID'}, + {key: 'id', type: "integer", label: 'ID'}, {key: 'name', label: 'Name'}, {key: 'name_alias', label: 'Name alias'}, {key: 'address', label: 'Address'}, @@ -81,8 +81,8 @@ module.exports = { {key: 'phone', label: 'Phone'}, {key: 'fax', label: 'Fax'}, {key: 'email', label: 'Email'}, - {key: 'client', label: 'Customer/Prospect 0/1/2/3'}, - {key: 'fournisseur', label: 'Supplier 0/1'}, + {key: 'client', type: "integer", label: 'Customer/Prospect 0/1/2/3'}, + {key: 'fournisseur', type: "integer", label: 'Supplier 0/1'}, {key: 'code_client', label: 'Customer code'}, {key: 'code_fournisseur', label: 'Supplier code'} ] diff --git a/dev/examples/zapier/index.js b/dev/examples/zapier/index.js index fc452a196e6..d1897673b39 100644 --- a/dev/examples/zapier/index.js +++ b/dev/examples/zapier/index.js @@ -1,33 +1,39 @@ /*jshint esversion: 6 */ -const triggerThirdparty = require('./triggers/thirdparty'); -const triggerOrder = require('./triggers/order'); const triggerAction = require('./triggers/action'); +const triggerOrder = require('./triggers/order'); +const triggerThirdparty = require('./triggers/thirdparty'); +const triggerTicket = require('./triggers/ticket'); +const triggerUser = require('./triggers/user'); const searchThirdparty = require('./searches/thirdparty'); const createThirdparty = require('./creates/thirdparty'); -const authentication = require('./authentication'); +const { + config: authentication, + befores = [], + afters = [], +} = require('./authentication'); // To include the session key header on all outbound requests, simply define a function here. // It runs runs before each request is sent out, allowing you to make tweaks to the request in a centralized spot -const includeSessionKeyHeader = (request, z, bundle) => { - if (bundle.authData.sessionKey) { - request.headers = request.headers || {}; - request.headers['DOLAPIKEY'] = bundle.authData.sessionKey; - } - return request; -}; +// const includeSessionKeyHeader = (request, z, bundle) => { +// if (bundle.authData.sessionKey) { +// request.headers = request.headers || {}; +// request.headers['DOLAPIKEY'] = bundle.authData.sessionKey; +// } +// return request; +// }; // If we get a response and it is a 401, we can raise a special error telling Zapier to retry this after another exchange. -const sessionRefreshIf401 = (response, z, bundle) => { - if (bundle.authData.sessionKey) { - if (response.status === 401) { - throw new z.errors.RefreshAuthError('Session apikey needs refreshing.'); - } - } - return response; -}; +// const sessionRefreshIf401 = (response, z, bundle) => { +// if (bundle.authData.sessionKey) { +// if (response.status === 401) { +// throw new z.errors.RefreshAuthError('Session apikey needs refreshing.'); +// } +// } +// return response; +// }; // We can roll up all our behaviors in an App. const App = { @@ -40,11 +46,11 @@ const App = { // beforeRequest & afterResponse are optional hooks into the provided HTTP client beforeRequest: [ - includeSessionKeyHeader + ...befores ], afterResponse: [ - sessionRefreshIf401 + ...afters ], // If you want to define optional resources to simplify creation of triggers, searches, creates - do that here! @@ -53,9 +59,11 @@ const App = { // If you want your trigger to show up, you better include it here! triggers: { - [triggerThirdparty.key]: triggerThirdparty, + [triggerAction.key]: triggerAction, [triggerOrder.key]: triggerOrder, - [triggerAction.key]: triggerAction + [triggerThirdparty.key]: triggerThirdparty, + [triggerTicket.key]: triggerTicket, + [triggerUser.key]: triggerUser, }, // If you want your searches to show up, you better include it here! diff --git a/dev/examples/zapier/package.json b/dev/examples/zapier/package.json index be13c719c97..5b5827b22b2 100644 --- a/dev/examples/zapier/package.json +++ b/dev/examples/zapier/package.json @@ -1,6 +1,6 @@ { "name": "dolibarr", - "version": "1.0.0", + "version": "1.13.0", "description": "An app for connecting Dolibarr to the Zapier platform.", "repository": "Dolibarr/dolibarr", "homepage": "https://www.dolibarr.org/", @@ -15,7 +15,7 @@ "npm": ">=5.6.0" }, "dependencies": { - "zapier-platform-core": "8.0.1" + "zapier-platform-core": "10.1.1" }, "devDependencies": { "mocha": "^5.2.0", diff --git a/dev/examples/zapier/searches/thirdparty.js b/dev/examples/zapier/searches/thirdparty.js index c71c2965789..8f72b9270e5 100644 --- a/dev/examples/zapier/searches/thirdparty.js +++ b/dev/examples/zapier/searches/thirdparty.js @@ -54,13 +54,20 @@ module.exports = { // outputFields: () => { return []; } // Alternatively, a static field definition should be provided, to specify labels for the fields outputFields: [ - {key: 'id', label: 'ID'}, - {key: 'createdAt', label: 'Created At'}, + { + key: 'id', + type: "integer", + label: 'ID' + }, + {key: 'createdAt', type: "integer", label: 'Created At'}, {key: 'name', label: 'Name'}, {key: 'firstname', label: 'Firstname'}, {key: 'directions', label: 'Directions'}, - {key: 'authorId', label: 'Author ID'}, - {key: 'style', label: 'Style'} + {key: 'authorId', type: "integer", label: 'Author ID'}, + { + key: 'style', + label: 'Style' + } ] } }; diff --git a/dev/examples/zapier/triggers/action.js b/dev/examples/zapier/triggers/action.js index d387d88ec1f..0e152473869 100644 --- a/dev/examples/zapier/triggers/action.js +++ b/dev/examples/zapier/triggers/action.js @@ -10,14 +10,14 @@ const subscribeHook = (z, bundle) => { action: bundle.inputData.action }; - const url = bundle.authData.url + '/api/index.php/zapierapi/hook'; + const url = bundle.authData.url + '/api/index.php/zapierapi/hook'; // You can build requests and our client will helpfully inject all the variables // you need to complete. You can also register middleware to control this. const options = { url: url, method: 'POST', - body: JSON.stringify(data) + body: data, }; // You may return a promise or a normal data structure from any perform method. @@ -32,7 +32,7 @@ const unsubscribeHook = (z, bundle) => { // You can build requests and our client will helpfully inject all the variables // you need to complete. You can also register middleware to control this. const options = { - url: bundle.authData.url + '/api/index.php/zapierapi/hook/' + bundle.subscribeData.id, + url: bundle.authData.url + '/api/index.php/zapierapi/hook/' + bundle.subscribeData.id, method: 'DELETE', }; @@ -74,7 +74,7 @@ const getFallbackRealAction = (z, bundle) => { // For the test poll, you should get some real data, to aid the setup process. const module = bundle.inputData.module; const options = { - url: bundle.authData.url + '/api/index.php/agendaevents/0', + url: bundle.authData.url + '/api/index.php/agendaevents/0', }; return z.request(options).then((response) => [JSON.parse(response.content)]); @@ -100,7 +100,7 @@ module.exports = { noun: 'Action', display: { label: 'New Agenda', - description: 'Trigger when a new agenda with action is done in Dolibarr.' + description: 'Triggers when a new agenda with action is done in Dolibarr.' }, // `operation` is where the business logic goes. @@ -111,6 +111,7 @@ module.exports = { inputFields: [ { key: 'action', + required: true, type: 'string', helpText: 'Which action of agenda this should trigger on.', choices: { @@ -145,12 +146,33 @@ module.exports = { // outputFields: () => { return []; } // Alternatively, a static field definition should be provided, to specify labels for the fields outputFields: [ - {key: 'id', label: 'ID'}, - {key: 'createdAt', label: 'Created At'}, - {key: 'name', label: 'Name'}, - {key: 'usertodo__name', label: 'UserToDo Name'}, - {key: 'authorId', label: 'Author ID'}, - {key: 'action', label: 'Action'} + { + key: 'id', + type: "integer", + label: 'ID' + }, + { + key: 'createdAt', + type: "integer", + label: 'Created At' + }, + { + key: 'name', + label: 'Name' + }, + { + key: 'usertodo__name', + label: 'UserToDo Name' + }, + { + key: 'authorId', + type: "integer", + label: 'Author ID' + }, + { + key: 'action', + label: 'Action' + } ] } }; diff --git a/dev/examples/zapier/triggers/order.js b/dev/examples/zapier/triggers/order.js index 6262d734edc..061ce218d10 100644 --- a/dev/examples/zapier/triggers/order.js +++ b/dev/examples/zapier/triggers/order.js @@ -17,7 +17,7 @@ const subscribeHook = (z, bundle) => { const options = { url: url, method: 'POST', - body: JSON.stringify(data) + body: data, }; // You may return a promise or a normal data structure from any perform method. @@ -90,7 +90,7 @@ module.exports = { noun: 'Order', display: { label: 'New Order', - description: 'Trigger when a new order with action is done in Dolibarr.' + description: 'Triggers when a new order with action is done in Dolibarr.' }, // `operation` is where the business logic goes. @@ -101,6 +101,7 @@ module.exports = { inputFields: [ { key: 'action', + required: true, type: 'string', helpText: 'Which action of order this should trigger on.', choices: { @@ -136,11 +137,11 @@ module.exports = { // outputFields: () => { return []; } // Alternatively, a static field definition should be provided, to specify labels for the fields outputFields: [ - {key: 'id', label: 'ID'}, - {key: 'createdAt', label: 'Created At'}, + {key: 'id', type: "integer", label: 'ID'}, + {key: 'createdAt', type: "integer", label: 'Created At'}, {key: 'name', label: 'Name'}, {key: 'directions', label: 'Directions'}, - {key: 'authorId', label: 'Author ID'}, + {key: 'authorId', type: "integer", label: 'Author ID'}, {key: 'module', label: 'Module'}, {key: 'action', label: 'Action'} ] diff --git a/dev/examples/zapier/triggers/thirdparty.js b/dev/examples/zapier/triggers/thirdparty.js index 4b13e23ff1c..4656f836e74 100644 --- a/dev/examples/zapier/triggers/thirdparty.js +++ b/dev/examples/zapier/triggers/thirdparty.js @@ -17,7 +17,7 @@ const subscribeHook = (z, bundle) => { const options = { url: url, method: 'POST', - body: JSON.stringify(data) + body: data, }; // You may return a promise or a normal data structure from any perform method. @@ -112,7 +112,7 @@ module.exports = { noun: 'Thirdparty', display: { label: 'New Thirdparty', - description: 'Trigger when a new thirdpaty action is done in Dolibarr.' + description: 'Triggers when a new thirdpaty action is done in Dolibarr.' }, // `operation` is where the business logic goes. @@ -123,6 +123,7 @@ module.exports = { inputFields: [ { key: 'action', + required: true, type: 'string', helpText: 'Which action of thirdparty this should trigger on.', choices: { @@ -159,12 +160,12 @@ module.exports = { // outputFields: () => { return []; } // Alternatively, a static field definition should be provided, to specify labels for the fields outputFields: [ - {key: 'id', label: 'ID'}, + {key: 'id', type: "integer", label: 'ID'}, {key: 'createdAt', label: 'Created At'}, {key: 'name', label: 'Name'}, {key: 'name_alias', label: 'Name alias'}, - {key: 'firstname', label: 'Firstame'}, - {key: 'authorId', label: 'Author ID'}, + {key: 'firstname', label: 'Firstname'}, + {key: 'authorId', type: "integer", label: 'Author ID'}, {key: 'action', label: 'Action'}, {key: 'client', label: 'Customer/Prospect 0/1/2/3'}, {key: 'fournisseur', label: 'Supplier 0/1'}, diff --git a/dev/examples/zapier/triggers/ticket.js b/dev/examples/zapier/triggers/ticket.js new file mode 100644 index 00000000000..c642099bd55 --- /dev/null +++ b/dev/examples/zapier/triggers/ticket.js @@ -0,0 +1,237 @@ +const subscribeHook = (z, bundle) => { + // `z.console.log()` is similar to `console.log()`. + z.console.log('suscribing hook!'); + + // bundle.targetUrl has the Hook URL this app should call when an action is created. + const data = { + url: bundle.targetUrl, + event: bundle.event, + module: 'ticket', + action: bundle.inputData.action + }; + + const url = bundle.authData.url + '/api/index.php/zapierapi/hook'; + + // You can build requests and our client will helpfully inject all the variables + // you need to complete. You can also register middleware to control this. + const options = { + url: url, + method: 'POST', + body: data, + }; + + // You may return a promise or a normal data structure from any perform method. + return z.request(options).then((response) => JSON.parse(response.content)); +}; + +const unsubscribeHook = (z, bundle) => { + // bundle.subscribeData contains the parsed response JSON from the subscribe + // request made initially. + z.console.log('unsuscribing hook!'); + + // You can build requests and our client will helpfully inject all the variables + // you need to complete. You can also register middleware to control this. + const options = { + url: bundle.authData.url + '/api/index.php/zapierapi/hook/' + bundle.subscribeData.id, + method: 'DELETE', + }; + + // You may return a promise or a normal data structure from any perform method. + return z.request(options).then((response) => JSON.parse(response.content)); +}; + +const getTicket = (z, bundle) => { + // bundle.cleanedRequest will include the parsed JSON object (if it's not a + // test poll) and also a .querystring property with the URL's query string. + const ticket = { + id: bundle.cleanedRequest.id, + track_id: bundle.cleanedRequest.track_id, + subject: bundle.cleanedRequest.subject, + message: bundle.cleanedRequest.message, + lastname: bundle.cleanedRequest.lastname, + firstname: bundle.cleanedRequest.firstname, + address: bundle.cleanedRequest.address, + zip: bundle.cleanedRequest.zip, + town: bundle.cleanedRequest.town, + email_from: bundle.cleanedRequest.email_from, + login: bundle.cleanedRequest.login, + authorId: bundle.cleanedRequest.authorId, + createdAt: bundle.cleanedRequest.createdAt, + action: bundle.cleanedRequest.action + }; + + return [ticket]; +}; + +const getFallbackRealTicket = (z, bundle) => { + // For the test poll, you should get some real data, to aid the setup process. + const module = bundle.inputData.module; + const options = { + url: bundle.authData.url + '/api/index.php/tickets/0', + }; + + return z.request(options).then((response) => [JSON.parse(response.content)]); +}; + +// const getModulesChoices = (z/*, bundle*/) => { +// // For the test poll, you should get some real data, to aid the setup process. +// const options = { +// url: bundle.authData.url + '/api/index.php/zapierapi/getmoduleschoices', +// }; + +// return z.request(options).then((response) => JSON.parse(response.content)); +// }; +// const getModulesChoices = () => { + +// return { +// orders: "Order", +// invoices: "Invoice", +// thirdparties: "Thirdparty", +// users: "User", +// tickets: "Ticket", +// contacts: "Contacts" +// }; +// }; + +// const getActionsChoices = (z, bundle) => { +// // For the test poll, you should get some real data, to aid the setup process. +// const module = bundle.inputData.module; +// const options = { +// url: url: bundle.authData.url + '/api/index.php/zapierapi/getactionschoices/thirparty`, +// }; + +// return z.request(options).then((response) => JSON.parse(response.content)); +// }; + +// We recommend writing your triggers separate like this and rolling them +// into the App definition at the end. +module.exports = { + key: 'ticket', + + // You'll want to provide some helpful display labels and descriptions + // for tickets. Zapier will put them into the UX. + noun: 'Ticket', + display: { + label: 'New Ticket', + description: 'Triggers when a new ticket action is done in Dolibarr.' + }, + + // `operation` is where the business logic goes. + operation: { + + // `inputFields` can define the fields a ticket could provide, + // we'll pass them in as `bundle.inputData` later. + inputFields: [ + { + key: 'action', + type: 'string', + required: true, + helpText: 'Which action of ticket this should trigger on.', + choices: { + create: "Create", + modify: "Modify", + validate: "Validate", + } + } + ], + + type: 'hook', + + performSubscribe: subscribeHook, + performUnsubscribe: unsubscribeHook, + + perform: getTicket, + performList: getFallbackRealTicket, + + // In cases where Zapier needs to show an example record to the user, but we are unable to get a live example + // from the API, Zapier will fallback to this hard-coded sample. It should reflect the data structure of + // returned records, and have obviously dummy values that we can show to any user. + sample: { + id: 1, + track_id: 'Xaz123er', + subject: 'Subject', + message: 'Message', + createdAt: 1472069465, + lastname: 'DOE', + firstname: 'John', + email: 'john@doe.com', + address: 'Park Avenue', + zip: '12345', + town: 'NEW-YORK', + email_from: 'doe.john@example;com', + authorId: 1, + action: 'create' + }, + + // If the resource can have fields that are custom on a per-user basis, define a function to fetch the custom + // field definitions. The result will be used to augment the sample. + // outputFields: () => { return []; } + // Alternatively, a static field definition should be provided, to specify labels for the fields + outputFields: [ + { + key: 'id', + type: "integer", + label: 'ID' + }, + { + key: 'track_id', + type: "string", + label: 'TrackID' + }, + { + key: 'subject', + type: "string", + label: 'Subject' + }, + { + key: 'message', + type: "string", + label: 'Message' + }, + { + key: 'createdAt', + type: "integer", + label: 'Created At' + }, + { + key: 'lastname', + label: 'Lastname' + }, + { + key: 'firstname', + label: 'Firstname' + }, + { + key: 'email', + label: 'Email' + }, + { + key: 'address', + label: 'Address' + }, + { + key: 'zip', + label: 'Zip' + }, + { + key: 'town', + label: 'Town' + }, + { + key: 'email_from', + type: 'string', + label: 'Email from' + }, + { + key: 'authorId', + type: "integer", + label: 'Author ID' + }, + { + key: 'action', + type: 'string', + label: 'Action' + } + ] + } +}; diff --git a/dev/examples/zapier/triggers/user.js b/dev/examples/zapier/triggers/user.js new file mode 100644 index 00000000000..92209bb8651 --- /dev/null +++ b/dev/examples/zapier/triggers/user.js @@ -0,0 +1,177 @@ +const subscribeHook = (z, bundle) => { + // `z.console.log()` is similar to `console.log()`. + z.console.log('suscribing hook!'); + + // bundle.targetUrl has the Hook URL this app should call when an action is created. + const data = { + url: bundle.targetUrl, + event: bundle.event, + module: 'user', + action: bundle.inputData.action + }; + + const url = bundle.authData.url + '/api/index.php/zapierapi/hook'; + + // You can build requests and our client will helpfully inject all the variables + // you need to complete. You can also register middleware to control this. + const options = { + url: url, + method: 'POST', + body: data, + }; + + // You may return a promise or a normal data structure from any perform method. + return z.request(options).then((response) => JSON.parse(response.content)); +}; + +const unsubscribeHook = (z, bundle) => { + // bundle.subscribeData contains the parsed response JSON from the subscribe + // request made initially. + z.console.log('unsuscribing hook!'); + + // You can build requests and our client will helpfully inject all the variables + // you need to complete. You can also register middleware to control this. + const options = { + url: bundle.authData.url + '/api/index.php/zapierapi/hook/' + bundle.subscribeData.id, + method: 'DELETE', + }; + + // You may return a promise or a normal data structure from any perform method. + return z.request(options).then((response) => JSON.parse(response.content)); +}; + +const getUser = (z, bundle) => { + // bundle.cleanedRequest will include the parsed JSON object (if it's not a + // test poll) and also a .querystring property with the URL's query string. + const user = { + id: bundle.cleanedRequest.id, + lastname: bundle.cleanedRequest.lastname, + firstname: bundle.cleanedRequest.firstname, + address: bundle.cleanedRequest.address, + zip: bundle.cleanedRequest.zip, + town: bundle.cleanedRequest.town, + email: bundle.cleanedRequest.email, + login: bundle.cleanedRequest.login, + authorId: bundle.cleanedRequest.authorId, + createdAt: bundle.cleanedRequest.createdAt, + action: bundle.cleanedRequest.action + }; + + return [user]; +}; + +const getFallbackRealUser = (z, bundle) => { + // For the test poll, you should get some real data, to aid the setup process. + const module = bundle.inputData.module; + const options = { + url: bundle.authData.url + '/api/index.php/users/0', + }; + + return z.request(options).then((response) => [JSON.parse(response.content)]); +}; + +// const getModulesChoices = (z/*, bundle*/) => { +// // For the test poll, you should get some real data, to aid the setup process. +// const options = { +// url: bundle.authData.url + '/api/index.php/zapierapi/getmoduleschoices', +// }; + +// return z.request(options).then((response) => JSON.parse(response.content)); +// }; +// const getModulesChoices = () => { + +// return { +// orders: "Order", +// invoices: "Invoice", +// thirdparties: "Thirdparty", +// users: "User", +// contacts: "Contacts" +// }; +// }; + +// const getActionsChoices = (z, bundle) => { +// // For the test poll, you should get some real data, to aid the setup process. +// const module = bundle.inputData.module; +// const options = { +// url: url: bundle.authData.url + '/api/index.php/zapierapi/getactionschoices/thirparty`, +// }; + +// return z.request(options).then((response) => JSON.parse(response.content)); +// }; + +// We recommend writing your triggers separate like this and rolling them +// into the App definition at the end. +module.exports = { + key: 'user', + + // You'll want to provide some helpful display labels and descriptions + // for users. Zapier will put them into the UX. + noun: 'User', + display: { + label: 'New User', + description: 'Triggers when a new user action is done in Dolibarr.' + }, + + // `operation` is where the business logic goes. + operation: { + + // `inputFields` can define the fields a user could provide, + // we'll pass them in as `bundle.inputData` later. + inputFields: [ + { + key: 'action', + required: true, + type: 'string', + helpText: 'Which action of user this should trigger on.', + choices: { + create: "Create", + modify: "Modify", + validate: "Validate", + } + } + ], + + type: 'hook', + + performSubscribe: subscribeHook, + performUnsubscribe: unsubscribeHook, + + perform: getUser, + performList: getFallbackRealUser, + + // In cases where Zapier needs to show an example record to the user, but we are unable to get a live example + // from the API, Zapier will fallback to this hard-coded sample. It should reflect the data structure of + // returned records, and have obviously dummy values that we can show to any user. + sample: { + id: 1, + createdAt: 1472069465, + lastname: 'DOE', + firstname: 'John', + email: 'john@doe.com', + address: 'Park Avenue', + zip: '12345', + town: 'NEW-YORK', + login: 'doe.john', + authorId: 1, + action: 'create' + }, + + // If the resource can have fields that are custom on a per-user basis, define a function to fetch the custom + // field definitions. The result will be used to augment the sample. + // outputFields: () => { return []; } + // Alternatively, a static field definition should be provided, to specify labels for the fields + outputFields: [ + {key: 'id', type: "integer", label: 'ID'}, + {key: 'createdAt', type: "integer", label: 'Created At'}, + {key: 'lastname', label: 'Lastname'}, + {key: 'firstname', label: 'Firstname'}, + {key: 'email', label: 'Email'}, + {key: 'address', label: 'Address'}, + {key: 'zip', label: 'Zip'}, + {key: 'town', label: 'Town'}, + {key: 'login', label: 'Login'}, + {key: 'authorId', type: "integer", label: 'Author ID'}, + {key: 'action', label: 'Action'} + ] + } +}; diff --git a/htdocs/adherents/class/adherent.class.php b/htdocs/adherents/class/adherent.class.php index a8cb095a889..009c73cf318 100644 --- a/htdocs/adherents/class/adherent.class.php +++ b/htdocs/adherents/class/adherent.class.php @@ -2306,14 +2306,16 @@ class Adherent extends CommonObject * Used to build previews or test instances. * id must be 0 if object instance is a specimen. * - * @return void + * @return int */ public function initAsSpecimen() { global $user, $langs; + $now = dol_now(); // Initialise parametres $this->id = 0; + $this->entity = 1; $this->specimen = 1; $this->civility_id = 0; $this->lastname = 'DOLIBARR'; @@ -2330,24 +2332,30 @@ class Adherent extends CommonObject $this->country = 'France'; $this->morphy = 'mor'; $this->email = 'specimen@specimen.com'; - $this->socialnetworks = array('skype' => 'skypepseudo', 'twitter' => 'twitterpseudo', 'facebook' => 'facebookpseudo', 'linkedin' => 'linkedinpseudo'); + $this->socialnetworks = array( + 'skype' => 'skypepseudo', + 'twitter' => 'twitterpseudo', + 'facebook' => 'facebookpseudo', + 'linkedin' => 'linkedinpseudo', + ); $this->phone = '0999999999'; $this->phone_perso = '0999999998'; $this->phone_mobile = '0999999997'; - $this->note_private = 'No comment'; - $this->birth = time(); + $this->note_public = 'This is a public note'; + $this->note_private = 'This is a private note'; + $this->birth = $now; $this->photo = ''; $this->public = 1; $this->statut = 0; - $this->datefin = time(); - $this->datevalid = time(); + $this->datefin = $now; + $this->datevalid = $now; $this->typeid = 1; // Id type adherent $this->type = 'Type adherent'; // Libelle type adherent $this->need_subscription = 0; - $this->first_subscription_date = time(); + $this->first_subscription_date = $now; $this->first_subscription_date_start = $this->first_subscription_date; $this->first_subscription_date_end = dol_time_plus_duree($this->first_subscription_date_start, 1, 'y'); $this->first_subscription_amount = 10; @@ -2356,6 +2364,7 @@ class Adherent extends CommonObject $this->last_subscription_date_start = $this->first_subscription_date; $this->last_subscription_date_end = dol_time_plus_duree($this->last_subscription_date_start, 1, 'y'); $this->last_subscription_amount = 10; + return 1; } diff --git a/htdocs/adherents/class/api_members.class.php b/htdocs/adherents/class/api_members.class.php index 954ea42f9b4..6fa3058dca1 100644 --- a/htdocs/adherents/class/api_members.class.php +++ b/htdocs/adherents/class/api_members.class.php @@ -67,12 +67,16 @@ class Members extends DolibarrApi } $member = new Adherent($this->db); - $result = $member->fetch($id); + if ($id == 0) { + $result = $member->initAsSpecimen(); + } else { + $result = $member->fetch($id); + } if (!$result) { throw new RestException(404, 'member not found'); } - if (!DolibarrApi::_checkAccessToResource('adherent', $member->id)) { + if (!DolibarrApi::_checkAccessToResource('adherent', $member->id) && $id > 0) { throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } diff --git a/htdocs/api/class/api.class.php b/htdocs/api/class/api.class.php index 5834324fa2b..80a608a0581 100644 --- a/htdocs/api/class/api.class.php +++ b/htdocs/api/class/api.class.php @@ -78,15 +78,15 @@ class DolibarrApi * @return array */ /* Disabled, most APIs does not share same signature for method index - function index() - { - return array( - 'success' => array( - 'code' => 200, - 'message' => __class__.' is up and running!' - ) - ); - }*/ + function index() + { + return array( + 'success' => array( + 'code' => 200, + 'message' => __class__.' is up and running!' + ) + ); + }*/ // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore /** @@ -221,11 +221,9 @@ class DolibarrApi } } - if (!empty($object->thirdparty) && is_object($object->thirdparty)) - { + if (!empty($object->thirdparty) && is_object($object->thirdparty)) { $this->_cleanObjectDatas($object->thirdparty); } - return $object; } diff --git a/htdocs/api/class/api_documents.class.php b/htdocs/api/class/api_documents.class.php index 5fff08b80ab..9408898a984 100644 --- a/htdocs/api/class/api_documents.class.php +++ b/htdocs/api/class/api_documents.class.php @@ -229,9 +229,7 @@ class Documents extends DolibarrApi if ($result <= 0) { throw new RestException(500, 'Error generating document'); } - } - else - { + } else { throw new RestException(403, 'Generation not available for this modulepart'); } @@ -277,6 +275,8 @@ class Documents extends DolibarrApi } $id = (empty($id) ? 0 : $id); + $recursive = 0; + $type = 'files'; if ($modulepart == 'societe' || $modulepart == 'thirdparty') { @@ -474,11 +474,27 @@ class Documents extends DolibarrApi } $upload_dir = $conf->categorie->multidir_output[$object->entity].'/'.get_exdir($object->id, 2, 0, 0, $object, 'category').$object->id."/photos/".dol_sanitizeFileName($object->ref); + } elseif ($modulepart == 'ecm') { + throw new RestException(500, 'Modulepart Ecm not implemented yet.'); + // // require_once DOL_DOCUMENT_ROOT.'/ecm/class/ecmdirectory.class.php'; + + // if (!DolibarrApiAccess::$user->rights->ecm->read) { + // throw new RestException(401); + // } + + // // $object = new EcmDirectory($this->db); + // // $result = $object->fetch($ref); + // // if (!$result) { + // // throw new RestException(404, 'EcmDirectory not found'); + // // } + // $upload_dir = $conf->ecm->dir_output; + // $type = 'all'; + // $recursive = 0; } else { throw new RestException(500, 'Modulepart '.$modulepart.' not implemented yet.'); } - $filearray = dol_dir_list($upload_dir, "files", 0, '', '(\.meta|_preview.*\.png)$', $sortfield, (strtolower($sortorder) == 'desc' ?SORT_DESC:SORT_ASC), 1); + $filearray = dol_dir_list($upload_dir, $type, $recursive, '', '(\.meta|_preview.*\.png)$', $sortfield, (strtolower($sortorder) == 'desc' ?SORT_DESC:SORT_ASC), 1); if (empty($filearray)) { throw new RestException(404, 'Search for modulepart '.$modulepart.' with Id '.$object->id.(!empty($object->ref) ? ' or Ref '.$object->ref : '').' does not return any document.'); } @@ -592,9 +608,7 @@ class Documents extends DolibarrApi { $tmpreldir = dol_sanitizeFileName($object->project->ref).'/'; } - } - else - { + } else { throw new RestException(500, 'Error while fetching Task '.$ref); } } @@ -619,10 +633,8 @@ class Documents extends DolibarrApi $modulepart = 'propale'; require_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propal.class.php'; $object = new Propal($this->db); - } - // TODO Implement additional moduleparts - else - { + } else { + // TODO Implement additional moduleparts throw new RestException(500, 'Modulepart '.$modulepart.' not implemented yet.'); } @@ -660,9 +672,7 @@ class Documents extends DolibarrApi { throw new RestException(500, 'This value of modulepart does not support yet usage of ref. Check modulepart parameter or try to use subdir parameter instead of ref.'); } - } - else - { + } else { if ($modulepart == 'invoice') $modulepart = 'facture'; if ($modulepart == 'member') $modulepart = 'adherent'; @@ -700,20 +710,16 @@ class Documents extends DolibarrApi } $fhandle = @fopen($destfiletmp, 'w'); - if ($fhandle) - { + if ($fhandle) { $nbofbyteswrote = fwrite($fhandle, $newfilecontent); fclose($fhandle); @chmod($destfiletmp, octdec($conf->global->MAIN_UMASK)); - } - else - { + } else { throw new RestException(500, "Failed to open file '".$destfiletmp."' for write"); } $result = dol_move($destfiletmp, $destfile, 0, $overwriteifexists, 1); - if (!$result) - { + if (!$result) { throw new RestException(500, "Failed to move file into '".$destfile."'"); } diff --git a/htdocs/core/triggers/interface_99_modZapier_ZapierTriggers.class.php b/htdocs/core/triggers/interface_99_modZapier_ZapierTriggers.class.php index 4224b46db89..de81e54165a 100644 --- a/htdocs/core/triggers/interface_99_modZapier_ZapierTriggers.class.php +++ b/htdocs/core/triggers/interface_99_modZapier_ZapierTriggers.class.php @@ -85,8 +85,28 @@ class InterfaceZapierTriggers extends DolibarrTriggers switch ($action) { // Users - //case 'USER_CREATE': - //case 'USER_MODIFY': + case 'USER_CREATE': + $resql = $this->db->query($sql); + // TODO voir comment regrouper les webhooks en un post + while ($resql && $obj = $this->db->fetch_array($resql)) { + $cleaned = cleanObjectDatas(dol_clone($object)); + $json = json_encode($cleaned); + // call the zapierPostWebhook() function + zapierPostWebhook($obj['url'], $json); + } + $logtriggeraction = true; + break; + case 'USER_MODIFY': + $resql = $this->db->query($sql); + // TODO voir comment regrouper les webhooks en un post + while ($resql && $obj = $this->db->fetch_array($resql)) { + $cleaned = cleanObjectDatas(dol_clone($object)); + $json = json_encode($cleaned); + // call the zapierPostWebhook() function + zapierPostWebhook($obj['url'], $json); + } + $logtriggeraction = true; + break; //case 'USER_NEW_PASSWORD': //case 'USER_ENABLEDISABLE': //case 'USER_DELETE': @@ -124,6 +144,12 @@ class InterfaceZapierTriggers extends DolibarrTriggers //case 'USERGROUP_MODIFY': //case 'USERGROUP_DELETE': + // Categories + // case 'CATEGORY_CREATE': + // case 'CATEGORY_MODIFY': + // case 'CATEGORY_DELETE': + // case 'CATEGORY_SET_MULTILANGS': + // Companies case 'COMPANY_CREATE': $resql = $this->db->query($sql); @@ -305,12 +331,6 @@ class InterfaceZapierTriggers extends DolibarrTriggers // case 'MEMBER_RESILIATE': // case 'MEMBER_DELETE': - // Categories - // case 'CATEGORY_CREATE': - // case 'CATEGORY_MODIFY': - // case 'CATEGORY_DELETE': - // case 'CATEGORY_SET_MULTILANGS': - // Projects // case 'PROJECT_CREATE': // case 'PROJECT_MODIFY': @@ -325,6 +345,21 @@ class InterfaceZapierTriggers extends DolibarrTriggers // case 'TASK_TIMESPENT_CREATE': // case 'TASK_TIMESPENT_MODIFY': // case 'TASK_TIMESPENT_DELETE': + case 'TICKET_CREATE': + $resql = $this->db->query($sql); + // TODO voir comment regrouper les webhooks en un post + while ($resql && $obj = $this->db->fetch_array($resql)) { + $cleaned = cleanObjectDatas(dol_clone($object)); + $json = json_encode($cleaned); + // call the zapierPostWebhook() function + zapierPostWebhook($obj['url'], $json); + } + $logtriggeraction = true; + break; + // case 'TICKET_MODIFY': + // break; + // case 'TICKET_DELETE': + // break; // Shipping // case 'SHIPPING_CREATE': @@ -439,13 +474,13 @@ function cleanObjectDatas($toclean) // If object has linked objects, remove $db property /* - if(isset($toclean->linkedObjects) && count($toclean->linkedObjects) > 0) { - foreach($toclean->linkedObjects as $type_object => $linked_object) { - foreach($linked_object as $toclean2clean) { - $this->cleanObjectDatas($toclean2clean); - } - } - }*/ + if(isset($toclean->linkedObjects) && count($toclean->linkedObjects) > 0) { + foreach($toclean->linkedObjects as $type_object => $linked_object) { + foreach($linked_object as $toclean2clean) { + $this->cleanObjectDatas($toclean2clean); + } + } + }*/ return $toclean; } @@ -453,7 +488,7 @@ function cleanObjectDatas($toclean) /** * Clean sensible object datas * - * @param object $toclean Object to clean + * @param Object $toclean Object to clean * @return Object Object with cleaned properties */ function cleanAgendaEventsDatas($toclean) diff --git a/htdocs/societe/class/api_thirdparties.class.php b/htdocs/societe/class/api_thirdparties.class.php index 2faccd3d106..08e839ecee1 100644 --- a/htdocs/societe/class/api_thirdparties.class.php +++ b/htdocs/societe/class/api_thirdparties.class.php @@ -1851,8 +1851,11 @@ class Thirdparties extends DolibarrApi if (!DolibarrApiAccess::$user->rights->societe->lire) { throw new RestException(401); } - - $result = $this->company->fetch($rowid, $ref, $ref_ext, $barcode, $idprof1, $idprof2, $idprof3, $idprof4, $idprof5, $idprof6, $email, $ref_alias); + if ($rowid == 0) { + $result = $this->company->initAsSpecimen(); + } else { + $result = $this->company->fetch($rowid, $ref, $ref_ext, $barcode, $idprof1, $idprof2, $idprof3, $idprof4, $idprof5, $idprof6, $email, $ref_alias); + } if (!$result) { throw new RestException(404, 'Thirdparty not found'); } diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php index 5bca91b0700..3f47d56ee79 100644 --- a/htdocs/societe/class/societe.class.php +++ b/htdocs/societe/class/societe.class.php @@ -3765,6 +3765,7 @@ class Societe extends CommonObject // Initialize parameters $this->id = 0; + $this->entity = 1; $this->name = 'THIRDPARTY SPECIMEN '.dol_print_date($now, 'dayhourlog'); $this->nom = $this->name; // For backward compatibility $this->ref_ext = 'Ref ext'; diff --git a/htdocs/ticket/class/api_tickets.class.php b/htdocs/ticket/class/api_tickets.class.php index bce4d03fd92..5ba67060552 100644 --- a/htdocs/ticket/class/api_tickets.class.php +++ b/htdocs/ticket/class/api_tickets.class.php @@ -29,542 +29,544 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/ticket.lib.php'; */ class Tickets extends DolibarrApi { - /** - * @var array $FIELDS Mandatory fields, checked when create and update object - */ - public static $FIELDS = array( - 'subject', - 'message' - ); + /** + * @var array $FIELDS Mandatory fields, checked when create and update object + */ + public static $FIELDS = array( + 'subject', + 'message' + ); - /** - * @var array $FIELDS_MESSAGES Mandatory fields, checked when create and update object - */ - public static $FIELDS_MESSAGES = array( - 'track_id', - 'message' - ); + /** + * @var array $FIELDS_MESSAGES Mandatory fields, checked when create and update object + */ + public static $FIELDS_MESSAGES = array( + 'track_id', + 'message' + ); - /** - * @var Ticket $ticket {@type Ticket} - */ - public $ticket; + /** + * @var Ticket $ticket {@type Ticket} + */ + public $ticket; - /** - * Constructor - */ - public function __construct() - { - global $db; - $this->db = $db; - $this->ticket = new Ticket($this->db); - } + /** + * Constructor + */ + public function __construct() + { + global $db; + $this->db = $db; + $this->ticket = new Ticket($this->db); + } - /** - * Get properties of a Ticket object. - * - * Return an array with ticket informations - * - * @param int $id ID of ticket - * @return array|mixed Data without useless information - * - * @throws RestException 401 - * @throws RestException 403 - * @throws RestException 404 - */ - public function get($id) - { - return $this->getCommon($id, '', ''); - } + /** + * Get properties of a Ticket object. + * + * Return an array with ticket informations + * + * @param int $id ID of ticket + * @return array|mixed Data without useless information + * + * @throws RestException 401 + * @throws RestException 403 + * @throws RestException 404 + */ + public function get($id) + { + return $this->getCommon($id, '', ''); + } - /** - * Get properties of a Ticket object from track id - * - * Return an array with ticket informations - * - * @param string $track_id Tracking ID of ticket - * @return array|mixed Data without useless information - * - * @url GET track_id/{track_id} - * - * @throws RestException 401 - * @throws RestException 403 - * @throws RestException 404 - */ - public function getByTrackId($track_id) - { - return $this->getCommon(0, $track_id, ''); - } + /** + * Get properties of a Ticket object from track id + * + * Return an array with ticket informations + * + * @param string $track_id Tracking ID of ticket + * @return array|mixed Data without useless information + * + * @url GET track_id/{track_id} + * + * @throws RestException 401 + * @throws RestException 403 + * @throws RestException 404 + */ + public function getByTrackId($track_id) + { + return $this->getCommon(0, $track_id, ''); + } - /** - * Get properties of a Ticket object from ref - * - * Return an array with ticket informations - * - * @param string $ref Reference for ticket - * @return array|mixed Data without useless information - * - * @url GET ref/{ref} - * - * @throws RestException 401 - * @throws RestException 403 - * @throws RestException 404 - */ - public function getByRef($ref) - { - try { - return $this->getCommon(0, '', $ref); - } catch (Exception $e) - { - throw $e; - } - } + /** + * Get properties of a Ticket object from ref + * + * Return an array with ticket informations + * + * @param string $ref Reference for ticket + * @return array|mixed Data without useless information + * + * @url GET ref/{ref} + * + * @throws RestException 401 + * @throws RestException 403 + * @throws RestException 404 + */ + public function getByRef($ref) + { + try { + return $this->getCommon(0, '', $ref); + } catch (Exception $e) + { + throw $e; + } + } - /** - * Get properties of a Ticket object - * Return an array with ticket informations - * - * @param int $id ID of ticket - * @param string $track_id Tracking ID of ticket - * @param string $ref Reference for ticket - * @return array|mixed Data without useless information - */ - private function getCommon($id = 0, $track_id = '', $ref = '') - { - if (!DolibarrApiAccess::$user->rights->ticket->read) { - throw new RestException(403); - } + /** + * Get properties of a Ticket object + * Return an array with ticket informations + * + * @param int $id ID of ticket + * @param string $track_id Tracking ID of ticket + * @param string $ref Reference for ticket + * @return array|mixed Data without useless information + */ + private function getCommon($id = 0, $track_id = '', $ref = '') + { + if (!DolibarrApiAccess::$user->rights->ticket->read) { + throw new RestException(403); + } - // Check parameters - if (!$id && !$track_id && !$ref) { - throw new RestException(401, 'Wrong parameters'); - } - - $result = $this->ticket->fetch($id, $ref, $track_id); - if (!$result) { - throw new RestException(404, 'Ticket not found'); - } - - // String for user assigned - if ($this->ticket->fk_user_assign > 0) { - $userStatic = new User($this->db); - $userStatic->fetch($this->ticket->fk_user_assign); - $this->ticket->fk_user_assign_string = $userStatic->firstname.' '.$userStatic->lastname; - } - - // Messages of ticket - $messages = array(); - $this->ticket->loadCacheMsgsTicket(); - if (is_array($this->ticket->cache_msgs_ticket) && count($this->ticket->cache_msgs_ticket) > 0) { - $num = count($this->ticket->cache_msgs_ticket); - $i = 0; - while ($i < $num) { - if ($this->ticket->cache_msgs_ticket[$i]['fk_user_author'] > 0) { - $user_action = new User($this->db); - $user_action->fetch($this->ticket->cache_msgs_ticket[$i]['fk_user_author']); - } - - // Now define messages - $messages[] = array( - 'id' => $this->ticket->cache_msgs_ticket[$i]['id'], - 'fk_user_action' => $this->ticket->cache_msgs_ticket[$i]['fk_user_author'], - 'fk_user_action_socid' => $user_action->socid, - 'fk_user_action_string' => dolGetFirstLastname($user_action->firstname, $user_action->lastname), - 'message' => $this->ticket->cache_msgs_ticket[$i]['message'], - 'datec' => $this->ticket->cache_msgs_ticket[$i]['datec'], - 'private' => $this->ticket->cache_msgs_ticket[$i]['private'] - ); - $i++; - } - $this->ticket->messages = $messages; - } - - // History - $history = array(); - $this->ticket->loadCacheLogsTicket(); - if (is_array($this->ticket->cache_logs_ticket) && count($this->ticket->cache_logs_ticket) > 0) { - $num = count($this->ticket->cache_logs_ticket); - $i = 0; - while ($i < $num) { - if ($this->ticket->cache_logs_ticket[$i]['fk_user_create'] > 0) { - $user_action = new User($this->db); - $user_action->fetch($this->ticket->cache_logs_ticket[$i]['fk_user_create']); - } - - // Now define messages - $history[] = array( - 'id' => $this->ticket->cache_logs_ticket[$i]['id'], - 'fk_user_author' => $this->ticket->cache_msgs_ticket[$i]['fk_user_author'], - 'fk_user_action' => $this->ticket->cache_logs_ticket[$i]['fk_user_create'], - 'fk_user_action_string' => dolGetFirstLastname($user_action->firstname, $user_action->lastname), - 'message' => $this->ticket->cache_logs_ticket[$i]['message'], - 'datec' => $this->ticket->cache_logs_ticket[$i]['datec'], - ); - $i++; - } - $this->ticket->history = $history; - } - - - if (!DolibarrApi::_checkAccessToResource('ticket', $this->ticket->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); - } - return $this->_cleanObjectDatas($this->ticket); - } - - /** - * List tickets - * - * Get a list of tickets - * - * @param int $socid Filter list with thirdparty ID - * @param string $sortfield Sort field - * @param string $sortorder Sort order - * @param int $limit Limit for list - * @param int $page Page number - * @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.ref:like:'SO-%') and (t.date_creation:<:'20160101') and (t.fk_statut:=:1)" - * - * @return array Array of ticket objects - * - */ - public function index($socid = 0, $sortfield = "t.rowid", $sortorder = "ASC", $limit = 100, $page = 0, $sqlfilters = '') - { - global $db, $conf; - - $obj_ret = array(); - - if (!$socid && DolibarrApiAccess::$user->socid) { - $socid = DolibarrApiAccess::$user->socid; - } - - // If the internal user must only see his customers, force searching by him - if (!DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) { - $search_sale = DolibarrApiAccess::$user->id; - } - - $sql = "SELECT t.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."ticket as t"; - - 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 .= ' WHERE t.entity IN ('.getEntity('ticket', 1).')'; - if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) || $search_sale > 0) { - $sql .= " AND t.fk_soc = sc.fk_soc"; - } - if ($socid > 0) { - $sql .= " AND t.fk_soc = ".$socid; - } - if ($search_sale > 0) { - $sql .= " AND t.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; - } - // Add sql filters - if ($sqlfilters) { - if (!DolibarrApi::_checkFilters($sqlfilters)) { - throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters); - } - $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)'; - $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; - } - - $sql .= $this->db->order($sortfield, $sortorder); - - if ($limit) { - if ($page < 0) { - $page = 0; - } - $offset = $limit * $page; - - $sql .= $this->db->plimit($limit, $offset); - } - - $result = $this->db->query($sql); - if ($result) { - $num = $this->db->num_rows($result); - $i = 0; - while ($i < $num) { - $obj = $this->db->fetch_object($result); - $ticket_static = new Ticket($this->db); - if ($ticket_static->fetch($obj->rowid)) { - if ($ticket_static->fk_user_assign > 0) { - $userStatic = new User($this->db); - $userStatic->fetch($ticket_static->fk_user_assign); - $ticket_static->fk_user_assign_string = $userStatic->firstname.' '.$userStatic->lastname; - } - $obj_ret[] = $this->_cleanObjectDatas($ticket_static); - } - $i++; - } + // Check parameters + if (($id < 0) && !$track_id && !$ref) { + throw new RestException(401, 'Wrong parameters'); + } + if ($id == 0) { + $result = $this->ticket->initAsSpecimen(); } else { - throw new RestException(503, 'Error when retrieve ticket list'); + $result = $this->ticket->fetch($id, $ref, $track_id); } - if (!count($obj_ret)) { - throw new RestException(404, 'No ticket found'); - } - return $obj_ret; - } + if (!$result) { + throw new RestException(404, 'Ticket not found'); + } - /** - * Create ticket object - * - * @param array $request_data Request datas - * @return int ID of ticket - */ - public function post($request_data = null) - { - $ticketstatic = new Ticket($this->db); - if (!DolibarrApiAccess::$user->rights->ticket->write) { - throw new RestException(401); - } - // Check mandatory fields - $result = $this->_validate($request_data); + // String for user assigned + if ($this->ticket->fk_user_assign > 0) { + $userStatic = new User($this->db); + $userStatic->fetch($this->ticket->fk_user_assign); + $this->ticket->fk_user_assign_string = $userStatic->firstname.' '.$userStatic->lastname; + } - foreach ($request_data as $field => $value) { - $this->ticket->$field = $value; - } - if (empty($this->ticket->ref)) { - $this->ticket->ref = $ticketstatic->getDefaultRef(); - } - if (empty($this->ticket->track_id)) { - $this->ticket->track_id = generate_random_id(16); - } + // Messages of ticket + $messages = array(); + $this->ticket->loadCacheMsgsTicket(); + if (is_array($this->ticket->cache_msgs_ticket) && count($this->ticket->cache_msgs_ticket) > 0) { + $num = count($this->ticket->cache_msgs_ticket); + $i = 0; + while ($i < $num) { + if ($this->ticket->cache_msgs_ticket[$i]['fk_user_author'] > 0) { + $user_action = new User($this->db); + $user_action->fetch($this->ticket->cache_msgs_ticket[$i]['fk_user_author']); + } - if ($this->ticket->create(DolibarrApiAccess::$user) < 0) { - throw new RestException(500, "Error creating ticket", array_merge(array($this->ticket->error), $this->ticket->errors)); - } + // Now define messages + $messages[] = array( + 'id' => $this->ticket->cache_msgs_ticket[$i]['id'], + 'fk_user_action' => $this->ticket->cache_msgs_ticket[$i]['fk_user_author'], + 'fk_user_action_socid' => $user_action->socid, + 'fk_user_action_string' => dolGetFirstLastname($user_action->firstname, $user_action->lastname), + 'message' => $this->ticket->cache_msgs_ticket[$i]['message'], + 'datec' => $this->ticket->cache_msgs_ticket[$i]['datec'], + 'private' => $this->ticket->cache_msgs_ticket[$i]['private'] + ); + $i++; + } + $this->ticket->messages = $messages; + } - return $this->ticket->id; - } + // History + $history = array(); + $this->ticket->loadCacheLogsTicket(); + if (is_array($this->ticket->cache_logs_ticket) && count($this->ticket->cache_logs_ticket) > 0) { + $num = count($this->ticket->cache_logs_ticket); + $i = 0; + while ($i < $num) { + if ($this->ticket->cache_logs_ticket[$i]['fk_user_create'] > 0) { + $user_action = new User($this->db); + $user_action->fetch($this->ticket->cache_logs_ticket[$i]['fk_user_create']); + } - /** - * Create ticket object - * - * @param array $request_data Request datas - * @return int ID of ticket - * - */ - public function postNewMessage($request_data = null) - { - $ticketstatic = new Ticket($this->db); - if (!DolibarrApiAccess::$user->rights->ticket->write) { - throw new RestException(401); - } - // Check mandatory fields - $result = $this->_validateMessage($request_data); + // Now define messages + $history[] = array( + 'id' => $this->ticket->cache_logs_ticket[$i]['id'], + 'fk_user_author' => $this->ticket->cache_msgs_ticket[$i]['fk_user_author'], + 'fk_user_action' => $this->ticket->cache_logs_ticket[$i]['fk_user_create'], + 'fk_user_action_string' => dolGetFirstLastname($user_action->firstname, $user_action->lastname), + 'message' => $this->ticket->cache_logs_ticket[$i]['message'], + 'datec' => $this->ticket->cache_logs_ticket[$i]['datec'], + ); + $i++; + } + $this->ticket->history = $history; + } - foreach ($request_data as $field => $value) { - $this->ticket->$field = $value; - } - $ticketMessageText = $this->ticket->message; - $result = $this->ticket->fetch('', '', $this->ticket->track_id); - if (!$result) { - throw new RestException(404, 'Ticket not found'); - } - $this->ticket->message = $ticketMessageText; - if (!$this->ticket->createTicketMessage(DolibarrApiAccess::$user)) { - throw new RestException(500); - } - return $this->ticket->id; - } + if (!DolibarrApi::_checkAccessToResource('ticket', $this->ticket->id)) { + throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + } + return $this->_cleanObjectDatas($this->ticket); + } - /** - * Update ticket - * - * @param int $id Id of ticket to update - * @param array $request_data Datas - * @return int - * - */ - public function put($id, $request_data = null) - { - if (!DolibarrApiAccess::$user->rights->ticket->write) { - throw new RestException(401); - } + /** + * List tickets + * + * Get a list of tickets + * + * @param int $socid Filter list with thirdparty ID + * @param string $sortfield Sort field + * @param string $sortorder Sort order + * @param int $limit Limit for list + * @param int $page Page number + * @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.ref:like:'SO-%') and (t.date_creation:<:'20160101') and (t.fk_statut:=:1)" + * + * @return array Array of ticket objects + * + */ + public function index($socid = 0, $sortfield = "t.rowid", $sortorder = "ASC", $limit = 100, $page = 0, $sqlfilters = '') + { + global $db, $conf; - $result = $this->ticket->fetch($id); - if (!$result) { - throw new RestException(404, 'Ticket not found'); - } + $obj_ret = array(); - if (!DolibarrApi::_checkAccessToResource('ticket', $this->ticket->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); - } + if (!$socid && DolibarrApiAccess::$user->socid) { + $socid = DolibarrApiAccess::$user->socid; + } - foreach ($request_data as $field => $value) { - $this->ticket->$field = $value; - } + // If the internal user must only see his customers, force searching by him + if (!DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) { + $search_sale = DolibarrApiAccess::$user->id; + } - if ($this->ticket->update($id, DolibarrApiAccess::$user)) { - return $this->get($id); - } + $sql = "SELECT t.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."ticket as t"; - return false; - } + 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 + } - /** - * Delete ticket - * - * @param int $id Ticket ID - * @return array - * - */ - public function delete($id) - { - if (!DolibarrApiAccess::$user->rights->ticket->delete) { - throw new RestException(401); - } - $result = $this->ticket->fetch($id); - if (!$result) { - throw new RestException(404, 'Ticket not found'); - } + $sql .= ' WHERE t.entity IN ('.getEntity('ticket', 1).')'; + if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) || $search_sale > 0) { + $sql .= " AND t.fk_soc = sc.fk_soc"; + } + if ($socid > 0) { + $sql .= " AND t.fk_soc = ".$socid; + } + if ($search_sale > 0) { + $sql .= " AND t.rowid = sc.fk_soc"; // Join for the needed table to filter by sale + } - if (!DolibarrApi::_checkAccessToResource('ticket', $this->ticket->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); - } + // Insert sale filter + if ($search_sale > 0) { + $sql .= " AND sc.fk_user = ".$search_sale; + } + // Add sql filters + if ($sqlfilters) { + if (!DolibarrApi::_checkFilters($sqlfilters)) { + throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters); + } + $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)'; + $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; + } - if (!$this->ticket->delete($id)) { - throw new RestException(500); - } + $sql .= $this->db->order($sortfield, $sortorder); - return array( - 'success' => array( - 'code' => 200, - 'message' => 'Ticket deleted' - ) - ); - } + if ($limit) { + if ($page < 0) { + $page = 0; + } + $offset = $limit * $page; - /** - * Validate fields before create or update object - * - * @param array $data Data to validate - * @return array - * - * @throws RestException - */ - private function _validate($data) - { - $ticket = array(); - foreach (Tickets::$FIELDS as $field) { - if (!isset($data[$field])) { - throw new RestException(400, "$field field missing"); - } - $ticket[$field] = $data[$field]; - } - return $ticket; - } + $sql .= $this->db->plimit($limit, $offset); + } - /** - * Validate fields before create or update object message - * - * @param array $data Data to validate - * @return array - * - * @throws RestException - */ - private function _validateMessage($data) - { - $ticket = array(); - foreach (Tickets::$FIELDS_MESSAGES as $field) { - if (!isset($data[$field])) { - throw new RestException(400, "$field field missing"); - } - $ticket[$field] = $data[$field]; - } - return $ticket; - } + $result = $this->db->query($sql); + if ($result) { + $num = $this->db->num_rows($result); + $i = 0; + while ($i < $num) { + $obj = $this->db->fetch_object($result); + $ticket_static = new Ticket($this->db); + if ($ticket_static->fetch($obj->rowid)) { + if ($ticket_static->fk_user_assign > 0) { + $userStatic = new User($this->db); + $userStatic->fetch($ticket_static->fk_user_assign); + $ticket_static->fk_user_assign_string = $userStatic->firstname.' '.$userStatic->lastname; + } + $obj_ret[] = $this->_cleanObjectDatas($ticket_static); + } + $i++; + } + } else { + throw new RestException(503, 'Error when retrieve ticket list'); + } + if (!count($obj_ret)) { + throw new RestException(404, 'No ticket found'); + } + return $obj_ret; + } - // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore - /** - * Clean sensible object datas - * - * @param Object $object Object to clean - * @return Object Object with cleaned properties - * - * @todo use an array for properties to clean - * - */ - protected function _cleanObjectDatas($object) - { - // phpcs:enable - $object = parent::_cleanObjectDatas($object); + /** + * Create ticket object + * + * @param array $request_data Request datas + * @return int ID of ticket + */ + public function post($request_data = null) + { + $ticketstatic = new Ticket($this->db); + if (!DolibarrApiAccess::$user->rights->ticket->write) { + throw new RestException(401); + } + // Check mandatory fields + $result = $this->_validate($request_data); - // Other attributes to clean - $attr2clean = array( - "contact", - "contact_id", - "ref_previous", - "ref_next", - "ref_ext", - "table_element_line", - "statut", - "country", - "country_id", - "country_code", - "barcode_type", - "barcode_type_code", - "barcode_type_label", - "barcode_type_coder", - "mode_reglement_id", - "cond_reglement_id", - "cond_reglement", - "fk_delivery_address", - "shipping_method_id", - "modelpdf", - "fk_account", - "note_public", - "note_private", - "note", - "total_ht", - "total_tva", - "total_localtax1", - "total_localtax2", - "total_ttc", - "fk_incoterms", - "label_incoterms", - "location_incoterms", - "name", - "lastname", - "firstname", - "civility_id", - "canvas", - "cache_msgs_ticket", - "cache_logs_ticket", - "cache_types_tickets", - "cache_category_tickets", - "regeximgext", - "statuts_short", - "statuts" - ); - foreach ($attr2clean as $toclean) { - unset($object->$toclean); - } + foreach ($request_data as $field => $value) { + $this->ticket->$field = $value; + } + if (empty($this->ticket->ref)) { + $this->ticket->ref = $ticketstatic->getDefaultRef(); + } + if (empty($this->ticket->track_id)) { + $this->ticket->track_id = generate_random_id(16); + } - // If object has lines, remove $db property - if (isset($object->lines) && count($object->lines) > 0) { - $nboflines = count($object->lines); - for ($i = 0; $i < $nboflines; $i++) { - $this->_cleanObjectDatas($object->lines[$i]); - } - } + if ($this->ticket->create(DolibarrApiAccess::$user) < 0) { + throw new RestException(500, "Error creating ticket", array_merge(array($this->ticket->error), $this->ticket->errors)); + } - // If object has linked objects, remove $db property - if (isset($object->linkedObjects) && count($object->linkedObjects) > 0) { - foreach ($object->linkedObjects as $type_object => $linked_object) { - foreach ($linked_object as $object2clean) { - $this->_cleanObjectDatas($object2clean); - } - } - } - return $object; - } + return $this->ticket->id; + } + + /** + * Create ticket object + * + * @param array $request_data Request datas + * @return int ID of ticket + * + */ + public function postNewMessage($request_data = null) + { + $ticketstatic = new Ticket($this->db); + if (!DolibarrApiAccess::$user->rights->ticket->write) { + throw new RestException(401); + } + // Check mandatory fields + $result = $this->_validateMessage($request_data); + + foreach ($request_data as $field => $value) { + $this->ticket->$field = $value; + } + $ticketMessageText = $this->ticket->message; + $result = $this->ticket->fetch('', '', $this->ticket->track_id); + if (!$result) { + throw new RestException(404, 'Ticket not found'); + } + $this->ticket->message = $ticketMessageText; + if (!$this->ticket->createTicketMessage(DolibarrApiAccess::$user)) { + throw new RestException(500); + } + return $this->ticket->id; + } + + /** + * Update ticket + * + * @param int $id Id of ticket to update + * @param array $request_data Datas + * @return int + * + */ + public function put($id, $request_data = null) + { + if (!DolibarrApiAccess::$user->rights->ticket->write) { + throw new RestException(401); + } + + $result = $this->ticket->fetch($id); + if (!$result) { + throw new RestException(404, 'Ticket not found'); + } + + if (!DolibarrApi::_checkAccessToResource('ticket', $this->ticket->id)) { + throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + } + + foreach ($request_data as $field => $value) { + $this->ticket->$field = $value; + } + + if ($this->ticket->update($id, DolibarrApiAccess::$user)) { + return $this->get($id); + } + + return false; + } + + /** + * Delete ticket + * + * @param int $id Ticket ID + * @return array + * + */ + public function delete($id) + { + if (!DolibarrApiAccess::$user->rights->ticket->delete) { + throw new RestException(401); + } + $result = $this->ticket->fetch($id); + if (!$result) { + throw new RestException(404, 'Ticket not found'); + } + + if (!DolibarrApi::_checkAccessToResource('ticket', $this->ticket->id)) { + throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + } + + if (!$this->ticket->delete($id)) { + throw new RestException(500); + } + + return array( + 'success' => array( + 'code' => 200, + 'message' => 'Ticket deleted' + ) + ); + } + + /** + * Validate fields before create or update object + * + * @param array $data Data to validate + * @return array + * + * @throws RestException + */ + private function _validate($data) + { + $ticket = array(); + foreach (Tickets::$FIELDS as $field) { + if (!isset($data[$field])) { + throw new RestException(400, "$field field missing"); + } + $ticket[$field] = $data[$field]; + } + return $ticket; + } + + /** + * Validate fields before create or update object message + * + * @param array $data Data to validate + * @return array + * + * @throws RestException + */ + private function _validateMessage($data) + { + $ticket = array(); + foreach (Tickets::$FIELDS_MESSAGES as $field) { + if (!isset($data[$field])) { + throw new RestException(400, "$field field missing"); + } + $ticket[$field] = $data[$field]; + } + return $ticket; + } + + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore + /** + * Clean sensible object datas + * + * @param Object $object Object to clean + * @return Object Object with cleaned properties + * + * @todo use an array for properties to clean + * + */ + protected function _cleanObjectDatas($object) + { + // phpcs:enable + $object = parent::_cleanObjectDatas($object); + + // Other attributes to clean + $attr2clean = array( + "contact", + "contact_id", + "ref_previous", + "ref_next", + "ref_ext", + "table_element_line", + "statut", + "country", + "country_id", + "country_code", + "barcode_type", + "barcode_type_code", + "barcode_type_label", + "barcode_type_coder", + "mode_reglement_id", + "cond_reglement_id", + "cond_reglement", + "fk_delivery_address", + "shipping_method_id", + "modelpdf", + "fk_account", + "note_public", + "note_private", + "note", + "total_ht", + "total_tva", + "total_localtax1", + "total_localtax2", + "total_ttc", + "fk_incoterms", + "label_incoterms", + "location_incoterms", + "name", + "lastname", + "firstname", + "civility_id", + "canvas", + "cache_msgs_ticket", + "cache_logs_ticket", + "cache_types_tickets", + "cache_category_tickets", + "regeximgext", + "statuts_short", + "statuts" + ); + foreach ($attr2clean as $toclean) { + unset($object->$toclean); + } + + // If object has lines, remove $db property + if (isset($object->lines) && count($object->lines) > 0) { + $nboflines = count($object->lines); + for ($i = 0; $i < $nboflines; $i++) { + $this->_cleanObjectDatas($object->lines[$i]); + } + } + + // If object has linked objects, remove $db property + if (isset($object->linkedObjects) && count($object->linkedObjects) > 0) { + foreach ($object->linkedObjects as $type_object => $linked_object) { + foreach ($linked_object as $object2clean) { + $this->_cleanObjectDatas($object2clean); + } + } + } + return $object; + } } diff --git a/htdocs/ticket/class/ticket.class.php b/htdocs/ticket/class/ticket.class.php index 0b7ce39a83c..e5818fa7762 100644 --- a/htdocs/ticket/class/ticket.class.php +++ b/htdocs/ticket/class/ticket.class.php @@ -108,7 +108,7 @@ class Ticket extends CommonObject /** * @var int Ticket statut - * @deprecated + * @deprecated */ public $fk_statut; @@ -197,6 +197,9 @@ class Ticket extends CommonObject */ public $notify_tiers_at_create; + /** + * @var string msgid + */ public $email_msgid; public $lines; @@ -1076,7 +1079,7 @@ class Ticket extends CommonObject * Initialise object with example values * Id must be 0 if object instance is a specimen * - * @return void + * @return int */ public function initAsSpecimen() { @@ -1101,6 +1104,7 @@ class Ticket extends CommonObject $this->date_read = ''; $this->date_close = ''; $this->tms = ''; + return 1; } /** diff --git a/htdocs/user/class/api_users.class.php b/htdocs/user/class/api_users.class.php index d04c735eeed..9a89ad8e81c 100644 --- a/htdocs/user/class/api_users.class.php +++ b/htdocs/user/class/api_users.class.php @@ -153,13 +153,16 @@ class Users extends DolibarrApi //if (!DolibarrApiAccess::$user->rights->user->user->lire) { //throw new RestException(401); //} - - $result = $this->useraccount->fetch($id); + if ($id == 0) { + $result = $this->useraccount->initAsSpecimen(); + } else { + $result = $this->useraccount->fetch($id); + } if (!$result) { throw new RestException(404, 'User not found'); } - if (!DolibarrApi::_checkAccessToResource('user', $this->useraccount->id, 'user')) { + if ($id > 0 && !DolibarrApi::_checkAccessToResource('user', $this->useraccount->id, 'user')) { throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } @@ -286,11 +289,11 @@ class Users extends DolibarrApi //} // check mandatory fields /*if (!isset($request_data["login"])) - throw new RestException(400, "login field missing"); - if (!isset($request_data["password"])) - throw new RestException(400, "password field missing"); - if (!isset($request_data["lastname"])) - throw new RestException(400, "lastname field missing");*/ + throw new RestException(400, "login field missing"); + if (!isset($request_data["password"])) + throw new RestException(400, "password field missing"); + if (!isset($request_data["lastname"])) + throw new RestException(400, "lastname field missing");*/ //assign field values foreach ($request_data as $field => $value) { $this->useraccount->$field = $value; @@ -327,9 +330,10 @@ class Users extends DolibarrApi throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } - foreach ($request_data as $field => $value) - { - if ($field == 'id') continue; + foreach ($request_data as $field => $value) { + if ($field == 'id') { + continue; + } // The status must be updated using setstatus() because it // is not handled by the update() method. if ($field == 'statut') { @@ -461,7 +465,9 @@ class Users extends DolibarrApi $sql = "SELECT t.rowid"; $sql .= " FROM ".MAIN_DB_PREFIX."usergroup as t"; $sql .= ' WHERE t.entity IN ('.getEntity('user').')'; - if ($group_ids) $sql .= " AND t.rowid IN (".$group_ids.")"; + if ($group_ids) { + $sql .= " AND t.rowid IN (".$group_ids.")"; + } // Add sql filters if ($sqlfilters) { if (!DolibarrApi::_checkFilters($sqlfilters)) { @@ -483,13 +489,11 @@ class Users extends DolibarrApi $result = $this->db->query($sql); - if ($result) - { + if ($result) { $i = 0; $num = $this->db->num_rows($result); $min = min($num, ($limit <= 0 ? $num : $limit)); - while ($i < $min) - { + while ($i < $min) { $obj = $this->db->fetch_object($result); $group_static = new UserGroup($this->db); if ($group_static->fetch($obj->rowid)) { @@ -562,8 +566,8 @@ class Users extends DolibarrApi /** * Clean sensible object datas * - * @param Object $object Object to clean - * @return Object Object with cleaned properties + * @param Object $object Object to clean + * @return Object Object with cleaned properties */ protected function _cleanObjectDatas($object) { @@ -681,8 +685,9 @@ class Users extends DolibarrApi { $account = array(); foreach (Users::$FIELDS as $field) { - if (!isset($data[$field])) + if (!isset($data[$field])) { throw new RestException(400, "$field field missing"); + } $account[$field] = $data[$field]; } return $account; diff --git a/htdocs/user/class/user.class.php b/htdocs/user/class/user.class.php index 0bee0101298..e0f2369ded3 100644 --- a/htdocs/user/class/user.class.php +++ b/htdocs/user/class/user.class.php @@ -87,13 +87,19 @@ class User extends CommonObject */ public $personal_email; - /** * @var array array of socialnetworks */ public $socialnetworks; - public $job; // job position + /** + * @var string job position + */ + public $job; + + /** + * @var string user signature + */ public $signature; /** @@ -113,12 +119,40 @@ class User extends CommonObject public $state_id; // The state/department public $state_code; public $state; + + /** + * @var string office phone + */ public $office_phone; + + /** + * @var string office fax + */ public $office_fax; + + /** + * @var string phone mobile + */ public $user_mobile; + + /** + * @var string personal phone mobile + */ public $personal_mobile; + + /** + * @var int 1 if admin 0 if standard user + */ public $admin; + + /** + * @var string user login + */ public $login; + + /** + * @var string user apikey + */ public $api_key; /** @@ -160,9 +194,14 @@ class User extends CommonObject */ public $datem; - //! If this is defined, it is an external user + /** + * @var int If this is defined, it is an external user + */ public $socid; - //! If this is defined, it is a user created from a contact + + /** + * @var int If this is defined, it is a user created from a contact + */ public $contact_id; /** @@ -175,27 +214,71 @@ class User extends CommonObject */ public $fk_user; + /** + * @var int User ID of expense validator + */ public $fk_user_expense_validator; + + /** + * @var int User ID of holidays validator + */ public $fk_user_holiday_validator; + /** + * @string clicktodial url + */ public $clicktodial_url; + + /** + * @var string clicktodial login + */ public $clicktodial_login; + + /** + * @var string clicktodial password + */ public $clicktodial_password; + + /** + * @var string clicktodial poste + */ public $clicktodial_poste; public $datelastlogin; public $datepreviouslogin; public $datestartvalidity; public $dateendvalidity; + + /** + * @var string photo filename + */ public $photo; public $lang; - public $rights; // Array of permissions user->rights->permx - public $all_permissions_are_loaded; // All permission are loaded - public $nb_rights; // Number of rights granted to the user - private $_tab_loaded = array(); // Cache array of already loaded permissions + /** + * @var stdClass Class of permissions user->rights->permx + */ + public $rights; - public $conf; // To store personal config + /** + * @var int All permissions are loaded + */ + public $all_permissions_are_loaded; + + /** + * @var int Number of rights granted to the user + */ + public $nb_rights; + + /** + * @var array Cache array of already loaded permissions + */ + private $_tab_loaded = array(); + + /** + * @var stdClass To store personal config + */ + public $conf; public $default_values; // To store default values for user public $lastsearch_values_tmp; // To store current search criterias for user public $lastsearch_values; // To store last saved search criterias for user @@ -213,7 +296,10 @@ class User extends CommonObject public $salaryextra; // Monthly salary extra - Denormalized value from llx_user_employment public $weeklyhours; // Weekly hours - Denormalized value from llx_user_employment - public $color; // Define background color for user in agenda + /** + * @var string Define background color for user in agenda + */ + public $color; public $dateemployment; // Define date of employment by company public $dateemploymentend; // Define date of employment end by company @@ -322,7 +408,8 @@ class User extends CommonObject } else { $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 {// The fetch was forced on an entity + } else { + // The fetch was forced on an entity 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 { @@ -342,21 +429,19 @@ class User extends CommonObject $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) - { + if ($result) { $obj = $this->db->fetch_object($result); - if ($obj) - { + if ($obj) { $this->id = $obj->rowid; $this->ref = $obj->rowid; - $this->ref_ext = $obj->ref_ext; + $this->ref_ext = $obj->ref_ext; - $this->ldap_sid = $obj->ldap_sid; - $this->lastname = $obj->lastname; + $this->ldap_sid = $obj->ldap_sid; + $this->lastname = $obj->lastname; $this->firstname = $obj->firstname; - $this->employee = $obj->employee; + $this->employee = $obj->employee; $this->login = $obj->login; $this->gender = $obj->gender; @@ -427,7 +512,9 @@ class User extends CommonObject // 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; + if (empty($conf->multicompany->enabled) && $this->admin && $this->entity == 1) { + $this->entity = 0; + } // Retrieve all extrafield // fetch optionals attributes and labels @@ -447,23 +534,22 @@ class User extends CommonObject } // To get back the global configuration unique to the user - if ($loadpersonalconf) - { + if ($loadpersonalconf) { // Load user->conf for user $sql = "SELECT param, value FROM ".MAIN_DB_PREFIX."user_param"; $sql .= " WHERE fk_user = ".$this->id; $sql .= " AND entity = ".$conf->entity; //dol_syslog(get_class($this).'::fetch load personalized conf', LOG_DEBUG); $resql = $this->db->query($sql); - if ($resql) - { + if ($resql) { $num = $this->db->num_rows($resql); $i = 0; - while ($i < $num) - { + while ($i < $num) { $obj = $this->db->fetch_object($resql); $p = (!empty($obj->param) ? $obj->param : ''); - if (!empty($p)) $this->conf->$p = $obj->value; + if (!empty($p)) { + $this->conf->$p = $obj->value; + } $i++; } $this->db->free($resql); @@ -474,8 +560,7 @@ class User extends CommonObject $result = $this->loadDefaultValues(); - if ($result < 0) - { + if ($result < 0) { $this->error = $this->db->lasterror(); return -3; } @@ -499,20 +584,16 @@ class User extends CommonObject $sql .= " WHERE entity IN (".($this->entity > 0 ? $this->entity.", " : "").$conf->entity.")"; // Entity of user (if defined) + current entity $sql .= " AND user_id IN (0".($this->id > 0 ? ", ".$this->id : "").")"; // User 0 (all) + me (if defined) $resql = $this->db->query($sql); - if ($resql) - { - while ($obj = $this->db->fetch_object($resql)) - { - if (!empty($obj->page) && !empty($obj->type) && !empty($obj->param)) - { + if ($resql) { + while ($obj = $this->db->fetch_object($resql)) { + if (!empty($obj->page) && !empty($obj->type) && !empty($obj->param)) { // $obj->page is relative URL with or without params // $obj->type can be 'filters', 'sortorder', 'createform', ... // $obj->param is key or param $pagewithoutquerystring = $obj->page; $pagequeries = ''; $reg = array(); - if (preg_match('/^([^\?]+)\?(.*)$/', $pagewithoutquerystring, $reg)) // There is query param - { + if (preg_match('/^([^\?]+)\?(.*)$/', $pagewithoutquerystring, $reg)) { // There is query param $pagewithoutquerystring = $reg[1]; $pagequeries = $reg[2]; } @@ -522,10 +603,8 @@ class User extends CommonObject } // Sort by key, so _noquery_ is last if (!empty($this->default_values)) { - foreach ($this->default_values as $a => $b) - { - foreach ($b as $c => $d) - { + foreach ($this->default_values as $a => $b) { + foreach ($b as $c => $d) { krsort($this->default_values[$a][$c]); } } @@ -562,8 +641,7 @@ class User extends CommonObject $this->db->begin(); - if (!empty($rid)) - { + if (!empty($rid)) { // Si on a demande ajout d'un droit en particulier, on recupere // les caracteristiques (module, perms et subperms) de ce droit. $sql = "SELECT module, perms, subperms"; @@ -585,27 +663,29 @@ class User extends CommonObject // Where pour la liste des droits a ajouter $whereforadd = "id=".$this->db->escape($rid); // Ajout des droits induits - if (!empty($subperms)) $whereforadd .= " OR (module='$module' AND perms='$perms' AND (subperms='lire' OR subperms='read'))"; - elseif (!empty($perms)) $whereforadd .= " OR (module='$module' AND (perms='lire' OR perms='read') AND subperms IS NULL)"; + if (!empty($subperms)) { + $whereforadd .= " OR (module='$module' AND perms='$perms' AND (subperms='lire' OR subperms='read'))"; + } elseif (!empty($perms)) { + $whereforadd .= " OR (module='$module' AND (perms='lire' OR perms='read') AND subperms IS NULL)"; + } } else { // On a pas demande un droit en particulier mais une liste de droits // sur la base d'un nom de module de de perms // Where pour la liste des droits a ajouter - if (!empty($allmodule)) - { - if ($allmodule == 'allmodules') - { + if (!empty($allmodule)) { + if ($allmodule == 'allmodules') { $whereforadd = 'allmodules'; } else { $whereforadd = "module='".$this->db->escape($allmodule)."'"; - if (!empty($allperms)) $whereforadd .= " AND perms='".$this->db->escape($allperms)."'"; + if (!empty($allperms)) { + $whereforadd .= " AND perms='".$this->db->escape($allperms)."'"; + } } } } // Ajout des droits trouves grace au critere whereforadd - if (!empty($whereforadd)) - { + if (!empty($whereforadd)) { //print "$module-$perms-$subperms"; $sql = "SELECT id"; $sql .= " FROM ".MAIN_DB_PREFIX."rights_def"; @@ -615,19 +695,21 @@ class User extends CommonObject } $result = $this->db->query($sql); - if ($result) - { + if ($result) { $num = $this->db->num_rows($result); $i = 0; - while ($i < $num) - { + while ($i < $num) { $obj = $this->db->fetch_object($result); $nid = $obj->id; $sql = "DELETE FROM ".MAIN_DB_PREFIX."user_rights WHERE fk_user = ".$this->id." AND fk_id=".$nid." AND entity = ".$entity; - if (!$this->db->query($sql)) $error++; + if (!$this->db->query($sql)) { + $error++; + } $sql = "INSERT INTO ".MAIN_DB_PREFIX."user_rights (entity, fk_user, fk_id) VALUES (".$entity.", ".$this->id.", ".$nid.")"; - if (!$this->db->query($sql)) $error++; + if (!$this->db->query($sql)) { + $error++; + } $i++; } @@ -637,14 +719,15 @@ class User extends CommonObject } } - if (!$error && !$notrigger) - { + if (!$error && !$notrigger) { $langs->load("other"); $this->context = array('audit'=>$langs->trans("PermissionsAdd").($rid ? ' (id='.$rid.')' : '')); // Call trigger $result = $this->call_trigger('USER_MODIFY', $user); - if ($result < 0) { $error++; } + if ($result < 0) { + $error++; + } // End call triggers } @@ -701,8 +784,12 @@ class User extends CommonObject // Where pour la liste des droits a supprimer $wherefordel = "id=".$this->db->escape($rid); // Suppression des droits induits - if ($subperms == 'lire' || $subperms == 'read') $wherefordel .= " OR (module='$module' AND perms='$perms' AND subperms IS NOT NULL)"; - if ($perms == 'lire' || $perms == 'read') $wherefordel .= " OR (module='$module')"; + if ($subperms == 'lire' || $subperms == 'read') { + $wherefordel .= " OR (module='$module' AND perms='$perms' AND subperms IS NOT NULL)"; + } + if ($perms == 'lire' || $perms == 'read') { + $wherefordel .= " OR (module='$module')"; + } } else { // On a demande suppression d'un droit sur la base d'un nom de module ou perms // Where pour la liste des droits a supprimer @@ -719,8 +806,7 @@ class User extends CommonObject } // Suppression des droits selon critere defini dans wherefordel - if (!empty($wherefordel)) - { + if (!empty($wherefordel)) { //print "$module-$perms-$subperms"; $sql = "SELECT id"; $sql .= " FROM ".MAIN_DB_PREFIX."rights_def"; @@ -730,8 +816,7 @@ class User extends CommonObject } // avoid admin can remove his own important rights - if ($this->admin == 1) - { + if ($this->admin == 1) { $sql .= " AND id NOT IN (251, 252, 253, 254, 255, 256)"; // other users rights $sql .= " AND id NOT IN (341, 342, 343, 344)"; // own rights $sql .= " AND id NOT IN (351, 352, 353, 354)"; // groups rights @@ -739,19 +824,19 @@ class User extends CommonObject } $result = $this->db->query($sql); - if ($result) - { + if ($result) { $num = $this->db->num_rows($result); $i = 0; - while ($i < $num) - { + while ($i < $num) { $obj = $this->db->fetch_object($result); $nid = $obj->id; $sql = "DELETE FROM ".MAIN_DB_PREFIX."user_rights"; $sql .= " WHERE fk_user = ".$this->id." AND fk_id=".$nid; $sql .= " AND entity = ".$entity; - if (!$this->db->query($sql)) $error++; + if (!$this->db->query($sql)) { + $error++; + } $i++; } @@ -761,14 +846,15 @@ class User extends CommonObject } } - if (!$error && !$notrigger) - { + if (!$error && !$notrigger) { $langs->load("other"); $this->context = array('audit'=>$langs->trans("PermissionsDelete").($rid ? ' (id='.$rid.')' : '')); // Call trigger $result = $this->call_trigger('USER_MODIFY', $user); - if ($result < 0) { $error++; } + if ($result < 0) { + $error++; + } // End call triggers } @@ -810,16 +896,13 @@ class User extends CommonObject { global $conf; - if (empty($forcereload)) - { - if ($moduletag && isset($this->_tab_loaded[$moduletag]) && $this->_tab_loaded[$moduletag]) - { + if (empty($forcereload)) { + if ($moduletag && isset($this->_tab_loaded[$moduletag]) && $this->_tab_loaded[$moduletag]) { // Rights for this module are already loaded, so we leave return; } - if (!empty($this->all_permissions_are_loaded)) - { + if (!empty($this->all_permissions_are_loaded)) { // We already loaded all rights for this user, so we leave return; } @@ -832,42 +915,48 @@ class User extends CommonObject $sql .= " FROM ".MAIN_DB_PREFIX."user_rights as ur"; $sql .= ", ".MAIN_DB_PREFIX."rights_def as r"; $sql .= " WHERE r.id = ur.fk_id"; - if (!empty($conf->global->MULTICOMPANY_BACKWARD_COMPATIBILITY)) - { + if (!empty($conf->global->MULTICOMPANY_BACKWARD_COMPATIBILITY)) { $sql .= " AND r.entity IN (0,".(!empty($conf->multicompany->enabled) && !empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE) ? "1," : "").$conf->entity.")"; } else { $sql .= " AND ur.entity = ".$conf->entity; } $sql .= " AND ur.fk_user= ".$this->id; $sql .= " AND r.perms IS NOT NULL"; - if ($moduletag) $sql .= " AND r.module = '".$this->db->escape($moduletag)."'"; + if ($moduletag) { + $sql .= " AND r.module = '".$this->db->escape($moduletag)."'"; + } $resql = $this->db->query($sql); - if ($resql) - { + if ($resql) { $num = $this->db->num_rows($resql); $i = 0; - while ($i < $num) - { + while ($i < $num) { $obj = $this->db->fetch_object($resql); $module = $obj->module; $perms = $obj->perms; $subperms = $obj->subperms; - if ($perms) - { - if (!isset($this->rights) || !is_object($this->rights)) $this->rights = new stdClass(); // For avoid error - if ($module) - { - if (!isset($this->rights->$module) || !is_object($this->rights->$module)) $this->rights->$module = new stdClass(); - if ($subperms) - { - if (!isset($this->rights->$module->$perms) || !is_object($this->rights->$module->$perms)) $this->rights->$module->$perms = new stdClass(); - if (empty($this->rights->$module->$perms->$subperms)) $this->nb_rights++; + if ($perms) { + if (!isset($this->rights) || !is_object($this->rights)) { + $this->rights = new stdClass(); // For avoid error + } + if ($module) { + if (!isset($this->rights->$module) || !is_object($this->rights->$module)) { + $this->rights->$module = new stdClass(); + } + if ($subperms) { + if (!isset($this->rights->$module->$perms) || !is_object($this->rights->$module->$perms)) { + $this->rights->$module->$perms = new stdClass(); + } + if (empty($this->rights->$module->$perms->$subperms)) { + $this->nb_rights++; + } $this->rights->$module->$perms->$subperms = 1; } else { - if (empty($this->rights->$module->$perms)) $this->nb_rights++; + if (empty($this->rights->$module->$perms)) { + $this->nb_rights++; + } $this->rights->$module->$perms = 1; } } @@ -883,8 +972,7 @@ class User extends CommonObject $sql .= " ".MAIN_DB_PREFIX."usergroup_user as gu,"; $sql .= " ".MAIN_DB_PREFIX."rights_def as r"; $sql .= " WHERE r.id = gr.fk_id"; - if (!empty($conf->global->MULTICOMPANY_BACKWARD_COMPATIBILITY)) - { + if (!empty($conf->global->MULTICOMPANY_BACKWARD_COMPATIBILITY)) { if (!empty($conf->multicompany->enabled) && !empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) { $sql .= " AND gu.entity IN (0,".$conf->entity.")"; } else { @@ -898,34 +986,44 @@ class User extends CommonObject $sql .= " AND gr.fk_usergroup = gu.fk_usergroup"; $sql .= " AND gu.fk_user = ".$this->id; $sql .= " AND r.perms IS NOT NULL"; - if ($moduletag) $sql .= " AND r.module = '".$this->db->escape($moduletag)."'"; + if ($moduletag) { + $sql .= " AND r.module = '".$this->db->escape($moduletag)."'"; + } $resql = $this->db->query($sql); - if ($resql) - { + if ($resql) { $num = $this->db->num_rows($resql); $i = 0; - while ($i < $num) - { + while ($i < $num) { $obj = $this->db->fetch_object($resql); $module = $obj->module; $perms = $obj->perms; $subperms = $obj->subperms; - if ($perms) - { - if (!isset($this->rights) || !is_object($this->rights)) $this->rights = new stdClass(); // For avoid error - if (!isset($this->rights->$module) || !is_object($this->rights->$module)) $this->rights->$module = new stdClass(); - if ($subperms) - { - if (!isset($this->rights->$module->$perms) || !is_object($this->rights->$module->$perms)) $this->rights->$module->$perms = new stdClass(); - if (empty($this->rights->$module->$perms->$subperms)) $this->nb_rights++; + if ($perms) { + if (!isset($this->rights) || !is_object($this->rights)) { + $this->rights = new stdClass(); // For avoid error + } + if (!isset($this->rights->$module) || !is_object($this->rights->$module)) { + $this->rights->$module = new stdClass(); + } + if ($subperms) { + if (!isset($this->rights->$module->$perms) || !is_object($this->rights->$module->$perms)) { + $this->rights->$module->$perms = new stdClass(); + } + if (empty($this->rights->$module->$perms->$subperms)) { + $this->nb_rights++; + } $this->rights->$module->$perms->$subperms = 1; } else { - if (empty($this->rights->$module->$perms)) $this->nb_rights++; + if (empty($this->rights->$module->$perms)) { + $this->nb_rights++; + } // if we have already define a subperm like this $this->rights->$module->level1->level2 with llx_user_rights, we don't want override level1 because the level2 can be not define on user group - if (!isset($this->rights->$module->$perms) || !is_object($this->rights->$module->$perms)) $this->rights->$module->$perms = 1; + if (!isset($this->rights->$module->$perms) || !is_object($this->rights->$module->$perms)) { + $this->rights->$module->$perms = 1; + } } } $i++; @@ -934,11 +1032,14 @@ class User extends CommonObject } // For backward compatibility - if (isset($this->rights->propale) && !isset($this->rights->propal)) $this->rights->propal = $this->rights->propale; - if (isset($this->rights->propal) && !isset($this->rights->propale)) $this->rights->propale = $this->rights->propal; + if (isset($this->rights->propale) && !isset($this->rights->propal)) { + $this->rights->propal = $this->rights->propale; + } + if (isset($this->rights->propal) && !isset($this->rights->propale)) { + $this->rights->propale = $this->rights->propal; + } - if (!$moduletag) - { + if (!$moduletag) { // Si module etait non defini, alors on a tout charge, on peut donc considerer // que les droits sont en cache (car tous charges) pour cet instance de user $this->all_permissions_are_loaded = 1; @@ -961,8 +1062,11 @@ class User extends CommonObject $error = 0; // Check parameters - if ($this->statut == $status) return 0; - else $this->statut = $status; + if ($this->statut == $status) { + return 0; + } else { + $this->statut = $status; + } $this->db->begin(); @@ -973,16 +1077,16 @@ class User extends CommonObject $result = $this->db->query($sql); dol_syslog(get_class($this)."::setstatus", LOG_DEBUG); - if ($result) - { + if ($result) { // Call trigger $result = $this->call_trigger('USER_ENABLEDISABLE', $user); - if ($result < 0) { $error++; } + if ($result < 0) { + $error++; + } // End call triggers } - if ($error) - { + if ($error) { $this->db->rollback(); return -$error; } else { @@ -1061,68 +1165,57 @@ class User extends CommonObject // Remove rights $sql = "DELETE FROM ".MAIN_DB_PREFIX."user_rights WHERE fk_user = ".$this->id; - if (!$error && !$this->db->query($sql)) - { + if (!$error && !$this->db->query($sql)) { $error++; $this->error = $this->db->lasterror(); } // Remove group $sql = "DELETE FROM ".MAIN_DB_PREFIX."usergroup_user WHERE fk_user = ".$this->id; - if (!$error && !$this->db->query($sql)) - { + if (!$error && !$this->db->query($sql)) { $error++; $this->error = $this->db->lasterror(); } // Remove params $sql = "DELETE FROM ".MAIN_DB_PREFIX."user_param WHERE fk_user = ".$this->id; - if (!$error && !$this->db->query($sql)) - { + if (!$error && !$this->db->query($sql)) { $error++; $this->error = $this->db->lasterror(); } // If contact, remove link - if ($this->contact_id > 0) - { + if ($this->contact_id > 0) { $sql = "UPDATE ".MAIN_DB_PREFIX."socpeople SET fk_user_creat = null WHERE rowid = ".$this->contact_id; - if (!$error && !$this->db->query($sql)) - { + if (!$error && !$this->db->query($sql)) { $error++; $this->error = $this->db->lasterror(); } } // Remove extrafields - if (!$error) - { + if (!$error) { $result = $this->deleteExtraFields(); - if ($result < 0) - { + if ($result < 0) { $error++; dol_syslog(get_class($this)."::delete error -4 ".$this->error, LOG_ERR); } } // Remove user - if (!$error) - { + if (!$error) { $sql = "DELETE FROM ".MAIN_DB_PREFIX."user WHERE rowid = ".$this->id; - dol_syslog(get_class($this)."::delete", LOG_DEBUG); - if (!$this->db->query($sql)) - { - $error++; - $this->error = $this->db->lasterror(); - } + dol_syslog(get_class($this)."::delete", LOG_DEBUG); + if (!$this->db->query($sql)) { + $error++; + $this->error = $this->db->lasterror(); + } } - if (!$error) - { + if (!$error) { // Call trigger $result = $this->call_trigger('USER_DELETE', $user); - if ($result < 0) - { + if ($result < 0) { $error++; $this->db->rollback(); return -1; @@ -1152,7 +1245,9 @@ class User extends CommonObject // Clean parameters $this->setUpperOrLowerCase(); $this->login = trim($this->login); - if (!isset($this->entity)) $this->entity = $conf->entity; // If not defined, we use default value + if (!isset($this->entity)) { + $this->entity = $conf->entity; // If not defined, we use default value + } dol_syslog(get_class($this)."::create login=".$this->login.", user=".(is_object($user) ? $user->id : ''), LOG_DEBUG); @@ -1179,13 +1274,11 @@ class User extends CommonObject dol_syslog(get_class($this)."::create", LOG_DEBUG); $resql = $this->db->query($sql); - if ($resql) - { + if ($resql) { $num = $this->db->num_rows($resql); $this->db->free($resql); - if ($num) - { + if ($num) { $this->error = 'ErrorLoginAlreadyExists'; dol_syslog(get_class($this)."::create ".$this->error, LOG_WARNING); $this->db->rollback(); @@ -1196,20 +1289,17 @@ class User extends CommonObject $result = $this->db->query($sql); dol_syslog(get_class($this)."::create", LOG_DEBUG); - if ($result) - { + if ($result) { $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."user"); // Set default rights - if ($this->set_default_rights() < 0) - { + if ($this->set_default_rights() < 0) { $this->error = 'ErrorFailedToSetDefaultRightOfUser'; $this->db->rollback(); return -5; } - if (!empty($conf->global->MAIN_DEFAULT_WAREHOUSE_USER) && !empty($conf->global->STOCK_USERSTOCK_AUTOCREATE)) - { + if (!empty($conf->global->MAIN_DEFAULT_WAREHOUSE_USER) && !empty($conf->global->STOCK_USERSTOCK_AUTOCREATE)) { require_once DOL_DOCUMENT_ROOT.'/product/stock/class/entrepot.class.php'; $langs->load("stocks"); $entrepot = new Entrepot($this->db); @@ -1225,22 +1315,21 @@ class User extends CommonObject // Update minor fields $result = $this->update($user, 1, 1); - if ($result < 0) - { + if ($result < 0) { $this->db->rollback(); return -4; } - if (!$notrigger) - { + if (!$notrigger) { // Call trigger $result = $this->call_trigger('USER_CREATE', $user); - if ($result < 0) { $error++; } + if ($result < 0) { + $error++; + } // End call triggers } - if (!$error) - { + if (!$error) { $this->db->commit(); return $this->id; } else { @@ -1306,22 +1395,24 @@ class User extends CommonObject // Create user and set $this->id. Trigger is disabled because executed later. $result = $this->create($user, 1); - if ($result > 0) - { + if ($result > 0) { $sql = "UPDATE ".MAIN_DB_PREFIX."user"; $sql .= " SET fk_socpeople=".$contact->id; - if ($contact->socid) $sql .= ", fk_soc=".$contact->socid; + if ($contact->socid) { + $sql .= ", fk_soc=".$contact->socid; + } $sql .= " WHERE rowid=".$this->id; $resql = $this->db->query($sql); dol_syslog(get_class($this)."::create_from_contact", LOG_DEBUG); - if ($resql) - { + if ($resql) { $this->context['createfromcontact'] = 'createfromcontact'; // Call trigger $result = $this->call_trigger('USER_CREATE', $user); - if ($result < 0) { $error++; $this->db->rollback(); return -1; } + if ($result < 0) { + $error++; $this->db->rollback(); return -1; + } // End call triggers $this->db->commit(); @@ -1382,33 +1473,31 @@ class User extends CommonObject // Create and set $this->id $result = $this->create($user); - if ($result > 0) - { + if ($result > 0) { if (!empty($this->pass)) { // If a clear password was received (this situation should not happen anymore now), we use it to save it into database $newpass = $this->setPassword($user, $this->pass); - if (is_numeric($newpass) && $newpass < 0) $result = -2; + if (is_numeric($newpass) && $newpass < 0) { + $result = -2; + } } elseif (!empty($this->pass_crypted)) { // If a crypted password is already known, we save it directly into database because the previous create did not save it. $sql = "UPDATE ".MAIN_DB_PREFIX."user"; $sql .= " SET pass_crypted = '".$this->db->escape($this->pass_crypted)."'"; $sql .= " WHERE rowid=".$this->id; $resql = $this->db->query($sql); - if (!$resql) - { + if (!$resql) { $result = -1; } } - if ($result > 0 && $member->fk_soc) // If member is linked to a thirdparty - { + if ($result > 0 && $member->fk_soc) { // If member is linked to a thirdparty $sql = "UPDATE ".MAIN_DB_PREFIX."user"; $sql .= " SET fk_soc=".$member->fk_soc; $sql .= " WHERE rowid=".$this->id; dol_syslog(get_class($this)."::create_from_member", LOG_DEBUG); $resql = $this->db->query($sql); - if ($resql) - { + if ($resql) { $this->db->commit(); return $this->id; } else { @@ -1420,8 +1509,7 @@ class User extends CommonObject } } - if ($result > 0) - { + if ($result > 0) { $this->db->commit(); return $this->id; } else { @@ -1466,7 +1554,9 @@ class User extends CommonObject $sql = "INSERT INTO ".MAIN_DB_PREFIX."user_rights (fk_user, fk_id) VALUES ($this->id, $rd[$i])"; $result = $this->db->query($sql); - if (!$result) return -1; + if (!$result) { + return -1; + } $i++; } @@ -1532,14 +1622,12 @@ class User extends CommonObject $this->fk_warehouse = trim(empty($this->fk_warehouse) ? '' : $this->fk_warehouse); // Check parameters - if (!empty($conf->global->USER_MAIL_REQUIRED) && !isValidEMail($this->email)) - { + if (!empty($conf->global->USER_MAIL_REQUIRED) && !isValidEMail($this->email)) { $langs->load("errors"); $this->error = $langs->trans("ErrorBadEMail", $this->email); return -1; } - if (empty($this->login)) - { + if (empty($this->login)) { $langs->load("errors"); $this->error = $langs->trans("ErrorFieldRequired", 'Login'); return -1; @@ -1556,7 +1644,9 @@ class User extends CommonObject $sql .= ", api_key = ".($this->api_key ? "'".$this->db->escape($this->api_key)."'" : "null"); $sql .= ", gender = ".($this->gender != -1 ? "'".$this->db->escape($this->gender)."'" : "null"); // 'man' or 'woman' $sql .= ", birth=".(strval($this->birth) != '' ? "'".$this->db->idate($this->birth)."'" : 'null'); - if (!empty($user->admin)) $sql .= ", admin = ".(int) $this->admin; // admin flag can be set/unset only by an admin user + if (!empty($user->admin)) { + $sql .= ", admin = ".(int) $this->admin; // admin flag can be set/unset only by an admin user + } $sql .= ", address = '".$this->db->escape($this->address)."'"; $sql .= ", zip = '".$this->db->escape($this->zip)."'"; $sql .= ", town = '".$this->db->escape($this->town)."'"; @@ -1584,10 +1674,18 @@ class User extends CommonObject $sql .= ", fk_user = ".($this->fk_user > 0 ? "'".$this->db->escape($this->fk_user)."'" : "null"); $sql .= ", fk_user_expense_validator = ".($this->fk_user_expense_validator > 0 ? "'".$this->db->escape($this->fk_user_expense_validator)."'" : "null"); $sql .= ", fk_user_holiday_validator = ".($this->fk_user_holiday_validator > 0 ? "'".$this->db->escape($this->fk_user_holiday_validator)."'" : "null"); - if (isset($this->thm) || $this->thm != '') $sql .= ", thm= ".($this->thm != '' ? "'".$this->db->escape($this->thm)."'" : "null"); - if (isset($this->tjm) || $this->tjm != '') $sql .= ", tjm= ".($this->tjm != '' ? "'".$this->db->escape($this->tjm)."'" : "null"); - if (isset($this->salary) || $this->salary != '') $sql .= ", salary= ".($this->salary != '' ? "'".$this->db->escape($this->salary)."'" : "null"); - if (isset($this->salaryextra) || $this->salaryextra != '') $sql .= ", salaryextra= ".($this->salaryextra != '' ? "'".$this->db->escape($this->salaryextra)."'" : "null"); + if (isset($this->thm) || $this->thm != '') { + $sql .= ", thm= ".($this->thm != '' ? "'".$this->db->escape($this->thm)."'" : "null"); + } + if (isset($this->tjm) || $this->tjm != '') { + $sql .= ", tjm= ".($this->tjm != '' ? "'".$this->db->escape($this->tjm)."'" : "null"); + } + if (isset($this->salary) || $this->salary != '') { + $sql .= ", salary= ".($this->salary != '' ? "'".$this->db->escape($this->salary)."'" : "null"); + } + if (isset($this->salaryextra) || $this->salaryextra != '') { + $sql .= ", salaryextra= ".($this->salaryextra != '' ? "'".$this->db->escape($this->salaryextra)."'" : "null"); + } $sql .= ", weeklyhours= ".($this->weeklyhours != '' ? "'".$this->db->escape($this->weeklyhours)."'" : "null"); $sql .= ", entity = '".$this->db->escape($this->entity)."'"; $sql .= ", default_range = ".($this->default_range > 0 ? $this->default_range : 'null'); @@ -1598,39 +1696,39 @@ class User extends CommonObject dol_syslog(get_class($this)."::update", LOG_DEBUG); $resql = $this->db->query($sql); - if ($resql) - { + if ($resql) { $nbrowsaffected += $this->db->affected_rows($resql); // Update password - if (!empty($this->pass)) - { - if ($this->pass != $this->pass_indatabase && $this->pass != $this->pass_indatabase_crypted) - { + if (!empty($this->pass)) { + if ($this->pass != $this->pass_indatabase && $this->pass != $this->pass_indatabase_crypted) { // Si mot de passe saisi et different de celui en base $result = $this->setPassword($user, $this->pass, 0, $notrigger, $nosyncmemberpass); - if (!$nbrowsaffected) $nbrowsaffected++; + if (!$nbrowsaffected) { + $nbrowsaffected++; + } } } // If user is linked to a member, remove old link to this member - if ($this->fk_member > 0) - { + if ($this->fk_member > 0) { dol_syslog(get_class($this)."::update remove link with member. We will recreate it later", LOG_DEBUG); $sql = "UPDATE ".MAIN_DB_PREFIX."user SET fk_member = NULL where fk_member = ".$this->fk_member; $resql = $this->db->query($sql); - if (!$resql) { $this->error = $this->db->error(); $this->db->rollback(); return -5; } + if (!$resql) { + $this->error = $this->db->error(); $this->db->rollback(); return -5; + } } // Set link to user dol_syslog(get_class($this)."::update set link with member", LOG_DEBUG); $sql = "UPDATE ".MAIN_DB_PREFIX."user SET fk_member =".($this->fk_member > 0 ? $this->fk_member : 'null')." where rowid = ".$this->id; $resql = $this->db->query($sql); - if (!$resql) { $this->error = $this->db->error(); $this->db->rollback(); return -5; } + if (!$resql) { + $this->error = $this->db->error(); $this->db->rollback(); return -5; + } - if ($nbrowsaffected) // If something has changed in data - { - if ($this->fk_member > 0 && !$nosyncmember) - { + if ($nbrowsaffected) { // If something has changed in data + if ($this->fk_member > 0 && !$nosyncmember) { dol_syslog(get_class($this)."::update user is linked with a member. We try to update member too.", LOG_DEBUG); require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php'; @@ -1640,8 +1738,7 @@ class User extends CommonObject $adh = new Adherent($this->db); $result = $adh->fetch($this->fk_member); - if ($result > 0) - { + if ($result > 0) { $adh->firstname = $this->firstname; $adh->lastname = $this->lastname; $adh->login = $this->login; @@ -1669,23 +1766,20 @@ class User extends CommonObject $adh->user_login = $this->login; $result = $adh->update($user, 0, 1, 0); - if ($result < 0) - { + if ($result < 0) { $this->error = $adh->error; $this->errors = $adh->errors; dol_syslog(get_class($this)."::update error after calling adh->update to sync it with user: ".$this->error, LOG_ERR); $error++; } - } elseif ($result < 0) - { + } elseif ($result < 0) { $this->error = $adh->error; $this->errors = $adh->errors; $error++; } } - if ($this->contact_id > 0 && !$nosynccontact) - { + if ($this->contact_id > 0 && !$nosynccontact) { dol_syslog(get_class($this)."::update user is linked with a contact. We try to update contact too.", LOG_DEBUG); require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php'; @@ -1694,8 +1788,7 @@ class User extends CommonObject $tmpobj = new Contact($this->db); $result = $tmpobj->fetch($this->contact_id); - if ($result >= 0) - { + if ($result >= 0) { $tmpobj->firstname = $this->firstname; $tmpobj->lastname = $this->lastname; $tmpobj->login = $this->login; @@ -1724,8 +1817,7 @@ class User extends CommonObject $tmpobj->user_login = $this->login; $result = $tmpobj->update($tmpobj->id, $user, 0, 'update', 1); - if ($result < 0) - { + if ($result < 0) { $this->error = $tmpobj->error; $this->errors = $tmpobj->errors; dol_syslog(get_class($this)."::update error after calling adh->update to sync it with user: ".$this->error, LOG_ERR); @@ -1742,25 +1834,23 @@ class User extends CommonObject $action = 'update'; // Actions on extra fields - if (!$error) - { + if (!$error) { $result = $this->insertExtraFields(); - if ($result < 0) - { + if ($result < 0) { $error++; } } - if (!$error && !$notrigger) - { + if (!$error && !$notrigger) { // Call trigger $result = $this->call_trigger('USER_MODIFY', $user); - if ($result < 0) { $error++; } + if ($result < 0) { + $error++; + } // End call triggers } - if (!$error) - { + if (!$error) { $this->db->commit(); return $nbrowsaffected; } else { @@ -1795,8 +1885,7 @@ class User extends CommonObject dol_syslog(get_class($this)."::update_last_login_date user->id=".$this->id." ".$sql, LOG_DEBUG); $resql = $this->db->query($sql); - if ($resql) - { + if ($resql) { $this->datepreviouslogin = $this->datelastlogin; $this->datelastlogin = $now; return 1; @@ -1827,8 +1916,7 @@ class User extends CommonObject dol_syslog(get_class($this)."::setPassword user=".$user->id." password=".preg_replace('/./i', '*', $password)." changelater=".$changelater." notrigger=".$notrigger." nosyncmember=".$nosyncmember, LOG_DEBUG); // If new password not provided, we generate one - if (!$password) - { + if (!$password) { $password = getRandomPassword(false); } @@ -1836,17 +1924,17 @@ class User extends CommonObject $password_crypted = dol_hash($password); // Mise a jour - if (!$changelater) - { - if (!is_object($this->oldcopy)) $this->oldcopy = clone $this; + if (!$changelater) { + if (!is_object($this->oldcopy)) { + $this->oldcopy = clone $this; + } $this->db->begin(); $sql = "UPDATE ".MAIN_DB_PREFIX."user"; $sql .= " SET pass_crypted = '".$this->db->escape($password_crypted)."',"; $sql .= " pass_temp = null"; - if (!empty($conf->global->DATABASE_PWD_ENCRYPTED)) - { + if (!empty($conf->global->DATABASE_PWD_ENCRYPTED)) { $sql .= ", pass = null"; } else { $sql .= ", pass = '".$this->db->escape($password)."'"; @@ -1855,16 +1943,13 @@ class User extends CommonObject dol_syslog(get_class($this)."::setPassword", LOG_DEBUG); $result = $this->db->query($sql); - if ($result) - { - if ($this->db->affected_rows($result)) - { + if ($result) { + if ($this->db->affected_rows($result)) { $this->pass = $password; $this->pass_indatabase = $password; $this->pass_indatabase_crypted = $password_crypted; - if ($this->fk_member && !$nosyncmember) - { + if ($this->fk_member && !$nosyncmember) { require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php'; // This user is linked with a member, so we also update members informations @@ -1872,11 +1957,9 @@ class User extends CommonObject $adh = new Adherent($this->db); $result = $adh->fetch($this->fk_member); - if ($result >= 0) - { + if ($result >= 0) { $result = $adh->setPassword($user, $this->pass, (empty($conf->global->DATABASE_PWD_ENCRYPTED) ? 0 : 1), 1); // Cryptage non gere dans module adherent - if ($result < 0) - { + if ($result < 0) { $this->error = $adh->error; dol_syslog(get_class($this)."::setPassword ".$this->error, LOG_ERR); $error++; @@ -1889,11 +1972,12 @@ class User extends CommonObject dol_syslog(get_class($this)."::setPassword notrigger=".$notrigger." error=".$error, LOG_DEBUG); - if (!$error && !$notrigger) - { + if (!$error && !$notrigger) { // Call trigger $result = $this->call_trigger('USER_NEW_PASSWORD', $user); - if ($result < 0) { $error++; $this->db->rollback(); return -1; } + if ($result < 0) { + $error++; $this->db->rollback(); return -1; + } // End call triggers } @@ -1917,8 +2001,7 @@ class User extends CommonObject dol_syslog(get_class($this)."::setPassword", LOG_DEBUG); // No log $result = $this->db->query($sql); - if ($result) - { + if ($result) { return $password; } else { dol_print_error($this->db); @@ -1953,8 +2036,7 @@ class User extends CommonObject $outputlangs = new Translate("", $conf); if (isset($this->conf->MAIN_LANG_DEFAULT) - && $this->conf->MAIN_LANG_DEFAULT != 'auto') - { // If user has defined its own language (rare because in most cases, auto is used) + && $this->conf->MAIN_LANG_DEFAULT != 'auto') { // If user has defined its own language (rare because in most cases, auto is used) $outputlangs->getDefaultLang($this->conf->MAIN_LANG_DEFAULT); } @@ -1968,7 +2050,9 @@ class User extends CommonObject $outputlangs->loadLangs(array("main", "errors", "users", "other")); $appli = constant('DOL_APPLICATION_TITLE'); - if (!empty($conf->global->MAIN_APPLICATION_TITLE)) $appli = $conf->global->MAIN_APPLICATION_TITLE; + if (!empty($conf->global->MAIN_APPLICATION_TITLE)) { + $appli = $conf->global->MAIN_APPLICATION_TITLE; + } $subject = $outputlangs->transnoentitiesnoconv("SubjectNewPassword", $appli); @@ -1976,8 +2060,7 @@ class User extends CommonObject $urlwithouturlroot = preg_replace('/'.preg_quote(DOL_URL_ROOT, '/').'$/i', '', trim($dolibarr_main_url_root)); $urlwithroot = $urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file - if (!$changelater) - { + if (!$changelater) { $url = $urlwithroot.'/'; $mesg .= $outputlangs->transnoentitiesnoconv("RequestToResetPasswordReceived").".\n"; $mesg .= $outputlangs->transnoentitiesnoconv("NewKeyIs")." :\n\n"; @@ -2024,8 +2107,7 @@ class User extends CommonObject $trackid ); - if ($mailfile->sendfile()) - { + if ($mailfile->sendfile()) { return 1; } else { $langs->trans("errors"); @@ -2059,10 +2141,8 @@ class User extends CommonObject $sql .= " WHERE u.fk_user = ".$this->id; $resql = $this->db->query($sql); - if ($resql) - { - if ($this->db->num_rows($resql)) - { + if ($resql) { + if ($this->db->num_rows($resql)) { $obj = $this->db->fetch_object($resql); $this->clicktodial_url = $obj->url; @@ -2108,8 +2188,7 @@ class User extends CommonObject dol_syslog(get_class($this).'::update_clicktodial', LOG_DEBUG); $result = $this->db->query($sql); - if ($result) - { + if ($result) { $this->db->commit(); return 1; } else { @@ -2149,21 +2228,20 @@ class User extends CommonObject $sql .= " VALUES (".$entity.",".$this->id.",".$group.")"; $result = $this->db->query($sql); - if ($result) - { - if (!$error && !$notrigger) - { + if ($result) { + if (!$error && !$notrigger) { $this->newgroupid = $group; // deprecated. Remove this. $this->context = array('audit'=>$langs->trans("UserSetInGroup"), 'newgroupid'=>$group); // Call trigger $result = $this->call_trigger('USER_MODIFY', $user); - if ($result < 0) { $error++; } + if ($result < 0) { + $error++; + } // End call triggers } - if (!$error) - { + if (!$error) { $this->db->commit(); return 1; } else { @@ -2202,21 +2280,20 @@ class User extends CommonObject $sql .= " AND entity = ".$entity; $result = $this->db->query($sql); - if ($result) - { - if (!$error && !$notrigger) - { + if ($result) { + if (!$error && !$notrigger) { $this->oldgroupid = $group; // deprecated. Remove this. $this->context = array('audit'=>$langs->trans("UserRemovedFromGroup"), 'oldgroupid'=>$group); // Call trigger $result = $this->call_trigger('USER_MODIFY', $user); - if ($result < 0) { $error++; } + if ($result < 0) { + $error++; + } // End call triggers } - if (!$error) - { + if (!$error) { $this->db->commit(); return 1; } else { @@ -2272,14 +2349,17 @@ class User extends CommonObject global $dolibarr_main_authentication, $dolibarr_main_demo; global $menumanager; - if (!$user->rights->user->user->lire && $user->id != $this->id) $option = 'nolink'; + if (!$user->rights->user->user->lire && $user->id != $this->id) { + $option = 'nolink'; + } - if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER) && $withpictoimg) $withpictoimg = 0; + if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER) && $withpictoimg) { + $withpictoimg = 0; + } $result = ''; $label = ''; - if (!empty($this->photo)) - { + if (!empty($this->photo)) { $label .= '
'; $label .= Form::showphoto('userphoto', $this, 0, 60, 0, 'photowithmargin photologintooltip', 'small', 0, 1); // Force height to 60 so we total height of tooltip can be calculated and collision can be managed $label .= '
'; @@ -2290,28 +2370,37 @@ class User extends CommonObject $label .= img_picto('', $this->picto).' '.$langs->trans("User").''; $label .= ' '.$this->getLibStatut(4); $label .= '
'.$langs->trans('Name').': '.$this->getFullName($langs, ''); - if (!empty($this->login)) $label .= '
'.$langs->trans('Login').': '.$this->login; - if (!empty($this->job)) $label .= '
'.$langs->trans("Job").': '.$this->job; + if (!empty($this->login)) { + $label .= '
'.$langs->trans('Login').': '.$this->login; + } + if (!empty($this->job)) { + $label .= '
'.$langs->trans("Job").': '.$this->job; + } $label .= '
'.$langs->trans("Email").': '.$this->email; - if (!empty($this->phone)) $label .= '
'.$langs->trans("Phone").': '.$this->phone; - if (!empty($this->admin)) + if (!empty($this->phone)) { + $label .= '
'.$langs->trans("Phone").': '.$this->phone; + } + if (!empty($this->admin)) { $label .= '
'.$langs->trans("Administrator").': '.yn($this->admin); - if (!empty($this->socid)) // Add thirdparty for external users - { + } + if (!empty($this->socid)) { // Add thirdparty for external users $thirdpartystatic = new Societe($db); $thirdpartystatic->fetch($this->socid); - if (empty($hidethirdpartylogo)) $companylink = ' '.$thirdpartystatic->getNomUrl(2, (($option == 'nolink') ? 'nolink' : '')); // picto only of company + if (empty($hidethirdpartylogo)) { + $companylink = ' '.$thirdpartystatic->getNomUrl(2, (($option == 'nolink') ? 'nolink' : '')); // picto only of company + } $company = ' ('.$langs->trans("Company").': '.$thirdpartystatic->name.')'; } $type = ($this->socid ? $langs->trans("External").$company : $langs->trans("Internal")); $label .= '
'.$langs->trans("Type").': '.$type; $label .= ''; - if ($infologin > 0) - { + if ($infologin > 0) { $label .= '
'; $label .= '
'.$langs->trans("Session").''; $label .= '
'.$langs->trans("IPAddress").': '.$_SERVER["REMOTE_ADDR"]; - if (!empty($conf->global->MAIN_MODULE_MULTICOMPANY)) $label .= '
'.$langs->trans("ConnectedOnMultiCompany").': '.$conf->entity.' (user entity '.$this->entity.')'; + if (!empty($conf->global->MAIN_MODULE_MULTICOMPANY)) { + $label .= '
'.$langs->trans("ConnectedOnMultiCompany").': '.$conf->entity.' (user entity '.$this->entity.')'; + } $label .= '
'.$langs->trans("AuthenticationMode").': '.$_SESSION["dol_authmode"].(empty($dolibarr_main_demo) ? '' : ' (demo)'); $label .= '
'.$langs->trans("ConnectedSince").': '.dol_print_date($this->datelastlogin, "dayhour", 'tzuser'); $label .= '
'.$langs->trans("PreviousConnexion").': '.dol_print_date($this->datepreviouslogin, "dayhour", 'tzuser'); @@ -2322,28 +2411,37 @@ class User extends CommonObject $label .= '
'.$langs->trans("Browser").': '.$conf->browser->name.($conf->browser->version ? ' '.$conf->browser->version : '').' ('.$_SERVER['HTTP_USER_AGENT'].')'; $label .= '
'.$langs->trans("Layout").': '.$conf->browser->layout; $label .= '
'.$langs->trans("Screen").': '.$_SESSION['dol_screenwidth'].' x '.$_SESSION['dol_screenheight']; - if ($conf->browser->layout == 'phone') $label .= '
'.$langs->trans("Phone").': '.$langs->trans("Yes"); - if (!empty($_SESSION["disablemodules"])) $label .= '
'.$langs->trans("DisabledModules").':
'.join(', ', explode(',', $_SESSION["disablemodules"])); + if ($conf->browser->layout == 'phone') { + $label .= '
'.$langs->trans("Phone").': '.$langs->trans("Yes"); + } + if (!empty($_SESSION["disablemodules"])) { + $label .= '
'.$langs->trans("DisabledModules").':
'.join(', ', explode(',', $_SESSION["disablemodules"])); + } + } + if ($infologin < 0) { + $label = ''; } - if ($infologin < 0) $label = ''; $url = DOL_URL_ROOT.'/user/card.php?id='.$this->id; - if ($option == 'leave') $url = DOL_URL_ROOT.'/holiday/list.php?id='.$this->id; + if ($option == 'leave') { + $url = DOL_URL_ROOT.'/holiday/list.php?id='.$this->id; + } - if ($option != 'nolink') - { + if ($option != 'nolink') { // Add param to save lastsearch_values or not $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0); - if ($save_lastsearch_value == -1 && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) $add_save_lastsearch_values = 1; - if ($add_save_lastsearch_values) $url .= '&save_lastsearch_values=1'; + if ($save_lastsearch_value == -1 && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) { + $add_save_lastsearch_values = 1; + } + if ($add_save_lastsearch_values) { + $url .= '&save_lastsearch_values=1'; + } } $linkstart = 'global->MAIN_OPTIMIZEFORTEXTBROWSER)) - { + if (empty($notooltip)) { + if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { $langs->load("users"); $label = $langs->trans("ShowUser"); $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"'; @@ -2364,22 +2462,33 @@ class User extends CommonObject //if ($withpictoimg == -1) $result.='
'; $result .= (($option == 'nolink') ? '' : $linkstart); - if ($withpictoimg) - { - $paddafterimage = ''; - if (abs($withpictoimg) == 1) $paddafterimage = 'style="margin-'.($langs->trans("DIRECTION") == 'rtl' ? 'left' : 'right').': 3px;"'; + if ($withpictoimg) { + $paddafterimage = ''; + if (abs($withpictoimg) == 1) { + $paddafterimage = 'style="margin-'.($langs->trans("DIRECTION") == 'rtl' ? 'left' : 'right').': 3px;"'; + } // Only picto - if ($withpictoimg > 0) $picto = ''.img_object('', 'user', $paddafterimage.' '.($notooltip ? '' : 'class="paddingright classfortooltip"'), 0, 0, $notooltip ? 0 : 1).''; + if ($withpictoimg > 0) { + $picto = ''.img_object('', 'user', $paddafterimage.' '.($notooltip ? '' : 'class="paddingright classfortooltip"'), 0, 0, $notooltip ? 0 : 1).''; + } // Picto must be a photo - else $picto = ''.Form::showphoto('userphoto', $this, 0, 0, 0, 'userphoto'.($withpictoimg == -3 ? 'small' : ''), 'mini', 0, 1).''; + else { + $picto = ''.Form::showphoto('userphoto', $this, 0, 0, 0, 'userphoto'.($withpictoimg == -3 ? 'small' : ''), 'mini', 0, 1).''; + } $result .= $picto; } - if ($withpictoimg > -2 && $withpictoimg != 2) - { - if (empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) $result .= ''; - if ($mode == 'login') $result .= dol_trunc($this->login, $maxlen); - else $result .= $this->getFullName($langs, '', ($mode == 'firstelselast' ? 3 : ($mode == 'firstname' ? 2 : -1)), $maxlen); - if (empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) $result .= ''; + if ($withpictoimg > -2 && $withpictoimg != 2) { + if (empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { + $result .= ''; + } + if ($mode == 'login') { + $result .= dol_trunc($this->login, $maxlen); + } else { + $result .= $this->getFullName($langs, '', ($mode == 'firstelselast' ? 3 : ($mode == 'firstname' ? 2 : -1)), $maxlen); + } + if (empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { + $result .= ''; + } } $result .= (($option == 'nolink') ? '' : $linkend); //if ($withpictoimg == -1) $result.='
'; @@ -2390,8 +2499,11 @@ class User extends CommonObject $hookmanager->initHooks(array('userdao')); $parameters = array('id'=>$this->id, 'getnomurl'=>$result); $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks - if ($reshook > 0) $result = $hookmanager->resPrint; - else $result .= $hookmanager->resPrint; + if ($reshook > 0) { + $result = $hookmanager->resPrint; + } else { + $result .= $hookmanager->resPrint; + } return $result; } @@ -2413,22 +2525,24 @@ class User extends CommonObject $linkend = '
'; //Check user's rights to see an other user - if ((!$user->rights->user->user->lire && $this->id != $user->id)) $option = 'nolink'; + if ((!$user->rights->user->user->lire && $this->id != $user->id)) { + $option = 'nolink'; + } - if ($option == 'xxx') - { + if ($option == 'xxx') { $linkstart = ''; $linkend = ''; } - if ($option == 'nolink') - { + if ($option == 'nolink') { $linkstart = ''; $linkend = ''; } $result .= $linkstart; - if ($withpicto) $result .= img_object($langs->trans("ShowUser"), 'user', 'class="paddingright"'); + if ($withpicto) { + $result .= img_object($langs->trans("ShowUser"), 'user', 'class="paddingright"'); + } $result .= $this->login; $result .= $linkend; return $result; @@ -2458,8 +2572,7 @@ class User extends CommonObject // phpcs:enable global $langs; - if (empty($this->labelStatus) || empty($this->labelStatusShort)) - { + if (empty($this->labelStatus) || empty($this->labelStatusShort)) { global $langs; //$langs->load("mymodule"); $this->labelStatus[self::STATUS_ENABLED] = $langs->trans('Enabled'); @@ -2469,7 +2582,9 @@ class User extends CommonObject } $statusType = 'status5'; - if ($status == self::STATUS_ENABLED) $statusType = 'status4'; + if ($status == self::STATUS_ENABLED) { + $statusType = 'status4'; + } return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusType, $mode); } @@ -2491,9 +2606,13 @@ class User extends CommonObject // phpcs:enable global $conf; $dn = ''; - if ($mode == 0) $dn = $conf->global->LDAP_KEY_USERS."=".$info[$conf->global->LDAP_KEY_USERS].",".$conf->global->LDAP_USER_DN; - elseif ($mode == 1) $dn = $conf->global->LDAP_USER_DN; - elseif ($mode == 2) $dn = $conf->global->LDAP_KEY_USERS."=".$info[$conf->global->LDAP_KEY_USERS]; + if ($mode == 0) { + $dn = $conf->global->LDAP_KEY_USERS."=".$info[$conf->global->LDAP_KEY_USERS].",".$conf->global->LDAP_USER_DN; + } elseif ($mode == 1) { + $dn = $conf->global->LDAP_USER_DN; + } elseif ($mode == 2) { + $dn = $conf->global->LDAP_KEY_USERS."=".$info[$conf->global->LDAP_KEY_USERS]; + } return $dn; } @@ -2536,63 +2655,77 @@ class User extends CommonObject ); // Champs - foreach ($ldapkey as $constname => $varname) - { - if (!empty($this->$varname) && !empty($conf->global->$constname)) - { + foreach ($ldapkey as $constname => $varname) { + if (!empty($this->$varname) && !empty($conf->global->$constname)) { $info[$conf->global->$constname] = $this->$varname; // Check if it is the LDAP key and if its value has been changed - if (!empty($conf->global->LDAP_KEY_USERS) && $conf->global->LDAP_KEY_USERS == $conf->global->$constname) - { - if (!empty($this->oldcopy) && $this->$varname != $this->oldcopy->$varname) $keymodified = true; // For check if LDAP key has been modified + if (!empty($conf->global->LDAP_KEY_USERS) && $conf->global->LDAP_KEY_USERS == $conf->global->$constname) { + if (!empty($this->oldcopy) && $this->$varname != $this->oldcopy->$varname) { + $keymodified = true; // For check if LDAP key has been modified + } } } } - if ($this->address && !empty($conf->global->LDAP_FIELD_ADDRESS)) $info[$conf->global->LDAP_FIELD_ADDRESS] = $this->address; - if ($this->zip && !empty($conf->global->LDAP_FIELD_ZIP)) $info[$conf->global->LDAP_FIELD_ZIP] = $this->zip; - if ($this->town && !empty($conf->global->LDAP_FIELD_TOWN)) $info[$conf->global->LDAP_FIELD_TOWN] = $this->town; - if ($this->note_public && !empty($conf->global->LDAP_FIELD_DESCRIPTION)) $info[$conf->global->LDAP_FIELD_DESCRIPTION] = dol_string_nohtmltag($this->note_public, 2); - if ($this->socid > 0) - { + if ($this->address && !empty($conf->global->LDAP_FIELD_ADDRESS)) { + $info[$conf->global->LDAP_FIELD_ADDRESS] = $this->address; + } + if ($this->zip && !empty($conf->global->LDAP_FIELD_ZIP)) { + $info[$conf->global->LDAP_FIELD_ZIP] = $this->zip; + } + if ($this->town && !empty($conf->global->LDAP_FIELD_TOWN)) { + $info[$conf->global->LDAP_FIELD_TOWN] = $this->town; + } + if ($this->note_public && !empty($conf->global->LDAP_FIELD_DESCRIPTION)) { + $info[$conf->global->LDAP_FIELD_DESCRIPTION] = dol_string_nohtmltag($this->note_public, 2); + } + if ($this->socid > 0) { $soc = new Societe($this->db); $soc->fetch($this->socid); $info[$conf->global->LDAP_FIELD_COMPANY] = $soc->name; - if ($soc->client == 1) $info["businessCategory"] = "Customers"; - if ($soc->client == 2) $info["businessCategory"] = "Prospects"; - if ($soc->fournisseur == 1) $info["businessCategory"] = "Suppliers"; + if ($soc->client == 1) { + $info["businessCategory"] = "Customers"; + } + if ($soc->client == 2) { + $info["businessCategory"] = "Prospects"; + } + if ($soc->fournisseur == 1) { + $info["businessCategory"] = "Suppliers"; + } } // When password is modified - if (!empty($this->pass)) - { - if (!empty($conf->global->LDAP_FIELD_PASSWORD)) $info[$conf->global->LDAP_FIELD_PASSWORD] = $this->pass; // this->pass = mot de passe non crypte - if (!empty($conf->global->LDAP_FIELD_PASSWORD_CRYPTED)) $info[$conf->global->LDAP_FIELD_PASSWORD_CRYPTED] = dol_hash($this->pass, 4); // Create OpenLDAP MD5 password (TODO add type of encryption) + if (!empty($this->pass)) { + if (!empty($conf->global->LDAP_FIELD_PASSWORD)) { + $info[$conf->global->LDAP_FIELD_PASSWORD] = $this->pass; // this->pass = mot de passe non crypte + } + if (!empty($conf->global->LDAP_FIELD_PASSWORD_CRYPTED)) { + $info[$conf->global->LDAP_FIELD_PASSWORD_CRYPTED] = dol_hash($this->pass, 4); // Create OpenLDAP MD5 password (TODO add type of encryption) + } } // Set LDAP password if possible - elseif ($conf->global->LDAP_SERVER_PROTOCOLVERSION !== '3') // If ldap key is modified and LDAPv3 we use ldap_rename function for avoid lose encrypt password - { - if (!empty($conf->global->DATABASE_PWD_ENCRYPTED)) - { + elseif ($conf->global->LDAP_SERVER_PROTOCOLVERSION !== '3') { // If ldap key is modified and LDAPv3 we use ldap_rename function for avoid lose encrypt password + if (!empty($conf->global->DATABASE_PWD_ENCRYPTED)) { // Just for the default MD5 ! - if (empty($conf->global->MAIN_SECURITY_HASH_ALGO)) - { + if (empty($conf->global->MAIN_SECURITY_HASH_ALGO)) { if ($this->pass_indatabase_crypted && !empty($conf->global->LDAP_FIELD_PASSWORD_CRYPTED)) { $info[$conf->global->LDAP_FIELD_PASSWORD_CRYPTED] = dol_hash($this->pass_indatabase_crypted, 5); // Create OpenLDAP MD5 password from Dolibarr MD5 password } } } // Use $this->pass_indatabase value if exists - elseif (!empty($this->pass_indatabase)) - { - if (!empty($conf->global->LDAP_FIELD_PASSWORD)) $info[$conf->global->LDAP_FIELD_PASSWORD] = $this->pass_indatabase; // $this->pass_indatabase = mot de passe non crypte - if (!empty($conf->global->LDAP_FIELD_PASSWORD_CRYPTED)) $info[$conf->global->LDAP_FIELD_PASSWORD_CRYPTED] = dol_hash($this->pass_indatabase, 4); // md5 for OpenLdap TODO add type of encryption + elseif (!empty($this->pass_indatabase)) { + if (!empty($conf->global->LDAP_FIELD_PASSWORD)) { + $info[$conf->global->LDAP_FIELD_PASSWORD] = $this->pass_indatabase; // $this->pass_indatabase = mot de passe non crypte + } + if (!empty($conf->global->LDAP_FIELD_PASSWORD_CRYPTED)) { + $info[$conf->global->LDAP_FIELD_PASSWORD_CRYPTED] = dol_hash($this->pass_indatabase, 4); // md5 for OpenLdap TODO add type of encryption + } } } - if ($conf->global->LDAP_SERVER_TYPE == 'egroupware') - { + if ($conf->global->LDAP_SERVER_TYPE == 'egroupware') { $info["objectclass"][4] = "phpgwContact"; // compatibilite egroupware $info['uidnumber'] = $this->id; @@ -2605,18 +2738,23 @@ class User extends CommonObject $info["phpgwContactCatId"] = 0; $info["phpgwContactAccess"] = "public"; - if (dol_strlen($this->egroupware_id) == 0) - { + if (dol_strlen($this->egroupware_id) == 0) { $this->egroupware_id = 1; } $info["phpgwContactOwner"] = $this->egroupware_id; - if ($this->email) $info["rfc822Mailbox"] = $this->email; - if ($this->phone_mobile) $info["phpgwCellTelephoneNumber"] = $this->phone_mobile; + if ($this->email) { + $info["rfc822Mailbox"] = $this->email; + } + if ($this->phone_mobile) { + $info["phpgwCellTelephoneNumber"] = $this->phone_mobile; + } } - if (!empty($conf->global->LDAP_FIELD_USERID))$info[$conf->global->LDAP_FIELD_USERID] = $this->id; + if (!empty($conf->global->LDAP_FIELD_USERID)) { + $info[$conf->global->LDAP_FIELD_USERID] = $this->id; + } if (!empty($info[$conf->global->LDAP_FIELD_GROUPID])) { $usergroup = new UserGroup($this->db); $groupslist = $usergroup->listGroupsForUser($this->id); @@ -2628,7 +2766,9 @@ class User extends CommonObject } } } - if (!empty($this->firstname) && !empty($conf->global->LDAP_FIELD_HOMEDIRECTORY) && !empty($conf->global->LDAP_FIELD_HOMEDIRECTORYPREFIX)) $info[$conf->global->LDAP_FIELD_HOMEDIRECTORY] = "{$conf->global->LDAP_FIELD_HOMEDIRECTORYPREFIX}/$this->firstname"; + if (!empty($this->firstname) && !empty($conf->global->LDAP_FIELD_HOMEDIRECTORY) && !empty($conf->global->LDAP_FIELD_HOMEDIRECTORYPREFIX)) { + $info[$conf->global->LDAP_FIELD_HOMEDIRECTORY] = "{$conf->global->LDAP_FIELD_HOMEDIRECTORYPREFIX}/$this->firstname"; + } return $info; } @@ -2639,7 +2779,7 @@ class User extends CommonObject * Used to build previews or test instances. * id must be 0 if object instance is a specimen. * - * @return void + * @return int */ public function initAsSpecimen() { @@ -2682,6 +2822,7 @@ class User extends CommonObject $this->statut = 1; $this->entity = 1; + return 1; } /** @@ -2698,10 +2839,8 @@ class User extends CommonObject $sql .= " WHERE u.rowid = ".$id; $result = $this->db->query($sql); - if ($result) - { - if ($this->db->num_rows($result)) - { + if ($result) { + if ($this->db->num_rows($result)) { $obj = $this->db->fetch_object($result); $this->id = $obj->rowid; @@ -2732,8 +2871,7 @@ class User extends CommonObject $sql .= " AND mc.statut NOT IN (-1,0)"; // -1 erreur, 0 non envoye, 1 envoye avec succes $resql = $this->db->query($sql); - if ($resql) - { + if ($resql) { $obj = $this->db->fetch_object($resql); $nb = $obj->nb; @@ -2759,19 +2897,23 @@ class User extends CommonObject $sql = "SELECT count(rowid) as nb"; $sql .= " FROM ".MAIN_DB_PREFIX."user"; - if ($option == 'superadmin') - { + if ($option == 'superadmin') { $sql .= " WHERE entity = 0"; - if ($admin >= 0) $sql .= " AND admin = ".$admin; + if ($admin >= 0) { + $sql .= " AND admin = ".$admin; + } } else { $sql .= " WHERE entity IN (".getEntity('user', 0).")"; - if ($limitTo == 'active') $sql .= " AND statut = 1"; - if ($admin >= 0) $sql .= " AND admin = ".$admin; + if ($limitTo == 'active') { + $sql .= " AND statut = 1"; + } + if ($admin >= 0) { + $sql .= " AND admin = ".$admin; + } } $resql = $this->db->query($sql); - if ($resql) - { + if ($resql) { $obj = $this->db->fetch_object($resql); $nb = $obj->nb; @@ -2838,11 +2980,9 @@ class User extends CommonObject dol_syslog(get_class($this)."::get_children sql=".$sql, LOG_DEBUG); $res = $this->db->query($sql); - if ($res) - { + if ($res) { $users = array(); - while ($rec = $this->db->fetch_array($res)) - { + while ($rec = $this->db->fetch_array($res)) { $user = new User($this->db); $user->fetch($rec['rowid']); $users[] = $user; @@ -2874,10 +3014,8 @@ class User extends CommonObject dol_syslog(get_class($this)."::loadParentOf", LOG_DEBUG); $resql = $this->db->query($sql); - if ($resql) - { - while ($obj = $this->db->fetch_object($resql)) - { + if ($resql) { + while ($obj = $this->db->fetch_object($resql)) { $this->parentof[$obj->id_son] = $obj->id_parent; } return 1; @@ -2926,15 +3064,15 @@ class User extends CommonObject } else { $sql .= " WHERE u.entity IN (".getEntity('user').")"; } - if ($filter) $sql .= " AND ".$filter; + if ($filter) { + $sql .= " AND ".$filter; + } dol_syslog(get_class($this)."::get_full_tree get user list", LOG_DEBUG); $resql = $this->db->query($sql); - if ($resql) - { + if ($resql) { $i = 0; - while ($obj = $this->db->fetch_object($resql)) - { + while ($obj = $this->db->fetch_object($resql)) { $this->users[$obj->rowid]['rowid'] = $obj->rowid; $this->users[$obj->rowid]['id'] = $obj->rowid; $this->users[$obj->rowid]['fk_user'] = $obj->fk_user; @@ -2957,29 +3095,24 @@ class User extends CommonObject // We add the fullpath property to each elements of first level (no parent exists) dol_syslog(get_class($this)."::get_full_tree call to build_path_from_id_user", LOG_DEBUG); - foreach ($this->users as $key => $val) - { + foreach ($this->users as $key => $val) { $result = $this->build_path_from_id_user($key, 0); // Process a branch from the root user key (this user has no parent) - if ($result < 0) - { + if ($result < 0) { $this->error = 'ErrorLoopInHierarchy'; return -1; } } // Exclude leaf including $deleteafterid from tree - if ($deleteafterid) - { + if ($deleteafterid) { //print "Look to discard user ".$deleteafterid."\n"; $keyfilter1 = '^'.$deleteafterid.'$'; $keyfilter2 = '_'.$deleteafterid.'$'; $keyfilter3 = '^'.$deleteafterid.'_'; $keyfilter4 = '_'.$deleteafterid.'_'; - foreach ($this->users as $key => $val) - { + foreach ($this->users as $key => $val) { if (preg_match('/'.$keyfilter1.'/', $val['fullpath']) || preg_match('/'.$keyfilter2.'/', $val['fullpath']) - || preg_match('/'.$keyfilter3.'/', $val['fullpath']) || preg_match('/'.$keyfilter4.'/', $val['fullpath'])) - { + || preg_match('/'.$keyfilter3.'/', $val['fullpath']) || preg_match('/'.$keyfilter4.'/', $val['fullpath'])) { unset($this->users[$key]); } } @@ -3005,8 +3138,7 @@ class User extends CommonObject { $childids = array(); - if (isset($this->cache_childids[$this->id])) - { + if (isset($this->cache_childids[$this->id])) { $childids = $this->cache_childids[$this->id]; } else { // Init this->users @@ -3015,15 +3147,18 @@ class User extends CommonObject $idtoscan = $this->id; dol_syslog("Build childid for id = ".$idtoscan); - foreach ($this->users as $id => $val) - { + foreach ($this->users as $id => $val) { //var_dump($val['fullpath']); - if (preg_match('/_'.$idtoscan.'_/', $val['fullpath'])) $childids[$val['id']] = $val['id']; + if (preg_match('/_'.$idtoscan.'_/', $val['fullpath'])) { + $childids[$val['id']] = $val['id']; + } } } $this->cache_childids[$this->id] = $childids; - if ($addcurrentuser) $childids[$this->id] = $this->id; + if ($addcurrentuser) { + $childids[$this->id] = $this->id; + } return $childids; } @@ -3042,8 +3177,7 @@ class User extends CommonObject // phpcs:enable //dol_syslog(get_class($this)."::build_path_from_id_user id_user=".$id_user." protection=".$protection, LOG_DEBUG); - if (!empty($this->users[$id_user]['fullpath'])) - { + if (!empty($this->users[$id_user]['fullpath'])) { // Already defined dol_syslog(get_class($this)."::build_path_from_id_user fullpath and fullname already defined", LOG_WARNING); return 0; @@ -3055,10 +3189,8 @@ class User extends CommonObject $i = 0; $cursor_user = $id_user; $useridfound = array($id_user); - while (!empty($this->parentof[$cursor_user])) - { - if (in_array($this->parentof[$cursor_user], $useridfound)) - { + while (!empty($this->parentof[$cursor_user])) { + if (in_array($this->parentof[$cursor_user], $useridfound)) { dol_syslog("The hierarchy of user has a recursive loop", LOG_WARNING); return -1; // Should not happen. Protection against looping hierarchy } @@ -3111,10 +3243,8 @@ class User extends CommonObject $sql .= " AND u.entity IN (".getEntity('user').")"; $resql = $this->db->query($sql); - if ($resql) - { - while ($obj = $this->db->fetch_object($resql)) - { + if ($resql) { + while ($obj = $this->db->fetch_object($resql)) { $this->nb["users"] = $obj->nb; } $this->db->free($resql); @@ -3144,10 +3274,8 @@ class User extends CommonObject $langs->load("user"); // Positionne le modele sur le nom du modele a utiliser - if (!dol_strlen($modele)) - { - if (!empty($conf->global->USER_ADDON_PDF)) - { + if (!dol_strlen($modele)) { + if (!empty($conf->global->USER_ADDON_PDF)) { $modele = $conf->global->USER_ADDON_PDF; } else { $modele = 'bluesky'; @@ -3172,23 +3300,26 @@ class User extends CommonObject // phpcs:enable $user_property = ''; - if (empty($rowid)) return ''; + if (empty($rowid)) { + return ''; + } $sql = "SELECT rowid, email, user_mobile, civility, lastname, firstname"; $sql .= " FROM ".MAIN_DB_PREFIX."user"; $sql .= " WHERE rowid = ".((int) $rowid); $resql = $this->db->query($sql); - if ($resql) - { + if ($resql) { $nump = $this->db->num_rows($resql); - if ($nump) - { + if ($nump) { $obj = $this->db->fetch_object($resql); - if ($mode == 'email') $user_property = dolGetFirstLastname($obj->firstname, $obj->lastname)." <".$obj->email.">"; - elseif ($mode == 'mobile') $user_property = $obj->user_mobile; + if ($mode == 'email') { + $user_property = dolGetFirstLastname($obj->firstname, $obj->lastname)." <".$obj->email.">"; + } elseif ($mode == 'mobile') { + $user_property = $obj->user_mobile; + } } return $user_property; } else { @@ -3215,10 +3346,8 @@ class User extends CommonObject $sql = "SELECT t.rowid"; $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t '; - if ($entityfilter) - { - if (!empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) - { + if ($entityfilter) { + if (!empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) { if (!empty($user->admin) && empty($user->entity) && $conf->entity == 1) { $sql .= " WHERE t.entity IS NOT NULL"; // Show all users } else { @@ -3253,19 +3382,18 @@ class User extends CommonObject $sql .= ' AND ('.implode(' '.$filtermode.' ', $sqlwhere).')'; } $sql .= $this->db->order($sortfield, $sortorder); - if ($limit) $sql .= $this->db->plimit($limit + 1, $offset); + if ($limit) { + $sql .= $this->db->plimit($limit + 1, $offset); + } dol_syslog(__METHOD__, LOG_DEBUG); $resql = $this->db->query($sql); - if ($resql) - { + if ($resql) { $this->users = array(); $num = $this->db->num_rows($resql); - if ($num) - { - while ($obj = $this->db->fetch_object($resql)) - { + if ($num) { + while ($obj = $this->db->fetch_object($resql)) { $line = new self($this->db); $result = $line->fetch($obj->rowid); if ($result > 0 && !empty($line->id)) { @@ -3302,8 +3430,7 @@ class User extends CommonObject */ public function findUserIdByEmail($email) { - if ($this->findUserIdByEmailCache[$email]) - { + if ($this->findUserIdByEmailCache[$email]) { return $this->findUserIdByEmailCache[$email]; } @@ -3314,25 +3441,21 @@ class User extends CommonObject $sql = 'SELECT rowid'; $sql .= ' FROM '.MAIN_DB_PREFIX.'user'; - if (!empty($conf->global->AGENDA_DISABLE_EXACT_USER_EMAIL_COMPARE_FOR_EXTERNAL_CALENDAR)) - { + if (!empty($conf->global->AGENDA_DISABLE_EXACT_USER_EMAIL_COMPARE_FOR_EXTERNAL_CALENDAR)) { $sql .= ' WHERE email LIKE "%'.$email.'%"'; - } - else { + } else { $sql .= ' WHERE email = "'.$email.'"'; } $sql .= ' LIMIT 1'; $resql = $this->db->query($sql); - if (!$resql) - { + if (!$resql) { return -1; } $obj = $this->db->fetch_object($resql); - if (!$obj) - { + if (!$obj) { return -1; } diff --git a/htdocs/zapier/class/api_zapier.class.php b/htdocs/zapier/class/api_zapier.class.php index 6118aa71241..bb3e42f5f05 100644 --- a/htdocs/zapier/class/api_zapier.class.php +++ b/htdocs/zapier/class/api_zapier.class.php @@ -93,14 +93,13 @@ class ZapierApi extends DolibarrApi * Get list of possibles choices for module * * Return an array with hook informations - * @param integer $id ID * - * @return array|mixed data + * @return array data * * @url GET /getmoduleschoices/ * @throws RestException */ - public function getModulesChoices($id) + public function getModulesChoices() { if (!DolibarrApiAccess::$user->rights->zapier->read) { throw new RestException(401); @@ -110,6 +109,7 @@ class ZapierApi extends DolibarrApi 'orders' => 'Orders', 'thirdparties' => 'Thirparties', 'contacts' => 'Contacts', + 'users' => 'Users', ); // $result = $this->hook->fetch($id); // if (! $result ) { @@ -244,6 +244,7 @@ class ZapierApi extends DolibarrApi $fields = array( 'url', ); + dol_syslog("API Zapier create hook receive : " . print_r($request_data, true), LOG_DEBUG); $result = $this->validate($request_data, $fields); foreach ($request_data as $field => $value) { diff --git a/htdocs/zapier/class/hook.class.php b/htdocs/zapier/class/hook.class.php index e7ce317096d..8e6d3fa725f 100644 --- a/htdocs/zapier/class/hook.class.php +++ b/htdocs/zapier/class/hook.class.php @@ -126,7 +126,7 @@ class Hook extends CommonObject ), 'module' => array( 'type' => 'varchar(128)', - 'label' => 'Url', + 'label' => 'Module', 'enabled' => 1, 'visible' => 1, 'position' => 30, @@ -137,7 +137,7 @@ class Hook extends CommonObject ), 'action' => array( 'type' => 'varchar(128)', - 'label' => 'Url', + 'label' => 'Action', 'enabled' => 1, 'visible' => 1, 'position' => 30,