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