mirror of
https://github.com/EGroupware/egroupware.git
synced 2025-01-13 01:18:42 +01:00
- added update from version 0.9.14.004-6 (security-fixes) and 0.9.14.508 (asyncservice)
- merged asyncservices from .16
This commit is contained in:
parent
3fcb565374
commit
6ab850d35c
@ -24,19 +24,27 @@
|
|||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
|
|
||||||
$path_to_phpgroupware = '../..'; // need to be adapted if this script is moved somewhere else
|
$path_to_phpgroupware = '../..'; // need to be adapted if this script is moved somewhere else
|
||||||
$GLOBALS['domain'] = 'default';
|
$_GET['domain'] = isset($_SERVER['argv'][1]) ? $_SERVER['argv'][1] : 'default';
|
||||||
|
|
||||||
$GLOBALS['phpgw_info']['flags'] = array(
|
$GLOBALS['phpgw_info']['flags'] = array(
|
||||||
'currentapp' => 'login'
|
'currentapp' => 'login',
|
||||||
|
'noapi' => True // this stops header.inc.php to include phpgwapi/inc/function.inc.php
|
||||||
);
|
);
|
||||||
include($path_to_phpgroupware.'/header.inc.php');
|
include($path_to_phpgroupware.'/header.inc.php');
|
||||||
|
unset($GLOBALS['phpgw_info']['flags']['noapi']);
|
||||||
|
|
||||||
$num = ExecMethod('phpgwapi.asyncservice.check_run');
|
$db_type = $GLOBALS['phpgw_domain'][$_GET['domain']]['db_type'];
|
||||||
|
if (!extension_loaded($db_type) && !dl($db_type.'.so'))
|
||||||
|
{
|
||||||
|
echo "Extension '$db_type' is not loaded and can't be loaded via dl('$db_type.so') !!!\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
$GLOBALS['phpgw_info']['server']['sessions_type'] = 'db';
|
||||||
|
|
||||||
|
include(PHPGW_API_INC.'/functions.inc.php');
|
||||||
|
|
||||||
|
$num = ExecMethod('phpgwapi.asyncservice.check_run','crontab');
|
||||||
// if the following comment got removed, you will get an email from cron for every check performed
|
// if the following comment got removed, you will get an email from cron for every check performed
|
||||||
//echo date('Y/m/d H:i:s ').($num ? "$num job(s) executed" : 'Nothing to execute')."\n";
|
//echo date('Y/m/d H:i:s ').$_GET['domain'].': '.($num ? "$num job(s) executed" : 'Nothing to execute')."\n";
|
||||||
|
|
||||||
$GLOBALS['phpgw']->common->phpgw_exit();
|
$GLOBALS['phpgw']->common->phpgw_exit();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -7,21 +7,21 @@
|
|||||||
* This library is part of the phpGroupWare API *
|
* This library is part of the phpGroupWare API *
|
||||||
* http://www.phpgroupware.org/ *
|
* http://www.phpgroupware.org/ *
|
||||||
* ------------------------------------------------------------------------ *
|
* ------------------------------------------------------------------------ *
|
||||||
* This library is free software; you can redistribute it and/or modify it *
|
* This program is free software; you can redistribute it and/or modify it *
|
||||||
* under the terms of the GNU Lesser General Public License as published by *
|
* under the terms of the GNU General Public License as published by the *
|
||||||
* the Free Software Foundation; either version 2.1 of the License, *
|
* Free Software Foundation; either version 2 of the License, or (at your *
|
||||||
* or any later version. *
|
* option) any later version. *
|
||||||
* This library is distributed in the hope that it will be useful, but *
|
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
|
|
||||||
* See the GNU Lesser General Public License for more details. *
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License *
|
|
||||||
* along with this library; if not, write to the Free Software Foundation, *
|
|
||||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
|
|
||||||
\**************************************************************************/
|
\**************************************************************************/
|
||||||
|
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@class asyncservice
|
||||||
|
@author Ralf Becker
|
||||||
|
@copyright GPL - GNU General Public License
|
||||||
|
@abstract The class implements a general phpGW service to execute callbacks at a given time.
|
||||||
|
@discussion see http://www.phpgroupware.org/wiki/TimedAsyncServices
|
||||||
|
*/
|
||||||
class asyncservice
|
class asyncservice
|
||||||
{
|
{
|
||||||
var $public_functions = array(
|
var $public_functions = array(
|
||||||
@ -31,47 +31,62 @@
|
|||||||
'read' => True,
|
'read' => True,
|
||||||
'install' => True,
|
'install' => True,
|
||||||
'installed' => True,
|
'installed' => True,
|
||||||
'test' => True
|
'last_check_run' => True
|
||||||
);
|
);
|
||||||
var $php = '';
|
var $php = '';
|
||||||
var $crontab = '';
|
var $crontab = '';
|
||||||
var $db;
|
var $db;
|
||||||
var $db_table = 'phpgw_async';
|
var $db_table = 'phpgw_async';
|
||||||
|
var $debug = 0;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@function asyncservice
|
||||||
|
@abstract constructor of the class
|
||||||
|
*/
|
||||||
function asyncservice()
|
function asyncservice()
|
||||||
{
|
{
|
||||||
$this->db = $GLOBALS['phpgw']->db;
|
$this->db = $GLOBALS['phpgw']->db;
|
||||||
|
|
||||||
|
$this->cronline = PHPGW_SERVER_ROOT . '/phpgwapi/cron/asyncservices.php '.$GLOBALS['phpgw_info']['user']['domain'];
|
||||||
|
|
||||||
|
$this->only_fallback = substr(php_uname(), 0, 7) == "Windows"; // atm cron-jobs dont work on win
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@function set_timer
|
@function set_timer
|
||||||
@abstract calculates the next run of the timer and puts that with the rest of the data in the db
|
@abstract calculates the next run of the timer and puts that with the rest of the data in the db for later execution.
|
||||||
@syntax set_timer($times,$id,$method,$data)
|
@syntax set_timer($times,$id,$method,$data,$account_id=False)
|
||||||
@param $times unix timestamp or array('min','hour','dow','day','month','year') with execution time. \
|
@param $times unix timestamp or array('min','hour','dow','day','month','year') with execution time.
|
||||||
Repeated events are possible to shedule by setting the array only partly, eg. \
|
Repeated events are possible to shedule by setting the array only partly, eg.
|
||||||
array('day' => 1) for first day in each month 0am or array('min' => '* /5', 'hour' => '9-17') \
|
array('day' => 1) for first day in each month 0am or array('min' => '* /5', 'hour' => '9-17')
|
||||||
for every 5mins in the time from 9am to 5pm.
|
for every 5mins in the time from 9am to 5pm.
|
||||||
@param $id unique id to cancel the request later, if necessary. Should be in a form like \
|
@param $id unique id to cancel the request later, if necessary. Should be in a form like
|
||||||
eg. '<app><id>X' where id is the internal id of app and X might indicate the action.
|
eg. '<app><id>X' where id is the internal id of app and X might indicate the action.
|
||||||
@param $method Method to be called via ExecMethod($method,$data). $method has the form \
|
@param $method Method to be called via ExecMethod($method,$data). $method has the form
|
||||||
'<app>.<class>.<public function>'.
|
'<app>.<class>.<public function>'.
|
||||||
@param $data This data is passed back when the method is called. It might simply be an \
|
@param $data This data is passed back when the method is called. It might simply be an
|
||||||
integer id, but it can also be a complete array.
|
integer id, but it can also be a complete array.
|
||||||
@Returns False if $id already exists, else True
|
@param $account_id account_id, under which the methode should be called or False for the actual user
|
||||||
|
@result False if $id already exists, else True
|
||||||
*/
|
*/
|
||||||
function set_timer($times,$id,$method,$data)
|
function set_timer($times,$id,$method,$data,$account_id=False)
|
||||||
{
|
{
|
||||||
if (empty($id) || empty($method) || $this->read($id) ||
|
if (empty($id) || empty($method) || $this->read($id) ||
|
||||||
!($next = $this->next_run($times)))
|
!($next = $this->next_run($times)))
|
||||||
{
|
{
|
||||||
return False;
|
return False;
|
||||||
}
|
}
|
||||||
|
if ($account_id === False)
|
||||||
|
{
|
||||||
|
$account_id = $GLOBALS['phpgw_info']['user']['account_id'];
|
||||||
|
}
|
||||||
$job = array(
|
$job = array(
|
||||||
'id' => $id,
|
'id' => $id,
|
||||||
'next' => $next,
|
'next' => $next,
|
||||||
'times' => $times,
|
'times' => $times,
|
||||||
'method' => $method,
|
'method' => $method,
|
||||||
'data' => $data
|
'data' => $data,
|
||||||
|
'account_id' => $account_id
|
||||||
);
|
);
|
||||||
$this->write($job);
|
$this->write($job);
|
||||||
|
|
||||||
@ -80,17 +95,23 @@
|
|||||||
|
|
||||||
/*!
|
/*!
|
||||||
@function next_run
|
@function next_run
|
||||||
@abstract calculates the next execution time for $time
|
@abstract calculates the next execution time for $times
|
||||||
@syntax next_run($time)
|
@syntax next_run($times)
|
||||||
@param $times unix timestamp or array('year'=>$year,'month'=>$month,'dow'=>$dow,'day'=>$day,'hour'=>$hour,'min'=>$min) \
|
@param $times unix timestamp or array('year'=>$year,'month'=>$month,'dow'=>$dow,'day'=>$day,'hour'=>$hour,'min'=>$min)
|
||||||
with execution time. Repeated execution is possible to shedule by setting the array only partly, \
|
with execution time. Repeated execution is possible to shedule by setting the array only partly,
|
||||||
eg. array('day' => 1) for first day in each month 0am or array('min' => '/5', 'hour' => '9-17') \
|
eg. array('day' => 1) for first day in each month 0am or array('min' => '/5', 'hour' => '9-17')
|
||||||
for every 5mins in the time from 9am to 5pm. All not set units before the smallest one set, \
|
for every 5mins in the time from 9am to 5pm. All not set units before the smallest one set,
|
||||||
are taken into account as every possible value, all after as the smallest possible value.
|
are taken into account as every possible value, all after as the smallest possible value.
|
||||||
@returns a unix timestamp of the next execution time or False if no more executions
|
@param $debug if True some debug-messages about syntax-errors in $times are echoed
|
||||||
|
@result a unix timestamp of the next execution time or False if no more executions
|
||||||
*/
|
*/
|
||||||
function next_run($times,$debug=False)
|
function next_run($times,$debug=False)
|
||||||
{
|
{
|
||||||
|
if ($this->debug)
|
||||||
|
{
|
||||||
|
echo "<p>next_run("; print_r($times); ",'$debug')</p>\n";
|
||||||
|
$debug = True; // enable syntax-error messages too
|
||||||
|
}
|
||||||
$now = time();
|
$now = time();
|
||||||
|
|
||||||
// $times is unix timestamp => if it's not expired return it, else False
|
// $times is unix timestamp => if it's not expired return it, else False
|
||||||
@ -154,7 +175,7 @@
|
|||||||
foreach($units as $u => $date_pattern)
|
foreach($units as $u => $date_pattern)
|
||||||
{
|
{
|
||||||
++$n;
|
++$n;
|
||||||
//echo "<p>$u: isset(times[$u]="; print_r($times[$u]); echo ")=".(isset($times[$u])?'True':'False')."</p>\n";
|
if ($this->debug) { echo "<p>n=$n, $u: isset(times[$u]="; print_r($times[$u]); echo ")=".(isset($times[$u])?'True':'False')."</p>\n"; }
|
||||||
if (isset($times[$u]))
|
if (isset($times[$u]))
|
||||||
{
|
{
|
||||||
$time = explode(',',$times[$u]);
|
$time = explode(',',$times[$u]);
|
||||||
@ -180,6 +201,8 @@
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if ($t == '*') $t = '*/1';
|
||||||
|
|
||||||
list($one,$inc) = $arr = explode('/',$t);
|
list($one,$inc) = $arr = explode('/',$t);
|
||||||
|
|
||||||
if (!(is_numeric($one) && count($arr) == 1 ||
|
if (!(is_numeric($one) && count($arr) == 1 ||
|
||||||
@ -214,34 +237,38 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
elseif ($n < $last_set) // => empty gets enumerated
|
elseif ($n < $last_set || $u == 'dow') // before last value set (or dow) => empty gets enumerated
|
||||||
{
|
{
|
||||||
for ($i = $min_unit[$u]; $i <= $max_unit[$u]; ++$i)
|
for ($i = $min_unit[$u]; $i <= $max_unit[$u]; ++$i)
|
||||||
{
|
{
|
||||||
$times[$u][$i] = True;
|
$times[$u][$i] = True;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else // => empty is min-value
|
else // => after last value set => empty is min-value
|
||||||
{
|
{
|
||||||
$times[$u][$min_unit[$u]] = True;
|
$times[$u][$min_unit[$u]] = True;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//echo "enumerated times=<pre>"; print_r($times); echo "</pre>\n";
|
if ($this->debug) { echo "enumerated times=<pre>"; print_r($times); echo "</pre>\n"; }
|
||||||
|
|
||||||
// now we have the times enumerated, lets find the first not expired one
|
// now we have the times enumerated, lets find the first not expired one
|
||||||
//
|
//
|
||||||
$found = array();
|
$found = array();
|
||||||
while (!isset($found['min']))
|
while (!isset($found['min']))
|
||||||
{
|
{
|
||||||
$found = array();
|
|
||||||
$future = False;
|
$future = False;
|
||||||
|
|
||||||
$n = 0;
|
|
||||||
foreach($units as $u => $date_pattern)
|
foreach($units as $u => $date_pattern)
|
||||||
{
|
{
|
||||||
$unit_now = $u != 'dow' ? intval(date($date_pattern)) :
|
$unit_now = $u != 'dow' ? intval(date($date_pattern)) :
|
||||||
intval(date($date_pattern,mktime(12,0,0,$found['month'],$found['day'],$found['year'])));
|
intval(date($date_pattern,mktime(12,0,0,$found['month'],$found['day'],$found['year'])));
|
||||||
|
|
||||||
|
if (isset($found[$u]))
|
||||||
|
{
|
||||||
|
$future = $future || $found[$u] > $unit_now;
|
||||||
|
if ($this->debug) echo "--> already have a $u = ".$found[$u].", future='$future'<br>\n";
|
||||||
|
continue; // already set
|
||||||
|
}
|
||||||
foreach($times[$u] as $unit_value => $nul)
|
foreach($times[$u] as $unit_value => $nul)
|
||||||
{
|
{
|
||||||
switch($u)
|
switch($u)
|
||||||
@ -267,21 +294,21 @@
|
|||||||
if (!isset($found[$u])) // we have to try the next one, if it exists
|
if (!isset($found[$u])) // we have to try the next one, if it exists
|
||||||
{
|
{
|
||||||
$next = array_keys($units);
|
$next = array_keys($units);
|
||||||
|
if (!isset($next[count($found)-1]))
|
||||||
if (!isset($next[$n-1]))
|
|
||||||
{
|
{
|
||||||
//echo "<p>Nothing found, exiting !!!</p>\n";
|
if ($this->debug) echo "<p>Nothing found, exiting !!!</p>\n";
|
||||||
return False;
|
return False;
|
||||||
}
|
}
|
||||||
$next = $next[$n-1];
|
$next = $next[count($found)-1];
|
||||||
$over = $found[$next];
|
$over = $found[$next];
|
||||||
//echo "<p>Have to try the next $next, $u's are over for $next=$over !!!</p>\n";
|
unset($found[$next]);
|
||||||
|
if ($this->debug) echo "<p>Have to try the next $next, $u's are over for $next=$over !!!</p>\n";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
$n++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//echo "<p>next="; print_r($found); echo "</p>\n";
|
if ($this->debug) { echo "<p>next="; print_r($found); echo "</p>\n"; }
|
||||||
|
|
||||||
return mktime($found['hour'],$found['min'],0,$found['month'],$found['day'],$found['year']);
|
return mktime($found['hour'],$found['min'],0,$found['month'],$found['day'],$found['year']);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -290,25 +317,122 @@
|
|||||||
@abstract cancels a timer
|
@abstract cancels a timer
|
||||||
@syntax cancel_timer($id)
|
@syntax cancel_timer($id)
|
||||||
@param $id has to be the one used to set it.
|
@param $id has to be the one used to set it.
|
||||||
@returns True if the timer exists and is not expired.
|
@result True if the timer exists and is not expired.
|
||||||
*/
|
*/
|
||||||
function cancel_timer($id)
|
function cancel_timer($id)
|
||||||
{
|
{
|
||||||
return $this->delete($id);
|
return $this->delete($id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@function last_check_run
|
||||||
|
@abstract checks when the last check_run was run or set the run-semaphore if $semaphore == True
|
||||||
|
@param $semaphore if False only check, if true try to set/release the semaphore
|
||||||
|
@param $release if $semaphore == True, tells if we should set or release the semaphore
|
||||||
|
@result if !$set array('start' => $start,'end' => $end) with timestamps of last check_run start and end, \
|
||||||
|
!$end means check_run is just running. If $set returns True if it was able to get the semaphore, else False
|
||||||
|
*/
|
||||||
|
function last_check_run($semaphore=False,$release=False,$run_by='')
|
||||||
|
{
|
||||||
|
//echo "<p>last_check_run(semaphore=".($semaphore?'True':'False').",release=".($release?'True':'False').")</p>\n";
|
||||||
|
if ($semaphore)
|
||||||
|
{
|
||||||
|
$this->db->lock($this->db_table,'write'); // this will block til we get exclusive access to the table
|
||||||
|
|
||||||
|
set_time_limit(0); // dont stop for an execution-time-limit
|
||||||
|
ignore_user_abort(True);
|
||||||
|
}
|
||||||
|
if ($exists = $this->read('##last-check-run##'))
|
||||||
|
{
|
||||||
|
list(,$last_run) = each($exists);
|
||||||
|
}
|
||||||
|
//echo "last_run (from db)=<pre>"; print_r($last_run); echo "</pre>\n";
|
||||||
|
|
||||||
|
if (!$semaphore)
|
||||||
|
{
|
||||||
|
return $last_run['data'];
|
||||||
|
}
|
||||||
|
elseif (!$release && !$last_run['data']['end'] && $last_run['data']['start'] > time()-600)
|
||||||
|
{
|
||||||
|
// already one instance running (started not more then 10min ago, else we ignore it)
|
||||||
|
|
||||||
|
$this->db->unlock(); // unlock the table again
|
||||||
|
|
||||||
|
//echo "<p>An other instance is running !!!</p>\n";
|
||||||
|
return False;
|
||||||
|
}
|
||||||
|
// no other instance runs ==> we should run
|
||||||
|
//
|
||||||
|
if ($release)
|
||||||
|
{
|
||||||
|
$last_run['data']['end'] = time();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$last_run = array(
|
||||||
|
'id' => '##last-check-run##',
|
||||||
|
'next' => 0,
|
||||||
|
'times' => array(),
|
||||||
|
'method' => 'none',
|
||||||
|
'data' => array(
|
||||||
|
'run_by'=> $run_by,
|
||||||
|
'start' => time(),
|
||||||
|
'end' => 0
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
//echo "last_run=<pre>"; print_r($last_run); echo "</pre>\n";
|
||||||
|
$this->write($last_run,!!$exits);
|
||||||
|
|
||||||
|
$this->db->unlock();
|
||||||
|
|
||||||
|
return True;
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@function check_run
|
@function check_run
|
||||||
@abstract checks if there are any jobs ready to run (timer expired) and executes them
|
@abstract checks if there are any jobs ready to run (timer expired) and executes them
|
||||||
*/
|
*/
|
||||||
function check_run()
|
function check_run($run_by='')
|
||||||
{
|
{
|
||||||
if (!($jobs = $this->read()))
|
flush();
|
||||||
|
|
||||||
|
if (!$this->last_check_run(True,False,$run_by))
|
||||||
{
|
{
|
||||||
return False;
|
return False; // cant obtain semaphore
|
||||||
}
|
}
|
||||||
|
if ($jobs = $this->read())
|
||||||
|
{
|
||||||
foreach($jobs as $id => $job)
|
foreach($jobs as $id => $job)
|
||||||
{
|
{
|
||||||
|
// checking / setting up phpgw_info/user
|
||||||
|
//
|
||||||
|
if ($GLOBALS['phpgw_info']['user']['account_id'] != $job['account_id'])
|
||||||
|
{
|
||||||
|
$domain = $GLOBALS['phpgw_info']['user']['domain'];
|
||||||
|
$lang = $GLOBALS['phpgw_info']['user']['preferences']['common']['lang'];
|
||||||
|
unset($GLOBALS['phpgw_info']['user']);
|
||||||
|
|
||||||
|
if ($GLOBALS['phpgw']->session->account_id = $job['account_id'])
|
||||||
|
{
|
||||||
|
$GLOBALS['phpgw']->session->account_lid = $GLOBALS['phpgw']->accounts->id2name($job['account_id']);
|
||||||
|
$GLOBALS['phpgw']->session->account_domain = $domain;
|
||||||
|
$GLOBALS['phpgw']->session->read_repositories(False,False);
|
||||||
|
$GLOBALS['phpgw_info']['user'] = $GLOBALS['phpgw']->session->user;
|
||||||
|
|
||||||
|
if ($lang != $GLOBALS['phpgw_info']['user']['preferences']['common']['lang'])
|
||||||
|
{
|
||||||
|
unset($GLOBALS['lang']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$GLOBALS['phpgw_info']['user']['domain'] = $domain;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
list($app) = explode('.',$job['method']);
|
||||||
|
$GLOBALS['phpgw']->translation->add_app($app);
|
||||||
|
|
||||||
ExecMethod($job['method'],$job['data']);
|
ExecMethod($job['method'],$job['data']);
|
||||||
|
|
||||||
if ($job['next'] = $this->next_run($job['times']))
|
if ($job['next'] = $this->next_run($job['times']))
|
||||||
@ -320,7 +444,10 @@
|
|||||||
$this->delete($job['id']);
|
$this->delete($job['id']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return count($jobs);
|
}
|
||||||
|
$this->last_check_run(True,True,$run_by); // release semaphore
|
||||||
|
|
||||||
|
return $jobs ? count($jobs) : False;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -329,18 +456,18 @@
|
|||||||
@syntax reay($id=0)
|
@syntax reay($id=0)
|
||||||
@param $id =0 reads all expired rows / jobs ready to run\
|
@param $id =0 reads all expired rows / jobs ready to run\
|
||||||
!= 0 reads all rows/jobs matching $id (sql-wildcards '%' and '_' can be used)
|
!= 0 reads all rows/jobs matching $id (sql-wildcards '%' and '_' can be used)
|
||||||
@returns db-rows / jobs as array or False if no matches
|
@result db-rows / jobs as array or False if no matches
|
||||||
*/
|
*/
|
||||||
function read($id=0)
|
function read($id=0)
|
||||||
{
|
{
|
||||||
$id = $this->db->db_addslashes($id);
|
$id = $this->db->db_addslashes($id);
|
||||||
if (strpos($id,'%') !== False || strpos($id,'_') !== False)
|
if (strpos($id,'%') !== False || strpos($id,'_') !== False)
|
||||||
{
|
{
|
||||||
$where = "id LIKE '$id'";
|
$where = "id LIKE '$id' AND id!='##last-check-run##'";
|
||||||
}
|
}
|
||||||
elseif (!$id)
|
elseif (!$id)
|
||||||
{
|
{
|
||||||
$where = 'next<='.time();
|
$where = 'next<='.time()." AND id!='##last-check-run##'";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -358,8 +485,10 @@
|
|||||||
'next' => $this->db->f('next'),
|
'next' => $this->db->f('next'),
|
||||||
'times' => unserialize($this->db->f('times')),
|
'times' => unserialize($this->db->f('times')),
|
||||||
'method' => $this->db->f('method'),
|
'method' => $this->db->f('method'),
|
||||||
'data' => unserialize($this->db->f('data'))
|
'data' => unserialize($this->db->f('data')),
|
||||||
|
'account_id' => $this->db->f('account_id')
|
||||||
);
|
);
|
||||||
|
//echo "job id='$id'<pre>"; print_r($jobs[$id]); echo "</pre>\n";
|
||||||
}
|
}
|
||||||
if (!count($jobs))
|
if (!count($jobs))
|
||||||
{
|
{
|
||||||
@ -379,23 +508,25 @@
|
|||||||
{
|
{
|
||||||
$job['times'] = $this->db->db_addslashes(serialize($job['times']));
|
$job['times'] = $this->db->db_addslashes(serialize($job['times']));
|
||||||
$job['data'] = $this->db->db_addslashes(serialize($job['data']));
|
$job['data'] = $this->db->db_addslashes(serialize($job['data']));
|
||||||
|
$job['next'] = intval($job['next']);
|
||||||
|
$job['account_id'] = intval($job['account_id']);
|
||||||
|
|
||||||
if ($exists || $this->read($job['id']))
|
if ($exists || $this->read($job['id']))
|
||||||
{
|
{
|
||||||
$this->db->query("UPDATE $this->db_table SET next=$job[next],times='$job[times]',".
|
$this->db->query("UPDATE $this->db_table SET next=$job[next],times='$job[times]',".
|
||||||
"method='$job[method]',data='$job[data]' WHERE id='$job[id]'",__FILE__,__LINE__);
|
"method='$job[method]',data='$job[data]',account_id=$job[account_id] WHERE id='$job[id]'",__LINE__,__FILE__);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
$this->db->query("INSERT INTO $this->db_table (id,next,times,method,data) VALUES ".
|
$this->db->query("INSERT INTO $this->db_table (id,next,times,method,data,account_id) VALUES ".
|
||||||
"('$job[id]',$job[next],'$job[times]','$job[method]','$job[data]')",__FILE__,__LINE__);
|
"('$job[id]',$job[next],'$job[times]','$job[method]','$job[data]',$job[account_id])",__LINE__,__FILE__);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@function delete
|
@function delete
|
||||||
@abstract delete db-row / job with $id
|
@abstract delete db-row / job with $id
|
||||||
@returns False if $id not found else True
|
@result False if $id not found else True
|
||||||
*/
|
*/
|
||||||
function delete($id)
|
function delete($id)
|
||||||
{
|
{
|
||||||
@ -419,7 +550,11 @@
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
$binarys = array('php' => '/usr/bin/php','crontab' => '/usr/bin/crontab');
|
$binarys = array(
|
||||||
|
'php' => '/usr/bin/php',
|
||||||
|
'php4' => '/usr/bin/php4', // this is for debian
|
||||||
|
'crontab' => '/usr/bin/crontab'
|
||||||
|
);
|
||||||
foreach ($binarys as $name => $path)
|
foreach ($binarys as $name => $path)
|
||||||
{
|
{
|
||||||
$this->$name = $path; // a reasonable default for *nix
|
$this->$name = $path; // a reasonable default for *nix
|
||||||
@ -435,8 +570,16 @@
|
|||||||
$this->$name = substr($this->$name,0,$pos);
|
$this->$name = substr($this->$name,0,$pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!is_executable($this->$name))
|
||||||
|
{
|
||||||
|
$this->$name = $name; // hopefully its in the path
|
||||||
|
}
|
||||||
//echo "<p>$name = '".$this->$name."'</p>\n";
|
//echo "<p>$name = '".$this->$name."'</p>\n";
|
||||||
}
|
}
|
||||||
|
if ($this->php4[0] == '/') // we found a php4 binary
|
||||||
|
{
|
||||||
|
$this->php = $this->php4;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -445,34 +588,50 @@
|
|||||||
@function installed
|
@function installed
|
||||||
@abstract checks if phpgwapi/cron/asyncservices.php is installed as cron-job
|
@abstract checks if phpgwapi/cron/asyncservices.php is installed as cron-job
|
||||||
@syntax installed()
|
@syntax installed()
|
||||||
@returns the times asyncservices are run (normaly 'min'=>'* /5') or False if not installed
|
@result the times asyncservices are run (normaly 'min'=>'* /5') or False if not installed or 0 if crontab not found
|
||||||
@note Not implemented for Windows at the moment, always returns False
|
@note Not implemented for Windows at the moment, always returns 0
|
||||||
*/
|
*/
|
||||||
function installed()
|
function installed()
|
||||||
{
|
{
|
||||||
if (substr(php_uname(), 0, 7) == "Windows") {
|
if ($this->only_fallback) {
|
||||||
False;
|
return 0;
|
||||||
}
|
}
|
||||||
$this->find_binarys();
|
$this->find_binarys();
|
||||||
|
|
||||||
|
if (!is_executable($this->crontab))
|
||||||
|
{
|
||||||
|
//echo "<p>Error: $this->crontab not found !!!</p>";
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
$times = False;
|
$times = False;
|
||||||
|
$this->other_cronlines = array();
|
||||||
if (($crontab = popen('/bin/sh -c "'.$this->crontab.' -l" 2>&1','r')) !== False)
|
if (($crontab = popen('/bin/sh -c "'.$this->crontab.' -l" 2>&1','r')) !== False)
|
||||||
{
|
{
|
||||||
while ($line = fgets($crontab,256))
|
while ($line = fgets($crontab,256))
|
||||||
{
|
{
|
||||||
if ($line[0] != '#' && strstr($line,'asyncservices.php'))
|
if ($this->debug) echo 'line '.++$n.": $line<br>\n";
|
||||||
|
$parts = split(' ',$line,6);
|
||||||
|
|
||||||
|
if ($line[0] == '#' || count($parts) < 6 || ($parts[5][0] != '/' && substr($parts[5],0,3) != 'php'))
|
||||||
|
{
|
||||||
|
// ignore comments
|
||||||
|
if ($line[0] != '#')
|
||||||
|
{
|
||||||
|
$times['error'] .= $line;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
elseif (strstr($line,$this->cronline) !== False)
|
||||||
{
|
{
|
||||||
$time = explode(' ',$line);
|
|
||||||
$cron_units = array('min','hour','day','month','dow');
|
$cron_units = array('min','hour','day','month','dow');
|
||||||
foreach($cron_units as $n => $u)
|
foreach($cron_units as $n => $u)
|
||||||
{
|
{
|
||||||
if ($time[$n] != '*')
|
$times[$u] = $parts[$n];
|
||||||
{
|
|
||||||
$times[$u] = $time[$n];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
$times['cronline'] = $line;
|
$times['cronline'] = $line;
|
||||||
break;
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$this->other_cronlines[] = $line;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@pclose($crontab);
|
@pclose($crontab);
|
||||||
@ -485,15 +644,15 @@
|
|||||||
@abstract installs /phpgwapi/cron/asyncservices.php as cron-job
|
@abstract installs /phpgwapi/cron/asyncservices.php as cron-job
|
||||||
@syntax install($times)
|
@syntax install($times)
|
||||||
@param $times array with keys 'min','hour','day','month','dow', not set is equal to '*'
|
@param $times array with keys 'min','hour','day','month','dow', not set is equal to '*'
|
||||||
@returns the times asyncservices are run or False if they are not installed
|
@result the times asyncservices are run or False if they are not installed or 0 if crontab not found
|
||||||
@note Not implemented for Windows at the moment, always dies with an error-message
|
@note Not implemented for Windows at the moment, always returns 0
|
||||||
*/
|
*/
|
||||||
function install($times)
|
function install($times)
|
||||||
{
|
{
|
||||||
if (substr(php_uname(), 0, 7) == "Windows") {
|
if ($this->only_fallback) {
|
||||||
die ("Sorry, no automatic on Windows at the moment !!!\n");
|
return 0;
|
||||||
}
|
}
|
||||||
$this->find_binarys();
|
$this->installed(); // find other installed cronlines
|
||||||
|
|
||||||
if (($crontab = popen('/bin/sh -c "'.$this->crontab.' -" 2>&1','w')) !== False)
|
if (($crontab = popen('/bin/sh -c "'.$this->crontab.' -" 2>&1','w')) !== False)
|
||||||
{
|
{
|
||||||
@ -502,121 +661,16 @@
|
|||||||
{
|
{
|
||||||
$cronline .= (isset($times[$cu]) ? $times[$cu] : '*') . ' ';
|
$cronline .= (isset($times[$cu]) ? $times[$cu] : '*') . ' ';
|
||||||
}
|
}
|
||||||
$cronline .= $this->php.' -q '.PHPGW_SERVER_ROOT . '/phpgwapi/cron/asyncservices.php'."\n";
|
$cronline .= $this->php.' -q '.$this->cronline."\n";
|
||||||
//echo "<p>Installing: '$cronline'</p>\n";
|
//echo "<p>Installing: '$cronline'</p>\n";
|
||||||
fwrite($crontab,$cronline);
|
fwrite($crontab,$cronline);
|
||||||
@pclose($crontab);
|
|
||||||
}
|
foreach ($this->other_cronlines as $cronline)
|
||||||
else
|
|
||||||
{
|
{
|
||||||
//echo "<p>Error: /usr/bin/crontab not found !!!</p>";
|
fwrite($crontab,$cronline); // preserv the other lines
|
||||||
return False;
|
}
|
||||||
|
@pclose($crontab);
|
||||||
}
|
}
|
||||||
return $this->installed();
|
return $this->installed();
|
||||||
}
|
}
|
||||||
|
|
||||||
function test($data)
|
|
||||||
{
|
|
||||||
echo "asyncservice::test: data =\n";
|
|
||||||
|
|
||||||
print_r($data);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (!isset($GLOBALS['phpgw_info']))
|
|
||||||
{
|
|
||||||
$GLOBALS['phpgw_info']['flags'] = array(
|
|
||||||
'currentapp' => 'login'
|
|
||||||
);
|
|
||||||
include('../../header.inc.php');
|
|
||||||
|
|
||||||
$async = new asyncservice;
|
|
||||||
$units = array(
|
|
||||||
'year' => 'Year',
|
|
||||||
'month' => 'Month',
|
|
||||||
'day' => 'Day',
|
|
||||||
'dow' => 'Day of week',
|
|
||||||
'hour' => 'Hour',
|
|
||||||
'min' => 'Minute'
|
|
||||||
);
|
|
||||||
|
|
||||||
if ($_POST['send'] || $_POST['test'] || $_POST['cancel'] || $_POST['install'])
|
|
||||||
{
|
|
||||||
$times = array();
|
|
||||||
foreach($units as $u => $ulabel)
|
|
||||||
{
|
|
||||||
if (!empty($_POST[$u]))
|
|
||||||
{
|
|
||||||
$times[$u] = $_POST[$u];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$next = $async->next_run($times,True);
|
|
||||||
|
|
||||||
echo "<p>async::next_run(";print_r($times);echo")=".($next === False ? 'False':"'$next'=".date('D(w) d.m.Y H:i',$next))."</p>\n";
|
|
||||||
|
|
||||||
if ($_POST['test'])
|
|
||||||
{
|
|
||||||
if (!$async->set_timer($times,'test','phpgwapi.asyncservice.test','Hello World!!!'))
|
|
||||||
{
|
|
||||||
echo "<p>Error setting timer, maybe there's one already running !!!</p>\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ($_POST['cancel'])
|
|
||||||
{
|
|
||||||
if (!$async->cancel_timer('test'))
|
|
||||||
{
|
|
||||||
echo "<p>Error canceling timer, maybe there's none set !!!</p>\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ($_POST['install'])
|
|
||||||
{
|
|
||||||
if ($install = $async->install($times))
|
|
||||||
{
|
|
||||||
echo "<p>Installing: '$install[cronline]'</p>\n";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
echo "<p>Error: $async->crontab not found or other error !!!</p>";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
echo '<form action="'.$_SERVER['PHP_SELF'].'" method="POST">'."\n";
|
|
||||||
foreach ($units as $u => $ulabel)
|
|
||||||
{
|
|
||||||
echo "$ulabel: <input name=\"$u\" value=\"$times[$u]\" size=5> \n";
|
|
||||||
}
|
|
||||||
echo "<input type=\"submit\" name=\"send\" value=\"Calculate next run\">\n";
|
|
||||||
echo "<input type=\"submit\" name=\"test\" value=\"Start TestJob!\">\n";
|
|
||||||
echo "<input type=\"submit\" name=\"cancel\" value=\"Cancel TestJob!\">\n";
|
|
||||||
echo "<p><b>crontab:</b> \n";
|
|
||||||
|
|
||||||
if ($installed = $async->installed())
|
|
||||||
{
|
|
||||||
echo "$installed[cronline]</p>";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
echo "$async->crontab not found or asyncservices not installed !!!</p>";
|
|
||||||
}
|
|
||||||
echo "<input type=\"submit\" name=\"install\" value=\"Install crontab\">\n";
|
|
||||||
|
|
||||||
echo "<p><b>jobs:</b></p>\n";
|
|
||||||
if ($jobs = $async->read('%'))
|
|
||||||
{
|
|
||||||
echo "<table border=1>\n<tr>\n<th>Id</th><th>Next run</th><th>Times</th><th>Method</th><th>Data</th></tr>\n";
|
|
||||||
foreach($jobs as $job)
|
|
||||||
{
|
|
||||||
echo "<tr>\n<td>$job[id]</td><td>".date('Y/m/d H:i',$job['next'])."</td><td>";
|
|
||||||
print_r($job['times']);
|
|
||||||
echo "</td><td>$job[method]</td><td>";
|
|
||||||
print_r($job['data']);
|
|
||||||
echo "</td></tr>\n";
|
|
||||||
}
|
|
||||||
echo "</table>\n";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
echo "<p>No jobs in the database !!!</p>\n";
|
|
||||||
}
|
|
||||||
echo "</form>\n";
|
|
||||||
}
|
|
||||||
|
@ -1661,6 +1661,12 @@ if (!@is_file(PHPGW_SERVER_ROOT . '/phpgwapi/templates/' . $GLOBALS['phpgw_info'
|
|||||||
}
|
}
|
||||||
$GLOBALS['phpgw']->xslttpl->pp();
|
$GLOBALS['phpgw']->xslttpl->pp();
|
||||||
}
|
}
|
||||||
|
// call the asyncservice check_run function if it is not explicitly set to cron-only
|
||||||
|
//
|
||||||
|
if (!$GLOBALS['phpgw_info']['server']['asyncservice']) // is default
|
||||||
|
{
|
||||||
|
ExecMethod('phpgwapi.asyncservice.check_run','fallback');
|
||||||
|
}
|
||||||
$GLOBALS['phpgw']->db->disconnect();
|
$GLOBALS['phpgw']->db->disconnect();
|
||||||
|
|
||||||
/* Clean up mcrypt */
|
/* Clean up mcrypt */
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
/* Basic information about this app */
|
/* Basic information about this app */
|
||||||
$setup_info['phpgwapi']['name'] = 'phpgwapi';
|
$setup_info['phpgwapi']['name'] = 'phpgwapi';
|
||||||
$setup_info['phpgwapi']['version'] = '0.9.15.013';
|
$setup_info['phpgwapi']['version'] = '0.9.15.014';
|
||||||
$setup_info['phpgwapi']['versions']['current_header'] = '1.23';
|
$setup_info['phpgwapi']['versions']['current_header'] = '1.23';
|
||||||
$setup_info['phpgwapi']['enable'] = 3;
|
$setup_info['phpgwapi']['enable'] = 3;
|
||||||
$setup_info['phpgwapi']['app_order'] = 1;
|
$setup_info['phpgwapi']['app_order'] = 1;
|
||||||
|
@ -71,6 +71,45 @@
|
|||||||
return $GLOBALS['setup_info']['phpgwapi']['currentver'];
|
return $GLOBALS['setup_info']['phpgwapi']['currentver'];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$test[] = '0.9.14.004';
|
||||||
|
function phpgwapi_upgrade0_9_14_004()
|
||||||
|
{
|
||||||
|
// this is the 0.9.15.001 update
|
||||||
|
$GLOBALS['phpgw_setup']->oProc->RenameTable('lang','phpgw_lang');
|
||||||
|
$GLOBALS['phpgw_setup']->oProc->RenameTable('languages','phpgw_languages');
|
||||||
|
|
||||||
|
// 0.9.15.002 are already included in 0.9.14.002
|
||||||
|
|
||||||
|
$GLOBALS['setup_info']['phpgwapi']['currentver'] = '0.9.15.003';
|
||||||
|
return $GLOBALS['setup_info']['phpgwapi']['currentver'];
|
||||||
|
}
|
||||||
|
|
||||||
|
$test[] = '0.9.14.005';
|
||||||
|
function phpgwapi_upgrade0_9_14_005()
|
||||||
|
{
|
||||||
|
// this is the 0.9.15.001 update
|
||||||
|
$GLOBALS['phpgw_setup']->oProc->RenameTable('lang','phpgw_lang');
|
||||||
|
$GLOBALS['phpgw_setup']->oProc->RenameTable('languages','phpgw_languages');
|
||||||
|
|
||||||
|
// 0.9.15.002 are already included in 0.9.14.002
|
||||||
|
|
||||||
|
$GLOBALS['setup_info']['phpgwapi']['currentver'] = '0.9.15.003';
|
||||||
|
return $GLOBALS['setup_info']['phpgwapi']['currentver'];
|
||||||
|
}
|
||||||
|
|
||||||
|
$test[] = '0.9.14.006';
|
||||||
|
function phpgwapi_upgrade0_9_14_006()
|
||||||
|
{
|
||||||
|
// this is the 0.9.15.001 update
|
||||||
|
$GLOBALS['phpgw_setup']->oProc->RenameTable('lang','phpgw_lang');
|
||||||
|
$GLOBALS['phpgw_setup']->oProc->RenameTable('languages','phpgw_languages');
|
||||||
|
|
||||||
|
// 0.9.15.002 are already included in 0.9.14.002
|
||||||
|
|
||||||
|
$GLOBALS['setup_info']['phpgwapi']['currentver'] = '0.9.15.003';
|
||||||
|
return $GLOBALS['setup_info']['phpgwapi']['currentver'];
|
||||||
|
}
|
||||||
|
|
||||||
$test[] = '0.9.14.500';
|
$test[] = '0.9.14.500';
|
||||||
function phpgwapi_upgrade0_9_14_500()
|
function phpgwapi_upgrade0_9_14_500()
|
||||||
{
|
{
|
||||||
@ -142,7 +181,11 @@
|
|||||||
$test[] = '0.9.14.506';
|
$test[] = '0.9.14.506';
|
||||||
function phpgwapi_upgrade0_9_14_506()
|
function phpgwapi_upgrade0_9_14_506()
|
||||||
{
|
{
|
||||||
// 0.9.15.001-13 are already included in 0.9.14.506
|
$GLOBALS['phpgw_setup']->oProc->AlterColumn('phpgw_vfs','content',array(
|
||||||
|
'type' => 'text',
|
||||||
|
'nullable' => True
|
||||||
|
));
|
||||||
|
|
||||||
$GLOBALS['setup_info']['phpgwapi']['currentver'] = '0.9.15.013';
|
$GLOBALS['setup_info']['phpgwapi']['currentver'] = '0.9.15.013';
|
||||||
return $GLOBALS['setup_info']['phpgwapi']['currentver'];
|
return $GLOBALS['setup_info']['phpgwapi']['currentver'];
|
||||||
}
|
}
|
||||||
@ -150,7 +193,15 @@
|
|||||||
$test[] = '0.9.14.507';
|
$test[] = '0.9.14.507';
|
||||||
function phpgwapi_upgrade0_9_14_507()
|
function phpgwapi_upgrade0_9_14_507()
|
||||||
{
|
{
|
||||||
// 0.9.15.001-14 are already included in 0.9.14.507
|
// 0.9.15.001-13 are already included in 0.9.14.507
|
||||||
|
$GLOBALS['setup_info']['phpgwapi']['currentver'] = '0.9.15.013';
|
||||||
|
return $GLOBALS['setup_info']['phpgwapi']['currentver'];
|
||||||
|
}
|
||||||
|
|
||||||
|
$test[] = '0.9.14.508';
|
||||||
|
function phpgwapi_upgrade0_9_14_508()
|
||||||
|
{
|
||||||
|
// 0.9.15.001-14 are already included in 0.9.14.508
|
||||||
$GLOBALS['setup_info']['phpgwapi']['currentver'] = '0.9.15.014';
|
$GLOBALS['setup_info']['phpgwapi']['currentver'] = '0.9.15.014';
|
||||||
return $GLOBALS['setup_info']['phpgwapi']['currentver'];
|
return $GLOBALS['setup_info']['phpgwapi']['currentver'];
|
||||||
}
|
}
|
||||||
@ -414,13 +465,14 @@
|
|||||||
return $GLOBALS['setup_info']['phpgwapi']['currentver'];
|
return $GLOBALS['setup_info']['phpgwapi']['currentver'];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
$test[] = '0.9.15.013';
|
$test[] = '0.9.15.013';
|
||||||
function phpgwapi_upgrade0_9_14_506()
|
function phpgwapi_upgrade0_9_15_013()
|
||||||
{
|
{
|
||||||
$GLOBALS['phpgw_setup']->oProc->AlterColumn('phpgw_vfs','content',array(
|
$GLOBALS['phpgw_setup']->oProc->AddColumn('phpgw_async','account_id',array(
|
||||||
'type' => 'text',
|
'type' => 'int',
|
||||||
'nullable' => True
|
'precision' => '4',
|
||||||
|
'nullable' => False,
|
||||||
|
'default' => '0'
|
||||||
));
|
));
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user