aboutsummaryrefslogtreecommitdiff
path: root/ratatoeskr
diff options
context:
space:
mode:
Diffstat (limited to 'ratatoeskr')
-rw-r--r--ratatoeskr/sys/models.php353
1 files changed, 177 insertions, 176 deletions
diff --git a/ratatoeskr/sys/models.php b/ratatoeskr/sys/models.php
index 057752e..6a90a8d 100644
--- a/ratatoeskr/sys/models.php
+++ b/ratatoeskr/sys/models.php
@@ -2602,8 +2602,7 @@ class Repository extends BySQLRowEnabled
}
}
-/*
- * Class: Article
+/**
* Representation of an article
*/
class Article extends BySQLRowEnabled
@@ -2611,120 +2610,114 @@ class Article extends BySQLRowEnabled
/** @var int */
private $id;
+ /** @var int */
private $section_id;
- private $section_obj;
- /*
- * Variables: Public class variables
- *
- * $urlname - URL name
- * $title - Title (an <Multilingual> object)
- * $text - The text (an <Multilingual> object)
- * $excerpt - Excerpt (an <Multilingual> object)
- * $meta - Keywords, comma seperated
- * $custom - Custom fields, is an array
- * $article_image - The article <Image>. If none: NULL
- * $status - One of the ARTICLE_STATUS_* constants
- * $timestamp - Timestamp
- * $allow_comments - Are comments allowed?
- */
+ /** @var null|Section */
+ private $section_obj = null;
+
+ /** @var string URL name */
public $urlname;
+
+ /** @var Multilingual Title */
public $title;
+
+ /** @var Multilingual The text */
public $text;
+
+ /** @var Multilingual Excerpt */
public $excerpt;
- public $meta;
+
+ /** @var string Keywords, comma separated */
+ public $meta;// TODO: Seems to be unused
+
+ /** @var array Custom fields */
public $custom;
- public $article_image;
+
+ /** @var Image|null The article image. If none: null */
+ public $article_image = null;
+
+ /** @var int One of the ARTICLE_STATUS_* constants */
public $status;
+
+ /** @var int Timestamp */
public $timestamp;
- public $allow_comments;
- protected function __construct()
- {
- $this->section_obj = null;
- }
+ /** @var bool Are comments allowed? */
+ public $allow_comments;
protected function populate_by_sqlrow($sqlrow)
{
$this->id = (int)$sqlrow["id"];
- $this->urlname = $sqlrow["urlname"];
+ $this->urlname = (string)$sqlrow["urlname"];
$this->title = Multilingual::by_id($sqlrow["title"]);
$this->text = Multilingual::by_id($sqlrow["text"]);
$this->excerpt = Multilingual::by_id($sqlrow["excerpt"]);
- $this->meta = $sqlrow["meta"];
+ $this->meta = (string)$sqlrow["meta"];
$this->custom = unserialize(base64_decode($sqlrow["custom"]));
$this->article_image = $sqlrow["article_image"] == 0 ? null : Image::by_id($sqlrow["article_image"]);
- $this->status = $sqlrow["status"];
- $this->section_id = $sqlrow["section"];
- $this->timestamp = $sqlrow["timestamp"];
+ $this->status = (int)$sqlrow["status"];
+ $this->section_id = (int)$sqlrow["section"];
+ $this->timestamp = (int)$sqlrow["timestamp"];
$this->allow_comments = $sqlrow["allow_comments"] == 1;
}
- /*
- * Function: get_id
- */
public function get_id(): int
{
return $this->id;
}
- /*
- * Function: test_urlname
+ /**
* Test, if a urlname is a valid urlname.
*
- * Parameters:
- * $urlname - Urlname to test
- *
- * Returns:
- * True, if the urlname is valid, False otherwise.
+ * @param string|mixed $urlname
+ * @return bool
*/
- public static function test_urlname($urlname)
+ public static function test_urlname($urlname): bool
{
+ $urlname = (string)$urlname;
return (bool) preg_match('/^[a-zA-Z0-9-_]+$/', $urlname);
}
- /*
- * Function: test_status
+ /**
* Test, if a status is valid.
*
- * Parameters:
- * $status - Status value to test.
- *
- * Returns:
- * True, if the status is a valid status value, False otherwise.
+ * @param mixed $status Status value to test.
+ * @return bool
*/
- public static function test_status($status)
+ public static function test_status($status): bool
{
- return is_numeric($status) and ($status >= 0) and ($status <= 3);
+ return is_numeric($status) && ($status >= 0) && ($status <= 3);
}
- /*
- * Constructor: create
+ /**
* Create a new Article object.
*
- * Parameters:
- * urlname - A unique URL name
- *
- * Throws:
- * <AlreadyExistsError>, <InvalidDataError>
+ * @param string|mixed $urlname
+ * @param Database|null $db
+ * @return self
+ * @throws AlreadyExistsError
+ * @throws InvalidDataError
*/
- public static function create($urlname)
+ public static function create($urlname, ?Database $db = null): self
{
global $ratatoeskr_settings;
- global $db_con;
+
+ $urlname = (string)$urlname;
+ $db = $db ?? Env::getGlobal()->database();
if (!self::test_urlname($urlname)) {
throw new InvalidDataError("invalid_urlname");
}
try {
- self::by_urlname($urlname);
+ self::by_urlname($urlname, $db);
} catch (DoesNotExistError $e) {
$obj = new self();
$obj->urlname = $urlname;
- $obj->title = Multilingual::create();
- $obj->text = Multilingual::create();
- $obj->excerpt = Multilingual::create();
+ $obj->title = Multilingual::create($db);
+ $obj->text = Multilingual::create($db);
+ $obj->excerpt = Multilingual::create($db);
$obj->meta = "";
$obj->custom = [];
$obj->article_image = null;
@@ -2733,7 +2726,7 @@ class Article extends BySQLRowEnabled
$obj->timestamp = time();
$obj->allow_comments = $ratatoeskr_settings["allow_comments_default"];
- qdb(
+ $db->query(
"INSERT INTO `PREFIX_articles` (`urlname`, `title`, `text`, `excerpt`, `meta`, `custom`, `article_image`, `status`, `section`, `timestamp`, `allow_comments`) VALUES ('', ?, ?, ?, '', ?, 0, ?, ?, ?, ?)",
$obj->title->get_id(),
$obj->text->get_id(),
@@ -2744,26 +2737,27 @@ class Article extends BySQLRowEnabled
$obj->timestamp,
$obj->allow_comments ? 1 : 0
);
- $obj->id = $db_con->lastInsertId();
+ $obj->id = $db->lastInsertId();
return $obj;
}
throw new AlreadyExistsError();
}
- /*
- * Constructor: by_id
+ /**
* Get by ID.
*
- * Parameters:
- * $id - The ID.
- *
- * Throws:
- * <DoesNotExistError>
+ * @param int|mixed $id
+ * @param Database|null $db
+ * @return self
+ * @throws DoesNotExistError
*/
- public static function by_id($id)
+ public static function by_id($id, ?Database $db = null): self
{
- $stmt = qdb("SELECT `id`, `urlname`, `title`, `text`, `excerpt`, `meta`, `custom`, `article_image`, `status`, `section`, `timestamp`, `allow_comments` FROM `PREFIX_articles` WHERE `id` = ?", $id);
+ $id = (int)$id;
+ $db = $db ?? Env::getGlobal()->database();
+
+ $stmt = $db->query("SELECT `id`, `urlname`, `title`, `text`, `excerpt`, `meta`, `custom`, `article_image`, `status`, `section`, `timestamp`, `allow_comments` FROM `PREFIX_articles` WHERE `id` = ?", $id);
$sqlrow = $stmt->fetch();
if ($sqlrow === false) {
throw new DoesNotExistError();
@@ -2772,19 +2766,20 @@ class Article extends BySQLRowEnabled
return self::by_sqlrow($sqlrow);
}
- /*
- * Constructor: by_urlname
+ /**
* Get by urlname
*
- * Parameters:
- * $urlname - The urlname
- *
- * Throws:
- * <DoesNotExistError>
+ * @param string|mixed $urlname
+ * @param Database|null $db
+ * @return self
+ * @throws DoesNotExistError
*/
- public static function by_urlname($urlname)
+ public static function by_urlname($urlname, ?Database $db = null): self
{
- $stmt = qdb("SELECT `id`, `urlname`, `title`, `text`, `excerpt`, `meta`, `custom`, `article_image`, `status`, `section`, `timestamp`, `allow_comments` FROM `PREFIX_articles` WHERE `urlname` = ?", $urlname);
+ $urlname = (string)$urlname;
+ $db = $db ?? Env::getGlobal()->database();
+
+ $stmt = $db->query("SELECT `id`, `urlname`, `title`, `text`, `excerpt`, `meta`, `custom`, `article_image`, `status`, `section`, `timestamp`, `allow_comments` FROM `PREFIX_articles` WHERE `urlname` = ?", $urlname);
$sqlrow = $stmt->fetch();
if ($sqlrow === false) {
throw new DoesNotExistError();
@@ -2793,60 +2788,67 @@ class Article extends BySQLRowEnabled
return self::by_sqlrow($sqlrow);
}
- /*
- * Constructor: by_multi
+ /**
* Get Articles by multiple criterias
*
- * Parameters:
- * $criterias - Array that can have these keys: id (int) , urlname (string), section (<Section> object), status (int), onlyvisible, langavail(string), tag (<Tag> object)
- * $sortby - Sort by this field (id, urlname, timestamp or title)
- * $sortdir - Sorting directory (ASC or DESC)
- * $count - How many entries (NULL for unlimited)
- * $offset - How many entries should be skipped (NULL for none)
- * $perpage - How many entries per page (NULL for no paging)
- * $page - Page number (starting at 1, NULL for no paging)
- * &$maxpage - Number of pages will be written here, if paging is activated.
- *
- * Returns:
- * Array of Article objects
+ * @param array|mixed $criterias Array that can have these keys: id (int) , urlname (string), section (<Section> object), status (int), onlyvisible, langavail(string), tag (<Tag> object)
+ * @param string|mixed $sortby Sort by this field (id, urlname, timestamp or title)
+ * @param string|mixed $sortdir Sorting directory (ASC or DESC)
+ * @param int|null|mixed $count How many entries (NULL for unlimited)
+ * @param int|null|mixed $offset How many entries should be skipped (NULL for none)
+ * @param int|null|mixed $perpage How many entries per page (NULL for no paging)
+ * @param int|null|mixed $page Page number (starting at 1, NULL for no paging)
+ * @param int $maxpage Number of pages will be written here, if paging is activated.
+ * @param Database|null $db
+ * @return self[]
*/
- public static function by_multi($criterias, $sortby, $sortdir, $count, $offset, $perpage, $page, &$maxpage)
+ public static function by_multi($criterias, $sortby, $sortdir, $count, $offset, $perpage, $page, &$maxpage, ?Database $db = null): array
{
+ $db = $db ?? Env::getGlobal()->database();
+
$subqueries = [];
$subparams = [];
foreach ($criterias as $k => $v) {
switch ($k) {
case "id":
$subqueries[] = "`a`.`id` = ?";
- $subparams[] = $v;
+ $subparams[] = (int)$v;
break;
case "urlname":
$subqueries[] = "`a`.`urlname` = ?";
- $subparams[] = $v;
+ $subparams[] = (string)$v;
break;
case "section":
+ if (!($v instanceof Section)) {
+ throw new InvalidArgumentException("criterias[section] must be a " . Section::class);
+ }
+
$subqueries[] = "`a`.`section` = ?";
$subparams[] = $v->get_id();
break;
case "status":
$subqueries[] = "`a`.`status` = ?";
- $subparams[] = $v;
+ $subparams[] = (int)$v;
break;
case "onlyvisible":
$subqueries[] = "`a`.`status` != 0";
break;
case "langavail":
$subqueries[] = "`b`.`language` = ?";
- $subparams[] = $v;
+ $subparams[] = (string)$v;
break;
case "tag":
+ if (!($v instanceof Tag)) {
+ throw new InvalidArgumentException("criterias[tag] must be a " . Tag::class);
+ }
+
$subqueries[] = "`c`.`tag` = ?";
$subparams[] = $v->get_id();
break;
}
}
- if (($sortdir != "ASC") and ($sortdir != "DESC")) {
+ if (($sortdir != "ASC") && ($sortdir != "DESC")) {
$sortdir = "ASC";
}
$sorting = "";
@@ -2857,7 +2859,7 @@ class Article extends BySQLRowEnabled
case "title": $sorting = "ORDER BY `b`.`text` $sortdir"; break;
}
- $stmt = prep_stmt("SELECT `a`.`id` AS `id`, `a`.`urlname` AS `urlname`, `a`.`title` AS `title`, `a`.`text` AS `text`, `a`.`excerpt` AS `excerpt`, `a`.`meta` AS `meta`, `a`.`custom` AS `custom`, `a`.`article_image` AS `article_image`, `a`.`status` AS `status`, `a`.`section` AS `section`, `a`.`timestamp` AS `timestamp`, `a`.`allow_comments` AS `allow_comments` FROM `PREFIX_articles` `a`
+ $stmt = $db->prepStmt("SELECT `a`.`id` AS `id`, `a`.`urlname` AS `urlname`, `a`.`title` AS `title`, `a`.`text` AS `text`, `a`.`excerpt` AS `excerpt`, `a`.`meta` AS `meta`, `a`.`custom` AS `custom`, `a`.`article_image` AS `article_image`, `a`.`status` AS `status`, `a`.`section` AS `section`, `a`.`timestamp` AS `timestamp`, `a`.`allow_comments` AS `allow_comments` FROM `PREFIX_articles` `a`
INNER JOIN `PREFIX_translations` `b` ON `a`.`title` = `b`.`multilingual`
LEFT OUTER JOIN `PREFIX_article_tag_relations` `c` ON `a`.`id` = `c`.`article`
WHERE " . implode(" AND ", $subqueries) . " $sorting");
@@ -2891,36 +2893,37 @@ WHERE " . implode(" AND ", $subqueries) . " $sorting");
return $rv;
}
- /*
- * Constructor: all
+ /**
* Get all articles
*
- * Returns:
- * Array of Article objects
+ * @param Database|null $db
+ * @return self[]
*/
- public static function all()
+ public static function all(?Database $db = null): array
{
+ $db = $db ?? Env::getGlobal()->database();
+
$rv = [];
- $stmt = qdb("SELECT `id`, `urlname`, `title`, `text`, `excerpt`, `meta`, `custom`, `article_image`, `status`, `section`, `timestamp`, `allow_comments` FROM `PREFIX_articles` WHERE 1");
+ $stmt = $db->query("SELECT `id`, `urlname`, `title`, `text`, `excerpt`, `meta`, `custom`, `article_image`, `status`, `section`, `timestamp`, `allow_comments` FROM `PREFIX_articles` WHERE 1");
while ($sqlrow = $stmt->fetch()) {
$rv[] = self::by_sqlrow($sqlrow);
}
return $rv;
}
- /*
- * Function: get_comments
+ /**
* Getting comments for this article.
*
* Parameters:
- * $limit_lang - Get only comments in a language (empty string for no limitation, this is the default).
- * $only_visible - Do you only want the visible comments? (Default: False)
- *
- * Returns:
- * Array of <Comment> objects.
+ * @param string $limit_lang Get only comments in a language (empty string for no limitation, this is the default).
+ * @param bool $only_visible Do you only want the visible comments? (Default: False)
+ * @param Database|null $db
+ * @return Comment[]
*/
- public function get_comments($limit_lang = "", $only_visible = false)
+ public function get_comments($limit_lang = "", $only_visible = false, ?Database $db = null): array
{
+ $db = $db ?? Env::getGlobal()->database();
+
$rv = [];
$conditions = ["`article` = ?"];
@@ -2933,7 +2936,7 @@ WHERE " . implode(" AND ", $subqueries) . " $sorting");
$conditions[] = "`visible` = 1";
}
- $stmt = prep_stmt("SELECT `id`, `article`, `language`, `author_name`, `author_mail`, `text`, `timestamp`, `visible`, `read_by_admin` FROM `PREFIX_comments` WHERE " . implode(" AND ", $conditions));
+ $stmt = $db->prepStmt("SELECT `id`, `article`, `language`, `author_name`, `author_mail`, `text`, `timestamp`, `visible`, `read_by_admin` FROM `PREFIX_comments` WHERE " . implode(" AND ", $conditions));
$stmt->execute($arguments);
while ($sqlrow = $stmt->fetch()) {
$rv[] = Comment::by_sqlrow($sqlrow);
@@ -2941,43 +2944,44 @@ WHERE " . implode(" AND ", $subqueries) . " $sorting");
return $rv;
}
- /*
- * Function: get_tags
+ /**
* Get all Tags of this Article.
*
- * Returns:
- * Array of <Tag> objects.
+ * @return Tag[]
*/
- public function get_tags()
+ public function get_tags(?Database $db = null): array
{
+ $db = $db ?? Env::getGlobal()->database();
+
$rv = [];
- $stmt = qdb("SELECT `a`.`id` AS `id`, `a`.`name` AS `name`, `a`.`title` AS `title` FROM `PREFIX_tags` `a` INNER JOIN `PREFIX_article_tag_relations` `b` ON `a`.`id` = `b`.`tag` WHERE `b`.`article` = ?", $this->id);
+ $stmt = $db->query("SELECT `a`.`id` AS `id`, `a`.`name` AS `name`, `a`.`title` AS `title` FROM `PREFIX_tags` `a` INNER JOIN `PREFIX_article_tag_relations` `b` ON `a`.`id` = `b`.`tag` WHERE `b`.`article` = ?", $this->id);
while ($sqlrow = $stmt->fetch()) {
$rv[] = Tag::by_sqlrow($sqlrow);
}
return $rv;
}
- /*
- * Function: set_tags
+ /**
* Set the Tags that should be associated with this Article.
*
- * Parameters:
- * $tags - Array of <Tag> objects.
+ * @param Tag[] $tags
+ * @param Database|null $db
*/
- public function set_tags($tags)
+ public function set_tags($tags, ?Database $db = null): void
{
- $tx = new Transaction();
+ $db = $db ?? Env::getGlobal()->database();
+
+ $tx = new DbTransaction($db);
try {
foreach ($tags as $tag) {
- $tag->save();
+ $tag->save($db);
}
- qdb("DELETE FROM `PREFIX_article_tag_relations` WHERE `article`= ?", $this->id);
+ $db->query("DELETE FROM `PREFIX_article_tag_relations` WHERE `article`= ?", $this->id);
$articleid = $this->id;
if (!empty($tags)) {
- $stmt = prep_stmt(
+ $stmt = $db->prepStmt(
"INSERT INTO `PREFIX_article_tag_relations` (`article`, `tag`) VALUES " .
implode(",", array_fill(0, count($tags), "(?,?)"))
);
@@ -2995,57 +2999,52 @@ WHERE " . implode(" AND ", $subqueries) . " $sorting");
}
}
- /*
- * Function: get_section
+ /**
* Get the section of this article.
*
- * Returns:
- * A <Section> object.
+ * @param Database|null $db
+ * @return Section
*/
- public function get_section()
+ public function get_section(?Database $db = null): Section
{
if ($this->section_obj === null) {
- $this->section_obj = Section::by_id($this->section_id);
+ $this->section_obj = Section::by_id($this->section_id, $db);
}
return $this->section_obj;
}
- /*
- * Function: set_section
+ /**
* Set the section of this article.
*
- * Parameters:
- * $section - A <Section> object.
+ * @param Section $section
*/
- public function set_section($section)
+ public function set_section(Section $section): void
{
$this->section_id = $section->get_id();
$this->section_obj = $section;
}
- /*
- * Function: get_extradata
+ /**
* Get the extradata for this article and the given plugin.
*
- * Parameters:
- * $plugin_id - The ID of the plugin.
- *
- * Returns:
- * An <ArticleExtradata> object.
+ * @param int|mixed $plugin_id The ID of the plugin.
+ * @param Database|null $db
+ * @return ArticleExtradata
*/
- public function get_extradata($plugin_id)
+ public function get_extradata($plugin_id, ?Database $db = null): ArticleExtradata
{
- return new ArticleExtradata($this->id, $plugin_id);
+ return new ArticleExtradata($this->id, (int)$plugin_id, $db);
}
- /*
- * Function: save
- *
- * Throws:
- * <AlreadyExistsError>, <InvalidDataError>
+ /**
+ * @param Database|null $db
+ * @throws AlreadyExistsError
+ * @throws InvalidDataError
*/
- public function save()
+ public function save(?Database $db = null): void
{
+ $db = $db ?? Env::getGlobal()->database();
+
if (!self::test_urlname($this->urlname)) {
throw new InvalidDataError("invalid_urlname");
}
@@ -3054,19 +3053,19 @@ WHERE " . implode(" AND ", $subqueries) . " $sorting");
throw new InvalidDataError("invalid_article_status");
}
- $tx = new Transaction();
+ $tx = new DbTransaction($db);
try {
- $stmt = qdb("SELECT COUNT(*) AS `n` FROM `PREFIX_articles` WHERE `urlname` = ? AND `id` != ?", $this->urlname, $this->id);
+ $stmt = $db->query("SELECT COUNT(*) AS `n` FROM `PREFIX_articles` WHERE `urlname` = ? AND `id` != ?", $this->urlname, $this->id);
$sqlrow = $stmt->fetch();
if ($sqlrow["n"] > 0) {
throw new AlreadyExistsError();
}
- $this->title->save();
- $this->text->save();
- $this->excerpt->save();
+ $this->title->save($db);
+ $this->text->save($db);
+ $this->excerpt->save($db);
- qdb(
+ $db->query(
"UPDATE `PREFIX_articles` SET `urlname` = ?, `title` = ?, `text` = ?, `excerpt` = ?, `meta` = ?, `custom` = ?, `article_image` = ?, `status` = ?, `section` = ?, `timestamp` = ?, `allow_comments` = ? WHERE `id` = ?",
$this->urlname,
$this->title->get_id(),
@@ -3088,24 +3087,26 @@ WHERE " . implode(" AND ", $subqueries) . " $sorting");
}
}
- /*
- * Function: delete
+ /**
+ * @param Database|null $db
*/
- public function delete()
+ public function delete(?Database $db = null): void
{
- $tx = new Transaction();
+ $db = $db ?? Env::getGlobal()->database();
+
+ $tx = new DbTransaction($db);
try {
- $this->title->delete();
- $this->text->delete();
- $this->excerpt->delete();
+ $this->title->delete($db);
+ $this->text->delete($db);
+ $this->excerpt->delete($db);
foreach ($this->get_comments() as $comment) {
- $comment->delete();
+ $comment->delete($db);
}
- qdb("DELETE FROM `PREFIX_article_tag_relations` WHERE `article` = ?", $this->id);
- qdb("DELETE FROM `PREFIX_article_extradata` WHERE `article` = ?", $this->id);
- qdb("DELETE FROM `PREFIX_articles` WHERE `id` = ?", $this->id);
+ $db->query("DELETE FROM `PREFIX_article_tag_relations` WHERE `article` = ?", $this->id);
+ $db->query("DELETE FROM `PREFIX_article_extradata` WHERE `article` = ?", $this->id);
+ $db->query("DELETE FROM `PREFIX_articles` WHERE `id` = ?", $this->id);
$tx->commit();
} catch (Exception $e) {
$tx->rollback();