diff --git a/ext/update/main.php b/ext/update/main.php index 9aad4c2c..6cd29b26 100644 --- a/ext/update/main.php +++ b/ext/update/main.php @@ -1,166 +1,111 @@ * Link: http://www.codeanimu.net * License: GPLv2 - * Description: Shimmie updater! (Requires php-curl library and admin panel extension) + * Description: Shimmie updater! (Requires admin panel extension & transload engine (cURL/fopen/Wget)) */ class Update extends Extension { public function onInitExt(InitExtEvent $event) { global $config; - $config->set_default_string("update_guser", "shish"); - $config->set_default_string("update_grepo", "shimmie2"); + $config->set_default_string("update_guserrepo", "shish/shimmie2"); $config->set_default_string("commit_hash", "unknown"); - $config->set_default_string("commit_time", "unknown"); + $config->set_default_string("update_time", "01/01/1970"); } public function onSetupBuilding(SetupBuildingEvent $event) { $sb = new SetupBlock("Update"); - $sb->add_text_option("update_guser", "User: "); - $sb->add_text_option("update_grepo", "
Repo: "); + $sb->add_text_option("update_guserrepo", "User/Repo: "); $event->panel->add_block($sb); } public function onAdminBuilding(AdminBuildingEvent $event) { - global $config, $page; - - $latestCommit = $this->get_latest_commit(); - if(is_null($latestCommit)) return; - - $commitMessage = $latestCommit["commit"]["message"]; - $commitDT = explode("T", $latestCommit["commit"]["committer"]["date"]); - $commitTD = explode("-", $commitDT[1]); - $commitDateTime = $commitDT[0]." (".$commitTD[0].")"; - $commitSHA = substr($latestCommit["sha"],0,7); - - $html = "". - "Current Commit: ".$config->get_string('commit_hash')." | ".$config->get_string('commit_time'). - "
Latest Commit: ".$commitSHA." | ".$commitDateTime." | ".$commitMessage. - "
Update". - ""; - $page->add_block(new Block("Software Update", $html, "main")); + global $config; + if($config->get_string('transload_engine') !== "none"){ + $this->theme->display_admin_block(); + } } public function onPageRequest(PageRequestEvent $event) { - global $config, $user; - if($event->page_matches("update") && $user->is_admin()) { - $ok = $this->update_shimmie(); + global $config, $user, $page; + if($user->is_admin() && isset($_GET['sha'])){ + if($event->page_matches("update/download")){ + $ok = $this->download_shimmie(); + + $page->set_mode("redirect"); + if($ok) $page->set_redirect(make_link("update/update", "sha=".$_GET['sha'])); + else $page->set_redirect(make_link("admin")); //TODO: Show error? + }elseif($event->page_matches("update/update")){ + $ok = $this->update_shimmie(); + + $page->set_mode("redirect"); + if($ok) $page->set_redirect(make_link("admin")); //TODO: Show success? + else $page->set_redirect(make_link("admin")); //TODO: Show error? + } } } - private function get_latest_commit() { + private function download_shimmie() { global $config; - if(!function_exists("curl_init")) return null; + $commitSHA = $_GET['sha']; + $g_userrepo = $config->get_string('update_guserrepo'); - //Grab latest info via JSON. - $g_user = $config->get_string("update_guser"); - $g_repo = $config->get_string("update_grepo"); - $base = "https://api.github.com/repos/".$g_user."/".$g_repo."/commits"; - $curl = curl_init(); - curl_setopt($curl, CURLOPT_URL, $base); - curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); - curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); - $content = curl_exec($curl); - curl_close($curl); - $commits = json_decode($content, true); - return $commits[0]; + $url = "https://codeload.github.com/".$g_userrepo."/zip/".$commitSHA; + $filename = "./data/update_{$commitSHA}.zip"; + + log_info("update", "Attempting to download Shimmie commit: ".$commitSHA); + if($headers = transload($url, $filename)){ + if(($headers['Content-Type'] !== "application/zip") || ((int) $headers['Content-Length'] !== filesize($filename))){ + unlink("./data/update_{$commitSHA}.zip"); + log_warning("update", "Download failed: not zip / not same size as remote file."); + return false; + } + + return true; + } + + log_warning("update", "Download failed to download."); + return false; } private function update_shimmie() { - //This is a REALLY ugly function. (Damn my limited PHP knowledge >_<) global $config, $page; - $latestCommit = $this->get_latest_commit(); - if(is_null($latestCommit)) return; + $commitSHA = $_GET['sha']; + $g_userrepo = $config->get_string('update_guserrepo'); - $commitDT = explode("T", $latestCommit["commit"]["committer"]["date"]); - $commitTD = explode("-", $commitDT[1]); - $commitDateTime = $commitDT[0]." (".$commitTD[0].")"; - $commitSHA = substr($latestCommit["sha"],0,7); + log_info("update", "Download succeeded. Attempting to update Shimmie."); + $config->set_bool("in_upgrade", TRUE); + $ok = FALSE; - $html = ""; - $url = "http://nodeload.github.com/".$g_user."/".$g_repo."/zipball/".$commitSHA; - $mfile = "master.zip"; - if(glob("*-shimmie2-".$commitSHA)) { //#3 - $dir = glob("*-shimmie2-".$commitSHA); - preg_match('@^([a-zA-Z0-9]+\-[0-9a-z]+\-)([^/]+)@i', $dir[0], $matches); - if(!empty($matches[2])) { - $html .= "commit: ".$matches[2]; - $commit = $matches[2]; - mkdir("./backup"); - $html .= "
backup folder created!"; - $d_dir = data_path("cache"); - //This should empty the /data/cache/ folder. - if (is_dir($d_dir)) { - $objects = scandir($d_dir); - foreach ($objects as $object) { - if ($object != "." && $object != "..") { - if (filetype($d_dir."/".$object) == "dir") rmdir($d_dir."/".$object); else unlink($d_dir."/".$object); - } - } - reset($objects); - $html .= "
data folder emptied!"; - } - copy ("./data/config/shimmie.conf.php", "./backup/shimmie.conf.php");//Although this stays the same, will keep backup just incase. - $folders = array("./core", "./lib", "./themes", "./.htaccess", "./doxygen.conf", "./index.php", "./install.php", "./ext", "./contrib"); - foreach($folders as $folder){ - //TODO: Check MD5 of each file, don't rename if same. - rename ($folder, "./backup".substr($folder, 1)); //Move old files to backup - rename ("./".$matches[0].substr($folder, 1), $folder); //Move new files to main - } - $html .= "
old shimmie setup has been moved to /backup/ (excluding images/thumbs)!"; - if (is_dir($matches[0])) { - $objects = scandir($matches[0]); - foreach ($objects as $object) { - if ($object != "." && $object != "..") { - if (filetype($matches[0]."/".$object) == "dir") rmdir($matches[0]."/".$object); else unlink($matches[0]."/".$object); - } - } - reset($objects); - rmdir($matches[0]); - $html .= "
".$matches[0]." deleted!"; - } - $html .= "
shimmie updated (although you may have gotten errors, it should have worked!"; - $html .= "
due to the way shimmie loads extensions, all optional extensions have been disabled"; - $config->set_string("commit_hash", $commit); - $config->set_string("commit_time", $commitDateTime); - $html .= "
new commit_hash has been set!"; - } - else { - $html .= "Error! Folder does not exist!?"; //Although this should be impossible, shall have it anyway. - } - } - elseif (file_exists($mfile)) { //#2 - $zip = new ZipArchive; - if ($zip->open($mfile) === TRUE) { - $zip->extractTo('./'); - $zip->close(); - $html .= "extracted!"; - $html .= "
refresh the page to continue!"; - unlink($mfile); //Deletes master.zip - } - else { - $html .= "failed!"; - } - } - else { //#1 - //Taken from the upload ext. - transload($url, $mfile); + /** TODO: Backup all folders (except /data, /images, /thumbs) before attempting this? + Either that or point to https://github.com/shish/shimmie2/blob/master/README.txt -> Upgrade from 2.3.X **/ - if(file_exists($mfile)) { - $html .= "downloaded!"; - $html .= "
refresh the page to continue!"; - } - else { - $html .= "download failed!"; - $html .= "
refresh to try again!"; - $html .= "
if you keep having this problem, you may have a problem with your transload engine!"; + $zip = new ZipArchive; + if ($zip->open("./data/update_$commitSHA.zip") === TRUE) { + for($i = 1; $i < $zip->numFiles; $i++) { + $filename = $zip->getNameIndex($i); + + if(substr($filename, -1) !== "/"){ + copy("zip://".dirname(dirname(__DIR__)).'/'."./data/update_$commitSHA.zip"."#".$filename, substr($filename, 50)); + } } + $ok = TRUE; //TODO: Do proper checking to see if everything copied properly + }else{ log_warning("update", "Update failed to open ZIP."); } + + $zip->close(); + unlink("./data/update_$commitSHA.zip"); + $config->set_bool("in_upgrade", FALSE); + + if($ok){ + $config->set_string("commit_hash", $commitSHA); + $config->set_string("update_time", date('d-m-Y')); + log_info("update", "Update succeeded?"); } - $page->add_block(new Block("Update", $html)); + return $ok; } } diff --git a/ext/update/script.js b/ext/update/script.js new file mode 100644 index 00000000..56117653 --- /dev/null +++ b/ext/update/script.js @@ -0,0 +1,14 @@ +$(function() { + if($('#updatecheck').length !== 0){ + $.getJSON('https://api.github.com/repos/shish/shimmie2/commits', function(data){ + var c = data[0]; + $('#updatecheck').html(''+c['sha']+'' + " ("+c['commit']['message']+")"); + + var params = $.param({sha: c['sha'], date: c['commit']['committer']['date']}); + $('#updatelink').attr('href', function(i, val){ return val + "?" + params; }); + $('#updatelink').text("Update"); + }).fail(function(){ + $('#updatecheck').text("Loading failed. (Github down?)"); + }); + } +}); diff --git a/ext/update/theme.php b/ext/update/theme.php new file mode 100644 index 00000000..4823e0c6 --- /dev/null +++ b/ext/update/theme.php @@ -0,0 +1,14 @@ +Current Commit: ".$config->get_string('commit_hash')." | (".$config->get_string('update_time').")". + "
Latest Commit: Loading...". + "
"; + //TODO: Show warning before use. + $page->add_block(new Block("Software Update", $html, "main", 75)); + } +} +?>