dolibarr  18.0.0
cronjob.class.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (C) 2007-2022 Laurent Destailleur <eldy@users.sourceforge.net>
3  * Copyright (C) 2013 Florian Henry <florian.henry@open-concept.pro>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <https://www.gnu.org/licenses/>.
17  */
18 
24 // Put here all includes required by your class file
25 require_once DOL_DOCUMENT_ROOT."/core/class/commonobject.class.php";
26 require_once DOL_DOCUMENT_ROOT."/core/lib/date.lib.php";
27 
28 
32 class Cronjob extends CommonObject
33 {
37  public $element = 'cronjob';
38 
42  public $table_element = 'cronjob';
43 
47  public $picto = 'cron';
48 
52  public $entity;
53 
57  public $jobtype;
58 
62  public $tms = '';
63 
67  public $datec = '';
68 
72  public $label;
73 
77  public $command;
78  public $classesname;
79  public $objectname;
80  public $methodename;
81  public $params;
82  public $md5params;
83  public $module_name;
84  public $priority;
85 
89  public $datelastrun = '';
90 
94  public $datenextrun = '';
95 
99  public $dateend = '';
100 
104  public $datestart = '';
105 
109  public $datelastresult = '';
110 
114  public $lastresult;
115 
119  public $lastoutput;
120 
124  public $unitfrequency;
125 
129  public $frequency;
130 
134  public $status;
135 
139  public $processing;
140 
144  public $pid;
145 
149  public $email_alert;
150 
154  public $fk_user_author;
155 
159  public $fk_user_mod;
160 
164  public $nbrun;
165 
169  public $maxrun;
170 
174  public $libname;
175 
179  public $test;
180 
184  public $autodelete;
185 
186 
187  const STATUS_DISABLED = 0;
188  const STATUS_ENABLED = 1;
189  const STATUS_ARCHIVED = 2;
190 
191 
197  public function __construct($db)
198  {
199  $this->db = $db;
200  }
201 
202 
210  public function create($user, $notrigger = 0)
211  {
212  global $conf, $langs;
213  $error = 0;
214 
215  $now = dol_now();
216 
217  // Clean parameters
218 
219  if (isset($this->label)) {
220  $this->label = trim($this->label);
221  }
222  if (isset($this->jobtype)) {
223  $this->jobtype = trim($this->jobtype);
224  }
225  if (isset($this->command)) {
226  $this->command = trim($this->command);
227  }
228  if (isset($this->classesname)) {
229  $this->classesname = trim($this->classesname);
230  }
231  if (isset($this->objectname)) {
232  $this->objectname = trim($this->objectname);
233  }
234  if (isset($this->methodename)) {
235  $this->methodename = trim($this->methodename);
236  }
237  if (isset($this->params)) {
238  $this->params = trim($this->params);
239  }
240  if (isset($this->md5params)) {
241  $this->md5params = trim($this->md5params);
242  }
243  if (isset($this->module_name)) {
244  $this->module_name = trim($this->module_name);
245  }
246  if (isset($this->priority)) {
247  $this->priority = trim($this->priority);
248  }
249  if (isset($this->lastoutput)) {
250  $this->lastoutput = trim($this->lastoutput);
251  }
252  if (isset($this->lastresult)) {
253  $this->lastresult = trim($this->lastresult);
254  }
255  if (isset($this->unitfrequency)) {
256  $this->unitfrequency = trim($this->unitfrequency);
257  }
258  if (isset($this->frequency)) {
259  $this->frequency = trim($this->frequency);
260  }
261  if (isset($this->status)) {
262  $this->status = trim($this->status);
263  }
264  if (isset($this->note_private)) {
265  $this->note_private = trim($this->note_private);
266  }
267  if (isset($this->nbrun)) {
268  $this->nbrun = (int) $this->nbrun;
269  }
270  if (isset($this->maxrun)) {
271  $this->maxrun = (int) $this->maxrun;
272  }
273  if (isset($this->libname)) {
274  $this->libname = trim($this->libname);
275  }
276  if (isset($this->test)) {
277  $this->test = trim($this->test);
278  }
279 
280  // Check parameters
281  // Put here code to add a control on parameters values
282  if (dol_strlen($this->datenextrun) == 0) {
283  $this->errors[] = $langs->trans('CronFieldMandatory', $langs->transnoentitiesnoconv('CronDtNextLaunch'));
284  $error++;
285  }
286  if (empty($this->label)) {
287  $this->errors[] = $langs->trans('CronFieldMandatory', $langs->transnoentitiesnoconv('CronLabel'));
288  $error++;
289  }
290  if ((dol_strlen($this->datestart) != 0) && (dol_strlen($this->dateend) != 0) && ($this->dateend < $this->datestart)) {
291  $this->errors[] = $langs->trans('CronErrEndDateStartDt');
292  $error++;
293  }
294  if (empty($this->unitfrequency)) {
295  $this->errors[] = $langs->trans('CronFieldMandatory', $langs->transnoentitiesnoconv('CronFrequency'));
296  $error++;
297  }
298  if (($this->jobtype == 'command') && (empty($this->command))) {
299  $this->errors[] = $langs->trans('CronFieldMandatory', $langs->transnoentitiesnoconv('CronCommand'));
300  $error++;
301  }
302  if (($this->jobtype == 'method') && (empty($this->classesname))) {
303  $this->errors[] = $langs->trans('CronFieldMandatory', $langs->transnoentitiesnoconv('CronClass'));
304  $error++;
305  }
306  if (($this->jobtype == 'method' || $this->jobtype == 'function') && (empty($this->methodename))) {
307  $this->errors[] = $langs->trans('CronFieldMandatory', $langs->transnoentitiesnoconv('CronMethod'));
308  $error++;
309  }
310  if (($this->jobtype == 'method') && (empty($this->objectname))) {
311  $this->errors[] = $langs->trans('CronFieldMandatory', $langs->transnoentitiesnoconv('CronObject'));
312  $error++;
313  }
314  if (($this->jobtype == 'function') && (empty($this->libname))) {
315  $this->errors[] = $langs->trans('CronFieldMandatory', $langs->transnoentitiesnoconv('CronLib'));
316  $error++;
317  }
318 
319  // Insert request
320  $sql = "INSERT INTO ".MAIN_DB_PREFIX."cronjob(";
321  $sql .= "entity,";
322  $sql .= "datec,";
323  $sql .= "jobtype,";
324  $sql .= "label,";
325  $sql .= "command,";
326  $sql .= "classesname,";
327  $sql .= "objectname,";
328  $sql .= "methodename,";
329  $sql .= "params,";
330  $sql .= "md5params,";
331  $sql .= "module_name,";
332  $sql .= "priority,";
333  $sql .= "datelastrun,";
334  $sql .= "datenextrun,";
335  $sql .= "dateend,";
336  $sql .= "datestart,";
337  $sql .= "lastresult,";
338  $sql .= "datelastresult,";
339  $sql .= "lastoutput,";
340  $sql .= "unitfrequency,";
341  $sql .= "frequency,";
342  $sql .= "status,";
343  $sql .= "fk_user_author,";
344  $sql .= "fk_user_mod,";
345  $sql .= "note,";
346  $sql .= "nbrun,";
347  $sql .= "maxrun,";
348  $sql .= "libname,";
349  $sql .= "test";
350  $sql .= ") VALUES (";
351  $sql .= " ".(!isset($this->entity) ? $conf->entity : $this->db->escape($this->entity)).",";
352  $sql .= " '".$this->db->idate($now)."',";
353  $sql .= " ".(!isset($this->jobtype) ? 'NULL' : "'".$this->db->escape($this->jobtype)."'").",";
354  $sql .= " ".(!isset($this->label) ? 'NULL' : "'".$this->db->escape($this->label)."'").",";
355  $sql .= " ".(!isset($this->command) ? 'NULL' : "'".$this->db->escape($this->command)."'").",";
356  $sql .= " ".(!isset($this->classesname) ? 'NULL' : "'".$this->db->escape($this->classesname)."'").",";
357  $sql .= " ".(!isset($this->objectname) ? 'NULL' : "'".$this->db->escape($this->objectname)."'").",";
358  $sql .= " ".(!isset($this->methodename) ? 'NULL' : "'".$this->db->escape($this->methodename)."'").",";
359  $sql .= " ".(!isset($this->params) ? 'NULL' : "'".$this->db->escape($this->params)."'").",";
360  $sql .= " ".(!isset($this->md5params) ? 'NULL' : "'".$this->db->escape($this->md5params)."'").",";
361  $sql .= " ".(!isset($this->module_name) ? 'NULL' : "'".$this->db->escape($this->module_name)."'").",";
362  $sql .= " ".(!isset($this->priority) ? '0' : $this->priority).",";
363  $sql .= " ".(!isset($this->datelastrun) || dol_strlen($this->datelastrun) == 0 ? 'NULL' : "'".$this->db->idate($this->datelastrun)."'").",";
364  $sql .= " ".(!isset($this->datenextrun) || dol_strlen($this->datenextrun) == 0 ? 'NULL' : "'".$this->db->idate($this->datenextrun)."'").",";
365  $sql .= " ".(!isset($this->dateend) || dol_strlen($this->dateend) == 0 ? 'NULL' : "'".$this->db->idate($this->dateend)."'").",";
366  $sql .= " ".(!isset($this->datestart) || dol_strlen($this->datestart) == 0 ? 'NULL' : "'".$this->db->idate($this->datestart)."'").",";
367  $sql .= " ".(!isset($this->lastresult) ? 'NULL' : "'".$this->db->escape($this->lastresult)."'").",";
368  $sql .= " ".(!isset($this->datelastresult) || dol_strlen($this->datelastresult) == 0 ? 'NULL' : "'".$this->db->idate($this->datelastresult)."'").",";
369  $sql .= " ".(!isset($this->lastoutput) ? 'NULL' : "'".$this->db->escape($this->lastoutput)."'").",";
370  $sql .= " ".(!isset($this->unitfrequency) ? 'NULL' : "'".$this->db->escape($this->unitfrequency)."'").",";
371  $sql .= " ".(!isset($this->frequency) ? '0' : ((int) $this->frequency)).",";
372  $sql .= " ".(!isset($this->status) ? '0' : ((int) $this->status)).",";
373  $sql .= " ".($user->id ? (int) $user->id : "NULL").",";
374  $sql .= " ".($user->id ? (int) $user->id : "NULL").",";
375  $sql .= " ".(!isset($this->note_private) ? 'NULL' : "'".$this->db->escape($this->note_private)."'").",";
376  $sql .= " ".(!isset($this->nbrun) ? '0' : ((int) $this->nbrun)).",";
377  $sql .= " ".(empty($this->maxrun) ? '0' : ((int) $this->maxrun)).",";
378  $sql .= " ".(!isset($this->libname) ? 'NULL' : "'".$this->db->escape($this->libname)."'").",";
379  $sql .= " ".(!isset($this->test) ? 'NULL' : "'".$this->db->escape($this->test)."'");
380  $sql .= ")";
381 
382  $this->db->begin();
383 
384  dol_syslog(get_class($this)."::create", LOG_DEBUG);
385  $resql = $this->db->query($sql);
386  if (!$resql) {
387  $error++;
388  $this->errors[] = "Error ".$this->db->lasterror();
389  }
390 
391  if (!$error) {
392  $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."cronjob");
393  }
394 
395  // Commit or rollback
396  if ($error) {
397  $this->db->rollback();
398  return -1 * $error;
399  } else {
400  $this->db->commit();
401  return $this->id;
402  }
403  }
404 
405 
414  public function fetch($id, $objectname = '', $methodname = '')
415  {
416  $sql = "SELECT";
417  $sql .= " t.rowid,";
418  $sql .= " t.entity,";
419  $sql .= " t.tms,";
420  $sql .= " t.datec,";
421  $sql .= " t.jobtype,";
422  $sql .= " t.label,";
423  $sql .= " t.command,";
424  $sql .= " t.classesname,";
425  $sql .= " t.objectname,";
426  $sql .= " t.methodename,";
427  $sql .= " t.params,";
428  $sql .= " t.md5params,";
429  $sql .= " t.module_name,";
430  $sql .= " t.priority,";
431  $sql .= " t.datelastrun,";
432  $sql .= " t.datenextrun,";
433  $sql .= " t.dateend,";
434  $sql .= " t.datestart,";
435  $sql .= " t.lastresult,";
436  $sql .= " t.datelastresult,";
437  $sql .= " t.lastoutput,";
438  $sql .= " t.unitfrequency,";
439  $sql .= " t.frequency,";
440  $sql .= " t.status,";
441  $sql .= " t.processing,";
442  $sql .= " t.pid,";
443  $sql .= " t.email_alert,";
444  $sql .= " t.fk_user_author,";
445  $sql .= " t.fk_user_mod,";
446  $sql .= " t.note as note_private,";
447  $sql .= " t.nbrun,";
448  $sql .= " t.maxrun,";
449  $sql .= " t.libname,";
450  $sql .= " t.test";
451  $sql .= " FROM ".MAIN_DB_PREFIX."cronjob as t";
452  if ($id > 0) {
453  $sql .= " WHERE t.rowid = ".((int) $id);
454  } else {
455  $sql .= " WHERE t.entity IN(0, ".getEntity('cron').")";
456  $sql .= " AND t.objectname = '".$this->db->escape($objectname)."'";
457  $sql .= " AND t.methodename = '".$this->db->escape($methodname)."'";
458  }
459 
460  dol_syslog(get_class($this)."::fetch", LOG_DEBUG);
461  $resql = $this->db->query($sql);
462  if ($resql) {
463  if ($this->db->num_rows($resql)) {
464  $obj = $this->db->fetch_object($resql);
465 
466  $this->id = $obj->rowid;
467  $this->ref = $obj->rowid;
468  $this->entity = $obj->entity;
469  $this->tms = $this->db->jdate($obj->tms);
470  $this->datec = $this->db->jdate($obj->datec);
471  $this->label = $obj->label;
472  $this->jobtype = $obj->jobtype;
473  $this->command = $obj->command;
474  $this->classesname = $obj->classesname;
475  $this->objectname = $obj->objectname;
476  $this->methodename = $obj->methodename;
477  $this->params = $obj->params;
478  $this->md5params = $obj->md5params;
479  $this->module_name = $obj->module_name;
480  $this->priority = $obj->priority;
481  $this->datelastrun = $this->db->jdate($obj->datelastrun);
482  $this->datenextrun = $this->db->jdate($obj->datenextrun);
483  $this->dateend = $this->db->jdate($obj->dateend);
484  $this->datestart = $this->db->jdate($obj->datestart);
485  $this->lastresult = $obj->lastresult;
486  $this->lastoutput = $obj->lastoutput;
487  $this->datelastresult = $this->db->jdate($obj->datelastresult);
488  $this->unitfrequency = $obj->unitfrequency;
489  $this->frequency = $obj->frequency;
490  $this->status = $obj->status;
491  $this->processing = $obj->processing;
492  $this->pid = $obj->pid;
493  $this->email_alert = $obj->email_alert;
494  $this->fk_user_author = $obj->fk_user_author;
495  $this->fk_user_mod = $obj->fk_user_mod;
496  $this->note_private = $obj->note_private;
497  $this->nbrun = $obj->nbrun;
498  $this->maxrun = $obj->maxrun;
499  $this->libname = $obj->libname;
500  $this->test = $obj->test;
501  }
502  $this->db->free($resql);
503 
504  return 1;
505  } else {
506  $this->error = "Error ".$this->db->lasterror();
507  return -1;
508  }
509  }
510 
524  public function fetchAll($sortorder = 'DESC', $sortfield = 't.rowid', $limit = 0, $offset = 0, $status = 1, $filter = '', $processing = -1)
525  {
526  $this->lines = array();
527 
528  $sql = "SELECT";
529  $sql .= " t.rowid,";
530  $sql .= " t.entity,";
531  $sql .= " t.tms,";
532  $sql .= " t.datec,";
533  $sql .= " t.jobtype,";
534  $sql .= " t.label,";
535  $sql .= " t.command,";
536  $sql .= " t.classesname,";
537  $sql .= " t.objectname,";
538  $sql .= " t.methodename,";
539  $sql .= " t.params,";
540  $sql .= " t.md5params,";
541  $sql .= " t.module_name,";
542  $sql .= " t.priority,";
543  $sql .= " t.datelastrun,";
544  $sql .= " t.datenextrun,";
545  $sql .= " t.dateend,";
546  $sql .= " t.datestart,";
547  $sql .= " t.lastresult,";
548  $sql .= " t.datelastresult,";
549  $sql .= " t.lastoutput,";
550  $sql .= " t.unitfrequency,";
551  $sql .= " t.frequency,";
552  $sql .= " t.status,";
553  $sql .= " t.processing,";
554  $sql .= " t.pid,";
555  $sql .= " t.email_alert,";
556  $sql .= " t.fk_user_author,";
557  $sql .= " t.fk_user_mod,";
558  $sql .= " t.note as note_private,";
559  $sql .= " t.nbrun,";
560  $sql .= " t.libname,";
561  $sql .= " t.test";
562  $sql .= " FROM ".MAIN_DB_PREFIX."cronjob as t";
563  $sql .= " WHERE 1 = 1";
564  if ($processing >= 0) {
565  $sql .= " AND t.processing = ".(empty($processing) ? '0' : '1');
566  }
567  if ($status >= 0 && $status < 2) {
568  $sql .= " AND t.status = ".(empty($status) ? '0' : '1');
569  } elseif ($status == 2) {
570  $sql .= " AND t.status = 2";
571  }
572  // Manage filter
573  if (is_array($filter) && count($filter) > 0) {
574  foreach ($filter as $key => $value) {
575  if ($key == 't.rowid') {
576  $sql .= " AND ".$key." = ".((int) $value);
577  } else {
578  $sql .= " AND ".$key." LIKE '%".$this->db->escape($value)."%'";
579  }
580  }
581  }
582 
583  $sql .= $this->db->order($sortfield, $sortorder);
584  if (!empty($limit) && !empty($offset)) {
585  $sql .= $this->db->plimit($limit + 1, $offset);
586  }
587 
588  $sqlwhere = array();
589 
590  if (count($sqlwhere) > 0) {
591  $sql .= " WHERE ".implode(' AND ', $sqlwhere);
592  }
593 
594  dol_syslog(get_class($this)."::fetchAll", LOG_DEBUG);
595  $resql = $this->db->query($sql);
596  if ($resql) {
597  $num = $this->db->num_rows($resql);
598  $i = 0;
599 
600  if ($num) {
601  while ($i < $num) {
602  $line = new Cronjobline();
603 
604  $obj = $this->db->fetch_object($resql);
605 
606  $line->id = $obj->rowid;
607  $line->ref = $obj->rowid;
608  $line->entity = $obj->entity;
609  $line->tms = $this->db->jdate($obj->tms);
610  $line->datec = $this->db->jdate($obj->datec);
611  $line->label = $obj->label;
612  $line->jobtype = $obj->jobtype;
613  $line->command = $obj->command;
614  $line->classesname = $obj->classesname;
615  $line->objectname = $obj->objectname;
616  $line->methodename = $obj->methodename;
617  $line->params = $obj->params;
618  $line->md5params = $obj->md5params;
619  $line->module_name = $obj->module_name;
620  $line->priority = $obj->priority;
621  $line->datelastrun = $this->db->jdate($obj->datelastrun);
622  $line->datenextrun = $this->db->jdate($obj->datenextrun);
623  $line->dateend = $this->db->jdate($obj->dateend);
624  $line->datestart = $this->db->jdate($obj->datestart);
625  $line->lastresult = $obj->lastresult;
626  $line->datelastresult = $this->db->jdate($obj->datelastresult);
627  $line->lastoutput = $obj->lastoutput;
628  $line->unitfrequency = $obj->unitfrequency;
629  $line->frequency = $obj->frequency;
630  $line->status = $obj->status;
631  $line->processing = $obj->processing;
632  $line->pid = $obj->pid;
633  $line->email_alert = $obj->email_alert;
634  $line->fk_user_author = $obj->fk_user_author;
635  $line->fk_user_mod = $obj->fk_user_mod;
636  $line->note_private = $obj->note_private;
637  $line->nbrun = $obj->nbrun;
638  $line->libname = $obj->libname;
639  $line->test = $obj->test;
640  $this->lines[] = $line;
641 
642  $i++;
643  }
644  }
645  $this->db->free($resql);
646 
647  return 1;
648  } else {
649  $this->error = "Error ".$this->db->lasterror();
650  return -1;
651  }
652  }
653 
654 
662  public function update($user = null, $notrigger = 0)
663  {
664  global $conf, $langs;
665 
666  $langs->load('cron');
667 
668  $error = 0;
669 
670  // Clean parameters
671  if (isset($this->label)) {
672  $this->label = trim($this->label);
673  }
674  if (isset($this->jobtype)) {
675  $this->jobtype = trim($this->jobtype);
676  }
677  if (isset($this->command)) {
678  $this->command = trim($this->command);
679  }
680  if (isset($this->classesname)) {
681  $this->classesname = trim($this->classesname);
682  }
683  if (isset($this->objectname)) {
684  $this->objectname = trim($this->objectname);
685  }
686  if (isset($this->methodename)) {
687  $this->methodename = trim($this->methodename);
688  }
689  if (isset($this->params)) {
690  $this->params = trim($this->params);
691  }
692  if (isset($this->md5params)) {
693  $this->md5params = trim($this->md5params);
694  }
695  if (isset($this->module_name)) {
696  $this->module_name = trim($this->module_name);
697  }
698  if (isset($this->priority)) {
699  $this->priority = trim($this->priority);
700  }
701  if (isset($this->lastoutput)) {
702  $this->lastoutput = trim($this->lastoutput);
703  }
704  if (isset($this->lastresult)) {
705  $this->lastresult = trim($this->lastresult);
706  }
707  if (isset($this->unitfrequency)) {
708  $this->unitfrequency = trim($this->unitfrequency);
709  }
710  if (isset($this->frequency)) {
711  $this->frequency = trim($this->frequency);
712  }
713  if (isset($this->status)) {
714  $this->status = trim($this->status);
715  }
716  if (isset($this->note_private)) {
717  $this->note_private = trim($this->note_private);
718  }
719  if (isset($this->nbrun)) {
720  $this->nbrun = trim($this->nbrun);
721  }
722  if (isset($this->libname)) {
723  $this->libname = trim($this->libname);
724  }
725  if (isset($this->test)) {
726  $this->test = trim($this->test);
727  }
728 
729  if (empty($this->maxrun)) {
730  $this->maxrun = 0;
731  }
732  if (empty($this->processing)) {
733  $this->processing = 0;
734  }
735  if (empty($this->pid)) {
736  $this->pid = null;
737  }
738  if (empty($this->email_alert)) {
739  $this->email_alert = '';
740  }
741 
742  // Check parameters
743  // Put here code to add a control on parameters values
744  if (dol_strlen($this->datenextrun) == 0 && $this->status == self::STATUS_ENABLED) {
745  $this->errors[] = $langs->trans('CronFieldMandatory', $langs->transnoentitiesnoconv('CronDtNextLaunch'));
746  $error++;
747  }
748  if ((dol_strlen($this->datestart) != 0) && (dol_strlen($this->dateend) != 0) && ($this->dateend < $this->datestart)) {
749  $this->errors[] = $langs->trans('CronErrEndDateStartDt');
750  $error++;
751  }
752  if (empty($this->label)) {
753  $this->errors[] = $langs->trans('CronFieldMandatory', $langs->transnoentitiesnoconv('CronLabel'));
754  $error++;
755  }
756  if (empty($this->unitfrequency)) {
757  $this->errors[] = $langs->trans('CronFieldMandatory', $langs->transnoentitiesnoconv('CronFrequency'));
758  $error++;
759  }
760  if (($this->jobtype == 'command') && (empty($this->command))) {
761  $this->errors[] = $langs->trans('CronFieldMandatory', $langs->transnoentitiesnoconv('CronCommand'));
762  $error++;
763  }
764  if (($this->jobtype == 'method') && (empty($this->classesname))) {
765  $this->errors[] = $langs->trans('CronFieldMandatory', $langs->transnoentitiesnoconv('CronClass'));
766  $error++;
767  }
768  if (($this->jobtype == 'method' || $this->jobtype == 'function') && (empty($this->methodename))) {
769  $this->errors[] = $langs->trans('CronFieldMandatory', $langs->transnoentitiesnoconv('CronMethod'));
770  $error++;
771  }
772  if (($this->jobtype == 'method') && (empty($this->objectname))) {
773  $this->errors[] = $langs->trans('CronFieldMandatory', $langs->transnoentitiesnoconv('CronObject'));
774  $error++;
775  }
776 
777  if (($this->jobtype == 'function') && (empty($this->libname))) {
778  $this->errors[] = $langs->trans('CronFieldMandatory', $langs->transnoentitiesnoconv('CronLib'));
779  $error++;
780  }
781 
782 
783  // Update request
784  $sql = "UPDATE ".MAIN_DB_PREFIX."cronjob SET";
785  $sql .= " entity=".(isset($this->entity) ? ((int) $this->entity) : $conf->entity).",";
786  $sql .= " label=".(isset($this->label) ? "'".$this->db->escape($this->label)."'" : "null").",";
787  $sql .= " jobtype=".(isset($this->jobtype) ? "'".$this->db->escape($this->jobtype)."'" : "null").",";
788  $sql .= " command=".(isset($this->command) ? "'".$this->db->escape($this->command)."'" : "null").",";
789  $sql .= " classesname=".(isset($this->classesname) ? "'".$this->db->escape($this->classesname)."'" : "null").",";
790  $sql .= " objectname=".(isset($this->objectname) ? "'".$this->db->escape($this->objectname)."'" : "null").",";
791  $sql .= " methodename=".(isset($this->methodename) ? "'".$this->db->escape($this->methodename)."'" : "null").",";
792  $sql .= " params=".(isset($this->params) ? "'".$this->db->escape($this->params)."'" : "null").",";
793  $sql .= " md5params=".(isset($this->md5params) ? "'".$this->db->escape($this->md5params)."'" : "null").",";
794  $sql .= " module_name=".(isset($this->module_name) ? "'".$this->db->escape($this->module_name)."'" : "null").",";
795  $sql .= " priority=".(isset($this->priority) ? ((int) $this->priority) : "null").",";
796  $sql .= " datelastrun=".(dol_strlen($this->datelastrun) != 0 ? "'".$this->db->idate($this->datelastrun)."'" : 'null').",";
797  $sql .= " datenextrun=".(dol_strlen($this->datenextrun) != 0 ? "'".$this->db->idate($this->datenextrun)."'" : 'null').",";
798  $sql .= " dateend=".(dol_strlen($this->dateend) != 0 ? "'".$this->db->idate($this->dateend)."'" : 'null').",";
799  $sql .= " datestart=".(dol_strlen($this->datestart) != 0 ? "'".$this->db->idate($this->datestart)."'" : 'null').",";
800  $sql .= " datelastresult=".(dol_strlen($this->datelastresult) != 0 ? "'".$this->db->idate($this->datelastresult)."'" : 'null').",";
801  $sql .= " lastresult=".(isset($this->lastresult) ? "'".$this->db->escape($this->lastresult)."'" : "null").",";
802  $sql .= " lastoutput=".(isset($this->lastoutput) ? "'".$this->db->escape($this->lastoutput)."'" : "null").",";
803  $sql .= " unitfrequency=".(isset($this->unitfrequency) ? $this->unitfrequency : "null").",";
804  $sql .= " frequency=".(isset($this->frequency) ? $this->frequency : "null").",";
805  $sql .= " status=".(isset($this->status) ? $this->status : "null").",";
806  $sql .= " processing=".((isset($this->processing) && $this->processing > 0) ? $this->processing : "0").",";
807  $sql .= " pid=".(isset($this->pid) ? ((int) $this->pid) : "null").",";
808  $sql .= " email_alert = ".(isset($this->email_alert) ? "'".$this->db->escape($this->email_alert)."'" : "null").",";
809  $sql .= " fk_user_mod = ".((int) $user->id).",";
810  $sql .= " note=".(isset($this->note_private) ? "'".$this->db->escape($this->note_private)."'" : "null").",";
811  $sql .= " nbrun=".((isset($this->nbrun) && $this->nbrun > 0) ? $this->nbrun : "null").",";
812  $sql .= " maxrun=".((isset($this->maxrun) && $this->maxrun > 0) ? $this->maxrun : "0").",";
813  $sql .= " libname=".(isset($this->libname) ? "'".$this->db->escape($this->libname)."'" : "null").",";
814  $sql .= " test=".(isset($this->test) ? "'".$this->db->escape($this->test)."'" : "null");
815  $sql .= " WHERE rowid=".((int) $this->id);
816 
817  $this->db->begin();
818 
819  dol_syslog(get_class($this)."::update", LOG_DEBUG);
820  $resql = $this->db->query($sql);
821  if (!$resql) {
822  $error++; $this->errors[] = "Error ".$this->db->lasterror();
823  }
824 
825  // Commit or rollback
826  if ($error) {
827  foreach ($this->errors as $errmsg) {
828  dol_syslog(get_class($this)."::update ".$errmsg, LOG_ERR);
829  $this->error .= ($this->error ? ', '.$errmsg : $errmsg);
830  }
831  $this->db->rollback();
832  return -1 * $error;
833  } else {
834  $this->db->commit();
835  return 1;
836  }
837  }
838 
839 
847  public function delete($user, $notrigger = 0)
848  {
849  $error = 0;
850 
851  $this->db->begin();
852 
853  $sql = "DELETE FROM ".MAIN_DB_PREFIX."cronjob";
854  $sql .= " WHERE rowid=".((int) $this->id);
855 
856  dol_syslog(get_class($this)."::delete", LOG_DEBUG);
857  $resql = $this->db->query($sql);
858  if (!$resql) {
859  $error++;
860  $this->errors[] = "Error ".$this->db->lasterror();
861  }
862 
863  // Commit or rollback
864  if ($error) {
865  foreach ($this->errors as $errmsg) {
866  dol_syslog(get_class($this)."::delete ".$errmsg, LOG_ERR);
867  $this->error .= ($this->error ? ', '.$errmsg : $errmsg);
868  }
869  $this->db->rollback();
870  return -1 * $error;
871  } else {
872  $this->db->commit();
873  return 1;
874  }
875  }
876 
877 
878 
886  public function createFromClone(User $user, $fromid)
887  {
888  global $langs;
889 
890  $error = 0;
891 
892  $object = new Cronjob($this->db);
893 
894  $this->db->begin();
895 
896  // Load source object
897  $object->fetch($fromid);
898  $object->id = 0;
899 
900  // Clear fields
901  $object->status = self::STATUS_DISABLED;
902  $object->label = $langs->trans("CopyOf").' '.$langs->trans($object->label);
903  $object->datelastrun = null;
904  $object->lastresult = '';
905  $object->datelastresult = null;
906  $object->lastoutput = '';
907  $object->nbrun = 0;
908 
909  // Create clone
910  $object->context['createfromclone'] = 'createfromclone';
911  $result = $object->create($user);
912 
913  // Other options
914  if ($result < 0) {
915  $this->error = $object->error;
916  $this->errors = $object->errors;
917  $error++;
918  }
919 
920  unset($object->context['createfromclone']);
921 
922  // End
923  if (!$error) {
924  $this->db->commit();
925  return $object->id;
926  } else {
927  $this->db->rollback();
928  return -1;
929  }
930  }
931 
932 
939  public function initAsSpecimen()
940  {
941  $this->id = 0;
942  $this->ref = 0;
943  $this->entity = 0;
944  $this->tms = '';
945  $this->datec = '';
946  $this->label = '';
947  $this->jobtype = '';
948  $this->command = '';
949  $this->classesname = '';
950  $this->objectname = '';
951  $this->methodename = '';
952  $this->params = '';
953  $this->md5params = '';
954  $this->module_name = '';
955  $this->priority = '';
956  $this->datelastrun = '';
957  $this->datenextrun = '';
958  $this->dateend = '';
959  $this->datestart = '';
960  $this->datelastresult = '';
961  $this->lastoutput = '';
962  $this->lastresult = '';
963  $this->unitfrequency = '';
964  $this->frequency = '';
965  $this->status = 0;
966  $this->processing = 0;
967  $this->pid = null;
968  $this->email_alert = '';
969  $this->fk_user_author = 0;
970  $this->fk_user_mod = 0;
971  $this->note_private = '';
972  $this->nbrun = '';
973  $this->maxrun = 100;
974  $this->libname = '';
975  }
976 
977 
984  public function getTooltipContentArray($params)
985  {
986  global $langs;
987 
988  $langs->load('cron');
989  $datas = [];
990 
991  $datas['picto'] = img_picto('', 'object_'.$this->picto).' <u>'.$langs->trans("CronTask").'</u>';
992  if (isset($this->status)) {
993  $datas['picto'] .= ' '.$this->getLibStatut(5);
994  }
995  $datas['ref'] = '<br><b>'.$langs->trans('Ref').':</b> '.dol_escape_htmltag($this->ref);
996  $datas['label'] = '<br><b>'.$langs->trans('Title').':</b> '.$langs->trans($this->label);
997  if ($this->label != $langs->trans($this->label)) {
998  $datas['label'] .= ' <span class="opacitymedium">('.$this->label.')</span>';
999  }
1000  if (!empty($this->params)) {
1001  $datas['params'] = '<br><b>'.$langs->trans('Parameters').':</b> '.dol_escape_htmltag($this->params);
1002  }
1003  $datas['space'] = '<br>';
1004 
1005  if (!empty($this->datestart) && $this->datestart >= dol_now()) {
1006  $datas['crondtstart'] = '<br><b>'.$langs->trans('CronDtStart').':</b> '.dol_print_date($this->datestart, 'dayhour', 'tzuserrel');
1007  }
1008  if (!empty($this->dateend)) {
1009  $datas['crondtend'] = '<br><b>'.$langs->trans('CronDtEnd').':</b> '.dol_print_date($this->dateend, 'dayhour', 'tzuserrel');
1010  }
1011  if (!empty($this->datelastrun)) {
1012  $datas['cronlastlaunch'] = '<br><b>'.$langs->trans('CronDtLastLaunch').':</b> '.dol_print_date($this->datelastrun, 'dayhour', 'tzuserrel');
1013  }
1014  if (!empty($this->datenextrun)) {
1015  $datas['crondtnextlaunch'] = '<br><b>'.$langs->trans('CronDtNextLaunch').':</b> '.dol_print_date($this->datenextrun, 'dayhour', 'tzuserrel');
1016  }
1017 
1018  return $datas;
1019  }
1020 
1031  public function getNomUrl($withpicto = 0, $option = '', $notooltip = 0, $morecss = '', $save_lastsearch_value = -1)
1032  {
1033  global $db, $conf, $langs;
1034 
1035  if (!empty($conf->dol_no_mouse_hover)) {
1036  $notooltip = 1; // Force disable tooltips
1037  }
1038 
1039  $result = '';
1040 
1041  $params = [
1042  'id' => $this->id,
1043  'objecttype' => $this->element,
1044  ];
1045  $classfortooltip = 'classfortooltip';
1046  $dataparams = '';
1047  if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) {
1048  $classfortooltip = 'classforajaxtooltip';
1049  $dataparams = ' data-params="'.dol_escape_htmltag(json_encode($params)).'"';
1050  $label = '';
1051  } else {
1052  $label = implode($this->getTooltipContentArray($params));
1053  }
1054 
1055  $url = DOL_URL_ROOT.'/cron/card.php?id='.$this->id;
1056 
1057  if ($option != 'nolink') {
1058  // Add param to save lastsearch_values or not
1059  $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
1060  if ($save_lastsearch_value == -1 && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
1061  $add_save_lastsearch_values = 1;
1062  }
1063  if ($add_save_lastsearch_values) {
1064  $url .= '&save_lastsearch_values=1';
1065  }
1066  }
1067 
1068  $linkclose = '';
1069  if (empty($notooltip)) {
1070  if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) {
1071  $label = $langs->trans("ShowCronJob");
1072  $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"';
1073  }
1074  $linkclose .= ($label ? ' title="'.dol_escape_htmltag($label, 1).'"' : ' title="tocomplete"');
1075  $linkclose .= $dataparams.' class="'.$classfortooltip.($morecss ? ' '.$morecss : '').'"';
1076  } else {
1077  $linkclose = ($morecss ? ' class="'.$morecss.'"' : '');
1078  }
1079 
1080  $linkstart = '<a href="'.$url.'"';
1081  $linkstart .= $linkclose.'>';
1082  $linkend = '</a>';
1083 
1084  $result .= $linkstart;
1085  if ($withpicto) {
1086  $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), (($withpicto != 2) ? 'class="paddingright"' : ''), 0, 0, $notooltip ? 0 : 1);
1087  }
1088  if ($withpicto != 2) {
1089  $result .= $this->ref;
1090  }
1091  $result .= $linkend;
1092  //if ($withpicto != 2) $result.=(($addlabel && $this->label) ? $sep . dol_trunc($this->label, ($addlabel > 1 ? $addlabel : 0)) : '');
1093 
1094  return $result;
1095  }
1096 
1097 
1104  public function info($id)
1105  {
1106  $sql = "SELECT";
1107  $sql .= " f.rowid, f.datec, f.tms, f.fk_user_mod, f.fk_user_author";
1108  $sql .= " FROM ".MAIN_DB_PREFIX."cronjob as f";
1109  $sql .= " WHERE f.rowid = ".((int) $id);
1110 
1111  dol_syslog(get_class($this)."::fetch", LOG_DEBUG);
1112  $resql = $this->db->query($sql);
1113  if ($resql) {
1114  if ($this->db->num_rows($resql)) {
1115  $obj = $this->db->fetch_object($resql);
1116  $this->id = $obj->rowid;
1117 
1118  $this->user_modification_id = $obj->fk_user_mod;
1119  $this->user_creation_id = $obj->fk_user_author;
1120  $this->date_creation = $this->db->jdate($obj->datec);
1121  $this->date_modification = $this->db->jdate($obj->tms);
1122  }
1123  $this->db->free($resql);
1124 
1125  return 1;
1126  } else {
1127  $this->error = "Error ".$this->db->lasterror();
1128  return -1;
1129  }
1130  }
1131 
1132 
1133  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1142  public function run_jobs($userlogin)
1143  {
1144  // phpcs:enable
1145  global $langs, $conf, $hookmanager;
1146 
1147  $hookmanager->initHooks(array('cron'));
1148 
1149  $now = dol_now();
1150  $error = 0;
1151  $retval = '';
1152 
1153  $langs->load('cron');
1154 
1155  if (empty($userlogin)) {
1156  $this->error = "User login is mandatory";
1157  dol_syslog(get_class($this)."::run_jobs ".$this->error, LOG_ERR);
1158  return -1;
1159  }
1160 
1161  // Force the environment of running to the environment declared for job, so jobs launched from command line will run into correct environment
1162  // When job is ran from GUI, the environment should already be same, except if job has entity 0 (visible into all environments)
1163  if ($conf->entity != $this->entity && $this->entity > 0) {
1164  dol_syslog("We try to run a job in entity ".$this->entity." when we are in entity ".$conf->entity, LOG_WARNING);
1165  }
1166  $savcurrententity = $conf->entity;
1167  $conf->setEntityValues($this->db, $this->entity);
1168  dol_syslog(get_class($this)."::run_jobs entity for running job is ".$conf->entity);
1169 
1170  require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php';
1171  $user = new User($this->db);
1172  $result = $user->fetch('', $userlogin);
1173  if ($result < 0) {
1174  $this->error = "User Error:".$user->error;
1175  dol_syslog(get_class($this)."::run_jobs ".$this->error, LOG_ERR);
1176  $conf->setEntityValues($this->db, $savcurrententity);
1177  return -1;
1178  } else {
1179  if (empty($user->id)) {
1180  $this->error = "User login: ".$userlogin." does not exist";
1181  dol_syslog(get_class($this)."::run_jobs ".$this->error, LOG_ERR);
1182  $conf->setEntityValues($this->db, $savcurrententity);
1183  return -1;
1184  }
1185  }
1186 
1187  dol_syslog(get_class($this)."::run_jobs jobtype=".$this->jobtype." userlogin=".$userlogin, LOG_DEBUG);
1188 
1189  // Increase limit of time. Works only if we are not in safe mode
1190  $ExecTimeLimit = 600;
1191  if (!empty($ExecTimeLimit)) {
1192  $err = error_reporting();
1193  error_reporting(0); // Disable all errors
1194  //error_reporting(E_ALL);
1195  @set_time_limit($ExecTimeLimit); // Need more than 240 on Windows 7/64
1196  error_reporting($err);
1197  }
1198  $MemoryLimit = 0;
1199  if (!empty($MemoryLimit)) {
1200  @ini_set('memory_limit', $MemoryLimit);
1201  }
1202 
1203  // Update last run date start (to track running jobs)
1204  $this->datelastrun = $now;
1205  $this->datelastresult = null;
1206  $this->lastoutput = '';
1207  $this->lastresult = '';
1208  $this->processing = 1; // To know job was started
1209  $this->pid = function_exists('getmypid') ? getmypid() : null; // Avoid dol_getmypid to get null if the function is not available
1210  $this->nbrun = $this->nbrun + 1;
1211  $result = $this->update($user); // This include begin/commit
1212  if ($result < 0) {
1213  dol_syslog(get_class($this)."::run_jobs ".$this->error, LOG_ERR);
1214  $conf->setEntityValues($this->db, $savcurrententity);
1215  return -1;
1216  }
1217 
1218  // Run a method
1219  if ($this->jobtype == 'method') {
1220  // load classes
1221  if (!$error) {
1222  $ret = dol_include_once($this->classesname);
1223  if ($ret === false || (!class_exists($this->objectname))) {
1224  if ($ret === false) {
1225  $this->error = $langs->transnoentitiesnoconv('CronCannotLoadClass', $this->classesname, $this->objectname);
1226  } else {
1227  $this->error = $langs->transnoentitiesnoconv('CronCannotLoadObject', $this->classesname, $this->objectname);
1228  }
1229  dol_syslog(get_class($this)."::run_jobs ".$this->error, LOG_ERR);
1230  $this->lastoutput = $this->error;
1231  $this->lastresult = -1;
1232  $retval = $this->lastresult;
1233  $error++;
1234  }
1235  }
1236 
1237  // test if method exists
1238  if (!$error) {
1239  if (!method_exists($this->objectname, $this->methodename)) {
1240  $this->error = $langs->transnoentitiesnoconv('CronMethodDoesNotExists', $this->objectname, $this->methodename);
1241  dol_syslog(get_class($this)."::run_jobs ".$this->error, LOG_ERR);
1242  $this->lastoutput = $this->error;
1243  $this->lastresult = -1;
1244  $retval = $this->lastresult;
1245  $error++;
1246  }
1247  if (in_array(strtolower(trim($this->methodename)), array('executecli'))) {
1248  $this->error = $langs->transnoentitiesnoconv('CronMethodNotAllowed', $this->methodename, $this->objectname);
1249  dol_syslog(get_class($this)."::run_jobs ".$this->error, LOG_ERR);
1250  $this->lastoutput = $this->error;
1251  $this->lastresult = -1;
1252  $retval = $this->lastresult;
1253  $error++;
1254  }
1255  }
1256 
1257  // Load langs
1258  if (!$error) {
1259  $result = $langs->load($this->module_name);
1260  $result = $langs->load($this->module_name.'@'.$this->module_name, 0, 0, '', 0, 1);
1261 
1262  if ($result < 0) { // If technical error
1263  dol_syslog(get_class($this)."::run_jobs Cannot load module lang file - ".$langs->error, LOG_ERR);
1264  $this->error = $langs->error;
1265  $this->lastoutput = $this->error;
1266  $this->lastresult = -1;
1267  $retval = $this->lastresult;
1268  $error++;
1269  }
1270  }
1271 
1272  if (!$error) {
1273  dol_syslog(get_class($this)."::run_jobs START ".$this->objectname."->".$this->methodename."(".$this->params.");", LOG_DEBUG);
1274 
1275  // Create Object for the called module
1276  $nameofclass = $this->objectname;
1277  $object = new $nameofclass($this->db);
1278  if ($this->entity > 0) {
1279  $object->entity = $this->entity; // We work on a dedicated entity
1280  }
1281 
1282  $params_arr = array();
1283  if (!empty($this->params) || $this->params === '0') {
1284  $params_arr = array_map('trim', explode(",", $this->params));
1285  }
1286 
1287  if (!is_array($params_arr)) {
1288  $result = call_user_func(array($object, $this->methodename), $this->params);
1289  } else {
1290  $result = call_user_func_array(array($object, $this->methodename), $params_arr);
1291  }
1292 
1293  if ($result === false || (!is_bool($result) && $result != 0)) {
1294  $langs->load("errors");
1295 
1296  $errmsg = '';
1297  if (!is_array($object->errors) || !in_array($object->error, $object->errors)) {
1298  $errmsg .= $object->error;
1299  }
1300  if (is_array($object->errors) && count($object->errors)) {
1301  $errmsg .= (($errmsg ? ', ' : '').join(', ', $object->errors));
1302  }
1303  if (empty($errmsg)) {
1304  $errmsg = $langs->trans('ErrorUnknown');
1305  }
1306 
1307  dol_syslog(get_class($this)."::run_jobs END result=".$result." error=".$errmsg, LOG_ERR);
1308 
1309  $this->error = $errmsg;
1310  $this->lastoutput = (!empty($object->output) ? $object->output."\n" : "").$errmsg;
1311  $this->lastresult = is_numeric($result) ? $result : -1;
1312  $retval = $this->lastresult;
1313  $error++;
1314  } else {
1315  dol_syslog(get_class($this)."::run_jobs END");
1316  $this->lastoutput = (!empty($object->output) ? $object->output : "");
1317  $this->lastresult = var_export($result, true);
1318  $retval = $this->lastresult;
1319  }
1320  }
1321  }
1322 
1323  if ($this->jobtype == 'function') {
1324  //load lib
1325  $libpath = '/'.strtolower($this->module_name).'/lib/'.$this->libname;
1326  $ret = dol_include_once($libpath);
1327  if ($ret === false) {
1328  $this->error = $langs->trans('CronCannotLoadLib').': '.$libpath;
1329  dol_syslog(get_class($this)."::run_jobs ".$this->error, LOG_ERR);
1330  $conf->setEntityValues($this->db, $savcurrententity);
1331  return -1;
1332  }
1333 
1334  // Load langs
1335  $result = $langs->load($this->module_name);
1336  $result = $langs->load($this->module_name.'@'.$this->module_name); // If this->module_name was an existing language file, this will make nothing
1337  if ($result < 0) { // If technical error
1338  dol_syslog(get_class($this)."::run_jobs Cannot load module langs".$langs->error, LOG_ERR);
1339  $conf->setEntityValues($this->db, $savcurrententity);
1340  return -1;
1341  }
1342 
1343  dol_syslog(get_class($this)."::run_jobs ".$this->libname."::".$this->methodename."(".$this->params.");", LOG_DEBUG);
1344  $params_arr = explode(", ", $this->params);
1345  if (!is_array($params_arr)) {
1346  $result = call_user_func($this->methodename, $this->params);
1347  } else {
1348  $result = call_user_func_array($this->methodename, $params_arr);
1349  }
1350 
1351  if ($result === false || (!is_bool($result) && $result != 0)) {
1352  $langs->load("errors");
1353  dol_syslog(get_class($this)."::run_jobs result=".$result, LOG_ERR);
1354  $this->error = $langs->trans('ErrorUnknown');
1355  $this->lastoutput = $this->error;
1356  $this->lastresult = is_numeric($result) ? $result : -1;
1357  $retval = $this->lastresult;
1358  $error++;
1359  } else {
1360  $this->lastoutput = var_export($result, true);
1361  $this->lastresult = var_export($result, true); // Return code
1362  $retval = $this->lastresult;
1363  }
1364  }
1365 
1366  // Run a command line
1367  if ($this->jobtype == 'command') {
1368  global $dolibarr_cron_allow_cli;
1369 
1370  if (empty($dolibarr_cron_allow_cli)) {
1371  $langs->load("errors");
1372  $this->error = $langs->trans("FailedToExecutCommandJob");
1373  $this->lastoutput = '';
1374  $this->lastresult = $langs->trans("ErrorParameterMustBeEnabledToAllwoThisFeature", 'dolibarr_cron_allow_cli');
1375  } else {
1376  $outputdir = $conf->cron->dir_temp;
1377  if (empty($outputdir)) {
1378  $outputdir = $conf->cronjob->dir_temp;
1379  }
1380 
1381  if (!empty($outputdir)) {
1382  dol_mkdir($outputdir);
1383  $outputfile = $outputdir.'/cronjob.'.$userlogin.'.out'; // File used with popen method
1384 
1385  // Execute a CLI
1386  include_once DOL_DOCUMENT_ROOT.'/core/class/utils.class.php';
1387  $utils = new Utils($this->db);
1388  $arrayresult = $utils->executeCLI($this->command, $outputfile);
1389 
1390  $retval = $arrayresult['result'];
1391  $this->error = $arrayresult['error'];
1392  $this->lastoutput = $arrayresult['output'];
1393  $this->lastresult = $arrayresult['result'];
1394  }
1395  }
1396  }
1397 
1398  dol_syslog(get_class($this)."::run_jobs now we update job to track it is finished (with success or error)");
1399 
1400  $this->datelastresult = dol_now();
1401  $this->processing = 0;
1402  $this->pid = null;
1403  $result = $this->update($user); // This include begin/commit
1404  if ($result < 0) {
1405  dol_syslog(get_class($this)."::run_jobs ".$this->error, LOG_ERR);
1406  $conf->setEntityValues($this->db, $savcurrententity);
1407  return -1;
1408  }
1409 
1410  $conf->setEntityValues($this->db, $savcurrententity);
1411 
1412  if ($error && !empty($this->email_alert)) {
1413  include_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php';
1414  $subject = $langs->trans("ErrorInBatch", $this->label);
1415  $msg = $langs->trans("ErrorInBatch", $this->label);
1416  $from = getDolGlobalString('MAIN_MAIL_EMAIL_FROM');
1417  $cmailfile = new CMailFile($subject, $this->email_alert, $from, $msg);
1418  $result = $cmailfile->sendfile(); // Do not test result
1419  }
1420 
1421  return $error ?-1 : 1;
1422  }
1423 
1424 
1425  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1433  public function reprogram_jobs($userlogin, $now)
1434  {
1435  // phpcs:enable
1436  dol_syslog(get_class($this)."::reprogram_jobs userlogin:$userlogin", LOG_DEBUG);
1437 
1438  require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php';
1439  $user = new User($this->db);
1440  $result = $user->fetch('', $userlogin);
1441  if ($result < 0) {
1442  $this->error = "User Error : ".$user->error;
1443  dol_syslog(get_class($this)."::reprogram_jobs ".$this->error, LOG_ERR);
1444  return -1;
1445  } else {
1446  if (empty($user->id)) {
1447  $this->error = " User user login:".$userlogin." do not exists";
1448  dol_syslog(get_class($this)."::reprogram_jobs ".$this->error, LOG_ERR);
1449  return -1;
1450  }
1451  }
1452 
1453  dol_syslog(get_class($this)."::reprogram_jobs datenextrun=".$this->datenextrun." ".dol_print_date($this->datenextrun, 'dayhourrfc')." frequency=".$this->frequency." unitfrequency=".$this->unitfrequency, LOG_DEBUG);
1454 
1455  if (empty($this->datenextrun)) {
1456  if (empty($this->datestart)) {
1457  if ($this->unitfrequency == 2678400) {
1458  $this->datenextrun = dol_time_plus_duree($now, $this->frequency, 'm');
1459  } else {
1460  $this->datenextrun = $now + ($this->frequency * $this->unitfrequency);
1461  }
1462  } else {
1463  if ($this->unitfrequency == 2678400) {
1464  $this->datenextrun = dol_time_plus_duree($this->datestart, $this->frequency, 'm');
1465  } else {
1466  $this->datenextrun = $this->datestart + ($this->frequency * $this->unitfrequency);
1467  }
1468  }
1469  }
1470 
1471  if ($this->datenextrun < $now && $this->frequency > 0 && $this->unitfrequency > 0) {
1472  // Loop until date is after future
1473  while ($this->datenextrun < $now) {
1474  if ($this->unitfrequency == 2678400) {
1475  $this->datenextrun = dol_time_plus_duree($this->datenextrun, $this->frequency, 'm');
1476  } else {
1477  $this->datenextrun += ($this->frequency * $this->unitfrequency);
1478  }
1479  }
1480  } else {
1481  dol_syslog(get_class($this)."::reprogram_jobs datenextrun is already in future, we do not change it");
1482  }
1483 
1484 
1485  // Archive job
1486  if ($this->autodelete == 2) {
1487  if (($this->maxrun > 0 && ($this->nbrun >= $this->maxrun))
1488  || ($this->dateend && ($this->datenextrun > $this->dateend))) {
1489  $this->status = self::STATUS_ARCHIVED;
1490  dol_syslog(get_class($this)."::reprogram_jobs Job will be set to archived", LOG_ERR);
1491  }
1492  }
1493 
1494  $result = $this->update($user);
1495  if ($result < 0) {
1496  dol_syslog(get_class($this)."::reprogram_jobs ".$this->error, LOG_ERR);
1497  return -1;
1498  }
1499 
1500  return 1;
1501  }
1502 
1509  public function getLibStatut($mode = 0)
1510  {
1511  return $this->LibStatut($this->status, $mode, $this->processing, $this->lastresult);
1512  }
1513 
1514  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1524  public function LibStatut($status, $mode = 0, $processing = 0, $lastresult = 0)
1525  {
1526  // phpcs:enable
1527  $this->labelStatus = array(); // Force reset o array because label depends on other fields
1528  $this->labelStatusShort = array();
1529 
1530  if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
1531  global $langs;
1532  $langs->load('users');
1533 
1534  $moretext = '';
1535  if ($processing) {
1536  $moretext = ' ('.$langs->trans("Running").')';
1537  } elseif ($lastresult) {
1538  $moretext .= ' ('.$langs->trans("Error").')';
1539  }
1540 
1541  $this->labelStatus[self::STATUS_DISABLED] = $langs->transnoentitiesnoconv('Disabled').$moretext;
1542  $this->labelStatus[self::STATUS_ENABLED] = $langs->transnoentitiesnoconv('Scheduled').$moretext;
1543  $this->labelStatusShort[self::STATUS_DISABLED] = $langs->transnoentitiesnoconv('Disabled');
1544  $this->labelStatusShort[self::STATUS_ENABLED] = $langs->transnoentitiesnoconv('Scheduled');
1545  }
1546 
1547  $statusType = 'status4';
1548  if ($status == 1 && $processing) {
1549  $statusType = 'status1';
1550  }
1551  if ($status == 0) {
1552  $statusType = 'status5';
1553  }
1554  if ($this->lastresult) {
1555  $statusType = 'status8';
1556  }
1557 
1558  return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusType, $mode);
1559  }
1560 }
1561 
1562 
1567 {
1568 
1572  public $id;
1573 
1574  public $entity;
1575 
1579  public $ref;
1580 
1581  public $tms = '';
1582  public $datec = '';
1583 
1587  public $label;
1588 
1589  public $jobtype;
1590  public $command;
1591  public $classesname;
1592  public $objectname;
1593  public $methodename;
1594  public $params;
1595  public $md5params;
1596  public $module_name;
1597  public $priority;
1598  public $datelastrun = '';
1599  public $datenextrun = '';
1600  public $dateend = '';
1601  public $datestart = '';
1602  public $datelastresult = '';
1603  public $lastresult = '';
1604  public $lastoutput;
1605  public $unitfrequency;
1606  public $frequency;
1607  public $processing;
1608 
1612  public $status;
1613 
1617  public $fk_user_author;
1618 
1622  public $fk_user_mod;
1623 
1624  public $note;
1625  public $note_private;
1626  public $nbrun;
1627  public $libname;
1628  public $test;
1629 
1634  public function __construct()
1635  {
1636  return 1;
1637  }
1638 }
$object ref
Definition: info.php:78
Class to send emails (with attachments or not) Usage: $mailfile = new CMailFile($subject,...
Parent class of all other business classes (invoices, contracts, proposals, orders,...
Cron Job class.
getNomUrl($withpicto=0, $option='', $notooltip=0, $morecss='', $save_lastsearch_value=-1)
Return a link to the object card (with optionaly the picto)
createFromClone(User $user, $fromid)
Load an object from its id and create a new one in database.
update($user=null, $notrigger=0)
Update object into database.
fetch($id, $objectname='', $methodname='')
Load object in memory from the database.
info($id)
Load object information.
getLibStatut($mode=0)
Return label of status of user (active, inactive)
initAsSpecimen()
Initialise object with example values Id must be 0 if object instance is a specimen.
fetchAll($sortorder='DESC', $sortfield='t.rowid', $limit=0, $offset=0, $status=1, $filter='', $processing=-1)
Load list of cron jobs in a memory array from the database @TODO Use object CronJob and not CronJobLi...
LibStatut($status, $mode=0, $processing=0, $lastresult=0)
Return label of a giver status.
run_jobs($userlogin)
Run a job.
reprogram_jobs($userlogin, $now)
Reprogram a job.
getTooltipContentArray($params)
getTooltipContentArray
create($user, $notrigger=0)
Create object into database.
__construct($db)
Constructor.
Crob Job line class.
__construct()
Constructor.
Class to manage Dolibarr users.
Definition: user.class.php:48
Class to manage utility methods.
Definition: utils.class.php:31
if(isModEnabled('facture') && $user->hasRight('facture', 'lire')) if((isModEnabled('fournisseur') &&empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) && $user->hasRight("fournisseur", "facture", "lire"))||(isModEnabled('supplier_invoice') && $user->hasRight("supplier_invoice", "lire"))) if(isModEnabled('don') && $user->hasRight('don', 'lire')) if(isModEnabled('tax') &&!empty($user->rights->tax->charges->lire)) if(isModEnabled('facture') &&isModEnabled('commande') && $user->hasRight("commande", "lire") &&empty($conf->global->WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER)) $sql
Social contributions to pay.
Definition: index.php:746
dol_time_plus_duree($time, $duration_value, $duration_unit, $ruleforendofmonth=0)
Add a delay to a date.
Definition: date.lib.php:122
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0)
Show a picto called object_picto (generic function)
dol_strlen($string, $stringencoding='UTF-8')
Make a strlen call.
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs='', $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
if(!function_exists('dol_getprefix')) dol_include_once($relpath, $classname='')
Make an include_once using default root and alternate root if it fails.
dol_now($mode='auto')
Return date for now.
getDolGlobalInt($key, $default=0)
Return dolibarr global constant int value.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
dolGetStatus($statusLabel='', $statusLabelShort='', $html='', $statusType='status0', $displayMode=0, $url='', $params=array())
Output the badge of a status.
getDolGlobalString($key, $default='')
Return dolibarr global constant string value.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
dol_mkdir($dir, $dataroot='', $newmask='')
Creation of a directory (this can create recursive subdir)
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags='', $escapeonlyhtmltags=0, $cleanalsojavascript=0)
Returns text escaped for inclusion in HTML alt or title or value tags, or into values of HTML input f...