Passed
Push — main ( 9a81fe...875825 )
by Rafael
41:55
created

Calendar::createFromClone()   F

Complexity

Conditions 23
Paths 13824

Size

Total Lines 89
Code Lines 46

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 23
eloc 46
nc 13824
nop 2
dl 0
loc 89
rs 0
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/* Copyright (C) 2017       Laurent Destailleur     <[email protected]>
4
 * Copyright (C) 2023-2024  Frédéric France         <[email protected]>
5
 * Copyright (C) 2023       Alice Adminson          <[email protected]>
6
 * Copyright (C) 2024		MDW						<[email protected]>
7
 * Copyright (C) 2024       Rafael San José         <[email protected]>
8
 *
9
 * This program is free software; you can redistribute it and/or modify
10
 * it under the terms of the GNU General Public License as published by
11
 * the Free Software Foundation; either version 3 of the License, or
12
 * (at your option) any later version.
13
 *
14
 * This program is distributed in the hope that it will be useful,
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 * GNU General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU General Public License
20
 * along with this program. If not, see <https://www.gnu.org/licenses/>.
21
 */
22
23
/**
24
 * \file        class/calendar.class.php
25
 * \ingroup     bookcal
26
 * \brief       This file is a CRUD class file for Calendar (Create/Read/Update/Delete)
27
 */
28
29
namespace DoliModules\BookCal\Model;
30
31
use DoliCore\Base\GenericDocument;
32
use DoliDB;
33
use Translate;
34
use User;
35
36
/**
37
 * Class for Calendar
38
 */
