]> jfr.im git - irc/unrealircd/unrealircd-webpanel.git/blame - Classes/class-upgrade.php
More towards upgrade proc
[irc/unrealircd/unrealircd-webpanel.git] / Classes / class-upgrade.php
CommitLineData
840c8c3e
VP
1<?php
2
3class Upgrade
4{
5 public $web_dir;
1ff0282b 6 private $temp_dir;
24432aab 7 private $temp_extracted_dir;
840c8c3e
VP
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).'/';
840c8c3e 25
1ff0282b 26 /** prepare the temp directory */
24432aab
VP
27 $temp_dir = $this->web_dir."panel_upgrade";
28 $temp_dir .= ($temp_dir[strlen($temp_dir) - 1] != '/') ? "/" : "";
1ff0282b
VP
29 array_map('unlink', array_filter((array) glob("$temp_dir/*.*")));
30 array_map('rmdir', array_filter((array) glob("$temp_dir/*")));
24432aab 31 if (file_exists($temp_dir)) rmdir($temp_dir);
1ff0282b
VP
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";
840c8c3e 36 Upgrade::$upgrade_available = false;
840c8c3e
VP
37 if ($this->error)
38 error_log($this->error);
840c8c3e
VP
39 }
40
41 /** Checks for a new upgrade */
42 function checkForNew()
43 {
44 global $config;
45 read_config_db();
24432aab
VP
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");
1ff0282b 50 return false;
24432aab
VP
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
840c8c3e
VP
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'];
24432aab 66 $last_check = time();
840c8c3e
VP
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'));
24432aab 75 $fp = fopen($this->temp_dir."unrealircd-webpanel-upgrade.zip", 'w+');
840c8c3e
VP
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);
1ff0282b
VP
84 $code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
85
24432aab 86 if ($code == "403" || $code == "404")
1ff0282b
VP
87 {
88 $this->error ="Unable to download";
89 }
840c8c3e
VP
90 curl_close($ch);
91 fclose($fp);
92
93 return $success;
94 }
1ff0282b
VP
95 function extractZip() {
96 $zip = new ZipArchive;
24432aab 97 if ($zip->open($this->temp_dir."unrealircd-webpanel-upgrade.zip") === true)
1ff0282b 98 {
24432aab 99 $zip->extractTo("$this->temp_dir");
1ff0282b 100 $zip->close();
24432aab
VP
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);
1ff0282b
VP
104 return true;
105 } else {
106 return false;
107 }
840c8c3e 108 }
1ff0282b
VP
109 function cleanupOldFiles()
110 {
111 $currentFiles = $this->listFiles($this->web_dir);
24432aab 112 $updateFiles = $this->listFiles($this->temp_extracted_dir);
1ff0282b
VP
113
114 $filesToDelete = array_diff($currentFiles, $updateFiles);
24432aab 115 error_log("Comparing... Files to delete:");
1ff0282b
VP
116 foreach ($filesToDelete as $file)
117 {
118 error_log($file);
24432aab 119 //unlink("$file");
1ff0282b 120 }
840c8c3e 121
840c8c3e 122 }
1ff0282b
VP
123
124 function extractToWebdir()
125 {
126 $zip = new ZipArchive;
24432aab 127 if ($zip->open($this->temp_dir."unrealircd-webpanel-upgrade.zip") === true)
1ff0282b 128 {
24432aab 129 $extracted = $zip->extractTo(str_replace("//","/",get_config('base_url')));
1ff0282b
VP
130 $zip->close();
131 if (!$extracted)
132 {
133 error_log("Cannot extract to web directory. Permission denied.");
134 return false;
135 }
1ff0282b 136 return true;
840c8c3e 137 } else {
1ff0282b
VP
138 return false;
139 }
140 }
24432aab
VP
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
1ff0282b
VP
152 function listFiles($dir) {
153 $files = [];
154 $iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir));
155 foreach ($iterator as $file)
156 {
157 if ($file->isFile())
158 {
24432aab
VP
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;
1ff0282b 167 }
840c8c3e 168 }
1ff0282b 169 return $files;
840c8c3e 170 }
840c8c3e 171}
24432aab
VP
172
173
174function 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}