1<?php 2/** 3 * Coppermine Photo Gallery 4 * 5 * v1.0 originally written by Gregory Demar 6 * 7 * @copyright Copyright (c) 2003-2018 Coppermine Dev Team 8 * @license GNU General Public License version 3 or later; see LICENSE 9 * 10 * include/upgrader.inc.php 11 * @since 1.6.06 12 */ 13defined('IN_COPPERMINE') or die('Not in Coppermine...'); 14 15class CPG_Updater 16{ 17 protected $updates = array(); 18 19 public function __construct ($quiet=false, $no_pre=true) 20 { 21 global $lang_update_php; 22 23 $releases = json_decode($this->getUrlData('https://api.github.com/repos/coppermine-gallery/cpg1.6.x/releases')); 24 if (!$releases) { 25 if ($quiet) return; 26 cpg_die(ERROR, $lang_update_php['not_found']?:'Releases of CPG not found at Github', __FILE__, __LINE__); 27 } 28 foreach ($releases as $r) { 29 if ($r->prerelease && $no_pre) continue; // don't offer any prereleases 30 $tag = $r->tag_name; 31 if (preg_match('/\d+\.\d+\.\d+/', $tag, $m)) { 32 if (version_compare($m[0], COPPERMINE_VERSION) == 1) { 33 $this->updates[] = array( 34 'id' => $r->id, 35 'tag' => $m[0], 36 'pre' => $r->prerelease, 37 'ball' => $r->zipball_url, 38 'name' => $r->name, 39 'body' => nl2br($r->body) 40 ); 41 } 42 } 43 } 44 } 45 46 public function getUpdates () 47 { 48 return $this->updates; 49 } 50 51 public function performUpdate ($id) 52 { 53 global $lang_update_php; 54 55 $updt = null; 56 foreach ($this->updates as $u) { 57 if ($u['id'] == $id) { 58 $updt = $u; 59 break; 60 } 61 } 62 if (!$updt) return; 63 64 unlink(UPDATER_LOG); 65 $this->logIt("UPDATING TO: {$updt['tag']}"); 66 $tmpf = (sys_get_temp_dir() ?: 'albums/edit').'/cpg_upd_'.time().'.zip'; 67 $newUpdate = $this->getUrlData($updt['ball']); 68 $dlHandler = fopen($tmpf, 'w'); 69 if (!fwrite($dlHandler, $newUpdate)) { cpg_die(ERROR, $lang_update_php['save_error'], __FILE__, __LINE__); } 70 fclose($dlHandler); 71 72 $f2p = array('include/config.inc.php','anycontent.php'); //files to preserve if they already exist 73 $p2s = array('albums/'); //paths to skip (whether they exist or not) 74 $zip = new ZipArchive; 75 $res = $zip->open($tmpf); 76 if ($res === TRUE) { 77 for ($i = 0; $i < $zip->numFiles; $i++ ) { 78 $stat = $zip->statIndex($i); 79 list($bd,$fp) = explode('/', $stat['name'], 2); 80 if (substr($fp, -1) == '/') { 81 if ($this->matchedPath($fp, $p2s)) continue; 82 if (!is_dir($fp)) @mkdir($fp); 83 $this->logIt("DIR: {$fp}"); 84 } elseif ($fp) { 85 if (in_array($fp, $f2p) && file_exists($fp)) continue; 86 if ($this->matchedPath($fp, $p2s)) continue; 87 $fc = $zip->getFromIndex($i); 88 file_put_contents($fp, $fc); 89 $this->logIt("PUT: {$fp}"); 90 } 91 } 92 $zip->close(); 93 } else { 94 echo 'failed, code:' . $res; 95 } 96 97 unlink($tmpf); 98 } 99 100 public function __toString () 101 { 102 return print_r($this->updates, true); 103 } 104 105 public function checkCpgDirs () 106 { 107 $cpgDirs = array('albums','bridge','css','images','include','js','lang','logs','plugins','sql','themes'); 108 $ng = array(); 109 foreach ($cpgDirs as $dir) { 110 if (!(is_dir($dir) && is_writable($dir))) $ng[] = $dir; 111 } 112 return $ng; 113 } 114 115 private function getUrlData ($url) 116 { 117 $ua = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_3) AppleWebKit/537.75.14 (KHTML, like Gecko) Version/7.0.3 Safari/537.75.14'; 118 if (ini_get('allow_url_fopen')) { 119 ini_set('user_agent', $ua); 120 $rfc = file_get_contents($url); 121 if (!$rfc) return $this->curly($url, $ua); 122 return $rfc; 123 } else { 124 return $this->curly($url, $ua); 125 } 126 } 127 128 private function curly ($url, $agent) 129 { 130 if (!extension_loaded('libcurl')) return ''; 131 // create curl resource 132 $ch = curl_init(); 133 // set url 134 curl_setopt($ch, CURLOPT_URL, $url); 135 //return the transfer as a string 136 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 137 curl_setopt($ch, CURLOPT_USERAGENT, $agent); 138 curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); 139 // $output contains the output string 140 $output = curl_exec($ch); 141 // close curl resource to free up system resources 142 curl_close($ch); 143 // return the data 144 return $output; 145 } 146 147 private function matchedPath ($file, $paths) 148 { 149 foreach ($paths as $p) { 150 $p = str_replace('/','\/',$p); 151 if (preg_match("/^{$p}/", $file)) return true; 152 } 153 return false; 154 } 155 156 private function logIt ($msg) 157 { 158 file_put_contents(UPDATER_LOG, "{$msg}\n", FILE_APPEND); 159 } 160 161} 162//EOF