39
class Calendar extends GenericDocument
40
{
41
    /**
42
     * @var string ID of module.
43
     */
44
    public $module = 'bookcal';
45
46
    /**
47
     * @var string ID to identify managed object.
48
     */
49
    public $element = 'calendar';
50
51
    /**
52
     * @var string Name of table without prefix where object is stored. This is also the key used for extrafields
53
     *      management.
54
     */
55
    public $table_element = 'bookcal_calendar';
56
57
    /**
58
     * @var int  Does this object support multicompany module ?
59
     * 0=No test on entity, 1=Test with field entity, 'field@table'=Test with link by field@table
60
     */
61
    public $ismultientitymanaged = 0;
62
63
    /**
64
     * @var int  Does object support extrafields ? 0=No, 1=Yes
65
     */
66
    public $isextrafieldmanaged = 1;
67
68
    /**
69
     * @var string String with name of icon for calendar. Must be a 'fa-xxx' fontawesome code (or
70
     *      'fa-xxx_fa_color_size') or 'calendar@bookcal' if picto is file 'img/object_calendar.png'.
71
     */
72
    public $picto = 'fa-calendar-check';
73
74
75
    const STATUS_DRAFT = 0;
76
    const STATUS_VALIDATED = 1;
77
    const STATUS_CANCELED = 9;
78
79
80
    /**
81
     *  'type' field format:
82
     *      'integer', 'integer:ObjectClass:PathToClass[:AddCreateButtonOrNot[:Filter[:Sortfield]]]',
83
     *      'select' (list of values are in 'options'),
84
     *      'sellist:TableName:LabelFieldName[:KeyFieldName[:KeyFieldParent[:Filter[:Sortfield]]]]',
85
     *      'chkbxlst:...',
86
     *      'varchar(x)',
87
     *      'text', 'text:none', 'html',
88
     *      'double(24,8)', 'real', 'price',
89
     *      'date', 'datetime', 'timestamp', 'duration',
90
     *      'boolean', 'checkbox', 'radio', 'array',
91
     *      'mail', 'phone', 'url', 'password', 'ip'
92
     *      Note: Filter must be a Dolibarr Universal Filter syntax string. Example: "(t.ref:like:'SO-%') or
93
     *      (t.date_creation:<:'20160101') or (t.status:!=:0) or (t.nature:is:NULL)"
94
     *  'label' the translation key.
95
     *  'picto' is code of a picto to show before value in forms
96
     *  'enabled' is a condition when the field must be managed (Example: 1 or 'getDolGlobalInt('MY_SETUP_PARAM') or
97
     *  'isModEnabled("multicurrency")' ...)
98
     *  'position' is the sort order of field.
99
     *  'notnull' is set to 1 if not null in database. Set to -1 if we must set data to null if empty ('' or 0).
100
     *  'visible' says if field is visible in list (Examples: 0=Not visible, 1=Visible on list and create/update/view
101
     *  forms, 2=Visible on list only, 3=Visible on create/update/view form only (not list), 4=Visible on list and
102
     *  update/view form only (not create). 5=Visible on list and view only (not create/not update). Using a negative
103
     *  value means field is not shown by default on list but can be selected for viewing)
104
     *  'noteditable' says if field is not editable (1 or 0)
105
     *  'alwayseditable' says if field can be modified also when status is not draft ('1' or '0')
106
     *  'default' is a default value for creation (can still be overwrote by the Setup of Default Values if field is
107
     *  editable in creation form). Note: If default is set to '(PROV)' and field is 'ref', the default value will be
108
     *  set to '(PROVid)' where id is rowid when a new record is created.
109
     *  'index' if we want an index in database.
110
     *  'foreignkey'=>'tablename.field' if the field is a foreign key (it is recommended to name the field fk_...).
111
     *  'searchall' is 1 if we want to search in this field when making a search from the quick search button.
112
     *  'isameasure' must be set to 1 or 2 if field can be used for measure. Field type must be summable like integer
113
     *  or double(24,8). Use 1 in most cases, or 2 if you don't want to see the column total into list (for example for
114
     *  percentage)
115
     *  'css' and 'cssview' and 'csslist' is the CSS style to use on field. 'css' is used in creation and update.
116
     *  'cssview' is used in view mode. 'csslist' is used for columns in lists. For example: 'css'=>'minwidth300
117
     *  maxwidth500 widthcentpercentminusx', 'cssview'=>'wordbreak', 'csslist'=>'tdoverflowmax200'
118
     *  'help' and 'helplist' is a 'TranslationString' to use to show a tooltip on field. You can also use
119
     *  'TranslationString:keyfortooltiponlick' for a tooltip on click.
120
     *  'showoncombobox' if value of the field must be visible into the label of the combobox that list record
121
     *  'disabled' is 1 if we want to have the field locked by a 'disabled' attribute. In most cases, this is never set
122
     *  into the definition of $fields into class, but is set dynamically by some part of code.
123
     *  'arrayofkeyval' to set a list of values if type is a list of predefined values. For example:
124
     *  array("0"=>"Draft","1"=>"Active","-1"=>"Cancel"). Note that type can be 'integer' or 'varchar'
125
     *  'autofocusoncreate' to have field having the focus on a create form. Only 1 field should have this property set
126
     *  to 1.
127
     *  'comment' is not used. You can store here any text of your choice. It is not used by application.
128
     *  'validate' is 1 if need to validate with $this->validateField()
129
     *  'copytoclipboard' is 1 or 2 to allow to add a picto to copy value into clipboard (1=picto after label, 2=picto
130
     *  after value)
131
     *
132
     *  Note: To have value dynamic, you can set value to 0 in definition and edit the value on the fly into the
133
     *  constructor.
134
     */
135
136
    // BEGIN MODULEBUILDER PROPERTIES
137
    /**
138
     * @var array<string,array{type:string,label:string,enabled:int<0,2>|string,position:int,notnull:int,visible:int,noteditable?:int,default?:string,index?:int,foreignkey?:string,searchall?:int,isameasure?:int,css?:string,csslist?:string,help?:string,showoncombobox?:int,disabled?:int,arrayofkeyval?:array<int,string>,comment?:string}>
0 ignored issues
show
Documentation Bug introduced by
The doc comment array<string,array{type:...ring>,comment?:string}> at position 16 could not be parsed: Expected '}' at position 16, but found 'int'.
Loading history...
139
     *       Array with all fields and their property. Do not use it as a static var. It may be modified by
140
     *       constructor.
141
     */
142
    public $fields = [
143
        'rowid' => ['type' => 'integer', 'label' => 'TechnicalID', 'enabled' => 1, 'position' => 1, 'notnull' => 1, 'visible' => 0, 'noteditable' => 1, 'index' => 1, 'css' => 'right', 'comment' => "Id"],
144
        'ref' => ['type' => 'varchar(128)', 'label' => 'Ref', 'enabled' => 1, 'position' => 20, 'notnull' => 1, 'visible' => 1, 'index' => 1, 'searchall' => 1, 'showoncombobox' => 1, 'validate' => 1, 'comment' => "Reference of object", 'css' => 'width100'],
145
        'label' => ['type' => 'varchar(255)', 'label' => 'Label', 'enabled' => 1, 'position' => 30, 'notnull' => 0, 'visible' => 1, 'alwayseditable' => 1, 'searchall' => 1, 'css' => 'minwidth300', 'cssview' => 'wordbreak', 'help' => "Help text", 'showoncombobox' => 2, 'validate' => 1,],
146
        'visibility' => ['type' => 'integer:User:user/class/user.class.php', 'label' => 'Owner', 'enabled' => 1, 'position' => 40, 'notnull' => 1, 'visible' => 1, 'picto' => 'user', 'css' => 'maxwidth500 widthcentpercentminusxx', 'csslist' => 'tdoverflowmax150',],
147
        'type' => ['type' => 'integer', 'label' => 'Type', 'enabled' => 1, 'position' => 42, 'notnull' => 1, 'visible' => 1, 'arrayofkeyval' => ['0' => 'Customer', '1' => 'Supplier', '3' => 'Other'],],
148
        'fk_soc' => ['type' => 'integer:Societe:societe/class/societe.class.php:1:((status:=:1) AND (entity:IN:__SHARED_ENTITIES__))', 'label' => 'ThirdParty', 'picto' => 'company', 'enabled' => 'isModEnabled("societe")', 'position' => 50, 'notnull' => -1, 'visible' => 1, 'index' => 1, 'css' => 'maxwidth500 widthcentpercentminusxx', 'csslist' => 'tdoverflowmax150', 'help' => "ThirdPartyBookCalHelp", 'validate' => 1,],
149
        'fk_project' => ['type' => 'integer:Project:projet/class/project.class.php:1', 'label' => 'Project', 'picto' => 'project', 'enabled' => 'isModEnabled("project")', 'position' => 52, 'notnull' => -1, 'visible' => -1, 'index' => 1, 'css' => 'maxwidth500 widthcentpercentminusxx', 'csslist' => 'tdoverflowmax150', 'validate' => 1,],
150
        'description' => ['type' => 'text', 'label' => 'Description', 'enabled' => 1, 'position' => 60, 'notnull' => 0, 'visible' => 3, 'validate' => 1,],
151
        'note_public' => ['type' => 'html', 'label' => 'NotePublic', 'enabled' => 1, 'position' => 61, 'notnull' => 0, 'visible' => 0, 'cssview' => 'wordbreak', 'validate' => 1,],
152
        'note_private' => ['type' => 'html', 'label' => 'NotePrivate', 'enabled' => 1, 'position' => 62, 'notnull' => 0, 'visible' => 0, 'cssview' => 'wordbreak', 'validate' => 1,],
153
        'date_creation' => ['type' => 'datetime', 'label' => 'DateCreation', 'enabled' => 1, 'position' => 500, 'notnull' => 1, 'visible' => -2,],
154
        'tms' => ['type' => 'timestamp', 'label' => 'DateModification', 'enabled' => 1, 'position' => 501, 'notnull' => 0, 'visible' => -2,],
155
        'fk_user_creat' => ['type' => 'integer:User:user/class/user.class.php', 'label' => 'UserAuthor', 'picto' => 'user', 'enabled' => 1, 'position' => 510, 'notnull' => 1, 'visible' => -2, 'foreignkey' => 'user.rowid', 'csslist' => 'tdoverflowmax150',],
156
        'fk_user_modif' => ['type' => 'integer:User:user/class/user.class.php', 'label' => 'UserModif', 'picto' => 'user', 'enabled' => 1, 'position' => 511, 'notnull' => -1, 'visible' => -2, 'csslist' => 'tdoverflowmax150',],
157
        'import_key' => ['type' => 'varchar(14)', 'label' => 'ImportId', 'enabled' => 1, 'position' => 1000, 'notnull' => -1, 'visible' => -2,],
158
        'status' => ['type' => 'integer', 'label' => 'Status', 'enabled' => 1, 'position' => 2000, 'notnull' => 1, 'default' => '0', 'visible' => 1, 'index' => 1, 'arrayofkeyval' => ['0' => 'Draft', '1' => 'Validated', '9' => 'Closed'], 'validate' => 1,],
159
    ];
160
    public $rowid;
161
    public $ref;
162
    public $label;
163
    public $type;
164
    public $visibility;
165
    public $fk_soc;
166
    public $fk_project;
167
    public $description;
168
    public $note_public;
169
    public $note_private;
170
    public $date_creation;
171
    public $fk_user_creat;
172
    public $fk_user_modif;
173
    public $import_key;
174
    public $status;
175
    // END MODULEBUILDER PROPERTIES
176
177
178
    /**
179
     * Constructor
180
     *
181
     * @param DoliDB $db Database handler
182
     */
183
    public function __construct(DoliDB $db)
184
    {
185
        global $langs, $user;
186
187
        $this->db = $db;
188
189
        if (!getDolGlobalInt('MAIN_SHOW_TECHNICAL_ID') && isset($this->fields['rowid']) && !empty($this->fields['ref'])) {
190
            $this->fields['rowid']['visible'] = 0;
191
        }
192
        if (!isModEnabled('multicompany') && isset($this->fields['entity'])) {
193
            $this->fields['entity']['enabled'] = 0;
194
        }
195
196
        // Example to show how to set values of fields definition dynamically
197
        /*if ($user->hasRight('bookcal', 'calendar', 'read')) {
198
            $this->fields['myfield']['visible'] = 1;
199
            $this->fields['myfield']['noteditable'] = 0;
200
        }*/
201
        $this->fields['visibility']['default'] = $user->id;
202
203
        // Unset fields that are disabled
204
        foreach ($this->fields as $key => $val) {
205
            if (isset($val['enabled']) && empty($val['enabled'])) {
206
                unset($this->fields[$key]);
207
            }
208
        }
209
210
        // Translate some data of arrayofkeyval
211
        if (is_object($langs)) {
212
            foreach ($this->fields as $key => $val) {
213
                if (!empty($val['arrayofkeyval']) && is_array($val['arrayofkeyval'])) {
214
                    foreach ($val['arrayofkeyval'] as $key2 => $val2) {
215
                        $this->fields[$key]['arrayofkeyval'][$key2] = $langs->trans($val2);
216
                    }
217
                }
218
            }
219
        }
220
    }
221
222
    /**
223
     * Create object into database
224
     *
225
     * @param User $user      User that creates
226
     * @param int  $notrigger 0=launch triggers after, 1=disable triggers
227
     *
228
     * @return int             Return integer <0 if KO, Id of created object if OK
229
     */
230
    public function create(User $user, $notrigger = 0)
231
    {
232
        $resultcreate = $this->createCommon($user, $notrigger);
233
234
        //$resultvalidate = $this->validate($user, $notrigger);
235
236
        return $resultcreate;
237
    }
238
239
    /**
240
     * Clone an object into another one
241
     *
242
     * @param User $user   User that creates
243
     * @param int  $fromid Id of object to clone
244
     *
245
     * @return  mixed               New object created, <0 if KO
246
     */
247
    public function createFromClone(User $user, $fromid)
248
    {
249
        global $langs, $extrafields;
250
        $error = 0;
251
252
        dol_syslog(__METHOD__, LOG_DEBUG);
253
254
        $object = new self($this->db);
255
256
        $this->db->begin();
257
258
        // Load source object
259
        $result = $object->fetchCommon($fromid);
260
        if ($result > 0 && !empty($object->table_element_line)) {
261
            $object->fetchLines();
262
        }
263
264
        // get lines so they will be clone
265
        //foreach($this->lines as $line)
266
        //  $line->fetch_optionals();
267
268
        // Reset some properties
269
        unset($object->id);
270
        unset($object->fk_user_creat);
271
        unset($object->import_key);
272
273
        // Clear fields
274
        if (property_exists($object, 'ref')) {
275
            $object->ref = empty($this->fields['ref']['default']) ? "Copy_Of_" . $object->ref : $this->fields['ref']['default'];
276
        }
277
        if (property_exists($object, 'label')) {
278
            $object->label = empty($this->fields['label']['default']) ? $langs->trans("CopyOf") . " " . $object->label : $this->fields['label']['default'];
279
        }
280
        if (property_exists($object, 'status')) {
281
            $object->status = self::STATUS_DRAFT;
282
        }
283
        if (property_exists($object, 'date_creation')) {
284
            $object->date_creation = dol_now();
285
        }
286
        if (property_exists($object, 'date_modification')) {
287
            $object->date_modification = null;
288
        }
289
        // ...
290
        // Clear extrafields that are unique
291
        if (is_array($object->array_options) && count($object->array_options) > 0) {
292
            $extrafields->fetch_name_optionals_label($this->table_element);
293
            foreach ($object->array_options as $key => $option) {
294
                $shortkey = preg_replace('/options_/', '', $key);
295
                if (!empty($extrafields->attributes[$this->table_element]['unique'][$shortkey])) {
296
                    //var_dump($key);
297
                    //var_dump($clonedObj->array_options[$key]); exit;
298
                    unset($object->array_options[$key]);
299
                }
300
            }
301
        }
302
303
        // Create clone
304
        $object->context['createfromclone'] = 'createfromclone';
305
        $result = $object->createCommon($user);
306
        if ($result < 0) {
307
            $error++;
308
            $this->setErrorsFromObject($object);
309
        }
310
311
        if (!$error) {
312
            // copy internal contacts
313
            if ($this->copy_linked_contact($object, 'internal') < 0) {
314
                $error++;
315
            }
316
        }
317
318
        if (!$error) {
319
            // copy external contacts if same company
320
            if (!empty($object->socid) && property_exists($this, 'fk_soc') && $this->fk_soc == $object->socid) {
0 ignored issues
show
Bug Best Practice introduced by
The property socid does not exist on DoliModules\BookCal\Model\Calendar. Did you maybe forget to declare it?
Loading history...
321
                if ($this->copy_linked_contact($object, 'external') < 0) {
322
                    $error++;
323
                }
324
            }
325
        }
326
327
        unset($object->context['createfromclone']);
328
329
        // End
330
        if (!$error) {
331
            $this->db->commit();
332
            return $object;
333
        } else {
334
            $this->db->rollback();
335
            return -1;
336
        }
337
    }
338
339
    /**
340
     * Load object in memory from the database
341
     *
342
     * @param int    $id  Id object
343
     * @param string $ref Ref
344
     *
345
     * @return int         Return integer <0 if KO, 0 if not found, >0 if OK
346
     */
347
    public function fetch($id, $ref = null)
348
    {
349
        $result = $this->fetchCommon($id, $ref);
350
        if ($result > 0 && !empty($this->table_element_line)) {
351
            $this->fetchLines();
352
        }
353
        return $result;
354
    }
355
356
    /**
357
     * Load object lines in memory from the database
358
     *
359
     * @return int         Return integer <0 if KO, 0 if not found, >0 if OK
360
     */
361
    public function fetchLines()
362
    {
363
        $this->lines = [];
364
365
        $result = $this->fetchLinesCommon();
366
        return $result;
367
    }
368
369
370
    /**
371
     * Load list of objects in memory from the database.
372
     *
373
     * @param string $sortorder             Sort Order
374
     * @param string $sortfield             Sort field
375
     * @param int    $limit                 limit
376
     * @param int    $offset                Offset
377
     * @param string $filter                Filter as an Universal Search string.
378
     *                                      Example: '((client:=:1) OR ((client:>=:2) AND (client:<=:3))) AND
379
     *                                      (client:!=:8) AND (nom:like:'a%')'
380
     * @param string $filtermode            No more used
381
     *
382
     * @return array|int                    int <0 if KO, array of pages if OK
383
     */
384
    public function fetchAll($sortorder = '', $sortfield = '', $limit = 0, $offset = 0, $filter = '', $filtermode = 'AND')
385
    {
386
        dol_syslog(__METHOD__, LOG_DEBUG);
387
388
        $records = [];
389
390
        $sql = "SELECT ";
391
        $sql .= $this->getFieldList('t');
392
        $sql .= " FROM " . $this->db->prefix() . $this->table_element . " as t";
393
        if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 1) {
394
            $sql .= " WHERE t.entity IN (" . getEntity($this->element) . ")";
395
        } else {
396
            $sql .= " WHERE 1 = 1";
397
        }
398
399
        // Manage filter
400
        $errormessage = '';
401
        $sql .= forgeSQLFromUniversalSearchCriteria($filter, $errormessage);
402
        if ($errormessage) {
403
            $this->errors[] = $errormessage;
404
            dol_syslog(__METHOD__ . ' ' . implode(',', $this->errors), LOG_ERR);
405
            return -1;
406
        }
407
408
        if (!empty($sortfield)) {
409
            $sql .= $this->db->order($sortfield, $sortorder);
410
        }
411
        if (!empty($limit)) {
412
            $sql .= $this->db->plimit($limit, $offset);
413
        }
414
415
        $resql = $this->db->query($sql);
416
        if ($resql) {
417
            $num = $this->db->num_rows($resql);
418
            $i = 0;
419
            while ($i < ($limit ? min($limit, $num) : $num)) {
420
                $obj = $this->db->fetch_object($resql);
421
422
                $record = new self($this->db);
423
                $record->setVarsFromFetchObj($obj);
424
425
                $records[$record->id] = $record;
426
427
                $i++;
428
            }
429
            $this->db->free($resql);
430
431
            return $records;
432
        } else {
433
            $this->errors[] = 'Error ' . $this->db->lasterror();
434
            dol_syslog(__METHOD__ . ' ' . implode(',', $this->errors), LOG_ERR);
435
436
            return -1;
437
        }
438
    }
