2021-12-14 18:32:47 +00:00
|
|
|
<?php
|
|
|
|
|
|
|
|
declare(strict_types=1);
|
2007-05-23 22:53:35 +00:00
|
|
|
|
2023-01-10 22:44:09 +00:00
|
|
|
namespace Shimmie2;
|
|
|
|
|
2023-02-13 22:28:50 +00:00
|
|
|
use GQLA\Type;
|
|
|
|
use GQLA\Field;
|
|
|
|
use GQLA\Query;
|
|
|
|
use GQLA\Mutation;
|
|
|
|
|
2019-05-28 16:59:38 +00:00
|
|
|
class WikiUpdateEvent extends Event
|
|
|
|
{
|
2021-03-14 23:43:50 +00:00
|
|
|
public User $user;
|
|
|
|
public WikiPage $wikipage;
|
2019-05-28 16:59:38 +00:00
|
|
|
|
|
|
|
public function __construct(User $user, WikiPage $wikipage)
|
|
|
|
{
|
2020-01-26 13:19:35 +00:00
|
|
|
parent::__construct();
|
2019-05-28 16:59:38 +00:00
|
|
|
$this->user = $user;
|
|
|
|
$this->wikipage = $wikipage;
|
|
|
|
}
|
2007-05-23 22:53:35 +00:00
|
|
|
}
|
2009-07-28 01:06:51 +00:00
|
|
|
|
2020-01-29 00:49:21 +00:00
|
|
|
class WikiDeleteRevisionEvent extends Event
|
|
|
|
{
|
2021-03-14 23:43:50 +00:00
|
|
|
public string $title;
|
|
|
|
public int $revision;
|
2020-01-28 21:19:59 +00:00
|
|
|
|
2021-03-14 23:43:50 +00:00
|
|
|
public function __construct(string $title, int $revision)
|
2020-01-29 00:49:21 +00:00
|
|
|
{
|
2020-01-28 21:19:59 +00:00
|
|
|
parent::__construct();
|
|
|
|
$this->title = $title;
|
|
|
|
$this->revision = $revision;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-01-29 00:49:21 +00:00
|
|
|
class WikiDeletePageEvent extends Event
|
|
|
|
{
|
2021-03-14 23:43:50 +00:00
|
|
|
public string $title;
|
2020-01-28 21:19:59 +00:00
|
|
|
|
2021-03-14 23:43:50 +00:00
|
|
|
public function __construct(string $title)
|
2020-01-29 00:49:21 +00:00
|
|
|
{
|
2020-01-28 21:19:59 +00:00
|
|
|
parent::__construct();
|
|
|
|
$this->title = $title;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-02-13 22:28:50 +00:00
|
|
|
#[Type(name: "WikiPage")]
|
2019-05-28 16:59:38 +00:00
|
|
|
class WikiPage
|
|
|
|
{
|
2021-03-14 23:43:50 +00:00
|
|
|
public int $id;
|
|
|
|
public int $owner_id;
|
|
|
|
public string $owner_ip;
|
2023-02-13 22:28:50 +00:00
|
|
|
#[Field]
|
2021-03-14 23:43:50 +00:00
|
|
|
public string $date;
|
2023-02-13 22:28:50 +00:00
|
|
|
#[Field]
|
2021-03-14 23:43:50 +00:00
|
|
|
public string $title;
|
2023-02-13 22:28:50 +00:00
|
|
|
#[Field]
|
2021-03-14 23:43:50 +00:00
|
|
|
public int $revision;
|
|
|
|
public bool $locked;
|
2021-11-21 14:10:03 +00:00
|
|
|
public bool $exists;
|
2023-02-13 22:28:50 +00:00
|
|
|
#[Field]
|
2021-03-14 23:43:50 +00:00
|
|
|
public string $body;
|
2019-05-28 16:59:38 +00:00
|
|
|
|
2024-01-20 14:10:59 +00:00
|
|
|
/**
|
|
|
|
* @param array<string, mixed> $row
|
|
|
|
*/
|
2024-08-31 23:04:34 +00:00
|
|
|
public function __construct(?array $row = null)
|
2019-05-28 16:59:38 +00:00
|
|
|
{
|
|
|
|
//assert(!empty($row));
|
2021-11-21 14:10:03 +00:00
|
|
|
global $database;
|
2019-05-28 16:59:38 +00:00
|
|
|
|
|
|
|
if (!is_null($row)) {
|
2020-01-28 21:19:59 +00:00
|
|
|
$this->id = (int)$row['id'];
|
|
|
|
$this->owner_id = (int)$row['owner_id'];
|
2019-05-28 16:59:38 +00:00
|
|
|
$this->owner_ip = $row['owner_ip'];
|
|
|
|
$this->date = $row['date'];
|
|
|
|
$this->title = $row['title'];
|
2020-01-28 21:19:59 +00:00
|
|
|
$this->revision = (int)$row['revision'];
|
2020-10-26 16:46:36 +00:00
|
|
|
$this->locked = bool_escape($row['locked']);
|
2023-11-11 21:49:12 +00:00
|
|
|
$this->exists = $database->exists("SELECT id FROM wiki_pages WHERE title = :title", ["title" => $this->title]);
|
2019-05-28 16:59:38 +00:00
|
|
|
$this->body = $row['body'];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-02-13 22:28:50 +00:00
|
|
|
#[Field(name: "owner")]
|
2019-05-28 16:59:38 +00:00
|
|
|
public function get_owner(): User
|
|
|
|
{
|
|
|
|
return User::by_id($this->owner_id);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function is_locked(): bool
|
|
|
|
{
|
|
|
|
return $this->locked;
|
|
|
|
}
|
2021-11-21 14:10:03 +00:00
|
|
|
|
|
|
|
public function exists(): bool
|
|
|
|
{
|
|
|
|
return $this->exists;
|
|
|
|
}
|
2007-05-23 23:17:45 +00:00
|
|
|
}
|
2007-07-19 12:51:12 +00:00
|
|
|
|
2020-03-23 12:48:38 +00:00
|
|
|
abstract class WikiConfig
|
|
|
|
{
|
2021-12-14 18:32:47 +00:00
|
|
|
public const TAG_PAGE_TEMPLATE = "wiki_tag_page_template";
|
|
|
|
public const EMPTY_TAGINFO = "wiki_empty_taginfo";
|
|
|
|
public const TAG_SHORTWIKIS = "shortwikis_on_tags";
|
|
|
|
public const ENABLE_REVISIONS = "wiki_revisions";
|
2020-03-23 12:48:38 +00:00
|
|
|
}
|
|
|
|
|
2019-05-28 16:59:38 +00:00
|
|
|
class Wiki extends Extension
|
|
|
|
{
|
2020-01-26 13:19:35 +00:00
|
|
|
/** @var WikiTheme */
|
2023-06-27 14:56:49 +00:00
|
|
|
protected Themelet $theme;
|
2020-01-26 13:19:35 +00:00
|
|
|
|
2024-01-15 11:52:35 +00:00
|
|
|
public function onInitExt(InitExtEvent $event): void
|
2020-03-23 12:48:38 +00:00
|
|
|
{
|
|
|
|
global $config;
|
2021-02-12 20:07:02 +00:00
|
|
|
$config->set_default_string(
|
|
|
|
WikiConfig::TAG_PAGE_TEMPLATE,
|
|
|
|
"{body}
|
2020-12-01 00:53:04 +00:00
|
|
|
|
|
|
|
[b]Aliases: [/b][i]{aliases}[/i]
|
2021-02-12 20:07:02 +00:00
|
|
|
[b]Auto tags: [/b][i]{autotags}[/i]"
|
|
|
|
);
|
2020-12-01 00:53:04 +00:00
|
|
|
$config->set_default_string(WikiConfig::EMPTY_TAGINFO, "none");
|
2020-03-23 12:48:38 +00:00
|
|
|
$config->set_default_bool(WikiConfig::TAG_SHORTWIKIS, false);
|
2020-12-28 02:02:06 +00:00
|
|
|
$config->set_default_bool(WikiConfig::ENABLE_REVISIONS, true);
|
2020-03-23 12:48:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Add a block to the Board Config / Setup
|
2024-01-15 11:52:35 +00:00
|
|
|
public function onSetupBuilding(SetupBuildingEvent $event): void
|
2020-03-23 12:48:38 +00:00
|
|
|
{
|
2020-10-26 15:13:28 +00:00
|
|
|
$sb = $event->panel->create_new_block("Wiki");
|
2020-12-28 02:02:06 +00:00
|
|
|
$sb->add_bool_option(WikiConfig::ENABLE_REVISIONS, "Enable wiki revisions: ");
|
2024-01-03 15:51:22 +00:00
|
|
|
$sb->add_longtext_option(WikiConfig::TAG_PAGE_TEMPLATE, "<br/>Tag page template: ");
|
|
|
|
$sb->add_text_option(WikiConfig::EMPTY_TAGINFO, "<br/>Empty list text: ");
|
|
|
|
$sb->add_bool_option(WikiConfig::TAG_SHORTWIKIS, "<br/>Show shortwiki entry when searching for a single tag: ");
|
2020-03-23 12:48:38 +00:00
|
|
|
}
|
|
|
|
|
2024-01-15 11:52:35 +00:00
|
|
|
public function onDatabaseUpgrade(DatabaseUpgradeEvent $event): void
|
2019-05-28 16:59:38 +00:00
|
|
|
{
|
2020-01-26 13:19:35 +00:00
|
|
|
global $database;
|
2009-08-03 10:04:43 +00:00
|
|
|
|
2019-11-03 23:43:35 +00:00
|
|
|
if ($this->get_version("ext_wiki_version") < 1) {
|
2019-05-28 16:59:38 +00:00
|
|
|
$database->create_table("wiki_pages", "
|
2009-08-03 10:04:43 +00:00
|
|
|
id SCORE_AIPK,
|
|
|
|
owner_id INTEGER NOT NULL,
|
|
|
|
owner_ip SCORE_INET NOT NULL,
|
2019-11-03 18:28:05 +00:00
|
|
|
date TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
2009-08-03 10:04:43 +00:00
|
|
|
title VARCHAR(255) NOT NULL,
|
|
|
|
revision INTEGER NOT NULL DEFAULT 1,
|
2020-10-26 22:37:25 +00:00
|
|
|
locked BOOLEAN NOT NULL DEFAULT FALSE,
|
2009-08-03 10:04:43 +00:00
|
|
|
body TEXT NOT NULL,
|
|
|
|
UNIQUE (title, revision),
|
2012-03-11 01:52:25 +00:00
|
|
|
FOREIGN KEY (owner_id) REFERENCES users(id) ON DELETE RESTRICT
|
2009-08-03 10:04:43 +00:00
|
|
|
");
|
2020-10-26 16:46:36 +00:00
|
|
|
$this->set_version("ext_wiki_version", 3);
|
2019-05-28 16:59:38 +00:00
|
|
|
}
|
2019-11-03 19:49:52 +00:00
|
|
|
if ($this->get_version("ext_wiki_version") < 2) {
|
2020-10-25 21:34:52 +00:00
|
|
|
$database->execute("ALTER TABLE wiki_pages ADD COLUMN
|
2009-08-03 10:04:43 +00:00
|
|
|
locked ENUM('Y', 'N') DEFAULT 'N' NOT NULL AFTER REVISION");
|
2019-11-03 19:49:52 +00:00
|
|
|
$this->set_version("ext_wiki_version", 2);
|
2019-05-28 16:59:38 +00:00
|
|
|
}
|
2020-10-26 16:46:36 +00:00
|
|
|
if ($this->get_version("ext_wiki_version") < 3) {
|
2020-10-26 17:28:21 +00:00
|
|
|
$database->standardise_boolean("wiki_pages", "locked", true);
|
2020-10-26 16:46:36 +00:00
|
|
|
$this->set_version("ext_wiki_version", 3);
|
|
|
|
}
|
2019-05-28 16:59:38 +00:00
|
|
|
}
|
|
|
|
|
2024-01-15 11:52:35 +00:00
|
|
|
public function onPageRequest(PageRequestEvent $event): void
|
2019-05-28 16:59:38 +00:00
|
|
|
{
|
|
|
|
global $page, $user;
|
2024-02-11 11:34:09 +00:00
|
|
|
if ($event->page_matches("wiki/{title}/{action}", method: "GET")) {
|
|
|
|
$title = $event->get_arg('title');
|
|
|
|
$action = $event->get_arg('action');
|
2024-02-10 16:40:38 +00:00
|
|
|
|
2024-08-31 16:05:18 +00:00
|
|
|
if ($action == "history") {
|
2024-02-10 16:40:38 +00:00
|
|
|
$history = $this->get_history($title);
|
|
|
|
$this->theme->display_page_history($page, $title, $history);
|
2024-08-31 16:05:18 +00:00
|
|
|
} elseif ($action == "edit") {
|
2024-02-10 16:40:38 +00:00
|
|
|
$content = $this->get_page($title);
|
|
|
|
if ($this->can_edit($user, $content)) {
|
|
|
|
$this->theme->display_page_editor($page, $content);
|
|
|
|
} else {
|
2024-02-11 15:47:40 +00:00
|
|
|
throw new PermissionDenied("You are not allowed to edit this page");
|
2024-02-10 16:40:38 +00:00
|
|
|
}
|
2024-02-11 11:34:09 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if ($event->page_matches("wiki/{title}/{action}", method: "POST")) {
|
|
|
|
$title = $event->get_arg('title');
|
|
|
|
$action = $event->get_arg('action');
|
|
|
|
|
2024-08-31 16:05:18 +00:00
|
|
|
if ($action == "save") {
|
2024-02-10 16:40:38 +00:00
|
|
|
$rev = int_escape($event->req_POST('revision'));
|
|
|
|
$body = $event->req_POST('body');
|
|
|
|
$lock = $user->can(Permissions::WIKI_ADMIN) && ($event->get_POST('lock') == "on");
|
|
|
|
|
|
|
|
if ($this->can_edit($user, $this->get_page($title))) {
|
|
|
|
$wikipage = $this->get_page($title);
|
|
|
|
$wikipage->revision = $rev;
|
|
|
|
$wikipage->body = $body;
|
|
|
|
$wikipage->locked = $lock;
|
|
|
|
send_event(new WikiUpdateEvent($user, $wikipage));
|
|
|
|
$u_title = url_escape($title);
|
|
|
|
$page->set_mode(PageMode::REDIRECT);
|
|
|
|
$page->set_redirect(make_link("wiki/$u_title"));
|
|
|
|
} else {
|
2024-02-11 15:47:40 +00:00
|
|
|
throw new PermissionDenied("You are not allowed to edit this page");
|
2024-02-10 16:40:38 +00:00
|
|
|
}
|
2024-08-31 16:05:18 +00:00
|
|
|
} elseif ($action == "delete_revision") {
|
2024-02-10 16:40:38 +00:00
|
|
|
$content = $this->get_page($title);
|
|
|
|
if ($user->can(Permissions::WIKI_ADMIN)) {
|
|
|
|
$revision = int_escape($event->req_POST('revision'));
|
|
|
|
send_event(new WikiDeleteRevisionEvent($title, $revision));
|
|
|
|
$u_title = url_escape($title);
|
|
|
|
$page->set_mode(PageMode::REDIRECT);
|
|
|
|
$page->set_redirect(make_link("wiki/$u_title"));
|
|
|
|
} else {
|
2024-02-11 15:47:40 +00:00
|
|
|
throw new PermissionDenied("You are not allowed to edit this page");
|
2024-02-10 16:40:38 +00:00
|
|
|
}
|
2024-08-31 16:05:18 +00:00
|
|
|
} elseif ($action == "delete_all") {
|
2024-02-10 16:40:38 +00:00
|
|
|
if ($user->can(Permissions::WIKI_ADMIN)) {
|
|
|
|
send_event(new WikiDeletePageEvent($title));
|
|
|
|
$u_title = url_escape($title);
|
|
|
|
$page->set_mode(PageMode::REDIRECT);
|
|
|
|
$page->set_redirect(make_link("wiki/$u_title"));
|
|
|
|
}
|
2019-05-28 16:59:38 +00:00
|
|
|
}
|
2024-02-11 11:34:09 +00:00
|
|
|
} elseif ($event->page_matches("wiki/{title}")) {
|
|
|
|
$title = $event->get_arg('title');
|
|
|
|
$revision = int_escape($event->get_GET('revision') ?? "-1");
|
|
|
|
$content = $this->get_page($title, $revision);
|
|
|
|
$this->theme->display_page($page, $content, $this->get_page("wiki:sidebar"));
|
|
|
|
} elseif ($event->page_matches("wiki")) {
|
|
|
|
$page->set_mode(PageMode::REDIRECT);
|
|
|
|
$page->set_redirect(make_link("wiki/Index"));
|
2019-05-28 16:59:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-01-15 11:52:35 +00:00
|
|
|
public function onPageNavBuilding(PageNavBuildingEvent $event): void
|
2019-08-02 19:54:48 +00:00
|
|
|
{
|
2019-09-29 13:30:55 +00:00
|
|
|
$event->add_nav_link("wiki", new Link('wiki'), "Wiki");
|
2019-08-02 19:54:48 +00:00
|
|
|
}
|
|
|
|
|
2024-01-15 11:52:35 +00:00
|
|
|
public function onPageSubNavBuilding(PageSubNavBuildingEvent $event): void
|
2019-08-02 19:54:48 +00:00
|
|
|
{
|
2023-11-11 21:49:12 +00:00
|
|
|
if ($event->parent == "wiki") {
|
2019-08-02 19:54:48 +00:00
|
|
|
$event->add_nav_link("wiki_rules", new Link('wiki/rules'), "Rules");
|
|
|
|
$event->add_nav_link("wiki_help", new Link('ext_doc/wiki'), "Help");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-01-15 11:52:35 +00:00
|
|
|
public function onWikiUpdate(WikiUpdateEvent $event): void
|
2019-05-28 16:59:38 +00:00
|
|
|
{
|
2020-12-28 02:02:06 +00:00
|
|
|
global $database, $config;
|
2019-05-28 16:59:38 +00:00
|
|
|
$wpage = $event->wikipage;
|
2020-12-28 02:02:06 +00:00
|
|
|
|
2023-11-11 21:49:12 +00:00
|
|
|
$exists = $database->exists("SELECT id FROM wiki_pages WHERE title = :title", ["title" => $wpage->title]);
|
2020-12-28 02:02:06 +00:00
|
|
|
|
2019-05-28 16:59:38 +00:00
|
|
|
try {
|
2023-11-11 21:49:12 +00:00
|
|
|
if ($config->get_bool(WikiConfig::ENABLE_REVISIONS) || !$exists) {
|
2020-12-28 02:02:06 +00:00
|
|
|
$database->execute(
|
|
|
|
"
|
2024-02-11 11:34:09 +00:00
|
|
|
INSERT INTO wiki_pages(owner_id, owner_ip, date, title, revision, locked, body)
|
|
|
|
VALUES (:owner_id, :owner_ip, now(), :title, :revision, :locked, :body)",
|
2023-11-11 21:49:12 +00:00
|
|
|
["owner_id" => $event->user->id, "owner_ip" => get_real_ip(),
|
|
|
|
"title" => $wpage->title, "revision" => $wpage->revision, "locked" => $wpage->locked, "body" => $wpage->body]
|
2020-12-28 02:02:06 +00:00
|
|
|
);
|
|
|
|
} else {
|
|
|
|
$database->execute(
|
|
|
|
"
|
2024-02-11 11:34:09 +00:00
|
|
|
UPDATE wiki_pages SET owner_id=:owner_id, owner_ip=:owner_ip, date=now(), locked=:locked, body=:body
|
|
|
|
WHERE title = :title ORDER BY revision DESC LIMIT 1",
|
2023-11-11 21:49:12 +00:00
|
|
|
["owner_id" => $event->user->id, "owner_ip" => get_real_ip(),
|
|
|
|
"title" => $wpage->title, "locked" => $wpage->locked, "body" => $wpage->body]
|
2020-12-28 02:02:06 +00:00
|
|
|
);
|
|
|
|
}
|
2023-01-10 22:44:09 +00:00
|
|
|
} catch (\Exception $e) {
|
2024-02-11 15:47:40 +00:00
|
|
|
throw new UserError("Somebody else edited that page at the same time :-(");
|
2019-05-28 16:59:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-01-15 11:52:35 +00:00
|
|
|
public function onWikiDeleteRevision(WikiDeleteRevisionEvent $event): void
|
2020-01-29 00:49:21 +00:00
|
|
|
{
|
2020-01-28 21:19:59 +00:00
|
|
|
global $database;
|
2020-10-25 21:34:52 +00:00
|
|
|
$database->execute(
|
2020-01-28 21:19:59 +00:00
|
|
|
"DELETE FROM wiki_pages WHERE title=:title AND revision=:rev",
|
2023-11-11 21:49:12 +00:00
|
|
|
["title" => $event->title, "rev" => $event->revision]
|
2020-01-28 21:19:59 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2024-01-15 11:52:35 +00:00
|
|
|
public function onWikiDeletePage(WikiDeletePageEvent $event): void
|
2020-01-29 00:49:21 +00:00
|
|
|
{
|
2020-01-28 21:19:59 +00:00
|
|
|
global $database;
|
2020-10-25 21:34:52 +00:00
|
|
|
$database->execute(
|
2020-01-28 21:19:59 +00:00
|
|
|
"DELETE FROM wiki_pages WHERE title=:title",
|
|
|
|
["title" => $event->title]
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2019-05-28 16:59:38 +00:00
|
|
|
/**
|
|
|
|
* See if the given user is allowed to edit the given page.
|
|
|
|
*/
|
|
|
|
public static function can_edit(User $user, WikiPage $page): bool
|
|
|
|
{
|
|
|
|
// admins can edit everything
|
2019-09-29 18:00:51 +00:00
|
|
|
if ($user->can(Permissions::WIKI_ADMIN)) {
|
2019-05-28 16:59:38 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// anon / user can't ever edit locked pages
|
|
|
|
if ($page->is_locked()) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// anon / user can edit if allowed by config
|
2019-07-09 14:10:21 +00:00
|
|
|
if ($user->can(Permissions::EDIT_WIKI_PAGE)) {
|
2019-05-28 16:59:38 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2024-01-20 14:10:59 +00:00
|
|
|
/**
|
|
|
|
* @return array<array{revision: string, date: string}>
|
|
|
|
*/
|
2021-12-21 23:36:30 +00:00
|
|
|
public static function get_history(string $title): array
|
|
|
|
{
|
|
|
|
global $database;
|
|
|
|
// first try and get the actual page
|
|
|
|
return $database->get_all(
|
|
|
|
"
|
|
|
|
SELECT revision, date
|
|
|
|
FROM wiki_pages
|
|
|
|
WHERE LOWER(title) LIKE LOWER(:title)
|
|
|
|
ORDER BY revision DESC
|
|
|
|
",
|
2023-11-11 21:49:12 +00:00
|
|
|
["title" => $title]
|
2021-12-21 23:36:30 +00:00
|
|
|
);
|
|
|
|
}
|
2023-02-13 22:28:50 +00:00
|
|
|
|
|
|
|
#[Query(name: "wiki")]
|
2023-11-11 21:49:12 +00:00
|
|
|
public static function get_page(string $title, ?int $revision = null): WikiPage
|
2019-05-28 16:59:38 +00:00
|
|
|
{
|
|
|
|
global $database;
|
|
|
|
// first try and get the actual page
|
|
|
|
$row = $database->get_row(
|
2020-02-01 22:44:50 +00:00
|
|
|
"
|
2007-05-23 22:53:35 +00:00
|
|
|
SELECT *
|
|
|
|
FROM wiki_pages
|
2019-12-15 16:07:46 +00:00
|
|
|
WHERE LOWER(title) LIKE LOWER(:title)
|
2021-12-21 23:06:24 +00:00
|
|
|
AND (:revision = -1 OR revision = :revision)
|
2020-02-01 22:44:50 +00:00
|
|
|
ORDER BY revision DESC
|
2020-02-01 23:04:40 +00:00
|
|
|
",
|
2023-11-11 21:49:12 +00:00
|
|
|
["title" => $title, "revision" => $revision ?? -1]
|
2019-05-28 16:59:38 +00:00
|
|
|
);
|
2009-07-28 01:06:51 +00:00
|
|
|
|
2019-05-28 16:59:38 +00:00
|
|
|
// fall back to wiki:default
|
|
|
|
if (empty($row)) {
|
|
|
|
$row = $database->get_row("
|
2020-02-01 22:44:50 +00:00
|
|
|
SELECT *
|
|
|
|
FROM wiki_pages
|
|
|
|
WHERE title LIKE :title
|
|
|
|
ORDER BY revision DESC
|
2023-11-11 21:49:12 +00:00
|
|
|
", ["title" => "wiki:default"]);
|
2019-05-28 16:59:38 +00:00
|
|
|
|
|
|
|
// fall further back to manual
|
|
|
|
if (empty($row)) {
|
|
|
|
$row = [
|
|
|
|
"id" => -1,
|
|
|
|
"owner_ip" => "0.0.0.0",
|
2023-02-15 21:59:32 +00:00
|
|
|
"date" => "1970-01-01 00:00:00",
|
2019-05-28 16:59:38 +00:00
|
|
|
"revision" => 0,
|
|
|
|
"locked" => false,
|
|
|
|
"body" => "This is a default page for when a page is empty, ".
|
|
|
|
"it can be edited by editing [[wiki:default]].",
|
|
|
|
];
|
|
|
|
}
|
|
|
|
|
|
|
|
// correct the default
|
|
|
|
global $config;
|
|
|
|
$row["title"] = $title;
|
|
|
|
$row["owner_id"] = $config->get_int("anon_id", 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
assert(!empty($row));
|
|
|
|
|
|
|
|
return new WikiPage($row);
|
|
|
|
}
|
|
|
|
|
2023-01-11 11:15:26 +00:00
|
|
|
public static function format_tag_wiki_page(WikiPage $page): string
|
2021-02-12 20:07:02 +00:00
|
|
|
{
|
2020-12-01 00:53:04 +00:00
|
|
|
global $database, $config;
|
2021-03-14 23:43:50 +00:00
|
|
|
|
2020-12-01 00:53:04 +00:00
|
|
|
$row = $database->get_row("
|
|
|
|
SELECT *
|
|
|
|
FROM tags
|
|
|
|
WHERE tag = :title
|
2023-11-11 21:49:12 +00:00
|
|
|
", ["title" => $page->title]);
|
2021-03-14 23:43:50 +00:00
|
|
|
|
2020-12-01 00:53:04 +00:00
|
|
|
if (!empty($row)) {
|
|
|
|
$template = $config->get_string(WikiConfig::TAG_PAGE_TEMPLATE);
|
2021-03-14 23:43:50 +00:00
|
|
|
|
2020-12-01 00:53:04 +00:00
|
|
|
//CATEGORIES
|
2024-01-20 01:03:01 +00:00
|
|
|
if (Extension::is_enabled(TagCategoriesInfo::KEY)) {
|
2021-12-14 18:32:47 +00:00
|
|
|
$tagcategories = new TagCategories();
|
2020-12-01 00:53:04 +00:00
|
|
|
$tag_category_dict = $tagcategories->getKeyedDict();
|
|
|
|
}
|
2021-03-14 23:43:50 +00:00
|
|
|
|
2020-12-01 00:53:04 +00:00
|
|
|
//ALIASES
|
|
|
|
$aliases = $database->get_col("
|
|
|
|
SELECT oldtag
|
|
|
|
FROM aliases
|
|
|
|
WHERE newtag = :title
|
|
|
|
ORDER BY oldtag ASC
|
2023-11-11 21:49:12 +00:00
|
|
|
", ["title" => $row["tag"]]);
|
2021-03-14 23:43:50 +00:00
|
|
|
|
2020-12-01 00:53:04 +00:00
|
|
|
if (!empty($aliases)) {
|
|
|
|
$template = str_replace("{aliases}", implode(", ", $aliases), $template);
|
|
|
|
} else {
|
|
|
|
$template = str_replace("{aliases}", $config->get_string(WikiConfig::EMPTY_TAGINFO), $template);
|
|
|
|
}
|
2021-03-14 23:43:50 +00:00
|
|
|
|
2020-12-01 00:53:04 +00:00
|
|
|
//Things before this line will be passed through html_escape.
|
|
|
|
$template = format_text($template);
|
|
|
|
//Things after this line will NOT be escaped!!! Be careful what you add.
|
2021-03-14 23:43:50 +00:00
|
|
|
|
2024-01-20 01:03:01 +00:00
|
|
|
if (Extension::is_enabled(AutoTaggerInfo::KEY)) {
|
2020-12-01 00:53:04 +00:00
|
|
|
$auto_tags = $database->get_one("
|
|
|
|
SELECT additional_tags
|
|
|
|
FROM auto_tag
|
|
|
|
WHERE tag = :title
|
2023-11-11 21:49:12 +00:00
|
|
|
", ["title" => $row["tag"]]);
|
2021-03-14 23:43:50 +00:00
|
|
|
|
2020-12-01 00:53:04 +00:00
|
|
|
if (!empty($auto_tags)) {
|
|
|
|
$auto_tags = Tag::explode($auto_tags);
|
|
|
|
$f_auto_tags = [];
|
2021-03-14 23:43:50 +00:00
|
|
|
|
2021-12-14 18:32:47 +00:00
|
|
|
$tag_list_t = new TagListTheme();
|
2021-03-14 23:43:50 +00:00
|
|
|
|
2020-12-01 00:53:04 +00:00
|
|
|
foreach ($auto_tags as $a_tag) {
|
|
|
|
$a_row = $database->get_row("
|
|
|
|
SELECT *
|
|
|
|
FROM tags
|
|
|
|
WHERE tag = :title
|
2023-11-11 21:49:12 +00:00
|
|
|
", ["title" => $a_tag]);
|
2021-03-14 23:43:50 +00:00
|
|
|
|
2020-12-01 00:53:04 +00:00
|
|
|
$tag_html = $tag_list_t->return_tag($a_row, $tag_category_dict ?? []);
|
2023-01-11 11:15:26 +00:00
|
|
|
$f_auto_tags[] = $tag_html[1];
|
2020-12-01 00:53:04 +00:00
|
|
|
}
|
2021-03-14 23:43:50 +00:00
|
|
|
|
2020-12-01 00:53:04 +00:00
|
|
|
$template = str_replace("{autotags}", implode(", ", $f_auto_tags), $template);
|
|
|
|
} else {
|
|
|
|
$template = str_replace("{autotags}", format_text($config->get_string(WikiConfig::EMPTY_TAGINFO)), $template);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2021-03-14 23:43:50 +00:00
|
|
|
|
2020-12-01 00:53:04 +00:00
|
|
|
//Insert page body AT LAST to avoid replacing its contents with the actions above.
|
2021-03-14 23:43:50 +00:00
|
|
|
return str_replace("{body}", format_text($page->body), $template ?? "{body}");
|
2020-12-01 00:53:04 +00:00
|
|
|
}
|
2007-05-23 22:53:35 +00:00
|
|
|
}
|