commit
eba73101b9
@ -1,6 +1,6 @@
|
|||||||
/*jshint esversion: 6 */
|
/*jshint esversion: 6 */
|
||||||
const testAuth = (z , bundle) => {
|
const test = (z , bundle) => {
|
||||||
const url = bundle.authData.url+'/api/index.php/login';
|
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
|
// 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.
|
// 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
|
// In this example, we'll hit httpbin, which validates the Authorization Header against the arguments passed in the URL path
|
||||||
@ -11,44 +11,69 @@ const testAuth = (z , bundle) => {
|
|||||||
// This method can return any truthy value to indicate the credentials are valid.
|
// This method can return any truthy value to indicate the credentials are valid.
|
||||||
// Raise an error to show
|
// Raise an error to show
|
||||||
return promise.then((response) => {
|
return promise.then((response) => {
|
||||||
if (response.status === 401) {
|
if (response.status === 400) {
|
||||||
throw new Error('The Session Key you supplied is invalid');
|
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;
|
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 url = bundle.authData.url + '/api/index.php/login';
|
||||||
|
|
||||||
const promise = z.request({
|
const response = await z.request({
|
||||||
method: 'POST',
|
|
||||||
url: url,
|
url: url,
|
||||||
|
method: 'POST',
|
||||||
body: {
|
body: {
|
||||||
login: bundle.authData.login,
|
login: bundle.authData.login,
|
||||||
password: bundle.authData.password,
|
password: bundle.authData.password,
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
return promise.then((response) => {
|
// if (response.status === 401) {
|
||||||
if (response.status === 401) {
|
// throw new Error('The login/password you supplied is invalid');
|
||||||
throw new Error('The login/password you supplied is invalid');
|
// }
|
||||||
}
|
|
||||||
const json = JSON.parse(response.content);
|
const json = JSON.parse(response.content);
|
||||||
return {
|
return {
|
||||||
sessionKey: json.success.token || 'secret'
|
sessionKey: json.success.token || '',
|
||||||
};
|
};
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
config: {
|
||||||
type: 'session',
|
type: 'session',
|
||||||
|
sessionConfig: {
|
||||||
|
perform: getSessionKey
|
||||||
|
},
|
||||||
// Define any auth fields your app requires here. The user will be prompted to enter this info when
|
// Define any auth fields your app requires here. The user will be prompted to enter this info when
|
||||||
// they connect their account.
|
// they connect their account.
|
||||||
fields: [
|
fields: [
|
||||||
{
|
{
|
||||||
key: 'url',
|
key: 'url',
|
||||||
label: 'Url of service',
|
label: 'Url of service without trailing-slash',
|
||||||
required: true,
|
required: true,
|
||||||
type: 'string'
|
type: 'string'
|
||||||
},
|
},
|
||||||
@ -67,11 +92,11 @@ module.exports = {
|
|||||||
],
|
],
|
||||||
// The test method allows Zapier to verify that the credentials a user provides are valid. We'll execute this
|
// 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.
|
// method whenever a user connects their account for the first time.
|
||||||
test: testAuth,
|
test,
|
||||||
// The method that will exchange the fields provided by the user for session credentials.
|
// The method that will exchange the fields provided by the user for session credentials.
|
||||||
sessionConfig: {
|
|
||||||
perform: getSessionKey
|
|
||||||
},
|
|
||||||
// assuming "login" is a key returned from the test
|
// assuming "login" is a key returned from the test
|
||||||
connectionLabel: '{{login}}'
|
connectionLabel: '{{login}}'
|
||||||
|
},
|
||||||
|
befores: [includeSessionKeyHeader],
|
||||||
|
afters: [sessionRefreshIf401],
|
||||||
};
|
};
|
||||||
|
|||||||
@ -72,7 +72,7 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
outputFields: [
|
outputFields: [
|
||||||
{key: 'id', label: 'ID'},
|
{key: 'id', type: "integer", label: 'ID'},
|
||||||
{key: 'name', label: 'Name'},
|
{key: 'name', label: 'Name'},
|
||||||
{key: 'name_alias', label: 'Name alias'},
|
{key: 'name_alias', label: 'Name alias'},
|
||||||
{key: 'address', label: 'Address'},
|
{key: 'address', label: 'Address'},
|
||||||
@ -81,8 +81,8 @@ module.exports = {
|
|||||||
{key: 'phone', label: 'Phone'},
|
{key: 'phone', label: 'Phone'},
|
||||||
{key: 'fax', label: 'Fax'},
|
{key: 'fax', label: 'Fax'},
|
||||||
{key: 'email', label: 'Email'},
|
{key: 'email', label: 'Email'},
|
||||||
{key: 'client', label: 'Customer/Prospect 0/1/2/3'},
|
{key: 'client', type: "integer", label: 'Customer/Prospect 0/1/2/3'},
|
||||||
{key: 'fournisseur', label: 'Supplier 0/1'},
|
{key: 'fournisseur', type: "integer", label: 'Supplier 0/1'},
|
||||||
{key: 'code_client', label: 'Customer code'},
|
{key: 'code_client', label: 'Customer code'},
|
||||||
{key: 'code_fournisseur', label: 'Supplier code'}
|
{key: 'code_fournisseur', label: 'Supplier code'}
|
||||||
]
|
]
|
||||||
|
|||||||
@ -1,33 +1,39 @@
|
|||||||
/*jshint esversion: 6 */
|
/*jshint esversion: 6 */
|
||||||
const triggerThirdparty = require('./triggers/thirdparty');
|
|
||||||
const triggerOrder = require('./triggers/order');
|
|
||||||
const triggerAction = require('./triggers/action');
|
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 searchThirdparty = require('./searches/thirdparty');
|
||||||
|
|
||||||
const createThirdparty = require('./creates/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.
|
// 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
|
// 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) => {
|
// const includeSessionKeyHeader = (request, z, bundle) => {
|
||||||
if (bundle.authData.sessionKey) {
|
// if (bundle.authData.sessionKey) {
|
||||||
request.headers = request.headers || {};
|
// request.headers = request.headers || {};
|
||||||
request.headers['DOLAPIKEY'] = bundle.authData.sessionKey;
|
// request.headers['DOLAPIKEY'] = bundle.authData.sessionKey;
|
||||||
}
|
// }
|
||||||
return request;
|
// 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.
|
// 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) => {
|
// const sessionRefreshIf401 = (response, z, bundle) => {
|
||||||
if (bundle.authData.sessionKey) {
|
// if (bundle.authData.sessionKey) {
|
||||||
if (response.status === 401) {
|
// if (response.status === 401) {
|
||||||
throw new z.errors.RefreshAuthError('Session apikey needs refreshing.');
|
// throw new z.errors.RefreshAuthError('Session apikey needs refreshing.');
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
return response;
|
// return response;
|
||||||
};
|
// };
|
||||||
|
|
||||||
// We can roll up all our behaviors in an App.
|
// We can roll up all our behaviors in an App.
|
||||||
const App = {
|
const App = {
|
||||||
@ -40,11 +46,11 @@ const App = {
|
|||||||
|
|
||||||
// beforeRequest & afterResponse are optional hooks into the provided HTTP client
|
// beforeRequest & afterResponse are optional hooks into the provided HTTP client
|
||||||
beforeRequest: [
|
beforeRequest: [
|
||||||
includeSessionKeyHeader
|
...befores
|
||||||
],
|
],
|
||||||
|
|
||||||
afterResponse: [
|
afterResponse: [
|
||||||
sessionRefreshIf401
|
...afters
|
||||||
],
|
],
|
||||||
|
|
||||||
// If you want to define optional resources to simplify creation of triggers, searches, creates - do that here!
|
// 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!
|
// If you want your trigger to show up, you better include it here!
|
||||||
triggers: {
|
triggers: {
|
||||||
[triggerThirdparty.key]: triggerThirdparty,
|
[triggerAction.key]: triggerAction,
|
||||||
[triggerOrder.key]: triggerOrder,
|
[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!
|
// If you want your searches to show up, you better include it here!
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "dolibarr",
|
"name": "dolibarr",
|
||||||
"version": "1.0.0",
|
"version": "1.13.0",
|
||||||
"description": "An app for connecting Dolibarr to the Zapier platform.",
|
"description": "An app for connecting Dolibarr to the Zapier platform.",
|
||||||
"repository": "Dolibarr/dolibarr",
|
"repository": "Dolibarr/dolibarr",
|
||||||
"homepage": "https://www.dolibarr.org/",
|
"homepage": "https://www.dolibarr.org/",
|
||||||
@ -15,7 +15,7 @@
|
|||||||
"npm": ">=5.6.0"
|
"npm": ">=5.6.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"zapier-platform-core": "8.0.1"
|
"zapier-platform-core": "10.1.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"mocha": "^5.2.0",
|
"mocha": "^5.2.0",
|
||||||
|
|||||||
@ -54,13 +54,20 @@ module.exports = {
|
|||||||
// outputFields: () => { return []; }
|
// outputFields: () => { return []; }
|
||||||
// Alternatively, a static field definition should be provided, to specify labels for the fields
|
// Alternatively, a static field definition should be provided, to specify labels for the fields
|
||||||
outputFields: [
|
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: 'name', label: 'Name'},
|
||||||
{key: 'firstname', label: 'Firstname'},
|
{key: 'firstname', label: 'Firstname'},
|
||||||
{key: 'directions', label: 'Directions'},
|
{key: 'directions', label: 'Directions'},
|
||||||
{key: 'authorId', label: 'Author ID'},
|
{key: 'authorId', type: "integer", label: 'Author ID'},
|
||||||
{key: 'style', label: 'Style'}
|
{
|
||||||
|
key: 'style',
|
||||||
|
label: 'Style'
|
||||||
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@ -17,7 +17,7 @@ const subscribeHook = (z, bundle) => {
|
|||||||
const options = {
|
const options = {
|
||||||
url: url,
|
url: url,
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
body: JSON.stringify(data)
|
body: data,
|
||||||
};
|
};
|
||||||
|
|
||||||
// You may return a promise or a normal data structure from any perform method.
|
// You may return a promise or a normal data structure from any perform method.
|
||||||
@ -100,7 +100,7 @@ module.exports = {
|
|||||||
noun: 'Action',
|
noun: 'Action',
|
||||||
display: {
|
display: {
|
||||||
label: 'New Agenda',
|
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.
|
// `operation` is where the business logic goes.
|
||||||
@ -111,6 +111,7 @@ module.exports = {
|
|||||||
inputFields: [
|
inputFields: [
|
||||||
{
|
{
|
||||||
key: 'action',
|
key: 'action',
|
||||||
|
required: true,
|
||||||
type: 'string',
|
type: 'string',
|
||||||
helpText: 'Which action of agenda this should trigger on.',
|
helpText: 'Which action of agenda this should trigger on.',
|
||||||
choices: {
|
choices: {
|
||||||
@ -145,12 +146,33 @@ module.exports = {
|
|||||||
// outputFields: () => { return []; }
|
// outputFields: () => { return []; }
|
||||||
// Alternatively, a static field definition should be provided, to specify labels for the fields
|
// Alternatively, a static field definition should be provided, to specify labels for the fields
|
||||||
outputFields: [
|
outputFields: [
|
||||||
{key: 'id', label: 'ID'},
|
{
|
||||||
{key: 'createdAt', label: 'Created At'},
|
key: 'id',
|
||||||
{key: 'name', label: 'Name'},
|
type: "integer",
|
||||||
{key: 'usertodo__name', label: 'UserToDo Name'},
|
label: 'ID'
|
||||||
{key: 'authorId', label: 'Author ID'},
|
},
|
||||||
{key: 'action', label: 'Action'}
|
{
|
||||||
|
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'
|
||||||
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@ -17,7 +17,7 @@ const subscribeHook = (z, bundle) => {
|
|||||||
const options = {
|
const options = {
|
||||||
url: url,
|
url: url,
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
body: JSON.stringify(data)
|
body: data,
|
||||||
};
|
};
|
||||||
|
|
||||||
// You may return a promise or a normal data structure from any perform method.
|
// You may return a promise or a normal data structure from any perform method.
|
||||||
@ -90,7 +90,7 @@ module.exports = {
|
|||||||
noun: 'Order',
|
noun: 'Order',
|
||||||
display: {
|
display: {
|
||||||
label: 'New Order',
|
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.
|
// `operation` is where the business logic goes.
|
||||||
@ -101,6 +101,7 @@ module.exports = {
|
|||||||
inputFields: [
|
inputFields: [
|
||||||
{
|
{
|
||||||
key: 'action',
|
key: 'action',
|
||||||
|
required: true,
|
||||||
type: 'string',
|
type: 'string',
|
||||||
helpText: 'Which action of order this should trigger on.',
|
helpText: 'Which action of order this should trigger on.',
|
||||||
choices: {
|
choices: {
|
||||||
@ -136,11 +137,11 @@ module.exports = {
|
|||||||
// outputFields: () => { return []; }
|
// outputFields: () => { return []; }
|
||||||
// Alternatively, a static field definition should be provided, to specify labels for the fields
|
// Alternatively, a static field definition should be provided, to specify labels for the fields
|
||||||
outputFields: [
|
outputFields: [
|
||||||
{key: 'id', label: 'ID'},
|
{key: 'id', type: "integer", label: 'ID'},
|
||||||
{key: 'createdAt', label: 'Created At'},
|
{key: 'createdAt', type: "integer", label: 'Created At'},
|
||||||
{key: 'name', label: 'Name'},
|
{key: 'name', label: 'Name'},
|
||||||
{key: 'directions', label: 'Directions'},
|
{key: 'directions', label: 'Directions'},
|
||||||
{key: 'authorId', label: 'Author ID'},
|
{key: 'authorId', type: "integer", label: 'Author ID'},
|
||||||
{key: 'module', label: 'Module'},
|
{key: 'module', label: 'Module'},
|
||||||
{key: 'action', label: 'Action'}
|
{key: 'action', label: 'Action'}
|
||||||
]
|
]
|
||||||
|
|||||||
@ -17,7 +17,7 @@ const subscribeHook = (z, bundle) => {
|
|||||||
const options = {
|
const options = {
|
||||||
url: url,
|
url: url,
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
body: JSON.stringify(data)
|
body: data,
|
||||||
};
|
};
|
||||||
|
|
||||||
// You may return a promise or a normal data structure from any perform method.
|
// You may return a promise or a normal data structure from any perform method.
|
||||||
@ -112,7 +112,7 @@ module.exports = {
|
|||||||
noun: 'Thirdparty',
|
noun: 'Thirdparty',
|
||||||
display: {
|
display: {
|
||||||
label: 'New Thirdparty',
|
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.
|
// `operation` is where the business logic goes.
|
||||||
@ -123,6 +123,7 @@ module.exports = {
|
|||||||
inputFields: [
|
inputFields: [
|
||||||
{
|
{
|
||||||
key: 'action',
|
key: 'action',
|
||||||
|
required: true,
|
||||||
type: 'string',
|
type: 'string',
|
||||||
helpText: 'Which action of thirdparty this should trigger on.',
|
helpText: 'Which action of thirdparty this should trigger on.',
|
||||||
choices: {
|
choices: {
|
||||||
@ -159,12 +160,12 @@ module.exports = {
|
|||||||
// outputFields: () => { return []; }
|
// outputFields: () => { return []; }
|
||||||
// Alternatively, a static field definition should be provided, to specify labels for the fields
|
// Alternatively, a static field definition should be provided, to specify labels for the fields
|
||||||
outputFields: [
|
outputFields: [
|
||||||
{key: 'id', label: 'ID'},
|
{key: 'id', type: "integer", label: 'ID'},
|
||||||
{key: 'createdAt', label: 'Created At'},
|
{key: 'createdAt', label: 'Created At'},
|
||||||
{key: 'name', label: 'Name'},
|
{key: 'name', label: 'Name'},
|
||||||
{key: 'name_alias', label: 'Name alias'},
|
{key: 'name_alias', label: 'Name alias'},
|
||||||
{key: 'firstname', label: 'Firstame'},
|
{key: 'firstname', label: 'Firstname'},
|
||||||
{key: 'authorId', label: 'Author ID'},
|
{key: 'authorId', type: "integer", label: 'Author ID'},
|
||||||
{key: 'action', label: 'Action'},
|
{key: 'action', label: 'Action'},
|
||||||
{key: 'client', label: 'Customer/Prospect 0/1/2/3'},
|
{key: 'client', label: 'Customer/Prospect 0/1/2/3'},
|
||||||
{key: 'fournisseur', label: 'Supplier 0/1'},
|
{key: 'fournisseur', label: 'Supplier 0/1'},
|
||||||
|
|||||||
237
dev/examples/zapier/triggers/ticket.js
Normal file
237
dev/examples/zapier/triggers/ticket.js
Normal file
@ -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'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
};
|
||||||
177
dev/examples/zapier/triggers/user.js
Normal file
177
dev/examples/zapier/triggers/user.js
Normal file
@ -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'}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
};
|
||||||
@ -2306,14 +2306,16 @@ class Adherent extends CommonObject
|
|||||||
* Used to build previews or test instances.
|
* Used to build previews or test instances.
|
||||||
* id must be 0 if object instance is a specimen.
|
* id must be 0 if object instance is a specimen.
|
||||||
*
|
*
|
||||||
* @return void
|
* @return int
|
||||||
*/
|
*/
|
||||||
public function initAsSpecimen()
|
public function initAsSpecimen()
|
||||||
{
|
{
|
||||||
global $user, $langs;
|
global $user, $langs;
|
||||||
|
$now = dol_now();
|
||||||
|
|
||||||
// Initialise parametres
|
// Initialise parametres
|
||||||
$this->id = 0;
|
$this->id = 0;
|
||||||
|
$this->entity = 1;
|
||||||
$this->specimen = 1;
|
$this->specimen = 1;
|
||||||
$this->civility_id = 0;
|
$this->civility_id = 0;
|
||||||
$this->lastname = 'DOLIBARR';
|
$this->lastname = 'DOLIBARR';
|
||||||
@ -2330,24 +2332,30 @@ class Adherent extends CommonObject
|
|||||||
$this->country = 'France';
|
$this->country = 'France';
|
||||||
$this->morphy = 'mor';
|
$this->morphy = 'mor';
|
||||||
$this->email = 'specimen@specimen.com';
|
$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 = '0999999999';
|
||||||
$this->phone_perso = '0999999998';
|
$this->phone_perso = '0999999998';
|
||||||
$this->phone_mobile = '0999999997';
|
$this->phone_mobile = '0999999997';
|
||||||
$this->note_private = 'No comment';
|
$this->note_public = 'This is a public note';
|
||||||
$this->birth = time();
|
$this->note_private = 'This is a private note';
|
||||||
|
$this->birth = $now;
|
||||||
$this->photo = '';
|
$this->photo = '';
|
||||||
$this->public = 1;
|
$this->public = 1;
|
||||||
$this->statut = 0;
|
$this->statut = 0;
|
||||||
|
|
||||||
$this->datefin = time();
|
$this->datefin = $now;
|
||||||
$this->datevalid = time();
|
$this->datevalid = $now;
|
||||||
|
|
||||||
$this->typeid = 1; // Id type adherent
|
$this->typeid = 1; // Id type adherent
|
||||||
$this->type = 'Type adherent'; // Libelle type adherent
|
$this->type = 'Type adherent'; // Libelle type adherent
|
||||||
$this->need_subscription = 0;
|
$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_start = $this->first_subscription_date;
|
||||||
$this->first_subscription_date_end = dol_time_plus_duree($this->first_subscription_date_start, 1, 'y');
|
$this->first_subscription_date_end = dol_time_plus_duree($this->first_subscription_date_start, 1, 'y');
|
||||||
$this->first_subscription_amount = 10;
|
$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_start = $this->first_subscription_date;
|
||||||
$this->last_subscription_date_end = dol_time_plus_duree($this->last_subscription_date_start, 1, 'y');
|
$this->last_subscription_date_end = dol_time_plus_duree($this->last_subscription_date_start, 1, 'y');
|
||||||
$this->last_subscription_amount = 10;
|
$this->last_subscription_amount = 10;
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -67,12 +67,16 @@ class Members extends DolibarrApi
|
|||||||
}
|
}
|
||||||
|
|
||||||
$member = new Adherent($this->db);
|
$member = new Adherent($this->db);
|
||||||
|
if ($id == 0) {
|
||||||
|
$result = $member->initAsSpecimen();
|
||||||
|
} else {
|
||||||
$result = $member->fetch($id);
|
$result = $member->fetch($id);
|
||||||
|
}
|
||||||
if (!$result) {
|
if (!$result) {
|
||||||
throw new RestException(404, 'member not found');
|
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);
|
throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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);
|
$this->_cleanObjectDatas($object->thirdparty);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $object;
|
return $object;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -229,9 +229,7 @@ class Documents extends DolibarrApi
|
|||||||
if ($result <= 0) {
|
if ($result <= 0) {
|
||||||
throw new RestException(500, 'Error generating document');
|
throw new RestException(500, 'Error generating document');
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
throw new RestException(403, 'Generation not available for this modulepart');
|
throw new RestException(403, 'Generation not available for this modulepart');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -277,6 +275,8 @@ class Documents extends DolibarrApi
|
|||||||
}
|
}
|
||||||
|
|
||||||
$id = (empty($id) ? 0 : $id);
|
$id = (empty($id) ? 0 : $id);
|
||||||
|
$recursive = 0;
|
||||||
|
$type = 'files';
|
||||||
|
|
||||||
if ($modulepart == 'societe' || $modulepart == 'thirdparty')
|
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);
|
$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 {
|
} else {
|
||||||
throw new RestException(500, 'Modulepart '.$modulepart.' not implemented yet.');
|
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)) {
|
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.');
|
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).'/';
|
$tmpreldir = dol_sanitizeFileName($object->project->ref).'/';
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
throw new RestException(500, 'Error while fetching Task '.$ref);
|
throw new RestException(500, 'Error while fetching Task '.$ref);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -619,10 +633,8 @@ class Documents extends DolibarrApi
|
|||||||
$modulepart = 'propale';
|
$modulepart = 'propale';
|
||||||
require_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propal.class.php';
|
require_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propal.class.php';
|
||||||
$object = new Propal($this->db);
|
$object = new Propal($this->db);
|
||||||
}
|
} else {
|
||||||
// TODO Implement additional moduleparts
|
// TODO Implement additional moduleparts
|
||||||
else
|
|
||||||
{
|
|
||||||
throw new RestException(500, 'Modulepart '.$modulepart.' not implemented yet.');
|
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.');
|
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 == 'invoice') $modulepart = 'facture';
|
||||||
if ($modulepart == 'member') $modulepart = 'adherent';
|
if ($modulepart == 'member') $modulepart = 'adherent';
|
||||||
|
|
||||||
@ -700,20 +710,16 @@ class Documents extends DolibarrApi
|
|||||||
}
|
}
|
||||||
|
|
||||||
$fhandle = @fopen($destfiletmp, 'w');
|
$fhandle = @fopen($destfiletmp, 'w');
|
||||||
if ($fhandle)
|
if ($fhandle) {
|
||||||
{
|
|
||||||
$nbofbyteswrote = fwrite($fhandle, $newfilecontent);
|
$nbofbyteswrote = fwrite($fhandle, $newfilecontent);
|
||||||
fclose($fhandle);
|
fclose($fhandle);
|
||||||
@chmod($destfiletmp, octdec($conf->global->MAIN_UMASK));
|
@chmod($destfiletmp, octdec($conf->global->MAIN_UMASK));
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
throw new RestException(500, "Failed to open file '".$destfiletmp."' for write");
|
throw new RestException(500, "Failed to open file '".$destfiletmp."' for write");
|
||||||
}
|
}
|
||||||
|
|
||||||
$result = dol_move($destfiletmp, $destfile, 0, $overwriteifexists, 1);
|
$result = dol_move($destfiletmp, $destfile, 0, $overwriteifexists, 1);
|
||||||
if (!$result)
|
if (!$result) {
|
||||||
{
|
|
||||||
throw new RestException(500, "Failed to move file into '".$destfile."'");
|
throw new RestException(500, "Failed to move file into '".$destfile."'");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -85,8 +85,28 @@ class InterfaceZapierTriggers extends DolibarrTriggers
|
|||||||
|
|
||||||
switch ($action) {
|
switch ($action) {
|
||||||
// Users
|
// Users
|
||||||
//case 'USER_CREATE':
|
case 'USER_CREATE':
|
||||||
//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_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_NEW_PASSWORD':
|
||||||
//case 'USER_ENABLEDISABLE':
|
//case 'USER_ENABLEDISABLE':
|
||||||
//case 'USER_DELETE':
|
//case 'USER_DELETE':
|
||||||
@ -124,6 +144,12 @@ class InterfaceZapierTriggers extends DolibarrTriggers
|
|||||||
//case 'USERGROUP_MODIFY':
|
//case 'USERGROUP_MODIFY':
|
||||||
//case 'USERGROUP_DELETE':
|
//case 'USERGROUP_DELETE':
|
||||||
|
|
||||||
|
// Categories
|
||||||
|
// case 'CATEGORY_CREATE':
|
||||||
|
// case 'CATEGORY_MODIFY':
|
||||||
|
// case 'CATEGORY_DELETE':
|
||||||
|
// case 'CATEGORY_SET_MULTILANGS':
|
||||||
|
|
||||||
// Companies
|
// Companies
|
||||||
case 'COMPANY_CREATE':
|
case 'COMPANY_CREATE':
|
||||||
$resql = $this->db->query($sql);
|
$resql = $this->db->query($sql);
|
||||||
@ -305,12 +331,6 @@ class InterfaceZapierTriggers extends DolibarrTriggers
|
|||||||
// case 'MEMBER_RESILIATE':
|
// case 'MEMBER_RESILIATE':
|
||||||
// case 'MEMBER_DELETE':
|
// case 'MEMBER_DELETE':
|
||||||
|
|
||||||
// Categories
|
|
||||||
// case 'CATEGORY_CREATE':
|
|
||||||
// case 'CATEGORY_MODIFY':
|
|
||||||
// case 'CATEGORY_DELETE':
|
|
||||||
// case 'CATEGORY_SET_MULTILANGS':
|
|
||||||
|
|
||||||
// Projects
|
// Projects
|
||||||
// case 'PROJECT_CREATE':
|
// case 'PROJECT_CREATE':
|
||||||
// case 'PROJECT_MODIFY':
|
// case 'PROJECT_MODIFY':
|
||||||
@ -325,6 +345,21 @@ class InterfaceZapierTriggers extends DolibarrTriggers
|
|||||||
// case 'TASK_TIMESPENT_CREATE':
|
// case 'TASK_TIMESPENT_CREATE':
|
||||||
// case 'TASK_TIMESPENT_MODIFY':
|
// case 'TASK_TIMESPENT_MODIFY':
|
||||||
// case 'TASK_TIMESPENT_DELETE':
|
// 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
|
// Shipping
|
||||||
// case 'SHIPPING_CREATE':
|
// case 'SHIPPING_CREATE':
|
||||||
@ -453,7 +488,7 @@ function cleanObjectDatas($toclean)
|
|||||||
/**
|
/**
|
||||||
* Clean sensible object datas
|
* Clean sensible object datas
|
||||||
*
|
*
|
||||||
* @param object $toclean Object to clean
|
* @param Object $toclean Object to clean
|
||||||
* @return Object Object with cleaned properties
|
* @return Object Object with cleaned properties
|
||||||
*/
|
*/
|
||||||
function cleanAgendaEventsDatas($toclean)
|
function cleanAgendaEventsDatas($toclean)
|
||||||
|
|||||||
@ -1851,8 +1851,11 @@ class Thirdparties extends DolibarrApi
|
|||||||
if (!DolibarrApiAccess::$user->rights->societe->lire) {
|
if (!DolibarrApiAccess::$user->rights->societe->lire) {
|
||||||
throw new RestException(401);
|
throw new RestException(401);
|
||||||
}
|
}
|
||||||
|
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);
|
$result = $this->company->fetch($rowid, $ref, $ref_ext, $barcode, $idprof1, $idprof2, $idprof3, $idprof4, $idprof5, $idprof6, $email, $ref_alias);
|
||||||
|
}
|
||||||
if (!$result) {
|
if (!$result) {
|
||||||
throw new RestException(404, 'Thirdparty not found');
|
throw new RestException(404, 'Thirdparty not found');
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3765,6 +3765,7 @@ class Societe extends CommonObject
|
|||||||
|
|
||||||
// Initialize parameters
|
// Initialize parameters
|
||||||
$this->id = 0;
|
$this->id = 0;
|
||||||
|
$this->entity = 1;
|
||||||
$this->name = 'THIRDPARTY SPECIMEN '.dol_print_date($now, 'dayhourlog');
|
$this->name = 'THIRDPARTY SPECIMEN '.dol_print_date($now, 'dayhourlog');
|
||||||
$this->nom = $this->name; // For backward compatibility
|
$this->nom = $this->name; // For backward compatibility
|
||||||
$this->ref_ext = 'Ref ext';
|
$this->ref_ext = 'Ref ext';
|
||||||
|
|||||||
@ -136,11 +136,14 @@ class Tickets extends DolibarrApi
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check parameters
|
// Check parameters
|
||||||
if (!$id && !$track_id && !$ref) {
|
if (($id < 0) && !$track_id && !$ref) {
|
||||||
throw new RestException(401, 'Wrong parameters');
|
throw new RestException(401, 'Wrong parameters');
|
||||||
}
|
}
|
||||||
|
if ($id == 0) {
|
||||||
|
$result = $this->ticket->initAsSpecimen();
|
||||||
|
} else {
|
||||||
$result = $this->ticket->fetch($id, $ref, $track_id);
|
$result = $this->ticket->fetch($id, $ref, $track_id);
|
||||||
|
}
|
||||||
if (!$result) {
|
if (!$result) {
|
||||||
throw new RestException(404, 'Ticket not found');
|
throw new RestException(404, 'Ticket not found');
|
||||||
}
|
}
|
||||||
@ -205,7 +208,6 @@ class Tickets extends DolibarrApi
|
|||||||
$this->ticket->history = $history;
|
$this->ticket->history = $history;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (!DolibarrApi::_checkAccessToResource('ticket', $this->ticket->id)) {
|
if (!DolibarrApi::_checkAccessToResource('ticket', $this->ticket->id)) {
|
||||||
throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
|
throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -197,6 +197,9 @@ class Ticket extends CommonObject
|
|||||||
*/
|
*/
|
||||||
public $notify_tiers_at_create;
|
public $notify_tiers_at_create;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string msgid
|
||||||
|
*/
|
||||||
public $email_msgid;
|
public $email_msgid;
|
||||||
|
|
||||||
public $lines;
|
public $lines;
|
||||||
@ -1076,7 +1079,7 @@ class Ticket extends CommonObject
|
|||||||
* Initialise object with example values
|
* Initialise object with example values
|
||||||
* Id must be 0 if object instance is a specimen
|
* Id must be 0 if object instance is a specimen
|
||||||
*
|
*
|
||||||
* @return void
|
* @return int
|
||||||
*/
|
*/
|
||||||
public function initAsSpecimen()
|
public function initAsSpecimen()
|
||||||
{
|
{
|
||||||
@ -1101,6 +1104,7 @@ class Ticket extends CommonObject
|
|||||||
$this->date_read = '';
|
$this->date_read = '';
|
||||||
$this->date_close = '';
|
$this->date_close = '';
|
||||||
$this->tms = '';
|
$this->tms = '';
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -153,13 +153,16 @@ class Users extends DolibarrApi
|
|||||||
//if (!DolibarrApiAccess::$user->rights->user->user->lire) {
|
//if (!DolibarrApiAccess::$user->rights->user->user->lire) {
|
||||||
//throw new RestException(401);
|
//throw new RestException(401);
|
||||||
//}
|
//}
|
||||||
|
if ($id == 0) {
|
||||||
|
$result = $this->useraccount->initAsSpecimen();
|
||||||
|
} else {
|
||||||
$result = $this->useraccount->fetch($id);
|
$result = $this->useraccount->fetch($id);
|
||||||
|
}
|
||||||
if (!$result) {
|
if (!$result) {
|
||||||
throw new RestException(404, 'User not found');
|
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);
|
throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -327,9 +330,10 @@ class Users extends DolibarrApi
|
|||||||
throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
|
throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($request_data as $field => $value)
|
foreach ($request_data as $field => $value) {
|
||||||
{
|
if ($field == 'id') {
|
||||||
if ($field == 'id') continue;
|
continue;
|
||||||
|
}
|
||||||
// The status must be updated using setstatus() because it
|
// The status must be updated using setstatus() because it
|
||||||
// is not handled by the update() method.
|
// is not handled by the update() method.
|
||||||
if ($field == 'statut') {
|
if ($field == 'statut') {
|
||||||
@ -461,7 +465,9 @@ class Users extends DolibarrApi
|
|||||||
$sql = "SELECT t.rowid";
|
$sql = "SELECT t.rowid";
|
||||||
$sql .= " FROM ".MAIN_DB_PREFIX."usergroup as t";
|
$sql .= " FROM ".MAIN_DB_PREFIX."usergroup as t";
|
||||||
$sql .= ' WHERE t.entity IN ('.getEntity('user').')';
|
$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
|
// Add sql filters
|
||||||
if ($sqlfilters) {
|
if ($sqlfilters) {
|
||||||
if (!DolibarrApi::_checkFilters($sqlfilters)) {
|
if (!DolibarrApi::_checkFilters($sqlfilters)) {
|
||||||
@ -483,13 +489,11 @@ class Users extends DolibarrApi
|
|||||||
|
|
||||||
$result = $this->db->query($sql);
|
$result = $this->db->query($sql);
|
||||||
|
|
||||||
if ($result)
|
if ($result) {
|
||||||
{
|
|
||||||
$i = 0;
|
$i = 0;
|
||||||
$num = $this->db->num_rows($result);
|
$num = $this->db->num_rows($result);
|
||||||
$min = min($num, ($limit <= 0 ? $num : $limit));
|
$min = min($num, ($limit <= 0 ? $num : $limit));
|
||||||
while ($i < $min)
|
while ($i < $min) {
|
||||||
{
|
|
||||||
$obj = $this->db->fetch_object($result);
|
$obj = $this->db->fetch_object($result);
|
||||||
$group_static = new UserGroup($this->db);
|
$group_static = new UserGroup($this->db);
|
||||||
if ($group_static->fetch($obj->rowid)) {
|
if ($group_static->fetch($obj->rowid)) {
|
||||||
@ -681,8 +685,9 @@ class Users extends DolibarrApi
|
|||||||
{
|
{
|
||||||
$account = array();
|
$account = array();
|
||||||
foreach (Users::$FIELDS as $field) {
|
foreach (Users::$FIELDS as $field) {
|
||||||
if (!isset($data[$field]))
|
if (!isset($data[$field])) {
|
||||||
throw new RestException(400, "$field field missing");
|
throw new RestException(400, "$field field missing");
|
||||||
|
}
|
||||||
$account[$field] = $data[$field];
|
$account[$field] = $data[$field];
|
||||||
}
|
}
|
||||||
return $account;
|
return $account;
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -93,14 +93,13 @@ class ZapierApi extends DolibarrApi
|
|||||||
* Get list of possibles choices for module
|
* Get list of possibles choices for module
|
||||||
*
|
*
|
||||||
* Return an array with hook informations
|
* Return an array with hook informations
|
||||||
* @param integer $id ID
|
|
||||||
*
|
*
|
||||||
* @return array|mixed data
|
* @return array data
|
||||||
*
|
*
|
||||||
* @url GET /getmoduleschoices/
|
* @url GET /getmoduleschoices/
|
||||||
* @throws RestException
|
* @throws RestException
|
||||||
*/
|
*/
|
||||||
public function getModulesChoices($id)
|
public function getModulesChoices()
|
||||||
{
|
{
|
||||||
if (!DolibarrApiAccess::$user->rights->zapier->read) {
|
if (!DolibarrApiAccess::$user->rights->zapier->read) {
|
||||||
throw new RestException(401);
|
throw new RestException(401);
|
||||||
@ -110,6 +109,7 @@ class ZapierApi extends DolibarrApi
|
|||||||
'orders' => 'Orders',
|
'orders' => 'Orders',
|
||||||
'thirdparties' => 'Thirparties',
|
'thirdparties' => 'Thirparties',
|
||||||
'contacts' => 'Contacts',
|
'contacts' => 'Contacts',
|
||||||
|
'users' => 'Users',
|
||||||
);
|
);
|
||||||
// $result = $this->hook->fetch($id);
|
// $result = $this->hook->fetch($id);
|
||||||
// if (! $result ) {
|
// if (! $result ) {
|
||||||
@ -244,6 +244,7 @@ class ZapierApi extends DolibarrApi
|
|||||||
$fields = array(
|
$fields = array(
|
||||||
'url',
|
'url',
|
||||||
);
|
);
|
||||||
|
dol_syslog("API Zapier create hook receive : " . print_r($request_data, true), LOG_DEBUG);
|
||||||
$result = $this->validate($request_data, $fields);
|
$result = $this->validate($request_data, $fields);
|
||||||
|
|
||||||
foreach ($request_data as $field => $value) {
|
foreach ($request_data as $field => $value) {
|
||||||
|
|||||||
@ -126,7 +126,7 @@ class Hook extends CommonObject
|
|||||||
),
|
),
|
||||||
'module' => array(
|
'module' => array(
|
||||||
'type' => 'varchar(128)',
|
'type' => 'varchar(128)',
|
||||||
'label' => 'Url',
|
'label' => 'Module',
|
||||||
'enabled' => 1,
|
'enabled' => 1,
|
||||||
'visible' => 1,
|
'visible' => 1,
|
||||||
'position' => 30,
|
'position' => 30,
|
||||||
@ -137,7 +137,7 @@ class Hook extends CommonObject
|
|||||||
),
|
),
|
||||||
'action' => array(
|
'action' => array(
|
||||||
'type' => 'varchar(128)',
|
'type' => 'varchar(128)',
|
||||||
'label' => 'Url',
|
'label' => 'Action',
|
||||||
'enabled' => 1,
|
'enabled' => 1,
|
||||||
'visible' => 1,
|
'visible' => 1,
|
||||||
'position' => 30,
|
'position' => 30,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user