439
440
    /**
441
     * Update object into database
442
     *
443
     * @param User $user      User that modifies
444
     * @param int  $notrigger 0=launch triggers after, 1=disable triggers
445
     *
446
     * @return int             Return integer <0 if KO, >0 if OK
447
     */
448
    public function update(User $user, $notrigger = 0)
449
    {
450
        return $this->updateCommon($user, $notrigger);
451
    }
452
453
    /**
454
     * Delete object in database
455
     *
456
     * @param User $user      User that deletes
457
     * @param int  $notrigger 0=launch triggers, 1=disable triggers
458
     *
459
     * @return int              Return integer <0 if KO, >0 if OK
460
     */
461
    public function delete(User $user, $notrigger = 0)
462
    {
463
        return $this->deleteCommon($user, $notrigger);
464
        //return $this->deleteCommon($user, $notrigger, 1);
465
    }
466
467
    /**
468
     *  Delete a line of object in database
469
     *
470
     * @param User $user      User that delete
471
     * @param int  $idline    Id of line to delete
472
     * @param int  $notrigger 0=launch triggers after, 1=disable triggers
473
     *
474
     * @return int                 >0 if OK, <0 if KO
475
     */
476
    public function deleteLine(User $user, $idline, $notrigger = 0)
477
    {
478
        if ($this->status < 0) {
479
            $this->error = 'ErrorDeleteLineNotAllowedByObjectStatus';
480
            return -2;
481
        }
482
483
        return $this->deleteLineCommon($user, $idline, $notrigger);
484
    }
