1<?php 2/* 3description : Provide caching mechanism for plugins 4author : Ikuo Obataya 5email : I.Obataya@gmail.com 6lastupdate : 2008-11-26 7license : GPL 2 (http://www.gnu.org/licenses/gpl.html) 8*/ 9if(!defined('DOKU_INC')) die(); 10class plugin_cache{ 11 var $namespace =''; 12 var $mediaDir =''; 13 var $mediaFormat=''; 14 var $linkFormat =''; 15 var $prefix =''; 16 var $extension =''; 17 var $tmpdir =''; 18 function plugin_cache($_name='plugin_cache',$_prefix='noname',$_ext='txt'){ 19 global $conf; 20 $this->namespace = strtolower($_name); 21 $this->prefix = strtolower($_prefix); 22 $this->extension = strtolower($_ext); 23 if (empty($_prefix)){ 24 $this->prefix = $_prefix; 25 }else{ 26 $this->prefix = $_prefix.'_'; 27 } 28 $delimiter = ($conf['useslash'])?'/':':'; 29 $this->mediaDir = $conf['mediadir'].'/'.$this->namespace; 30 $this->mediaFormat = $this->mediaDir.'/'.$this->prefix.'%s.'.$this->extension; 31 $this->linkFormat = $this->namespace.$delimiter.$this->prefix.'%s.'.$this->extension; 32 33 $this->useTmpDir = false; 34 $this->tmpDir = '/var/tmp'; 35 $this->tmpFormat = $this->tmpDir.'/'.$this->namespace.'_'.$this->prefix.'%s.'.$this->extension; 36 37 $this->CheckDir(); 38 } 39 40 /** 41 * Get media file path 42 */ 43 function GetMediaPath($id){ 44 $id = strtolower($id); 45 if($this->useTmpDir===false){ 46 return sprintf($this->mediaFormat,$id); 47 }else{ 48 return sprintf($this->tmpFormat,$id); 49 } 50 } 51 52 /** 53 * Get all media file paths array 54 * array(ID,filepath) 55 */ 56 function GetAllMediaPaths(){ 57 $dir = $this->mediaDir; 58 $dirhandle = opendir($dir); 59 $files = array(); 60 61 $patten = array($this->prefix,'.'.$this->extension); 62 $replace = array('',''); 63 while($name = readdir($dirhandle)){ 64 if (strpos($name,$this->extension)!==false){ 65 $path = $dir.'/'.$name; 66 $id = str_replace($patten,$replace,$name); 67 $files[$id] = $path; 68 } 69 } 70 closedir(); 71 return $files; 72 } 73 74 /** 75 * Get media link 76 */ 77 function GetMediaLink($id){ 78 return ml(sprintf($this->linkFormat,$id),'',true,'',true); 79 } 80 81 /** 82 * Get text from cache. If none, return false 83 * 84 * Uses gzip if extension is .gz 85 * and bz2 if extension is .bz2 86 */ 87 function GetMediaText($id){ 88 $filepath = $this->GetMediaPath($id); 89 if (@file_exists($filepath)){ 90 @touch($filepath); 91 return io_readFile($filepath); 92 } 93 return false; 94 } 95 /** 96 * Save string to cache with a permission of $conf['fmode']. 97 * 98 * Uses gzip if extension is .gz 99 * and bz2 if extension is .bz2 100 */ 101 function PutMediaText($id,$text){ 102 global $conf; 103 $path = $this->GetMediaPath($id); 104 if(io_saveFile($path,$text)){ 105 @chmod($path,$conf['fmode']); 106 return true; 107 } 108 return false; 109 } 110 /** 111 * Check cache directories 112 */ 113 function CheckDir(){ 114 global $conf; 115 $dummyFN=mediaFN($this->namespace.':_dummy'); 116 $tmp = dirname($dummyFN); 117 if (!@is_dir($tmp)){ 118 io_makeFileDir($dummyFN); 119 @chmod($tmp,$conf['dmode']); 120 } 121 if (auth_aclcheck($this->namespace.":*","","@ALL")==0){ 122 global $AUTH_ACL; 123 $acl = join("",file(DOKU_CONF.'acl.auth.php')); 124 $p_acl = $this->namespace.":*\t@ALL\t1\n"; 125 $new_acl = $acl.$p_acl; 126 io_saveFile(DOKU_CONF.'acl.auth.php', $new_acl); 127 $AUTH_ACL = file(DOKU_CONF.'acl.auth.php'); // Reload ACL 128 } 129 } 130 /** 131 * Return true if the file exists 132 */ 133 function Exists($id){ 134 $path = $this->GetMediaPath($id); 135 if(@file_exists($path)!==false){ 136 @touch($path); 137 return true; 138 } 139 return false; 140 } 141 142 /** 143 * Clear all media files in a plugin's media directory 144 */ 145 function ClearCache(){ 146 global $conf; 147 $handle = @opendir($this->mediaDir); 148 if ($handle === false) 149 return; 150 while (($entry = readdir($handle))){ 151 $path = $this->mediaDir.'/'.$entry; 152 if(is_file($path)) 153 @unlink($path); 154 } 155 closedir($handle); 156 } 157 /** 158 * Remove cache and directory 159 */ 160 function RemoveDir(){ 161 $this->ClearCache(); 162 @rmdir($this->mediaDir); 163 } 164 /** 165 * save array as tab-text 166 */ 167 function _save_array($id,$ar=''){ 168 $_st = _microtime(); 169 if(empty($id)) return false; 170 global $conf; 171 if (empty($ar)){ 172 }else{ 173 $rep_pair = array("\n"=>"","\t"=>""); 174 $values = array_values($ar); 175 $keys = array_keys($ar); 176 $sz = count($values); 177 for($i=0;$i<$sz;$i++){ 178 $k = $keys[$i]; 179 if(empty($k)) $k=$i; 180 $v=strtr($ar[$k],$rep_pair); 181 $file.= $k."\t".$v."\n"; 182 } 183 } 184 if (empty($file)){$file='#not found';} 185 $path = $this->GetMediaPath($id); 186 if(io_saveFile($path,$file)){ 187 @chmod($path,$conf['fmode']); 188 _stopwatch('save_array',$_st); 189 return true; 190 }else{ 191 _stopwatch('save_array',$_st); 192 return false; 193 } 194 } 195 196 /** 197 * read array from tab-text 198 */ 199 function _read_array($id){ 200 $_st = _microtime(); 201 if (empty($id) || !$this->Exists($id)) return NULL; 202 $path = $this->GetMediaPath($id); 203 $lines = split("\n",io_readFile($path)); 204 $a = array(); 205 $sz = count($lines); 206 for($i=0;$i<$sz;$i++){ 207 if ($line=='#not found') return null; 208 $line = chop($lines[$i]); 209 if (empty($line)) continue; 210 $items = explode("\t",$line); 211 if (count($items)!=2)continue; 212 $a[$items[0]] = $items[1]; 213 } 214 _stopwatch('read_array',$_st); 215 @touch($path); 216 return $a; 217 } 218 219} 220