isUpdateNeeded($myAppVersion)) { $getter->updateFromVersion($myAppVersion); } */ class Getter { var $base_url = ''; var $base_path = ''; var $current_version = false; // Internal cache var $base_cache = ''; var $versions = array(); // Class initialisation // $updates_url string URL where to get the XML updates file // $base_path string The path where to do file operation function Getter($updates_url='', $base_path='') { if (empty($updates_url) OR empty($base_path)) die('Getter class need a valid updates xml url and base path'); $this->base_path = $base_path; if (!ini_get('allow_url_fopen')) die('allow_url_fopen is disabled, you can\'t use Getter class.'); if (!function_exists('file_get_contents')) die('Getter class require PHP >= 4.3.0'); $this->base_cache = file_get_contents($updates_url) or die('Getter class error: Unable to reach '.$updates_url); if (!preg_match('/.*<\/getter>/si', $this->base_cache)) die('Getter class error: invalid XML file: '.$this->base_cache); preg_match('/([^<]*)<\/currentVersion>/i', $this->base_cache, $match); $this->current_version = (string) $match[1]; preg_match('/([^<]*)<\/baseUrl>/i', $this->base_cache, $match); $this->base_url = $match[1]; } // Do I need to upgrade ? (I got version $version) function isUpdateNeeded($version) { if ((string) $version < $this->current_version) return true; else return false; } // Fetch and parse XML file function _fetchVersionsHistory() { if (!empty($this->versions)) return true; preg_match_all('/(.*)<\/release>/isU', $this->base_cache, $matches, PREG_SET_ORDER); foreach ($matches as $match) { $item = $match[1]; preg_match('/([^<]*)<\/version>/i', $item, $match); $version = (string) $match[1]; $this->versions[$version] = array(); preg_match('/(.*)<\/changelog>/isU', $item, $match); $this->versions[$version]['changelog'] = $match[1]; $this->versions[$version]['files'] = $this->_extractFilesOperations($item); } ksort($this->versions); return true; } function _extractFilesOperations($item) { preg_match_all('/([^<]*)<\/file>/i', $item, $match, PREG_SET_ORDER); $files = array(); $i = 0; foreach ($match as $m) { // Order as this: remove, then make dirs, then get files if ($m[1] == 'remove') $count = $i; elseif ($m[1] == 'mkdir') $count = $i + 1000; else $count = $i + 2000; $files[$count] = array( 'action' => $m[1], 'source' => (!empty($m[3]) ? $m[3] : ''), 'destination'=> trim($m[4]) ); $i++; } ksort($files); return $files; } // Apply updates from $version, and apply only $limit updates at one time function updateFromVersion($version, $limit=100) { $this->_fetchVersionsHistory(); $i = 0; foreach ($this->versions as $v=>$release) { if ($v <= $version) continue; if ($i >= $limit) return true; $this->doRelease($v); $i++; } } // File operations function _delete($destination) { if (is_dir($this->base_path.$destination)) { $dir = opendir($this->base_path.$destination); while ($file = readdir($dir)) { if ($file != '.' && $file != '..') $this->_delete($destination.'/'.$file); } closedir($dir); rmdir($this->base_path.$destination); } else { unlink($this->base_path.$destination); } } function _mkdir($destination) { @mkdir($this->base_path.$destination); } function _copy($src, $dest) { if (!@copy($this->base_url.$src, $this->base_path.$dest)) die("Can't copy ".$this->base_url.$src." to ".$this->base_path.$dest); } // Apply an update function doRelease($release) { $this->_fetchVersionsHistory(); if (empty($this->versions[$release])) return false; foreach ($this->versions[$release]['files'] as $file) { if ($file['action'] == 'remove') $this->_delete($file['destination']); elseif ($file['action'] == 'mkdir') $this->_mkdir($file['destination']); else $this->_copy($file['source'], $file['destination']); } return true; } // Show me needed updates function getNeededUpdates($version) { $this->_fetchVersionsHistory(); $out = array(); foreach ($this->versions as $v=>$release) { if ($v <= $version) continue; $out[$v] = $release; } return $out; } // Install from scratch function Install() { preg_match('/(.*)<\/install>/is', $this->base_cache, $match); $files = $this->_extractFilesOperations($match[1]); foreach ($files as $file) { if ($file['action'] == 'mkdir') $this->_mkdir($file['destination']); elseif ($file['action'] == 'get') $this->_copy($file['source'], $file['destination']); } return true; } } ?>