485
486
487
    /**
488
     *  Validate object
489
     *
490
     * @param User $user      User making status change
491
     * @param int  $notrigger 1=Does not execute triggers, 0= execute triggers
492
     *
493
     * @return     int                     Return integer <=0 if OK, 0=Nothing done, >0 if KO
494
     */
495
    public function validate($user, $notrigger = 0)
496
    {
497
        global $conf;
498
499
        require_once BASE_PATH . '/../Dolibarr/Lib/Files.php';
500
501
        $error = 0;
502
503
        // Protection
504
        if ($this->status == self::STATUS_VALIDATED) {
505
            dol_syslog(get_class($this) . "::validate action abandoned: already validated", LOG_WARNING);
506
            return 0;
507
        }
508
509
        $now = dol_now();
510
511
        $this->db->begin();
512
513
        // Define new ref
514
        if (!$error && (preg_match('/^[\(]?PROV/i', $this->ref) || empty($this->ref))) { // empty should not happened, but when it occurs, the test save life
515
            $num = $this->getNextNumRef();
516
        } else {
517
            $num = $this->ref;
518
        }
519
        $this->newref = $num;
520
521
        if (!empty($num)) {
522
            // Validate
523
            $sql = "UPDATE " . MAIN_DB_PREFIX . $this->table_element;
524
            $sql .= " SET ref = '" . $this->db->escape($num) . "',";
525
            $sql .= " status = " . self::STATUS_VALIDATED;
526
            if (!empty($this->fields['date_validation'])) {
527
                $sql .= ", date_validation = '" . $this->db->idate($now) . "'";
528
            }
529
            if (!empty($this->fields['fk_user_valid'])) {
530
                $sql .= ", fk_user_valid = " . ((int) $user->id);
531
            }
532
            $sql .= " WHERE rowid = " . ((int) $this->id);
533
534
            dol_syslog(get_class($this) . "::validate()", LOG_DEBUG);
535
            $resql = $this->db->query($sql);
536
            if (!$resql) {
537
                dol_print_error($this->db);
538
                $this->error = $this->db->lasterror();
539
                $error++;
540
            }
541
542
            if (!$error && !$notrigger) {
543
                // Call trigger
544
                $result = $this->call_trigger('MYOBJECT_VALIDATE', $user);
545
                if ($result < 0) {
546
                    $error++;
547
                }
548
                // End call triggers
549
            }
550
        }
551
552
        if (!$error) {
553
            $this->oldref = $this->ref;
554
555
            // Rename directory if dir was a temporary ref
556
            if (preg_match('/^[\(]?PROV/i', $this->ref)) {
557
                // Now we rename also files into index
558
                $sql = 'UPDATE ' . MAIN_DB_PREFIX . "ecm_files set filename = CONCAT('" . $this->db->escape($this->newref) . "', SUBSTR(filename, " . (strlen($this->ref) + 1) . ")), filepath = 'calendar/" . $this->db->escape($this->newref) . "'";
559
                $sql .= " WHERE filename LIKE '" . $this->db->escape($this->ref) . "%' AND filepath = 'calendar/" . $this->db->escape($this->ref) . "' and entity = " . $conf->entity;
560
                $resql = $this->db->query($sql);
561
                if (!$resql) {
562
                    $error++;
563
                    $this->error = $this->db->lasterror();
564
                }
565
                $sql = 'UPDATE ' . MAIN_DB_PREFIX . "ecm_files set filepath = 'calendar/" . $this->db->escape($this->newref) . "'";
566
                $sql .= " WHERE filepath = 'calendar/" . $this->db->escape($this->ref) . "' and entity = " . $conf->entity;
567
                $resql = $this->db->query($sql);
568
                if (!$resql) {
569
                    $error++;
570
                    $this->error = $this->db->lasterror();
571
                }
572
573
                // We rename directory ($this->ref = old ref, $num = new ref) in order not to lose the attachments
574
                $oldref = dol_sanitizeFileName($this->ref);
575
                $newref = dol_sanitizeFileName($num);
576
                $dirsource = $conf->bookcal->dir_output . '/calendar/' . $oldref;
577
                $dirdest = $conf->bookcal->dir_output . '/calendar/' . $newref;
578
                if (!$error && file_exists($dirsource)) {
579
                    dol_syslog(get_class($this) . "::validate() rename dir " . $dirsource . " into " . $dirdest);
580
581
                    if (@rename($dirsource, $dirdest)) {
582
                        dol_syslog("Rename ok");
583
                        // Rename docs starting with $oldref with $newref
584
                        $listoffiles = dol_dir_list($conf->bookcal->dir_output . '/calendar/' . $newref, 'files', 1, '^' . preg_quote($oldref, '/'));
585
                        foreach ($listoffiles as $fileentry) {
586
                            $dirsource = $fileentry['name'];
587
                            $dirdest = preg_replace('/^' . preg_quote($oldref, '/') . '/', $newref, $dirsource);
588
                            $dirsource = $fileentry['path'] . '/' . $dirsource;
589
                            $dirdest = $fileentry['path'] . '/' . $dirdest;
590
                            @rename($dirsource, $dirdest);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for rename(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unhandled  annotation

590
                            /** @scrutinizer ignore-unhandled */ @rename($dirsource, $dirdest);

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
591
                        }
592
                    }
593
                }
594
            }
595
        }
596
597
        // Set new ref and current status
598
        if (!$error) {
599
            $this->ref = $num;
600
            $this->status = self::STATUS_VALIDATED;
601
        }
602
603
        if (!$error) {
604
            $this->db->commit();
605
            return 1;
606
        } else {
607
            $this->db->rollback();
608
            return -1;
609
        }
610
    }
611
612
613
    /**
614
     *  Set draft status
615
     *
616
     * @param User $user      Object user that modify
617
     * @param int  $notrigger 1=Does not execute triggers, 0=Execute triggers
618
     *
619
     * @return int                     Return integer <0 if KO, >0 if OK
620
     */
621
    public function setDraft($user, $notrigger = 0)
622
    {
623
        // Protection
624
        if ($this->status <= self::STATUS_DRAFT) {
625
            return 0;
626
        }
627
628
        return $this->setStatusCommon($user, self::STATUS_DRAFT, $notrigger, 'MYOBJECT_UNVALIDATE');
629
    }
630
631
    /**
632
     *  Set cancel status
633
     *
634
     * @param User $user      Object user that modify
635
     * @param int  $notrigger 1=Does not execute triggers, 0=Execute triggers
636
     *
637
     * @return int                     Return integer <0 if KO, 0=Nothing done, >0 if OK
638
     */
639
    public function cancel($user, $notrigger = 0)
640
    {
641
        // Protection
642
        if ($this->status != self::STATUS_VALIDATED) {
643
            return 0;
644
        }
645
646
        return $this->setStatusCommon($user, self::STATUS_CANCELED, $notrigger, 'MYOBJECT_CANCEL');
647
    }
648
649
    /**
650
     *  Set back to validated status
651
     *
652
     * @param User $user      Object user that modify
653
     * @param int  $notrigger 1=Does not execute triggers, 0=Execute triggers
654
     *
655
     * @return int                     Return integer <0 if KO, 0=Nothing done, >0 if OK
656
     */
657
    public function reopen($user, $notrigger = 0)
658
    {
659
        // Protection
660
        if ($this->status == self::STATUS_VALIDATED) {
661
            return 0;
662
        }
663
664
        return $this->setStatusCommon($user, self::STATUS_VALIDATED, $notrigger, 'MYOBJECT_REOPEN');
665
    }
666
667
    /**
668
     * getTooltipContentArray
669
     *
670
     * @param array $params Params to construct tooltip data
671
     *
672
     * @return  array
673
     * @since   v18
674
     */
675
    public function getTooltipContentArray($params)
676
    {
677
        global $langs;
678
679
        $datas = [];
680
681
        if (getDolGlobalInt('MAIN_OPTIMIZEFORTEXTBROWSER')) {
682
            return ['optimize' => $langs->trans("ShowCalendar")];
683
        }
684
        $datas['picto'] = img_picto('', $this->picto) . ' <u>' . $langs->trans("Calendar") . '</u>';
685
        if (isset($this->status)) {
686
            $datas['picto'] .= ' ' . $this->getLibStatut(5);
687
        }
688
        $datas['ref'] = '<br><b>' . $langs->trans('Ref') . ':</b> ' . $this->ref;
689
690
        return $datas;
691
    }
692
693
    /**
694
     *  Return a link to the object card (with optionally the picto)
695
     *
696
     * @param int    $withpicto             Include picto in link (0=No picto, 1=Include picto into link, 2=Only picto)
697
     * @param string $option                On what the link point to ('nolink', ...)
698
     * @param int    $notooltip             1=Disable tooltip
699
     * @param string $morecss               Add more css on link
700
     * @param int    $save_lastsearch_value -1=Auto, 0=No save of lastsearch_values when clicking, 1=Save
701
     *                                      lastsearch_values whenclicking
702
     *
703
     * @return string                              String with URL
704
     */
705
    public function getNomUrl($withpicto = 0, $option = '', $notooltip = 0, $morecss = '', $save_lastsearch_value = -1)
706
    {
707
        global $conf, $langs, $hookmanager;
708
709
        if (!empty($conf->dol_no_mouse_hover)) {
710
            $notooltip = 1; // Force disable tooltips
711
        }
712
713
        $result = '';
714
        $params = [
715
            'id' => $this->id,
716
            'objecttype' => $this->element . ($this->module ? '@' . $this->module : ''),
717
            'option' => $option,
718
        ];
719
        $classfortooltip = 'classfortooltip';
720
        $dataparams = '';
721
        if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) {
722
            $classfortooltip = 'classforajaxtooltip';
723
            $dataparams = ' data-params="' . dol_escape_htmltag(json_encode($params)) . '"';
724
            $label = '';
725
        } else {
726
            $label = implode($this->getTooltipContentArray($params));
727
        }
728
729
        $url = dol_buildpath('/bookcal/calendar_card.php', 1) . '?id=' . $this->id;
730
731
        if ($option !== 'nolink') {
732
            // Add param to save lastsearch_values or not
733
            $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
734
            if ($save_lastsearch_value == -1 && isset($_SERVER['PHP_SELF']) && preg_match('/list\.php/', $_SERVER['PHP_SELF'])) {
735
                $add_save_lastsearch_values = 1;
736
            }
737
            if ($url && $add_save_lastsearch_values) {
738
                $url .= '&save_lastsearch_values=1';
739
            }
740
        }
741
742
        $linkclose = '';
743
        if (empty($notooltip)) {
744
            if (getDolGlobalInt('MAIN_OPTIMIZEFORTEXTBROWSER')) {
745
                $label = $langs->trans("ShowCalendar");
746
                $linkclose .= ' alt="' . dol_escape_htmltag($label, 1) . '"';
747
            }
748
            $linkclose .= ($label ? ' title="' . dol_escape_htmltag($label, 1) . '"' : ' title="tocomplete"');
749
            $linkclose .= $dataparams . ' class="' . $classfortooltip . ($morecss ? ' ' . $morecss : '') . '"';
750
        } else {
751
            $linkclose = ($morecss ? ' class="' . $morecss . '"' : '');
752
        }
753
754
        if ($option == 'nolink' || empty($url)) {
755
            $linkstart = '<span';
756
        } else {
757
            $linkstart = '<a href="' . $url . '"';
758
        }
759
        $linkstart .= $linkclose . '>';
760
        if ($option == 'nolink' || empty($url)) {
761
            $linkend = '</span>';
762
        } else {
763
            $linkend = '</a>';
764
        }
765
766
        $result .= $linkstart;
767
768
        if (empty($this->showphoto_on_popup)) {
769
            if ($withpicto) {
770
                $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), (($withpicto != 2) ? 'class="paddingright"' : ''), 0, 0, $notooltip ? 0 : 1);
771
            }
