[update] remove extension - unzipping new code over the top of old code is fundamentally unsafe
This commit is contained in:
parent
cc9de6b4b2
commit
79087c51a5
5 changed files with 88 additions and 285 deletions
|
@ -294,162 +294,135 @@ class Pools extends Extension
|
||||||
if ($event->page_matches("pool/edit")) {
|
if ($event->page_matches("pool/edit")) {
|
||||||
$pool_id = int_escape($event->req_POST("pool_id"));
|
$pool_id = int_escape($event->req_POST("pool_id"));
|
||||||
$pool = $this->get_single_pool($pool_id);
|
$pool = $this->get_single_pool($pool_id);
|
||||||
|
$this->assert_permission($user, $pool);
|
||||||
|
|
||||||
if ($this->have_permission($user, $pool)) {
|
$result = $database->execute("SELECT image_id FROM pool_images WHERE pool_id=:pid ORDER BY image_order ASC", ["pid" => $pool_id]);
|
||||||
$result = $database->execute("SELECT image_id FROM pool_images WHERE pool_id=:pid ORDER BY image_order ASC", ["pid" => $pool_id]);
|
$images = [];
|
||||||
$images = [];
|
while ($row = $result->fetch()) {
|
||||||
while ($row = $result->fetch()) {
|
$images[] = Image::by_id((int) $row["image_id"]);
|
||||||
$images[] = Image::by_id((int) $row["image_id"]);
|
|
||||||
}
|
|
||||||
$this->theme->edit_pool($page, $pool, $images);
|
|
||||||
} else {
|
|
||||||
$page->set_mode(PageMode::REDIRECT);
|
|
||||||
$page->set_redirect(make_link("pool/view/" . $pool_id));
|
|
||||||
}
|
}
|
||||||
|
$this->theme->edit_pool($page, $pool, $images);
|
||||||
}
|
}
|
||||||
if ($event->page_matches("pool/order")) {
|
if ($event->page_matches("pool/order")) {
|
||||||
$pool_id = int_escape($event->req_POST("pool_id"));
|
$pool_id = int_escape($event->req_POST("pool_id"));
|
||||||
$pool = $this->get_single_pool($pool_id);
|
$pool = $this->get_single_pool($pool_id);
|
||||||
|
$this->assert_permission($user, $pool);
|
||||||
|
|
||||||
if ($event->get_POST("order_view")) {
|
if ($event->get_POST("order_view")) {
|
||||||
if ($this->have_permission($user, $pool)) {
|
$result = $database->execute(
|
||||||
$result = $database->execute(
|
"SELECT image_id FROM pool_images WHERE pool_id=:pid ORDER BY image_order ASC",
|
||||||
"SELECT image_id FROM pool_images WHERE pool_id=:pid ORDER BY image_order ASC",
|
["pid" => $pool_id]
|
||||||
["pid" => $pool_id]
|
);
|
||||||
);
|
$images = [];
|
||||||
$images = [];
|
|
||||||
|
|
||||||
while ($row = $result->fetch()) {
|
while ($row = $result->fetch()) {
|
||||||
$image = $database->get_row(
|
$image = $database->get_row(
|
||||||
"
|
"
|
||||||
SELECT * FROM images AS i
|
SELECT * FROM images AS i
|
||||||
INNER JOIN pool_images AS p ON i.id = p.image_id
|
INNER JOIN pool_images AS p ON i.id = p.image_id
|
||||||
WHERE pool_id=:pid AND i.id=:iid",
|
WHERE pool_id=:pid AND i.id=:iid",
|
||||||
["pid" => $pool_id, "iid" => (int) $row['image_id']]
|
["pid" => $pool_id, "iid" => (int) $row['image_id']]
|
||||||
);
|
);
|
||||||
$images[] = ($image ? new Image($image) : null);
|
$images[] = ($image ? new Image($image) : null);
|
||||||
}
|
|
||||||
|
|
||||||
$this->theme->edit_order($page, $pool, $images);
|
|
||||||
} else {
|
|
||||||
$page->set_mode(PageMode::REDIRECT);
|
|
||||||
$page->set_redirect(make_link("pool/view/" . $pool_id));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$this->theme->edit_order($page, $pool, $images);
|
||||||
} else {
|
} else {
|
||||||
if ($this->have_permission($user, $pool)) {
|
foreach ($event->POST as $key => $value) {
|
||||||
foreach ($event->POST as $key => $value) {
|
if (str_starts_with($key, "order_")) {
|
||||||
if (str_starts_with($key, "order_")) {
|
$imageID = (int) substr($key, 6);
|
||||||
$imageID = (int) substr($key, 6);
|
$database->execute(
|
||||||
$database->execute(
|
"
|
||||||
"
|
|
||||||
UPDATE pool_images
|
UPDATE pool_images
|
||||||
SET image_order = :ord
|
SET image_order = :ord
|
||||||
WHERE pool_id = :pid AND image_id = :iid",
|
WHERE pool_id = :pid AND image_id = :iid",
|
||||||
["ord" => $value, "pid" => int_escape($event->req_POST('pool_id')), "iid" => $imageID]
|
["ord" => $value, "pid" => int_escape($event->req_POST('pool_id')), "iid" => $imageID]
|
||||||
);
|
);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
$page->set_mode(PageMode::REDIRECT);
|
|
||||||
$page->set_redirect(make_link("pool/view/" . $pool_id));
|
|
||||||
} else {
|
|
||||||
$this->theme->display_error(403, "Permission Denied", "You do not have permission to access this page");
|
|
||||||
}
|
}
|
||||||
|
$page->set_mode(PageMode::REDIRECT);
|
||||||
|
$page->set_redirect(make_link("pool/view/" . $pool_id));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ($event->page_matches("pool/reverse")) {
|
if ($event->page_matches("pool/reverse")) {
|
||||||
$pool_id = int_escape($event->req_POST("pool_id"));
|
$pool_id = int_escape($event->req_POST("pool_id"));
|
||||||
$pool = $this->get_single_pool($pool_id);
|
$pool = $this->get_single_pool($pool_id);
|
||||||
|
$this->assert_permission($user, $pool);
|
||||||
|
|
||||||
if ($this->have_permission($user, $pool)) {
|
$database->with_savepoint(function () use ($pool_id) {
|
||||||
$database->with_savepoint(function () use ($pool_id) {
|
global $database;
|
||||||
global $database;
|
$result = $database->execute(
|
||||||
$result = $database->execute(
|
"SELECT image_id FROM pool_images WHERE pool_id=:pid ORDER BY image_order DESC",
|
||||||
"SELECT image_id FROM pool_images WHERE pool_id=:pid ORDER BY image_order DESC",
|
["pid" => $pool_id]
|
||||||
["pid" => $pool_id]
|
);
|
||||||
);
|
$image_order = 1;
|
||||||
$image_order = 1;
|
while ($row = $result->fetch()) {
|
||||||
while ($row = $result->fetch()) {
|
$database->execute(
|
||||||
$database->execute(
|
"
|
||||||
"
|
|
||||||
UPDATE pool_images
|
UPDATE pool_images
|
||||||
SET image_order=:ord
|
SET image_order=:ord
|
||||||
WHERE pool_id = :pid AND image_id = :iid",
|
WHERE pool_id = :pid AND image_id = :iid",
|
||||||
["ord" => $image_order, "pid" => $pool_id, "iid" => (int) $row['image_id']]
|
["ord" => $image_order, "pid" => $pool_id, "iid" => (int) $row['image_id']]
|
||||||
);
|
);
|
||||||
$image_order = $image_order + 1;
|
$image_order = $image_order + 1;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
$page->set_mode(PageMode::REDIRECT);
|
$page->set_mode(PageMode::REDIRECT);
|
||||||
$page->set_redirect(make_link("pool/view/" . $pool_id));
|
$page->set_redirect(make_link("pool/view/" . $pool_id));
|
||||||
} else {
|
|
||||||
$this->theme->display_error(403, "Permission Denied", "You do not have permission to access this page");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if ($event->page_matches("pool/import")) {
|
if ($event->page_matches("pool/import")) {
|
||||||
$pool_id = int_escape($event->req_POST("pool_id"));
|
$pool_id = int_escape($event->req_POST("pool_id"));
|
||||||
$pool = $this->get_single_pool($pool_id);
|
$pool = $this->get_single_pool($pool_id);
|
||||||
|
$this->assert_permission($user, $pool);
|
||||||
|
|
||||||
if ($this->have_permission($user, $pool)) {
|
$images = Search::find_images(
|
||||||
$images = Search::find_images(
|
limit: $config->get_int(PoolsConfig::MAX_IMPORT_RESULTS, 1000),
|
||||||
limit: $config->get_int(PoolsConfig::MAX_IMPORT_RESULTS, 1000),
|
tags: Tag::explode($event->req_POST("pool_tag"))
|
||||||
tags: Tag::explode($event->req_POST("pool_tag"))
|
);
|
||||||
);
|
$this->theme->pool_result($page, $images, $pool);
|
||||||
$this->theme->pool_result($page, $images, $pool);
|
|
||||||
} else {
|
|
||||||
$this->theme->display_error(403, "Permission Denied", "You do not have permission to access this page");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if ($event->page_matches("pool/add_posts")) {
|
if ($event->page_matches("pool/add_posts")) {
|
||||||
$pool_id = int_escape($event->req_POST("pool_id"));
|
$pool_id = int_escape($event->req_POST("pool_id"));
|
||||||
$pool = $this->get_single_pool($pool_id);
|
$pool = $this->get_single_pool($pool_id);
|
||||||
|
$this->assert_permission($user, $pool);
|
||||||
|
|
||||||
if ($this->have_permission($user, $pool)) {
|
$image_ids = array_map('intval', $event->req_POST_array('check'));
|
||||||
$image_ids = array_map('intval', $event->req_POST_array('check'));
|
send_event(new PoolAddPostsEvent($pool_id, $image_ids));
|
||||||
send_event(new PoolAddPostsEvent($pool_id, $image_ids));
|
$page->set_mode(PageMode::REDIRECT);
|
||||||
$page->set_mode(PageMode::REDIRECT);
|
$page->set_redirect(make_link("pool/view/" . $pool_id));
|
||||||
$page->set_redirect(make_link("pool/view/" . $pool_id));
|
|
||||||
} else {
|
|
||||||
$this->theme->display_error(403, "Permission Denied", "You do not have permission to access this page");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if ($event->page_matches("pool/remove_posts")) {
|
if ($event->page_matches("pool/remove_posts")) {
|
||||||
$pool_id = int_escape($event->req_POST("pool_id"));
|
$pool_id = int_escape($event->req_POST("pool_id"));
|
||||||
$pool = $this->get_single_pool($pool_id);
|
$pool = $this->get_single_pool($pool_id);
|
||||||
|
$this->assert_permission($user, $pool);
|
||||||
|
|
||||||
if ($this->have_permission($user, $pool)) {
|
$images = "";
|
||||||
$images = "";
|
foreach ($event->req_POST_array('check') as $imageID) {
|
||||||
foreach ($event->req_POST_array('check') as $imageID) {
|
$database->execute(
|
||||||
$database->execute(
|
"DELETE FROM pool_images WHERE pool_id = :pid AND image_id = :iid",
|
||||||
"DELETE FROM pool_images WHERE pool_id = :pid AND image_id = :iid",
|
["pid" => $pool_id, "iid" => $imageID]
|
||||||
["pid" => $pool_id, "iid" => $imageID]
|
|
||||||
);
|
|
||||||
$images .= " " . $imageID;
|
|
||||||
}
|
|
||||||
$count = (int) $database->get_one(
|
|
||||||
"SELECT COUNT(*) FROM pool_images WHERE pool_id=:pid",
|
|
||||||
["pid" => $pool_id]
|
|
||||||
);
|
);
|
||||||
$this->add_history($pool_id, 0, $images, $count);
|
$images .= " " . $imageID;
|
||||||
$page->set_mode(PageMode::REDIRECT);
|
|
||||||
$page->set_redirect(make_link("pool/view/" . $pool_id));
|
|
||||||
} else {
|
|
||||||
$this->theme->display_error(403, "Permission Denied", "You do not have permission to access this page");
|
|
||||||
}
|
}
|
||||||
|
$count = (int) $database->get_one(
|
||||||
|
"SELECT COUNT(*) FROM pool_images WHERE pool_id=:pid",
|
||||||
|
["pid" => $pool_id]
|
||||||
|
);
|
||||||
|
$this->add_history($pool_id, 0, $images, $count);
|
||||||
|
$page->set_mode(PageMode::REDIRECT);
|
||||||
|
$page->set_redirect(make_link("pool/view/" . $pool_id));
|
||||||
}
|
}
|
||||||
if ($event->page_matches("pool/edit_description")) {
|
if ($event->page_matches("pool/edit_description")) {
|
||||||
$pool_id = int_escape($event->req_POST("pool_id"));
|
$pool_id = int_escape($event->req_POST("pool_id"));
|
||||||
$pool = $this->get_single_pool($pool_id);
|
$pool = $this->get_single_pool($pool_id);
|
||||||
|
$this->assert_permission($user, $pool);
|
||||||
|
|
||||||
if ($this->have_permission($user, $pool)) {
|
$database->execute(
|
||||||
$database->execute(
|
"UPDATE pools SET description=:dsc,lastupdated=CURRENT_TIMESTAMP WHERE id=:pid",
|
||||||
"UPDATE pools SET description=:dsc,lastupdated=CURRENT_TIMESTAMP WHERE id=:pid",
|
["dsc" => $event->req_POST('description'), "pid" => $pool_id]
|
||||||
["dsc" => $event->req_POST('description'), "pid" => $pool_id]
|
);
|
||||||
);
|
$page->set_mode(PageMode::REDIRECT);
|
||||||
$page->set_mode(PageMode::REDIRECT);
|
$page->set_redirect(make_link("pool/view/" . $pool_id));
|
||||||
$page->set_redirect(make_link("pool/view/" . $pool_id));
|
|
||||||
} else {
|
|
||||||
$this->theme->display_error(403, "Permission Denied", "You do not have permission to access this page");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if ($event->page_matches("pool/nuke")) {
|
if ($event->page_matches("pool/nuke")) {
|
||||||
// Completely remove the given pool.
|
// Completely remove the given pool.
|
||||||
|
@ -462,7 +435,7 @@ class Pools extends Extension
|
||||||
$page->set_mode(PageMode::REDIRECT);
|
$page->set_mode(PageMode::REDIRECT);
|
||||||
$page->set_redirect(make_link("pool/list"));
|
$page->set_redirect(make_link("pool/list"));
|
||||||
} else {
|
} else {
|
||||||
$this->theme->display_error(403, "Permission Denied", "You do not have permission to access this page");
|
throw new PermissionDeniedException("You do not have permission to access this page");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -646,6 +619,13 @@ class Pools extends Extension
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function assert_permission(User $user, Pool $pool): void
|
||||||
|
{
|
||||||
|
if (!$this->have_permission($user, $pool)) {
|
||||||
|
throw new PermissionDeniedException("You do not have permission to access this pool");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private function list_pools(Page $page, int $pageNumber, ?string $search): void
|
private function list_pools(Page $page, int $pageNumber, ?string $search): void
|
||||||
{
|
{
|
||||||
global $config, $database;
|
global $config, $database;
|
||||||
|
@ -758,9 +738,7 @@ class Pools extends Extension
|
||||||
global $database, $user;
|
global $database, $user;
|
||||||
|
|
||||||
$pool = $this->get_single_pool($event->pool_id);
|
$pool = $this->get_single_pool($event->pool_id);
|
||||||
if (!$this->have_permission($user, $pool)) {
|
$this->assert_permission($user, $pool);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$images = [];
|
$images = [];
|
||||||
foreach ($event->posts as $post_id) {
|
foreach ($event->posts as $post_id) {
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace Shimmie2;
|
|
||||||
|
|
||||||
class UpdateInfo extends ExtensionInfo
|
|
||||||
{
|
|
||||||
public const KEY = "update";
|
|
||||||
|
|
||||||
public string $key = self::KEY;
|
|
||||||
public string $name = "Update";
|
|
||||||
public string $url = "http://www.codeanimu.net";
|
|
||||||
public array $authors = ["DakuTree" => "dakutree@codeanimu.net"];
|
|
||||||
public string $license = self::LICENSE_GPLV2;
|
|
||||||
public string $description = "Shimmie updater!";
|
|
||||||
public array $dependencies = [AdminPageInfo::KEY];
|
|
||||||
public ExtensionCategory $category = ExtensionCategory::ADMIN;
|
|
||||||
}
|
|
|
@ -1,120 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace Shimmie2;
|
|
||||||
|
|
||||||
class Update extends Extension
|
|
||||||
{
|
|
||||||
/** @var UpdateTheme */
|
|
||||||
protected Themelet $theme;
|
|
||||||
|
|
||||||
public function onInitExt(InitExtEvent $event): void
|
|
||||||
{
|
|
||||||
global $config;
|
|
||||||
$config->set_default_string("update_guserrepo", "shish/shimmie2");
|
|
||||||
$config->set_default_string("commit_hash", "unknown");
|
|
||||||
$config->set_default_string("update_time", "01/01/1970");
|
|
||||||
}
|
|
||||||
|
|
||||||
public function onSetupBuilding(SetupBuildingEvent $event): void
|
|
||||||
{
|
|
||||||
$sb = $event->panel->create_new_block("Update");
|
|
||||||
$sb->add_text_option("update_guserrepo", "User/Repo: ");
|
|
||||||
}
|
|
||||||
|
|
||||||
public function onAdminBuilding(AdminBuildingEvent $event): void
|
|
||||||
{
|
|
||||||
global $config;
|
|
||||||
if ($config->get_string(UploadConfig::TRANSLOAD_ENGINE) !== "none") {
|
|
||||||
$this->theme->display_admin_block();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function onPageRequest(PageRequestEvent $event): void
|
|
||||||
{
|
|
||||||
global $user, $page;
|
|
||||||
$sha = $event->get_GET('sha');
|
|
||||||
|
|
||||||
// FIXME: use POST
|
|
||||||
if ($event->page_matches("update/download", permission: Permissions::EDIT_FILES)) {
|
|
||||||
assert(!is_null($sha));
|
|
||||||
$ok = $this->download_shimmie($sha);
|
|
||||||
|
|
||||||
$page->set_mode(PageMode::REDIRECT);
|
|
||||||
if ($ok) {
|
|
||||||
$page->set_redirect(make_link("update/update", "sha=".$sha));
|
|
||||||
} else {
|
|
||||||
$page->set_redirect(make_link("admin"));
|
|
||||||
} //TODO: Show error?
|
|
||||||
}
|
|
||||||
if ($event->page_matches("update/update", permission: Permissions::EDIT_FILES)) {
|
|
||||||
assert(!is_null($sha));
|
|
||||||
$ok = $this->update_shimmie($sha);
|
|
||||||
|
|
||||||
$page->set_mode(PageMode::REDIRECT);
|
|
||||||
if ($ok) {
|
|
||||||
$page->set_redirect(make_link("admin"));
|
|
||||||
} //TODO: Show success?
|
|
||||||
else {
|
|
||||||
$page->set_redirect(make_link("admin"));
|
|
||||||
} //TODO: Show error?
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private function download_shimmie(string $commitSHA): bool
|
|
||||||
{
|
|
||||||
global $config;
|
|
||||||
|
|
||||||
$g_userrepo = $config->get_string('update_guserrepo');
|
|
||||||
|
|
||||||
$url = "https://codeload.github.com/".$g_userrepo."/zip/".$commitSHA;
|
|
||||||
$filename = "./data/update_{$commitSHA}.zip";
|
|
||||||
|
|
||||||
log_info("update", "Attempting to download Shimmie commit: ".$commitSHA);
|
|
||||||
$headers = fetch_url($url, $filename);
|
|
||||||
if (($headers['Content-Type'] !== MimeType::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;
|
|
||||||
}
|
|
||||||
|
|
||||||
private function update_shimmie(string $commitSHA): bool
|
|
||||||
{
|
|
||||||
global $config;
|
|
||||||
|
|
||||||
log_info("update", "Download succeeded. Attempting to update Shimmie.");
|
|
||||||
$ok = false;
|
|
||||||
|
|
||||||
/** 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 **/
|
|
||||||
|
|
||||||
$zip = new \ZipArchive();
|
|
||||||
if ($zip->open("./data/update_$commitSHA.zip") === true) {
|
|
||||||
for ($i = 1; $i < $zip->numFiles; $i++) {
|
|
||||||
$filename = false_throws($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");
|
|
||||||
|
|
||||||
if ($ok) {
|
|
||||||
$config->set_string("commit_hash", $commitSHA);
|
|
||||||
$config->set_string("update_time", date('d-m-Y'));
|
|
||||||
log_info("update", "Update succeeded?");
|
|
||||||
}
|
|
||||||
|
|
||||||
return $ok;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,16 +0,0 @@
|
||||||
/*jshint bitwise:true, curly:true, forin:false, noarg:true, noempty:true, nonew:true, undef:true, strict:false, browser:true, jquery:true */
|
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', () => {
|
|
||||||
if($('#updatecheck').length !== 0){
|
|
||||||
$.getJSON('https://api.github.com/repos/shish/shimmie2/commits', function(data){
|
|
||||||
var c = data[0];
|
|
||||||
$('#updatecheck').html('<a href="'+ c.html_url+'">'+ c.sha+'</a>' + " ("+ 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?)");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
|
@ -1,20 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace Shimmie2;
|
|
||||||
|
|
||||||
class UpdateTheme extends Themelet
|
|
||||||
{
|
|
||||||
public function display_admin_block(): void
|
|
||||||
{
|
|
||||||
global $page, $config;
|
|
||||||
|
|
||||||
$html = "".
|
|
||||||
"<b>Current Commit</b>: ".$config->get_string('commit_hash')." | (".$config->get_string('update_time').")".
|
|
||||||
"<br><b>Latest Commit</b>: <span id='updatecheck'>Loading...</span>".
|
|
||||||
"<br><a href='" . make_link('update/download') . "' id='updatelink'></a>";
|
|
||||||
//TODO: Show warning before use.
|
|
||||||
$page->add_block(new Block("Software Update", $html, "main", 75));
|
|
||||||
}
|
|
||||||
}
|
|
Reference in a new issue