]>
Commit | Line | Data |
---|---|---|
1 | <?php | |
2 | ||
3 | class Upgrade | |
4 | { | |
5 | public $web_dir; | |
6 | private $temp_dir; | |
7 | private $temp_extracted_dir; | |
8 | public static $upgrade_available; | |
9 | public static $last_check; | |
10 | public $error; | |
11 | public static $latest_version; | |
12 | function __construct() | |
13 | { | |
14 | global $config; | |
15 | read_config_db(); | |
16 | if (!get_config('upgrade')) | |
17 | { | |
18 | $config['upgrade'] =[]; | |
19 | write_config('upgrade'); | |
20 | } | |
21 | ||
22 | $tok = split(__DIR__, '/'); | |
23 | unset($tok[count($tok) - 1]); | |
24 | $this->web_dir = implode('/',$tok).'/'; | |
25 | ||
26 | /** prepare the temp directory */ | |
27 | $temp_dir = $this->web_dir."panel_upgrade"; | |
28 | $temp_dir .= ($temp_dir[strlen($temp_dir) - 1] != '/') ? "/" : ""; | |
29 | array_map('unlink', array_filter((array) glob("$temp_dir/*.*"))); | |
30 | array_map('rmdir', array_filter((array) glob("$temp_dir/*"))); | |
31 | if (file_exists($temp_dir)) rmdir($temp_dir); | |
32 | $mkdir = mkdir($temp_dir, 0755, true); | |
33 | ||
34 | $this->temp_dir = $mkdir ? $temp_dir : NULL; | |
35 | $this->error = $mkdir ? NULL : "Could not create directory: $temp_dir"; | |
36 | Upgrade::$upgrade_available = false; | |
37 | if ($this->error) | |
38 | error_log($this->error); | |
39 | } | |
40 | ||
41 | /** Checks for a new upgrade */ | |
42 | function checkForNew() | |
43 | { | |
44 | global $config; | |
45 | read_config_db(); | |
46 | $last_check = &$config['upgrade']['last_check']; | |
47 | if (isset($last_check) && time() - $last_check < 300) // only check every 15 mins | |
48 | { | |
49 | error_log("Skipping upgrade check, checked ".time() - $last_check." seconds ago"); | |
50 | return false; | |
51 | } | |
52 | error_log(time()." - ".$last_check." = ".time()-$last_check); | |
53 | $apiUrl = "https://api.github.com/repos/unrealircd/unrealircd-webpanel/releases"; | |
54 | $response = file_get_contents($apiUrl, false, stream_context_create( | |
55 | ["http" => ["method" => "GET", "header" => "User-agent: UnrealIRCd Webpanel"]] | |
56 | )); | |
57 | ||
58 | if ($response === false) | |
59 | { | |
60 | $this->error = "Couldn't check github."; | |
61 | return false; | |
62 | } | |
63 | $data = json_decode($response, true); | |
64 | $latest = $data[count($data) - 1]; | |
65 | $config['upgrade']['latest_version'] = $latest['tag_name']; | |
66 | $last_check = time(); | |
67 | $config['upgrade']['download_link'] = $latest['zipball_url']; | |
68 | write_config('upgrade'); | |
69 | Upgrade::$upgrade_available = (float)$latest['tag_name'] > WEBPANEL_VERSION ? true : false; | |
70 | } | |
71 | ||
72 | function downloadUpgradeZip() | |
73 | { | |
74 | $ch = curl_init(get_config('upgrade::download_link')); | |
75 | $fp = fopen($this->temp_dir."unrealircd-webpanel-upgrade.zip", 'w+'); | |
76 | ||
77 | curl_setopt($ch, CURLOPT_FILE, $fp); | |
78 | curl_setopt($ch, CURLOPT_TIMEOUT, 60); | |
79 | curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); | |
80 | curl_setopt($ch, CURLOPT_HTTPHEADER, [ | |
81 | 'User-Agent: UnrealIRCd Webpanel', | |
82 | ]); | |
83 | $success = curl_exec($ch); | |
84 | $code = curl_getinfo($ch, CURLINFO_HTTP_CODE); | |
85 | ||
86 | if ($code == "403" || $code == "404") | |
87 | { | |
88 | $this->error ="Unable to download"; | |
89 | } | |
90 | curl_close($ch); | |
91 | fclose($fp); | |
92 | ||
93 | return $success; | |
94 | } | |
95 | function extractZip() { | |
96 | $zip = new ZipArchive; | |
97 | if ($zip->open($this->temp_dir."unrealircd-webpanel-upgrade.zip") === true) | |
98 | { | |
99 | $zip->extractTo("$this->temp_dir"); | |
100 | $zip->close(); | |
101 | unlink($this->temp_dir."unrealircd-webpanel-upgrade.zip"); | |
102 | $this->temp_extracted_dir = findOnlyDirectory($this->temp_dir); | |
103 | error_log($this->temp_extracted_dir); | |
104 | return true; | |
105 | } else { | |
106 | return false; | |
107 | } | |
108 | } | |
109 | function cleanupOldFiles() | |
110 | { | |
111 | $currentFiles = $this->listFiles($this->web_dir); | |
112 | $updateFiles = $this->listFiles($this->temp_extracted_dir); | |
113 | ||
114 | $filesToDelete = array_diff($currentFiles, $updateFiles); | |
115 | error_log("Comparing... Files to delete:"); | |
116 | foreach ($filesToDelete as $file) | |
117 | { | |
118 | error_log($file); | |
119 | //unlink("$file"); | |
120 | } | |
121 | ||
122 | } | |
123 | ||
124 | function extractToWebdir() | |
125 | { | |
126 | $zip = new ZipArchive; | |
127 | if ($zip->open($this->temp_dir."unrealircd-webpanel-upgrade.zip") === true) | |
128 | { | |
129 | $extracted = $zip->extractTo(str_replace("//","/",get_config('base_url'))); | |
130 | $zip->close(); | |
131 | if (!$extracted) | |
132 | { | |
133 | error_log("Cannot extract to web directory. Permission denied."); | |
134 | return false; | |
135 | } | |
136 | return true; | |
137 | } else { | |
138 | return false; | |
139 | } | |
140 | } | |
141 | ||
142 | /** | |
143 | * Cleans up the extracted update files | |
144 | * @return void | |
145 | */ | |
146 | function cleanupDownloadFiles() | |
147 | { | |
148 | array_map('unlink', array_filter((array) glob("$this->temp_dir/*.*"))); | |
149 | array_map('rmdir', array_filter((array) glob("$this->temp_dir/*"))); | |
150 | } | |
151 | ||
152 | function listFiles($dir) { | |
153 | $files = []; | |
154 | $iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir)); | |
155 | foreach ($iterator as $file) | |
156 | { | |
157 | if ($file->isFile()) | |
158 | { | |
159 | $f = substr($file->getPathname(), strlen($dir)); | |
160 | if ($f[0] == "/") $f = substr($f,1); | |
161 | error_log("$dir => $f"); | |
162 | ||
163 | ||
164 | ||
165 | ||
166 | $files[] = $f; | |
167 | } | |
168 | } | |
169 | return $files; | |
170 | } | |
171 | } | |
172 | ||
173 | ||
174 | function findOnlyDirectory($topDir) { | |
175 | // Ensure the directory exists and is indeed a directory | |
176 | if (!is_dir($topDir)) { | |
177 | die("The specified path is not a directory."); | |
178 | } | |
179 | ||
180 | // Open the directory | |
181 | $dirHandle = opendir($topDir); | |
182 | if ($dirHandle === false) { | |
183 | die("Unable to open directory."); | |
184 | } | |
185 | ||
186 | $directories = []; | |
187 | ||
188 | // Read through the directory contents | |
189 | while (($entry = readdir($dirHandle)) !== false) { | |
190 | $fullPath = $topDir . DIRECTORY_SEPARATOR . $entry; | |
191 | // Check if the entry is a directory and not . or .. | |
192 | if (is_dir($fullPath) && $entry !== '.' && $entry !== '..') { | |
193 | $directories[] = $fullPath; | |
194 | } | |
195 | } | |
196 | ||
197 | // Close the directory handle | |
198 | closedir($dirHandle); | |
199 | ||
200 | // Check if there is exactly one directory | |
201 | if (count($directories) === 1) { | |
202 | return $directories[0]; | |
203 | } elseif (count($directories) === 0) { | |
204 | return "No directories found after extracting. Possibly missing php-zip extention. Aborting upgrade."; | |
205 | } else { | |
206 | return "Multiple directories found. Previous cleanup was unsuccessful for some reason, maybe a permissions error? Aborting upgrade."; | |
207 | } | |
208 | } |