772
        } else {
773
            if ($withpicto) {
774
                require_once BASE_PATH . '/../Dolibarr/Lib/Files.php';
775
776
                [$class, $module] = explode('@', $this->picto);
777
                $upload_dir = $conf->$module->multidir_output[$conf->entity] . "/$class/" . dol_sanitizeFileName($this->ref);
778
                $filearray = dol_dir_list($upload_dir, "files");
779
                $filename = $filearray[0]['name'];
780
                if (!empty($filename)) {
781
                    $pospoint = strpos($filearray[0]['name'], '.');
782
783
                    $pathtophoto = $class . '/' . $this->ref . '/thumbs/' . substr($filename, 0, $pospoint) . '_mini' . substr($filename, $pospoint);
784
                    if (!getDolGlobalInt(strtoupper($module . '_' . $class) . '_FORMATLISTPHOTOSASUSERS')) {
785
                        $result .= '<div class="floatleft inline-block valignmiddle divphotoref"><div class="photoref"><img class="photo' . $module . '" alt="No photo" border="0" src="' . DOL_URL_ROOT . '/viewimage.php?modulepart=' . $module . '&entity=' . $conf->entity . '&file=' . urlencode($pathtophoto) . '"></div></div>';
786
                    } else {
787
                        $result .= '<div class="floatleft inline-block valignmiddle divphotoref"><img class="photouserphoto userphoto" alt="No photo" border="0" src="' . DOL_URL_ROOT . '/viewimage.php?modulepart=' . $module . '&entity=' . $conf->entity . '&file=' . urlencode($pathtophoto) . '"></div>';
788
                    }
789
790
                    $result .= '</div>';
791
                } else {
792
                    $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="' . (($withpicto != 2) ? 'paddingright ' : '') . '"'), 0, 0, $notooltip ? 0 : 1);
793
                }
794
            }
795
        }
