source: trunk/phpgwapi/inc/class.asyncservice.inc.php @ 2

Revision 2, 21.1 KB checked in by niltonneto, 17 years ago (diff)

Removida todas as tags usadas pelo CVS ($Id, $Source).
Primeira versão no CVS externo.

  • Property svn:eol-style set to native
  • Property svn:executable set to *
Line 
1<?php
2        /**************************************************************************\
3        * phpGroupWare API - Timed Asynchron Services for eGroupWare               *
4        * Written by Ralf Becker <RalfBecker@outdoor-training.de>                  *
5        * Class for creating cron-job like timed calls of eGroupWare methods       *
6        * -------------------------------------------------------------------------*
7        * This library is part of the eGroupWare API                               *
8        * http://www.eGroupWare.org                                                *
9        * ------------------------------------------------------------------------ *
10        *  This program is free software; you can redistribute it and/or modify it *
11        *  under the terms of the GNU General Public License as published by the   *
12        *  Free Software Foundation; either version 2 of the License, or (at your  *
13        *  option) any later version.                                              *
14        \**************************************************************************/
15
16
17        /*!
18        @class asyncservice
19        @author Ralf Becker
20        @copyright GPL - GNU General Public License
21        @abstract The class implements a general eGW service to execute callbacks at a given time.
22        @discussion see http://www.egroupware.org/wiki/TimedAsyncServices
23        */
24        class asyncservice
25        {
26                var $public_functions = array(
27                        'set_timer' => True,
28                        'check_run' => True,
29                        'cancel_timer' => True,
30                        'read'      => True,
31                        'install'   => True,
32                        'installed' => True,
33                        'last_check_run' => True
34                );
35                var $php = '';
36                var $crontab = '';
37                var $db;
38                var $db_table = 'phpgw_async';
39                var $debug = 0;
40               
41                /*!
42                @function asyncservice
43                @abstract constructor of the class
44                */
45                function asyncservice()
46                {
47                        $this->db = $GLOBALS['phpgw']->db;
48                               
49                        $this->cronline = PHPGW_SERVER_ROOT . '/phpgwapi/cron/asyncservices.php '.$GLOBALS['phpgw_info']['user']['domain'];
50                       
51                        $this->only_fallback = substr(php_uname(), 0, 7) == "Windows";  // atm cron-jobs dont work on win
52                }
53
54                /*!
55                @function set_timer
56                @abstract calculates the next run of the timer and puts that with the rest of the data in the db for later execution.
57                @syntax set_timer($times,$id,$method,$data,$account_id=False)
58                @param $times unix timestamp or array('min','hour','dow','day','month','year') with execution time.
59                        Repeated events are possible to shedule by setting the array only partly, eg.
60                        array('day' => 1) for first day in each month 0am or array('min' => '* /5', 'hour' => '9-17')
61                        for every 5mins in the time from 9am to 5pm.
62                @param $id unique id to cancel the request later, if necessary. Should be in a form like
63                        eg. '<app><id>X' where id is the internal id of app and X might indicate the action.
64                @param $method Method to be called via ExecMethod($method,$data). $method has the form
65                        '<app>.<class>.<public function>'.
66                @param $data This data is passed back when the method is called. It might simply be an
67                        integer id, but it can also be a complete array.
68                @param $account_id account_id, under which the methode should be called or False for the actual user
69                @result False if $id already exists, else True 
70                */
71                function set_timer($times,$id,$method,$data,$account_id=False)
72                {
73                        if (empty($id) || empty($method) || $this->read($id) ||
74                            !($next = $this->next_run($times)))
75                        {
76                                return False;
77                        }
78                        if ($account_id === False)
79                        {
80                                $account_id = $GLOBALS['phpgw_info']['user']['account_id'];
81                        }
82                        $job = array(
83                                'id'     => $id,
84                                'next'   => $next,
85                                'times'  => $times,
86                                'method' => $method,
87                                'data'   => $data,
88                                'account_id' => $account_id
89                        );
90                        $this->write($job);
91                       
92                        return True;
93                }
94
95                /*!
96                @function next_run
97                @abstract calculates the next execution time for $times
98                @syntax next_run($times)
99                @param $times unix timestamp or array('year'=>$year,'month'=>$month,'dow'=>$dow,'day'=>$day,'hour'=>$hour,'min'=>$min)
100                        with execution time. Repeated execution is possible to shedule by setting the array only partly,
101                        eg. array('day' => 1) for first day in each month 0am or array('min' => '/5', 'hour' => '9-17')
102                        for every 5mins in the time from 9am to 5pm. All not set units before the smallest one set,
103                        are taken into account as every possible value, all after as the smallest possible value.
104                @param $debug if True some debug-messages about syntax-errors in $times are echoed
105                @result a unix timestamp of the next execution time or False if no more executions
106                */
107                function next_run($times,$debug=False)
108                {
109                        if ($this->debug)
110                        {
111                                echo "<p>next_run("; print_r($times); ",'$debug')</p>\n";
112                                $debug = True;  // enable syntax-error messages too
113                        }
114                        $now = time();
115                       
116                        // $times is unix timestamp => if it's not expired return it, else False
117                        //
118                        if (!is_array($times)) 
119                        {
120                                $next = (int)$times;
121
122                                return $next > $now ? $next : False;
123                        }
124                        // If an array is given, we have to enumerate the possible times first
125                        //
126                        $units = array(
127                                'year'  => 'Y',
128                                'month' => 'm',
129                                'day'   => 'd',
130                                'dow'   => 'w',
131                                'hour'  => 'H',
132                                'min'   => 'i'
133                        );
134                        $max_unit = array(
135                                'min'   => 59,
136                                'hour'  => 23,
137                                'dow'   => 6,
138                                'day'   => 31,
139                                'month' => 12,
140                                'year'  => date('Y')+10 // else */[0-9] would never stop returning numbers
141                        );
142                        $min_unit = array(
143                                'min'   => 0,
144                                'hour'  => 0,
145                                'dow'   => 0,
146                                'day'   => 1,
147                                'month' => 1,
148                                'year'  => date('Y')
149                        );
150
151                        // get the number of the first and last pattern set in $times,
152                        // as empty patterns get enumerated before the the last pattern and
153                        // get set to the minimum after
154                        //
155                        $n = $first_set = $last_set = 0;
156                        foreach($units as $u => $date_pattern)
157                        {
158                                ++$n;
159                                if (isset($times[$u]))
160                                {
161                                        $last_set = $n;
162
163                                        if (!$first_set)
164                                        {
165                                                $first_set = $n;
166                                        }
167                                }
168                        }
169
170                        // now we go through all units and enumerate all patterns and not set patterns
171                        // (as descript above), enumerations are arrays with unit-values as keys
172                        //
173                        $n = 0;
174                        foreach($units as $u => $date_pattern)
175                        {
176                                ++$n;
177                                if ($this->debug) { echo "<p>n=$n, $u: isset(times[$u]="; print_r($times[$u]); echo ")=".(isset($times[$u])?'True':'False')."</p>\n"; }
178                                if (isset($times[$u]))
179                                {
180                                        $time = explode(',',$times[$u]);
181
182                                        $times[$u] = array();
183
184                                        foreach($time as $t)
185                                        {
186                                                if (strstr($t,'-') !== False && strstr($t,'/') === False)
187                                                {
188                                                        list($min,$max) = $arr = explode('-',$t);
189                                                       
190                                                        if (count($arr) != 2 || !is_numeric($min) || !is_numeric($max) || $min > $max)
191                                                        {
192                                                                if ($debug) echo "<p>Syntax error in $u='$t', allowed is 'min-max', min <= max, min='$min', max='$max'</p>\n";
193
194                                                                return False;
195                                                        }
196                                                        for ($i = (int)$min; $i <= $max; ++$i)
197                                                        {
198                                                                $times[$u][$i] = True;
199                                                        }
200                                                }
201                                                else
202                                                {
203                                                        if ($t == '*') $t = '*/1';
204
205                                                        list($one,$inc) = $arr = explode('/',$t);
206                                                       
207                                                        if (!(is_numeric($one) && count($arr) == 1 ||
208                                                              count($arr) == 2 && is_numeric($inc)))
209                                                        {
210                                                                if ($debug) echo "<p>Syntax error in $u='$t', allowed is a number or '{*|range}/inc', inc='$inc'</p>\n";
211
212                                                                return False;
213                                                        }
214                                                        if (count($arr) == 1)
215                                                        {
216                                                                $times[$u][(int)$one] = True;
217                                                        }
218                                                        else
219                                                        {
220                                                                list($min,$max) = $arr = explode('-',$one);
221                                                                if (empty($one) || $one == '*')
222                                                                {
223                                                                        $min = $min_unit[$u];
224                                                                        $max = $max_unit[$u];
225                                                                }
226                                                                elseif (count($arr) != 2 || $min > $max)
227                                                                {
228                                                                        if ($debug) echo "<p>Syntax error in $u='$t', allowed is '{*|min-max}/inc', min='$min',max='$max', inc='$inc'</p>\n";
229                                                                        return False;
230                                                                }
231                                                                for ($i = $min; $i <= $max; $i += $inc)
232                                                                {
233                                                                        $times[$u][$i] = True;
234                                                                }
235                                                        }
236                                                }
237                                        }
238                                }
239                                elseif ($n < $last_set || $u == 'dow')  // before last value set (or dow) => empty gets enumerated
240                                {
241                                        for ($i = $min_unit[$u]; $i <= $max_unit[$u]; ++$i)
242                                        {
243                                                $times[$u][$i] = True;
244                                        }
245                                }
246                                else    // => after last value set => empty is min-value
247                                {
248                                        $times[$u][$min_unit[$u]] = True;
249                                }
250                        }
251                        if ($this->debug) { echo "enumerated times=<pre>"; print_r($times); echo "</pre>\n"; }
252                       
253                        // now we have the times enumerated, lets find the first not expired one
254                        //
255                        $found = array();
256                        while (!isset($found['min']))
257                        {
258                                $future = False;
259
260                                foreach($units as $u => $date_pattern)
261                                {
262                                        $unit_now = $u != 'dow' ? (int)date($date_pattern) :
263                                                (int)date($date_pattern,mktime(12,0,0,$found['month'],$found['day'],$found['year']));
264
265                                        if (isset($found[$u]))
266                                        {
267                                                $future = $future || $found[$u] > $unit_now;
268                                                if ($this->debug) echo "--> already have a $u = ".$found[$u].", future='$future'<br>\n";
269                                                continue;       // already set
270                                        }
271                                        foreach($times[$u] as $unit_value => $nul)
272                                        {
273                                                switch($u)
274                                                {
275                                                        case 'dow':
276                                                                $valid = $unit_value == $unit_now;
277                                                                break;
278                                                        case 'min':
279                                                                $valid = $future || $unit_value > $unit_now;
280                                                                break;
281                                                        default:
282                                                                $valid = $future || $unit_value >= $unit_now;
283                                                                break;
284                                                       
285                                                }
286                                                if ($valid && ($u != $next || $unit_value > $over))      // valid and not over
287                                                {
288                                                        $found[$u] = $unit_value;
289                                                        $future = $future || $unit_value > $unit_now;
290                                                        break;
291                                                }
292                                        }
293                                        if (!isset($found[$u]))         // we have to try the next one, if it exists
294                                        {
295                                                $next = array_keys($units);
296                                                if (!isset($next[count($found)-1]))
297                                                {
298                                                        if ($this->debug) echo "<p>Nothing found, exiting !!!</p>\n";
299                                                        return False;                                                   
300                                                }
301                                                $next = $next[count($found)-1];
302                                                $over = $found[$next];
303                                                unset($found[$next]);
304                                                if ($this->debug) echo "<p>Have to try the next $next, $u's are over for $next=$over !!!</p>\n";
305                                                break;
306                                        }
307                                }
308                        }
309                        if ($this->debug) { echo "<p>next="; print_r($found); echo "</p>\n"; }
310
311                        return mktime($found['hour'],$found['min'],0,$found['month'],$found['day'],$found['year']);
312                }
313
314                /*!
315                @function cancel_timer
316                @abstract cancels a timer
317                @syntax cancel_timer($id)
318                @param $id has to be the one used to set it.
319                @result True if the timer exists and is not expired.
320                */
321                function cancel_timer($id)
322                {
323                        return $this->delete($id);
324                }
325
326                /*!
327                @function last_check_run
328                @abstract checks when the last check_run was run or set the run-semaphore if $semaphore == True
329                @param $semaphore if False only check, if true try to set/release the semaphore
330                @param $release if $semaphore == True, tells if we should set or release the semaphore
331                @result if !$set array('start' => $start,'end' => $end) with timestamps of last check_run start and end,  \
332                        !$end means check_run is just running. If $set returns True if it was able to get the semaphore, else False
333                */
334                function last_check_run($semaphore=False,$release=False,$run_by='')
335                {
336                        //echo "<p>last_check_run(semaphore=".($semaphore?'True':'False').",release=".($release?'True':'False').")</p>\n";
337                        if ($semaphore)
338                        {
339                                $this->db->lock($this->db_table,'write');       // this will block til we get exclusive access to the table
340
341                                @set_time_limit(0);             // dont stop for an execution-time-limit
342                                ignore_user_abort(True);
343                        }
344                        if ($exists = $this->read('##last-check-run##'))
345                        {
346                                list(,$last_run) = each($exists);
347                        }
348                        //echo "last_run (from db)=<pre>"; print_r($last_run); echo "</pre>\n";
349
350                        if (!$semaphore)
351                        {
352                                return $last_run['data'];
353                        }
354                        //elseif (!$release && !$last_run['data']['end'] && $last_run['data']['start'] > time()-600)
355                        elseif (!$release && !$last_run['data']['end'])
356                        {
357                                // already one instance running (started not more then 10min ago, else we ignore it)
358
359                                $this->db->unlock();    // unlock the table again
360
361                                //echo "<p>An other instance is running !!!</p>\n";
362                                //return False;
363                        }
364                        // no other instance runs ==> we should run
365                        //
366                        if ($release)
367                        {
368                                $last_run['data']['end'] = time();
369                        }
370                        else
371                        {
372                                $last_run = array(
373                                        'id'     => '##last-check-run##',
374                                        'next'   => 0,
375                                        'times'  => array(),
376                                        'method' => 'none',
377                                        'data'   => array(
378                                                'run_by'=> $run_by,
379                                                'start' => time(),
380                                                'end'   => 0
381                                        )
382                                );
383                        }
384                        //echo "last_run=<pre>"; print_r($last_run); echo "</pre>\n";
385                        $this->write($last_run,!!$exits);
386                       
387                        $this->db->unlock();
388
389                        return True;
390                }
391
392                /*!
393                @function check_run
394                @abstract checks if there are any jobs ready to run (timer expired) and executes them
395                */
396                function check_run($run_by='')
397                {
398                        flush();
399                       
400                        if (!$this->last_check_run(True,False,$run_by))
401                        {
402                                return False;   // cant obtain semaphore
403                        }
404                        if ($jobs = $this->read())
405                        {
406                                foreach($jobs as $id => $job)
407                                {
408                                        // checking / setting up phpgw_info/user
409                                        //
410                                        if ($GLOBALS['phpgw_info']['user']['account_id'] != $job['account_id'])
411                                        {
412                                                $domain = $GLOBALS['phpgw_info']['user']['domain'];
413                                                $lang   = $GLOBALS['phpgw_info']['user']['preferences']['common']['lang'];
414                                                unset($GLOBALS['phpgw_info']['user']);
415
416                                                if ($GLOBALS['phpgw']->session->account_id = $job['account_id'])
417                                                {
418                                                        $GLOBALS['phpgw']->session->account_lid = $GLOBALS['phpgw']->accounts->id2name($job['account_id']);
419                                                        $GLOBALS['phpgw']->session->account_domain = $domain;
420                                                        $GLOBALS['phpgw']->session->read_repositories(False,False);
421                                                        $GLOBALS['phpgw_info']['user']  = $GLOBALS['phpgw']->session->user;
422                                                       
423                                                        if ($lang != $GLOBALS['phpgw_info']['user']['preferences']['common']['lang'])
424                                                        {
425                                                                unset($GLOBALS['lang']);
426                                                                $GLOBALS['phpgw']->translation->add_app('common');
427                                                        }
428                                                }
429                                                else
430                                                {
431                                                        $GLOBALS['phpgw_info']['user']['domain'] = $domain;
432                                                }
433                                        }
434                                        list($app) = explode('.',$job['method']);
435                                        $GLOBALS['phpgw']->translation->add_app($app);
436
437                                        ExecMethod($job['method'],$job['data']);
438
439                                        // re-read job, in case it had been updated or even deleted in the method
440                                        $updated = $this->read($id);
441                                        if ($updated && isset($updated[$id]))
442                                        {
443                                                $job = $updated[$id];
444                                               
445                                                if ($job['next'] = $this->next_run($job['times']))
446                                                {
447                                                        $this->write($job,True);
448                                                }
449                                                else    // no further runs
450                                                {
451                                                        $this->delete($job['id']);
452                                                }
453                                        }
454                                }
455                        }
456                        $this->last_check_run(True,True,$run_by);       // release semaphore
457
458                        return $jobs ? count($jobs) : False;
459                }
460
461                /*!
462                @function read
463                @abstract reads all matching db-rows / jobs
464                @syntax reay($id=0)
465                @param $id =0 reads all expired rows / jobs ready to run\
466                        != 0 reads all rows/jobs matching $id (sql-wildcards '%' and '_' can be used)
467                @result db-rows / jobs as array or False if no matches
468                */
469                function read($id=0)
470                {
471                        $id = $this->db->db_addslashes($id);
472                        if (strpos($id,'%') !== False || strpos($id,'_') !== False)
473                        {
474                                $where = "id LIKE '$id' AND id!='##last-check-run##'";
475                        }
476                        elseif (!$id)
477                        {
478                                $where = 'next<='.time()." AND id!='##last-check-run##'";
479                        }
480                        else
481                        {
482                                $where = "id='$id'";
483                        }
484                        $this->db->query($sql="SELECT * FROM $this->db_table WHERE $where",__LINE__,__FILE__);
485
486                        $jobs = array();
487                        while ($this->db->next_record())
488                        {
489                                $id = $this->db->f('id');
490
491                                $jobs[$id] = array(
492                                        'id'     => $id,
493                                        'next'   => $this->db->f('next'),
494                                        'times'  => unserialize($this->db->f('times')),
495                                        'method' => $this->db->f('method'),
496                                        'data'   => unserialize($this->db->f('data')),
497                                        'account_id'   => $this->db->f('account_id')
498                                );
499                                //echo "job id='$id'<pre>"; print_r($jobs[$id]); echo "</pre>\n";
500                        }
501                        if (!count($jobs))
502                        {
503                                return False;
504                        }
505                        return $jobs;
506                }
507               
508                /*!
509                @function write
510                @abstract write a job / db-row to the db
511                @syntax write($job,$exists = False)
512                @param $job db-row as array
513                @param $exits if True, we do an update, else we check if update or insert necesary
514                */
515                function write($job,$exists = False)
516                {
517                        $job['times'] = $this->db->db_addslashes(serialize($job['times']));
518                        $job['data']  = $this->db->db_addslashes(serialize($job['data']));
519                        $job['next']  = (int)$job['next'];
520                        $job['account_id']  = (int)$job['account_id'];
521
522                        if ($exists || $this->read($job['id']))
523                        {
524                                $this->db->query("UPDATE $this->db_table SET next=$job[next],times='$job[times]',".
525                                        "method='$job[method]',data='$job[data]',account_id=$job[account_id] WHERE id='$job[id]'",__LINE__,__FILE__);
526                        }
527                        else
528                        {
529                                $this->db->query("INSERT INTO $this->db_table (id,next,times,method,data,account_id) VALUES ".
530                                        "('$job[id]',$job[next],'$job[times]','$job[method]','$job[data]',$job[account_id])",__LINE__,__FILE__);
531                        }
532                }
533
534                /*!
535                @function delete
536                @abstract delete db-row / job with $id
537                @result False if $id not found else True
538                */
539                function delete($id)
540                {
541                        $this->db->query("DELETE FROM $this->db_table WHERE id='$id'",__LINE__,__FILE__);
542
543                        return $this->db->affected_rows();
544                }
545               
546                function find_binarys()
547                {
548                        static $run = False;
549                        if ($run)
550                        {
551                                return;
552                        }
553                        $run = True;
554
555                        if (substr(php_uname(), 0, 7) == "Windows")
556                        {
557                                // ToDo: find php-cgi on windows
558                        }
559                        else
560                        {
561                                $binarys = array(
562                                        'php'  => '/usr/bin/php',
563                                        'php4' => '/usr/bin/php4',              // this is for debian
564                                        'crontab' => '/usr/bin/crontab'
565                                );
566                                foreach ($binarys as $name => $path)
567                                {
568                                        $this->$name = $path;   // a reasonable default for *nix
569
570                                        if (!($Ok = @is_executable($this->$name)))
571                                        {
572                                                if (file_exists($this->$name))
573                                                {
574                                                        echo '<p>'.lang('%1 is not executable by the webserver !!!',$this->$name)."</p>\n";
575                                                        $perms = fileperms($this->$name);
576                                                        if (!($perms & 0x0001) && ($perms & 0x0008))    // only executable by group
577                                                        {
578                                                                $group = posix_getgrgid(filegroup($this->$name));
579                                                                $webserver = posix_getpwuid(posix_getuid ());
580                                                                echo '<p>'.lang("You need to add the webserver user '%1' to the group '%2'.",$webserver['name'],$group['name'])."</p>\n";                                                       }
581                                                }
582                                                if ($fd = popen('/bin/sh -c "type -p '.$name.'"','r'))
583                                                {
584                                                        $this->$name = fgets($fd,256);
585                                                        @pclose($fd);
586                                                }
587                                                if ($pos = strpos($this->$name,"\n"))
588                                                {
589                                                        $this->$name = substr($this->$name,0,$pos);
590                                                }
591                                        }
592                                        if (!$Ok && !@is_executable($this->$name))
593                                        {
594                                                $this->$name = $name;   // hopefully its in the path
595                                        }
596                                        //echo "<p>$name = '".$this->$name."'</p>\n";
597                                }
598                                if ($this->php4[0] == '/')      // we found a php4 binary
599                                {
600                                        $this->php = $this->php4;
601                                }
602                        }
603               
604                }
605               
606                /*!
607                @function installed
608                @abstract checks if phpgwapi/cron/asyncservices.php is installed as cron-job
609                @syntax installed()
610                @result the times asyncservices are run (normaly 'min'=>'* /5') or False if not installed or 0 if crontab not found
611                @note Not implemented for Windows at the moment, always returns 0
612                */
613                function installed()
614                {
615                        if ($this->only_fallback) {
616                                return 0;
617                        }
618                        $this->find_binarys();
619                       
620                        // Nao eh executavel porque esta fora do openbase_dir
621                        /*
622                        if (!is_executable($this->crontab))
623                        {
624                                //echo "<p>Error: $this->crontab not found !!!</p>";
625                                return 0;
626                        }
627                        */
628                       
629                        $times = False;
630                        $this->other_cronlines = array();
631                        if (($crontab = popen('/bin/sh -c "'.$this->crontab.' -l" 2>&1','r')) !== False)
632                        {
633                                while ($line = fgets($crontab,256))
634                                {
635                                        if ($this->debug) echo 'line '.++$n.": $line<br>\n";
636                                        $parts = split(' ',$line,6);
637                                       
638                                        // Foi customizado para a Celepar.
639                                        //if ($line[0] == '#' || count($parts) < 6 || ($parts[5][0] != '/' && substr($parts[5],0,3) != 'php'))
640                                        if ($line[0] == '#' || count($parts) < 6)
641                                        {
642                                                // ignore comments
643                                                if ($line[0] != '#')
644                                                {
645                                                        $times['error'] .= $line;
646                                                }
647                                        }
648                                        elseif (strstr($line,$this->cronline) !== False)
649                                        {
650                                                $cron_units = array('min','hour','day','month','dow');
651                                                foreach($cron_units as $n => $u)
652                                                {
653                                                        $times[$u] = $parts[$n];
654                                                }
655                                                $times['cronline'] = $line;
656                                        }
657                                        else
658                                        {
659                                                $this->other_cronlines[] = $line;
660                                        }
661                                }
662                                @pclose($crontab);
663                        }
664                        return $times;
665                }
666               
667                /*!
668                @function insall
669                @abstract installs /phpgwapi/cron/asyncservices.php as cron-job
670                @syntax install($times)
671                @param $times array with keys 'min','hour','day','month','dow', not set is equal to '*'.
672                        False means de-install our own crontab line
673                @result the times asyncservices are run, False if they are not installed,
674                        0 if crontab not found and ' ' if crontab is deinstalled
675                @note Not implemented for Windows at the moment, always returns 0
676                */
677                function install($times)
678                {
679                        if ($this->only_fallback && $times !== False) {
680                                return 0;
681                        }
682                        $this->installed();     // find other installed cronlines
683
684                        if (($crontab = popen('/bin/sh -c "'.$this->crontab.' -" 2>&1','w')) !== False)
685                        {
686                                if (is_array($this->other_cronlines))
687                                {
688                                        foreach ($this->other_cronlines as $cronline)
689                                        {
690                                                fwrite($crontab,$cronline);             // preserv the other lines on install
691                                        }
692                                }
693                                if ($times !== False)
694                                {
695                                        $cron_units = array('min','hour','day','month','dow');
696                                        $cronline = '';
697                                        foreach($cron_units as $cu)
698                                        {
699                                                $cronline .= (isset($times[$cu]) ? $times[$cu] : '*') . ' ';
700                                        }
701                                        //$cronline .= $this->php.' -q '.$this->cronline."\n";
702                                        $cronline .= "cd /var/www/expresso/phpgwapi/cron/; php4 -c /etc/php4/apache2/php.ini-q /var/www/expresso/phpgwapi/cron/asyncservices.php default\n";
703                                        //echo "<p>Installing: '$cronline'</p>\n";
704                                        fwrite($crontab,$cronline);
705                                }
706                                @pclose($crontab);
707                        }
708                        return $times !== False ? $this->installed() : ' ';
709                }
710        }
Note: See TracBrowser for help on using the repository browser.