Location: PHPKode > scripts > twzCronChart > twzCronChart.php
<?php
/*
    twzCrontab, twzCronChart    v1.1.0 2010-12-24
    ------------------------
    
    twzCrontab parses a crontab and provides methods to retrieve
    the list of cron tasks and next/previous dates for any task.
    
    twzCronChart extends the twzCrontab class and allows you to 
    display a Gantt chart of cron tasks.
    
    
    COPYRIGHT INFORMATION
    All code in this file and associated files is copyright
    ©2010 tweezy.net.au unless otherwise noted.
    Please read licence.txt
    ___________________________________________________________
    
    Download from http://tweezy.net.au/twzCronChart.html
    ___________________________________________________________
*/ 
class twzCrontab { protected $vTWZ1=array(); protected $vTWZ2=''; protected $vTWZ3=array(); protected $vTWZ4; protected $vTWZ5; public function __construct($vTWZ6='') { if(!$vTWZ6) { $vTWZ6=shell_exec('crontab -l'); } if(is_string($vTWZ6)) { $vTWZ6=explode("\n", $vTWZ6); } if(!$vTWZ6) { $this->vTWZ3[]='No crontab'; die('No crontab'); } $vTWZ7=1; foreach($vTWZ6 as $vTWZ8) { if(preg_match('/^MAILTO\s*=\s*"(.*)"/i', $vTWZ8, $vTWZ9)) { $this->vTWZ2=$vTWZ9[1]; } else { if($this->_getCommand($vTWZ8)) { $this->vTWZ1[$vTWZ7]['name']='Task '.$vTWZ7; $this->vTWZ1[$vTWZ7]['cron']=trim($vTWZ8); $vTWZ7++; } elseif(trim($vTWZ8)!='') { $this->vTWZ3[]='Unrecognised crontab line: '.$vTWZ8; } } } $this->_validateTasks(); $this->SetDateFormat(); $this->SetTimeLimit(); } public function SetDateFormat($vTWZ4='j M Y H:i') { $this->vTWZ4=$vTWZ4; } public function GetTaskNames() { $vTWZ10=array(); foreach($this->vTWZ1 as $vTWZ7=>$vTWZ11) { $vTWZ10[$vTWZ7]=$vTWZ11['name']; } return $vTWZ10; } public function GetTaskCrons() { $vTWZ10=array(); foreach($this->vTWZ1 as $vTWZ7=>$vTWZ11) { $vTWZ10[$vTWZ7]=$vTWZ11['cron']; } return $vTWZ10; } public function GetMailto() { return $this->vTWZ2; } public function GetErrors() { return $this->vTWZ3; } public function GetLastRun($vTWZ1, $vTWZ12=null) { $vTWZ13=$this->_getNextLastRun($vTWZ1, $vTWZ12, -1); if(false===$vTWZ13) return false; if(is_null($vTWZ13)) return 'Time exceeded!'; if(0==$vTWZ13) return 'Last reboot!'; return date($this->vTWZ4, $vTWZ13); } public function GetNextRun($vTWZ1, $vTWZ12=null) { $vTWZ14=$this->_getNextLastRun($vTWZ1, $vTWZ12, 1); if(false===$vTWZ14) return false; if(is_null($vTWZ14)) return 'Time exceeded!'; if(0==$vTWZ14) return 'Next reboot!'; return date($this->vTWZ4, $vTWZ14); } protected function _getNextLastRun($vTWZ1, $vTWZ12, $vTWZ15) { if(!$vTWZ7=$this->_getTaskId($vTWZ1)) return false; if(is_null($vTWZ12)) $vTWZ12=time(); elseif(is_string($vTWZ12)) $vTWZ12=strtotime($vTWZ12); if(!$vTWZ12 or $vTWZ12<0) return false; if(0==count($this->vTWZ1[$vTWZ7]['run']['day'])) { return ('@reboot'==substr($this->vTWZ1[$vTWZ7]['cron'],0,7)) ? 0 : false; } $vTWZ5=time()+$this->vTWZ5; while(time()<$vTWZ5) { list($vTWZ16, $vTWZ17, $vTWZ18, $vTWZ19, $vTWZ20, $vTWZ21)=explode(',', date('Y,n,j,G,i,w', $vTWZ12)); $vTWZ22=true; while(!in_array($vTWZ17, $this->vTWZ1[$vTWZ7]['run']['month'])) { if($vTWZ15>0) { $vTWZ17++; $vTWZ18=1; $vTWZ19=0; $vTWZ20=0; } else { $vTWZ18 = date('j', mktime($vTWZ19, $vTWZ20, 0, $vTWZ17, 0, $vTWZ16)); $vTWZ17--; $vTWZ19=23; $vTWZ20=59; } $vTWZ23=date('Y', mktime($vTWZ19, $vTWZ20, 0, $vTWZ17, $vTWZ18, $vTWZ16)); if($vTWZ23!=$vTWZ16) { $vTWZ12=mktime($vTWZ19, $vTWZ20, 0, $vTWZ17, $vTWZ18, $vTWZ16); $vTWZ22=false; break; } } $vTWZ24=$this->vTWZ1[$vTWZ7]['run']['dayboth']; while($vTWZ22 and ( ($vTWZ24 and !in_array($vTWZ18, $this->vTWZ1[$vTWZ7]['run']['day']) and !in_array($vTWZ21, $this->vTWZ1[$vTWZ7]['run']['weekday'])) or (!$vTWZ24 and (!in_array($vTWZ18, $this->vTWZ1[$vTWZ7]['run']['day']) or !in_array($vTWZ21, $this->vTWZ1[$vTWZ7]['run']['weekday']))) ) ) { if($vTWZ15>0) { $vTWZ18++; $vTWZ19=0; $vTWZ20=0; $vTWZ21++; if($vTWZ21>6) $vTWZ21=0; } else { $vTWZ18--; $vTWZ19=23; $vTWZ20=59; $vTWZ21--; if($vTWZ21<0) $vTWZ21=6; } $vTWZ25=date('n', mktime($vTWZ19, $vTWZ20, 0, $vTWZ17, $vTWZ18, $vTWZ16)); if($vTWZ25!=$vTWZ17) { $vTWZ12=mktime($vTWZ19, $vTWZ20, 0, $vTWZ17, $vTWZ18, $vTWZ16); $vTWZ22=false; break; } } while($vTWZ22 and !in_array($vTWZ19, $this->vTWZ1[$vTWZ7]['run']['hour'])) { if($vTWZ15>0) { $vTWZ19++; $vTWZ20=0; } else { $vTWZ19--; $vTWZ20=59; } $vTWZ26=date('j', mktime($vTWZ19, $vTWZ20, 0, $vTWZ17, $vTWZ18, $vTWZ16)); if($vTWZ26!=$vTWZ18) { $vTWZ12=mktime($vTWZ19, $vTWZ20, 0, $vTWZ17, $vTWZ18, $vTWZ16); $vTWZ22=false; break; } } while($vTWZ22 and !in_array($vTWZ20, $this->vTWZ1[$vTWZ7]['run']['minute'])) { $vTWZ20+=$vTWZ15; $vTWZ27=date('G', mktime($vTWZ19, $vTWZ20, 0, $vTWZ17, $vTWZ18, $vTWZ16)); if($vTWZ27!=$vTWZ19) { $vTWZ12=mktime($vTWZ19, $vTWZ20, 0, $vTWZ17, $vTWZ18, $vTWZ16); $vTWZ22=false; break; } } if($vTWZ22) return mktime($vTWZ19, $vTWZ20, 0, $vTWZ17, $vTWZ18, $vTWZ16); } return null; } protected function _getTaskId($vTWZ1) { if(is_numeric($vTWZ1)) { return (isset($this->vTWZ1[$vTWZ1])) ? $vTWZ1 : false; } foreach($this->vTWZ1 as $vTWZ7=>$vTWZ11) { if(strtolower($vTWZ11['name'])==strtolower($vTWZ1)) return $vTWZ7; } return false; } public function SetTaskNames($vTWZ28=array()) { foreach($vTWZ28 as $vTWZ29=>$vTWZ30) { if(is_int($vTWZ29) and isset($this->vTWZ1[$vTWZ29])) { $this->vTWZ1[$vTWZ29]['name']=$vTWZ30; } else { foreach($this->vTWZ1 as $vTWZ7=>$vTWZ31) { if(strpos($vTWZ31['cron'], $vTWZ29)!==false) { $this->vTWZ1[$vTWZ7]['name']=$vTWZ30; break; } } } } } protected function _validateTasks() { foreach($this->vTWZ1 as $vTWZ7=>$vTWZ31) { $this->vTWZ1[$vTWZ7]['run']=$this->_getRunTimes($vTWZ31['cron']); $this->vTWZ1[$vTWZ7]['command']=$this->_getCommand($vTWZ31['cron']); } } protected function _getCommand($vTWZ32) { $vTWZ32=trim($vTWZ32); if('@'==substr($vTWZ32,0,1)) { $vTWZ33=explode(' ', $vTWZ32, 2); return (count($vTWZ33)==2 and $this->_getSpecialCron($vTWZ33[0])) ? $vTWZ33[1] : false; } else { $vTWZ33=explode(' ', $vTWZ32, 6); return (count($vTWZ33)>5) ? $vTWZ33[5] : false; } } protected function _getSpecialCron($vTWZ34) { switch(strtolower($vTWZ34)) { case '@reboot': return 'x x x x x'; break; case '@yearly': case '@annually': return '0 0 1 1 *'; break; case '@monthly': return '0 0 1 * *'; break; case '@weekly': return '0 0 * * 0'; break; case '@daily': case '@midnight': return '0 0 * * *'; break; case '@hourly': return '0 * * * *'; break; default: return false; } } public function SetTimeLimit($vTWZ5=2) { $this->vTWZ5=$vTWZ5; } protected function _getRunTimes($vTWZ32) { $vTWZ35=array('minute','hour','day','month','weekday'); $vTWZ36=array(0,0,1,1,0); $vTWZ37=array(59,23,31,12,6); $vTWZ38=array('sun'=>0, 'mon'=>1, 'tue'=>2, 'wed'=>3, 'thu'=>4, 'fri'=>5, 'sat'=>6); $vTWZ39=array('jan'=>1, 'feb'=>2, 'mar'=>3, 'apr'=>4, 'may'=>5, 'jun'=>6, 'jul'=>7, 'aug'=>8, 'sep'=>9, 'oct'=>10, 'nov'=>11, 'dec'=>12); $vTWZ40=array(); foreach($vTWZ35 as $vTWZ41) { $vTWZ40[$vTWZ41]=array(); } $vTWZ40['dayboth']=false; $vTWZ33=explode(' ', $vTWZ32, 6); if('@'==substr($vTWZ33[0],0,1)) { if(!$vTWZ42=$this->_getSpecialCron($vTWZ33[0])) { $this->vTWZ3[]='Unrecognised cron: '.$vTWZ32; return $vTWZ40; } $vTWZ33=explode(' ', $vTWZ42); } if(count($vTWZ33)<5) { $this->vTWZ3[]='Unrecognised cron: '.$vTWZ32; return $vTWZ40; } if($vTWZ33[2]!='*' and $vTWZ33[4]!='*') $vTWZ40['dayboth']=true; for($vTWZ43=0; $vTWZ43<5; $vTWZ43++) { $vTWZ44=trim($vTWZ33[$vTWZ43]); if('weekday'==$vTWZ35[$vTWZ43]) $vTWZ44=str_replace(array_keys($vTWZ38), $vTWZ38, strtolower($vTWZ44)); if('month'==$vTWZ35[$vTWZ43]) $vTWZ44=str_replace(array_keys($vTWZ39), $vTWZ39, strtolower($vTWZ44)); if('x'==$vTWZ44) { $vTWZ45=array(); } else { $vTWZ44=str_replace('*', $vTWZ36[$vTWZ43].'-'.$vTWZ37[$vTWZ43], $vTWZ44); if(preg_match('#[^-,0-9/]#', $vTWZ44)) { $this->vTWZ3[]=$vTWZ44.' is unrecognised '.$vTWZ35[$vTWZ43].' in line: '.$vTWZ32; $vTWZ45=array(); } else { if(preg_match_all('#([0-9]+)-([0-9]+)(/[0-9])?#', $vTWZ44, $vTWZ9)) { foreach($vTWZ9[0] as $vTWZ46=>$vTWZ47) { $vTWZ48=1; if($vTWZ9[3][$vTWZ46]!='') { $vTWZ48=substr($vTWZ9[3][$vTWZ46], 1); if(0==$vTWZ48) $vTWZ48=1; } $vTWZ44=str_replace($vTWZ47, implode(',', range($vTWZ9[1][$vTWZ46], $vTWZ9[2][$vTWZ46], $vTWZ48)), $vTWZ44); } } $vTWZ45=explode(',', $vTWZ44); } } $vTWZ45=array_unique($vTWZ45); if('weekday'==$vTWZ35[$vTWZ43]) { $vTWZ46=array_search(7, $vTWZ45); if($vTWZ46!==false) $vTWZ45[$vTWZ46]=0; } sort($vTWZ45); if(count($vTWZ45)>0 and min($vTWZ45)<$vTWZ36[$vTWZ43]) { $this->vTWZ3[]=$vTWZ35[$vTWZ43].' below minimum in line: '.$vTWZ32; } if(count($vTWZ45)>0 and max($vTWZ45)>$vTWZ37[$vTWZ43]) { $this->vTWZ3[]=$vTWZ35[$vTWZ43].' above maximum in line: '.$vTWZ32; } $vTWZ40[$vTWZ35[$vTWZ43]]=$vTWZ45; } return $vTWZ40; } } 
class twzCronChart extends twzCrontab { private $vTWZ49=''; private $vTWZ50; private $vTWZ51; public function __construct($vTWZ6='') { parent::__construct($vTWZ6); $this->SetSwitchLimit(); } public function Chart($vTWZ12='now', $vTWZ52='+5 days', $vTWZ53=750, $vTWZ54=60) { if(is_string($vTWZ53) and preg_match('/^([0-9]+)>([0-9]+)$/', $vTWZ53, $vTWZ9)) { $vTWZ55=true; $vTWZ53=$vTWZ9[1]; $vTWZ56=$vTWZ9[2]; } else { $vTWZ55=false; } $vTWZ57 = ''; if(0==count($this->vTWZ1)) return false; if(!is_numeric($vTWZ12)) $vTWZ12=strtotime($vTWZ12); if(!is_numeric($vTWZ52)) $vTWZ52=strtotime($vTWZ52); if(!$vTWZ12 or $vTWZ12<0 or !$vTWZ52 or $vTWZ52<0) return false; $vTWZ12-=60*(date('i', $vTWZ12)%10); if(date('i', $vTWZ52)%10>0) $vTWZ52+=60*(10-date('i', $vTWZ52)%10); $vTWZ53=(int)$vTWZ53; $vTWZ58=($vTWZ52-$vTWZ12)/($vTWZ54*60)+1; $vTWZ59=round($vTWZ53 / $vTWZ58)-1; if($vTWZ59<1) $vTWZ59=1; $vTWZ53=round(($vTWZ59+1)*$vTWZ58); $vTWZ57.='<div class="cron">'."\r\n" .'  <div class="title">'.$this->vTWZ49 .'<div class="range">period '.date($this->vTWZ4, $vTWZ12) .' to '.date($this->vTWZ4, $vTWZ52).'</div>' ."</div>\r\n"; if($this->vTWZ51) $vTWZ60=microtime(true); if($vTWZ55) { $vTWZ57.="<div class=\"outer\">\r\n<div class=\"lhs\">\r\n"; foreach($this->vTWZ1 as $vTWZ7=>$vTWZ31) { $vTWZ57.='  <div class="taskname" title="'.$vTWZ31['cron'].'">'.$vTWZ31['name']."</div>\r\n"; } $vTWZ57.="</div>\r\n"; $vTWZ57.='<div class="rhs" style="width:'.$vTWZ56.'px;">'."\r\n"; } foreach($this->vTWZ1 as $vTWZ7=>$vTWZ31) { if(!$vTWZ55) $vTWZ57.='  <div class="taskname" title="'.$vTWZ31['cron'].'">'.$vTWZ31['name']."</div>\r\n"; $vTWZ57.='  <div class="sched" style="min-width:'.$vTWZ53.'px;">'; list($vTWZ61, $vTWZ62, $vTWZ63)=explode(',', date('G,j,n', $vTWZ12)); $vTWZ64=$vTWZ12-60; for($vTWZ65=$vTWZ12; $vTWZ65<=$vTWZ52; $vTWZ65+=$vTWZ54*60) { $vTWZ66='<span style="width:'.$vTWZ59.'px;">'; if(date('n', $vTWZ65)!=$vTWZ63) $vTWZ66=$this->_htmlAddClass('mon', $vTWZ66); elseif(date('j', $vTWZ65)!=$vTWZ62) $vTWZ66=$this->_htmlAddClass('day', $vTWZ66); elseif(date('G', $vTWZ65)!=$vTWZ61) $vTWZ66=$this->_htmlAddClass('hour', $vTWZ66); list($vTWZ61, $vTWZ62, $vTWZ63)=explode(',', date('G,j,n', $vTWZ65)); $vTWZ67=$this->_getLastInStep($vTWZ7, $vTWZ64, $vTWZ65); if($vTWZ67) { $vTWZ66=$this->_htmlAddClass('run', $vTWZ66); $vTWZ66=$this->_htmlAddAttribute('title', date($this->vTWZ4, $vTWZ67), $vTWZ66); } $vTWZ57.=$vTWZ66.'&nbsp;</span>'; $vTWZ64=$vTWZ65; } $vTWZ57.="</div>\r\n"; } if($this->vTWZ51) $this->vTWZ3[]='Elapsed time = '.(microtime(true)-$vTWZ60); if($vTWZ55) $vTWZ57.="</div>\r\n</div>\r\n"; $vTWZ57.='</div>'; return $vTWZ57; } private function _getLastInStep($vTWZ7, $vTWZ12, $vTWZ52) { if($vTWZ52 - $vTWZ12 < $this->vTWZ50) { if($this->vTWZ51) $this->vTWZ3[]='Method 1 ('.($vTWZ52 - $vTWZ12).' seconds) Task='.$vTWZ7; $vTWZ68=&$this->vTWZ1[$vTWZ7]['run']; for($vTWZ65=$vTWZ52; $vTWZ65>$vTWZ12; $vTWZ65-=60) { list($vTWZ20, $vTWZ19, $vTWZ18, $vTWZ17, $vTWZ21)=explode(',', date('i,G,j,n,w', $vTWZ65)); if( in_array($vTWZ20, $vTWZ68['minute']) && in_array($vTWZ19, $vTWZ68['hour']) && in_array($vTWZ18, $vTWZ68['day']) && in_array($vTWZ17, $vTWZ68['month']) && in_array($vTWZ21, $vTWZ68['weekday']) ) { return $vTWZ65; } } return false; } else { if($this->vTWZ51) $this->vTWZ3[]='Method 2 ('.($vTWZ52 - $vTWZ12).' seconds) Task='.$vTWZ7; $vTWZ13=$this->_getNextLastRun($vTWZ7, $vTWZ52, -1); return ($vTWZ13 and $vTWZ13>$vTWZ12) ? $vTWZ13 : false; } } public function SetChartName($vTWZ49) { $this->vTWZ49=$vTWZ49; } public function SetSwitchLimit($vTWZ50=false, $vTWZ51=false) { if(!is_int($vTWZ50)) $vTWZ50=60*60*24; $this->vTWZ50=$vTWZ50; $this->vTWZ51=(bool)$vTWZ51; } private function _htmlAddClass($vTWZ69, $vTWZ70) { if(''==trim($vTWZ69)) return $vTWZ70; $vTWZ71=(preg_match('#(\s?/>)#', $vTWZ70, $vTWZ9)) ? $vTWZ9[1] : '>'; if(strpos($vTWZ70, 'class=')===false) { $vTWZ70 = str_replace($vTWZ71, ' class="'.$vTWZ69.'"'.$vTWZ71, $vTWZ70); } else { $vTWZ70 = str_replace('class="', 'class="'.$vTWZ69.' ', $vTWZ70); } return $vTWZ70; } private function _htmlAddAttribute($vTWZ72, $vTWZ73, $vTWZ70) { if(''==trim($vTWZ73)) return $vTWZ70; $vTWZ71=(preg_match('#(\s?/>)#', $vTWZ70, $vTWZ9)) ? $vTWZ9[1] : '>'; if(strpos($vTWZ70, $vTWZ72.'=')===false) { $vTWZ70 = str_replace($vTWZ71, ' '.$vTWZ72.'="'.$vTWZ73.'"'.$vTWZ71, $vTWZ70); } else { $vTWZ70 = str_replace($vTWZ72.'="', $vTWZ72.'="'.$vTWZ73.' ', $vTWZ70); } return $vTWZ70; } } 
?>
Return current item: twzCronChart