796
797
        if ($withpicto != 2) {
798
            $result .= $this->ref;
799
        }
800
801
        $result .= $linkend;
802
        //if ($withpicto != 2) $result.=(($addlabel && $this->label) ? $sep . dol_trunc($this->label, ($addlabel > 1 ? $addlabel : 0)) : '');
803
804
        global $action, $hookmanager;
805
        $hookmanager->initHooks([$this->element . 'dao']);
806
        $parameters = ['id' => $this->id, 'getnomurl' => &$result];
807
        $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
808
        if ($reshook > 0) {
809
            $result = $hookmanager->resPrint;
810
        } else {
811
            $result .= $hookmanager->resPrint;
812
        }
813
814
        return $result;
815
    }
816
817
    /**
818
     *  Return a thumb for kanban views
819
     *
820
     * @param string $option    Where point the link (0=> main card, 1,2 => shipment, 'nolink'=>No link)
821
     * @param array  $arraydata Array of data
822
     *
823
     * @return     string                              HTML Code for Kanban thumb.
824
     */
825
    public function getKanbanView($option = '', $arraydata = null)
826
    {
827
        global $conf, $langs;
828
829
        $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']);
830
831
        $return = '<div class="box-flex-item box-flex-grow-zero">';
832
        $return .= '<div class="info-box info-box-sm">';
833
        $return .= '<span class="info-box-icon bg-infobox-action">';
834
        $return .= img_picto('', $this->picto);
835
        $return .= '</span>';
836
        $return .= '<div class="info-box-content">';
837
        $return .= '<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">' . (method_exists($this, 'getNomUrl') ? $this->getNomUrl() : $this->ref) . '</span>';
838
        if ($selected >= 0) {
839
            $return .= '<input id="cb' . $this->id . '" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="' . $this->id . '"' . ($selected ? ' checked="checked"' : '') . '>';
840
        }
841
        if (property_exists($this, 'label')) {
842
            $return .= ' <div class="inline-block opacitymedium valignmiddle tdoverflowmax100">' . $this->label . '</div>';
843
        }
844
        if (property_exists($this, 'amount')) {
845
            $return .= '<br>';
846
            $return .= '<span class="info-box-label amount">' . price($this->amount, 0, $langs, 1, -1, -1, $conf->currency) . '</span>';
847
        }
848
        if (method_exists($this, 'getLibStatut')) {
849
            $return .= '<br><div class="info-box-status">' . $this->getLibStatut(3) . '</div>';
850
        }
851
        $return .= '</div>';
852
        $return .= '</div>';
853
        $return .= '</div>';
854
855
        return $return;
856
    }
