Passed
Push — EXTRACT_CLASSES ( 231cec...0382f2 )
by Rafael
65:54 queued 05:18
created

Calendar::getNomUrl()   F

Complexity

Conditions 37
Paths > 20000

Size

Total Lines 110
Code Lines 74

Duplication

Lines 0
Ratio 0 %

Importance

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

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