857
858
    /**
859
     *  Return the label of the status
860
     *
861
     * @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short
862
     *                  label + Picto, 6=Long label + Picto
863
     *
864
     * @return string                 Label of status
865
     */
866
    public function getLabelStatus($mode = 0)
867
    {
868
        return $this->LibStatut($this->status, $mode);
869
    }
870
871
    /**
872
     *  Return the label of the status
873
     *
874
     * @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short
875
     *                  label + Picto, 6=Long label + Picto
876
     *
877
     * @return string                 Label of status
878
     */
879
    public function getLibStatut($mode = 0)
880
    {
881
        return $this->LibStatut($this->status, $mode);
882
    }
883
884
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
885
886
    /**
887
     *  Return the label of a given status
888
     *
889
     * @param int $status Id status
890
     * @param int $mode   0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short
891
     *                    label + Picto, 6=Long label + Picto
892
     *
893
     * @return string                 Label of status
894
     */
895
    public function LibStatut($status, $mode = 0)
896
    {
897
        // phpcs:enable
898
        if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
899
            global $langs;
900
901
            $this->labelStatus[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft');
902
            $this->labelStatus[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Enabled');
903
            $this->labelStatus[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('Disabled');
904
            $this->labelStatusShort[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft');
905
            $this->labelStatusShort[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Enabled');
906
            $this->labelStatusShort[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('Disabled');
907
        }
908
909
        $statusType = 'status' . $status;
910
        if ($status == self::STATUS_VALIDATED) {
911
            $statusType = 'status4';
912
        }
913
        if ($status == self::STATUS_CANCELED) {
914
            $statusType = 'status6';
915
        }
916
917
        return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusType, $mode);
918
    }
919
920
    /**
921
     *  Load the info information in the object
922
     *
923
     * @param int $id Id of object
924
     *
925
     * @return void
926
     */
927
    public function info($id)
928
    {
929
        $sql = "SELECT rowid,";
930
        $sql .= " date_creation as datec, tms as datem,";
931
        $sql .= " fk_user_creat, fk_user_modif";
932
        $sql .= " FROM " . MAIN_DB_PREFIX . $this->table_element . " as t";
933
        $sql .= " WHERE t.rowid = " . ((int) $id);
934
935
        $result = $this->db->query($sql);
936
        if ($result) {
937
            if ($this->db->num_rows($result)) {
938
                $obj = $this->db->fetch_object($result);
939
940
                $this->id = $obj->rowid;
941
942
                $this->user_creation_id = $obj->fk_user_creat;
943
                $this->user_modification_id = $obj->fk_user_modif;
944
                $this->date_creation = $this->db->jdate($obj->datec);
945
                $this->date_modification = empty($obj->datem) ? '' : $this->db->jdate($obj->datem);
946
            }
947
948
            $this->db->free($result);
949
        } else {
950
            dol_print_error($this->db);
951
        }
952
    }
953
954
    /**
955
     * Initialise object with example values
956
     * Id must be 0 if object instance is a specimen
957
     *
958
     * @return int
959
     */
960
    public function initAsSpecimen()
961
    {
962
        // Set here init that are not commonf fields
963
        // $this->property1 = ...
964
        // $this->property2 = ...
965
966
        return $this->initAsSpecimenCommon();
967
    }
968
969
    /**
970
     *  Create an array of lines
971
     *
972
     * @return array|int       array of lines if OK, <0 if KO
973
     */
974
    public function getLinesArray()
975
    {
976
        $this->lines = [];
977
978
        $objectline = new CalendarLine($this->db);
979
        $result = $objectline->fetchAll('ASC', 'position', 0, 0, '(fk_calendar:=:' . ((int) $this->id) . ')');
980
981
        if (is_numeric($result)) {
982
            $this->setErrorsFromObject($objectline);
983
            return $result;
984
        } else {
985
            $this->lines = $result;
986
            return $this->lines;
987
        }
988
    }
989
990
    /**
991
     *  Returns the reference to the following non used object depending on the active numbering module.
992
     *
993
     * @return string              Object free reference
994
     */
995
    public function getNextNumRef()
996
    {
997
        global $langs, $conf;
998
        $langs->load("agenda");
999
1000
        if (getDolGlobalString('BOOKCAL_MYOBJECT_ADDON')) {
1001
            $conf->global->BOOKCAL_MYOBJECT_ADDON = 'mod_calendar_standard';
1002
        }
1003
1004
        if (getDolGlobalString('BOOKCAL_MYOBJECT_ADDON')) {
1005
            $mybool = false;
1006
1007
            $file = getDolGlobalString('BOOKCAL_MYOBJECT_ADDON') . ".php";
1008
            $classname = getDolGlobalString('BOOKCAL_MYOBJECT_ADDON');
1009
1010
            // Include file with class
1011
            $dirmodels = array_merge(['/'], (array) $conf->modules_parts['models']);
1012
            foreach ($dirmodels as $reldir) {
1013
                $dir = dol_buildpath($reldir . "core/modules/bookcal/");
1014
1015
                // Load file with numbering class (if found)
1016
                $mybool |= @include_once $dir . $file;
1017
            }
1018
1019
            if ($mybool === false) {
1020
                dol_print_error(null, "Failed to include file " . $file);
1021
                return '';
1022
            }
1023
1024
            if (class_exists($classname)) {
1025
                $obj = new $classname();
1026
                $numref = $obj->getNextValue($this);
1027
1028
                if ($numref != '' && $numref != '-1') {
1029
                    return $numref;
1030
                } else {
1031
                    $this->error = $obj->error;
1032
                    //dol_print_error($this->db,get_class($this)."::getNextNumRef ".$obj->error);
1033
                    return "";
1034
                }
1035
            } else {
1036
                print $langs->trans("Error") . " " . $langs->trans("ClassNotFound") . ' ' . $classname;
1037
                return "";
1038
            }
1039
        } else {
1040
            print $langs->trans("ErrorNumberingModuleNotSetup", $this->element);
1041
            return "";
1042
        }
1043
    }
1044
1045
    /**
1046
     *  Create a document onto disk according to template module.
1047
     *
1048
     * @param string     $modele      Force template to use ('' to not force)
1049
     * @param Translate  $outputlangs object lang a utiliser pour traduction
1050
     * @param int        $hidedetails Hide details of lines
1051
     * @param int        $hidedesc    Hide description
1052
     * @param int        $hideref     Hide ref
1053
     * @param null|array $moreparams  Array to provide more information
1054
     *
1055
     * @return     int                         0 if KO, 1 if OK
1056
     */
1057
    public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null)
1058
    {
1059
        global $conf, $langs;
1060
1061
        $result = 0;
1062
        $includedocgeneration = 0;
1063
1064
        $langs->load("agenda");
1065
1066
        if (!dol_strlen($modele)) {
1067
            $modele = 'standard_calendar';
1068
1069
            if (!empty($this->model_pdf)) {
1070
                $modele = $this->model_pdf;
1071
            } elseif (getDolGlobalString('MYOBJECT_ADDON_PDF')) {
1072
                $modele = getDolGlobalString('MYOBJECT_ADDON_PDF');
1073
            }
1074
        }
1075
1076
        $modelpath = "core/modules/bookcal/doc/";
1077
1078
        if ($includedocgeneration && !empty($modele)) {
1079
            $result = $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
1080
        }
1081
1082
        return $result;
1083
    }
1084
1085
    /**
1086
     * Action executed by scheduler
1087
     * CAN BE A CRON TASK. In such a case, parameters come from the schedule job setup field 'Parameters'
1088
     * Use public function doScheduledJob($param1, $param2, ...) to get parameters
1089
     *
1090
     * @return  int         0 if OK, <>0 if KO (this function is used also by cron so only 0 is OK)
1091
     */
1092
    public function doScheduledJob()
1093
    {
1094
        //global $conf, $langs;
1095
1096
        //$conf->global->SYSLOG_FILE = 'DOL_DATA_ROOT/dolibarr_mydedicatedlofile.log';
1097
1098
        $error = 0;
1099
        $this->output = '';
1100
        $this->error = '';
1101
1102
        dol_syslog(__METHOD__, LOG_DEBUG);
1103
1104
        $now = dol_now();
1105
1106
        $this->db->begin();
1107
1108
        // ...
1109
1110
        $this->db->commit();
1111
1112
        return $error;
1113
    }
1114
}
1115