From edad8581bb6ec2cb0e198f1cc5e415ce526147b7 Mon Sep 17 00:00:00 2001 From: Kevin Chabowski Date: Tue, 27 Dec 2011 22:16:29 +0100 Subject: Article::by_multi improved and frontend modifications. * Article::by_multi now has more criterias and can perform sorting, paging and limiting. Also only generates full articles when needed. * In the frontend there are now some "hidden" __obj STE variables, so some objects do not need to be created multiple times. --- ratatoeskr/backend.php | 5 +- ratatoeskr/frontend.php | 242 ++++++++++++++++++++++++---------------------- ratatoeskr/sys/models.php | 58 ++++++++--- 3 files changed, 177 insertions(+), 128 deletions(-) (limited to 'ratatoeskr') diff --git a/ratatoeskr/backend.php b/ratatoeskr/backend.php index 365fe7a..0316589 100644 --- a/ratatoeskr/backend.php +++ b/ratatoeskr/backend.php @@ -14,7 +14,7 @@ require_once(dirname(__FILE__) . "/sys/pwhash.php"); require_once(dirname(__FILE__) . "/sys/textprocessors.php"); require_once(dirname(__FILE__) . "/languages.php"); -$admin_grp = Group::by_name("admins"); +$admin_grp = NULL; /* Mass creation of tags. */ function maketags($tagnames, $lang) @@ -65,6 +65,9 @@ $backend_subactions = url_action_subactions(array( { global $ratatoeskr_settings, $admin_grp, $ste, $languages; + if($admin_grp === NULL) + $admin_grp = Group::by_name("admins"); + $ste->vars["all_languages"] = array(); $ste->vars["all_langcodes"] = array(); foreach($languages as $code => $data) diff --git a/ratatoeskr/frontend.php b/ratatoeskr/frontend.php index 142915c..8d2c767 100644 --- a/ratatoeskr/frontend.php +++ b/ratatoeskr/frontend.php @@ -34,7 +34,8 @@ function section_transform_ste($section, $lang) return array( "id" => $section->get_id(), "name" => $section->name, - "title" => $section->title[$lang]->text + "title" => $section->title[$lang]->text, + "__obj" => $section ); } @@ -57,7 +58,8 @@ function tag_transform_ste($tag, $lang) return array( "id" => $tag->get_id(), "name" => $tag->name, - "title" => $tag->title[$lang]->text + "title" => $tag->title[$lang]->text, + "__obj" => $tag ); } @@ -106,7 +108,8 @@ function article_transform_ste($article, $lang) "timestamp" => $article->timestamp, "tags" => array_map(function($tag) use ($lang) { return tag_transform_ste($tag, $lang); }, $article->get_tags()), "languages" => $languages, - "comments_allowed" => $article->comments_allowed + "comments_allowed" => $article->comments_allowed, + "__obj" => $article ); } @@ -132,7 +135,8 @@ function comment_transform_ste($comment) "id" => $comment->get_id(), "text" => $comment->create_html(), "author" => htmlesc($comment->author_name), - "timestamp" => $comment->get_timestamp() + "timestamp" => $comment->get_timestamp(), + "__obj" => $comment ); } @@ -180,66 +184,40 @@ $ste->register_tag("articles_get", function($ste, $params, $sub) } } - $result = Article::by_multi($params); - - /* - FIXME: + $criterias = array("langavail" => $lang, "onlyvisible" => True); + if(isset($params["id"])) + $criterias["id"] = $params["id"]; + if(isset($params["urlname"])) + $criterias["urlname"]; + if(isset($params["section"])) + $criterias["section"] = $params["section"]; + if(isset($params["status"])) + $criterias["status"] = $params["status"]; if(isset($params["tag"])) { - if(!isset($result)) - $result = Article::all(); - $result = array_filter($result, function($article) use ($params) { return isset($article->tags[$params["tag"]]); }); - }*/ - - /* Now filter out the articles, where the current language does not exist */ - $result = array_filter($result, function($article) use ($lang) { return isset($article->title[$lang]); }); - - /* Also filter the hidden ones out */ - $result = array_filter($result, function($article) { return $article->status != ARTICLE_STATUS_HIDDEN; }); - - /* Convert articles to arrays */ - $result = array_map(function($article) use ($lang) { return article_transform_ste($article, $lang); }, $result); - - function sort_fx_factory($cmpfx, $field, $direction) - { - return function($a, $b) use ($cmpfx, $field, $direction) { return $cmpfx($a[$field], $b[$field]) * $direction; }; + try + { + $criterias["tag"] = Tag::by_name($params["tag"]); + } + catch(DoesNotExistError $e) {} } + $field = NULL; + $direction = NULL; if(isset($params["sort"])) { list($field, $direction) = explode(" ", $params["sort"]); - if((@$direction != "asc") and (@$direction != "desc")) - $direction = "asc"; - $direction = ($direction == "asc") ? 1 : -1; - $sort_fx = NULL; - - switch($field) - { - case "id": $sort_fx = sort_fx_factory("intcmp", "id", $direction); break; - case "urlname": $sort_fx = sort_fx_factory("strcmp", "urlname", $direction); break; - case "title": $sort_fx = sort_fx_factory("strcmp", "title", $direction); break; - case "timestamp": $sort_fx = sort_fx_factory("intcmp", "timestamp", $direction); break; - } - - if($sort_fx !== NULL) - usort($result, $sort_fx); - } - if(isset($params["perpage"])) - { - if(isset($params["maxpage"])) - { - $maxpage = ceil(count($result) / $params["perpage"]); - $ste->set_var_by_name($params["maxpage"], $maxpage == 0 ? 1 : $maxpage); - } - $page = isset($params["page"]) ? $params["page"] : 1; - $result = array_slice($result, ($page - 1) * $params["perpage"], $params["perpage"]); + if($direction === NULL) + $field = NULL; + $direction = strtoupper($direction); } - else if(isset($params["skip"]) and isset($params["count"])) - $result = array_slice($result, $params["skip"], $params["count"]); - else if(isset($params["skip"])) - $result = array_slice($result, $params["skip"]); - else if(isset($params["count"])) - $result = array_slice($result, 0, $params["count"]); + + $result = Article::by_multi($criterias, $field, $direction, @$params["count"], @$params["skip"], @$params["perpage"], @$params["page"], $maxpage); + + $result = array_map(function($article) use ($lang) { return article_transform_ste($article, $lang); }, $result); + + if(isset($params["perpage"]) and isset($params["maxpage"])) + $ste->set_var_by_name($params["maxpage"], $maxpage == 0 ? 1 : $maxpage); $output = ""; foreach($result as $article) @@ -315,18 +293,25 @@ $ste->register_tag("article_comments_count", function($ste, $params, $sub) { if(!isset($params["article"])) throw new Exception("Need parameter 'article' in ste:article_comments_count."); - $tpl_article = $ste->get_var_by_name($params["article"]); + $tpl_article = $ste->get_var_reference($params["article"], False); $lang = $ste->vars["language"]; - try - { - $article = Article::by_id(@$tpl_article["id"]); - return count($article->get_comments($lang, True)); - } - catch(DoesNotExistError $e) + if(isset($tpl_article["__obj"])) + $article = $tpl_article["__obj"]; + else { - return 0; + try + { + $article = Article::by_id(@$tpl_article["id"]); + } + catch(DoesNotExistError $e) + { + return 0; + } } + $comments = $article->get_comments($lang, True); + $tpl_article["__comments"] = $comments; + return count($comments); }); /* @@ -351,19 +336,30 @@ $ste->register_tag("article_comments", function($ste, $params, $sub) throw new Exception("Need parameter 'var' in ste:article_comments."); if(!isset($params["article"])) throw new Exception("Need parameter 'article' in ste:article_comments."); - $tpl_article = $ste->get_var_by_name($params["article"]); + $tpl_article = $ste->get_var_reference($params["article"], False); $lang = $ste->vars["language"]; - try - { - $article = Article::by_id(@$tpl_article["id"]); - } - catch(DoesNotExistError $e) + if(isset($tpl_article["__comments"])) + $comments = $tpl_article["__comments"]; + else { - return ""; + if(isset($tpl_article["__obj"])) + $article = $tpl_article["__obj"]; + else + { + try + { + $article = Article::by_id(@$tpl_article["id"]); + } + catch(DoesNotExistError $e) + { + return ""; + } + } + + $comments = $article->get_comments($lang, True); } - $comments = $article->get_comments($lang, True); $sortdir = (@$params["sort"] == "desc") ? -1 : 1; usort($comments, function($a,$b) use ($sortdir) { return intcmp($a->get_timestamp(), $b->get_timestamp()) * $sortdir; }); @@ -412,15 +408,20 @@ $ste->register_tag("comment_form", function($ste, $params, $sub) global $translation; if(!isset($params["article"])) throw new Exception("Need parameter 'article' in ste:comment_form."); - $tpl_article = $ste->get_var_by_name($params["article"]); + $tpl_article = $ste->get_var_reference($params["article"], False); - try - { - $article = Article::by_id($tpl_article["id"]); - } - catch (DoesNotExistError $e) + if(isset($tpl_article["__obj"])) + $article = $tpl_article["__obj"]; + else { - return ""; + try + { + $article = Article::by_id(@$tpl_article["id"]); + } + catch(DoesNotExistError $e) + { + return ""; + } } if(!$article->allow_comments) @@ -532,13 +533,18 @@ $ste->register_tag("languages", function($ste, $params, $sub) $langs = array(); if(isset($ste->vars["current"]["article"])) { - try + if(isset($ste->vars["current"]["article"]["__obj"])) + $article = $ste->vars["current"]["article"]["__obj"]; + else { - $article = Article::by_id($ste->vars["current"]["article"]["id"]); - foreach($article->title as $lang => $_) - $langs[] = $lang; + try + { + $article = Article::by_id($ste->vars["current"]["article"]["id"]); + } + catch(DoesNotExistError $e) {} } - catch(DoesNotExistError $e) {} + foreach($article->title as $lang => $_) + $langs[] = $lang; } else { @@ -581,16 +587,24 @@ $ste->register_tag("styles_load", function($ste, $params, $sub) if($mode == "embed") { $output = ""; - foreach($ste->vars["current"]["styles"] as $stylename) + if(isset($ste->vars["current"]["__style_objs"])) { - try - { - $style = Style::by_name($stylename); - $output .= "/* Style: $stylename */\n" . $style->code . "\n"; - } - catch(DoesNotExistError $e) + foreach($ste->vars["current"]["__style_objs"] as $style) + $output .= "/* Style: {$style->name} */\n" . $style->code . "\n"; + } + else + { + foreach($ste->vars["current"]["styles"] as $stylename) { - $output .= "/* Warning: Failed to load style: $stylename */\n"; + try + { + $style = Style::by_name($stylename); + $output .= "/* Style: $stylename */\n" . $style->code . "\n"; + } + catch(DoesNotExistError $e) + { + $output .= "/* Warning: Failed to load style: $stylename */\n"; + } } } $output = ""; @@ -599,17 +613,7 @@ $ste->register_tag("styles_load", function($ste, $params, $sub) { $output = ""; foreach($ste->vars["current"]["styles"] as $stylename) - { - try - { - $style = Style::by_name($stylename); - $output .= "\n"; - } - catch(DoesNotExistError $e) - { - $output .= "\n"; - } - } + $output .= "\n"; } return $output; }); @@ -690,9 +694,7 @@ function frontend_url_handler(&$data, $url_now, &$url_next) { global $ste, $ratatoeskr_settings, $languages, $metasections, $comment_validators; $path = array_merge(array($url_now), $url_next); - $url_next = array(); - - $default_section = Section::by_id($ratatoeskr_settings["default_section"]); + $url_next = array(); /* If no language or an invalid language was given, fix it. */ if((count($path) == 0) or (!isset($languages[$path[0]]))) @@ -708,10 +710,10 @@ function frontend_url_handler(&$data, $url_now, &$url_next) $ste->vars["language"] = $lang; load_language($languages[$lang]["translation_exist"] ? $lang : "en"); /* English is always available */ - if(count($path) == 0) - array_unshift($path, $default_section->name); - - $section_name = array_shift($path); + if(count($path) != 0) + $section_name = array_shift($path); + else + $section_name = NULL; if($section_name == "_tags") { @@ -727,13 +729,18 @@ function frontend_url_handler(&$data, $url_now, &$url_next) } else { - try - { - $section = Section::by_name($section_name); - } - catch(DoesNotExistError $e) + if($section_name === NULL) + $section = Section::by_id($ratatoeskr_settings["default_section"]); + else { - throw new NotFoundError(); + try + { + $section = Section::by_name($section_name); + } + catch(DoesNotExistError $e) + { + throw new NotFoundError(); + } } if(count($path)== 0) @@ -787,7 +794,10 @@ function frontend_url_handler(&$data, $url_now, &$url_next) $section = $default_section; foreach($section->get_styles() as $style) + { $ste->vars["current"]["styles"][] = $style->name; + $ste->vars["current"]["__style_objs"][] = $style; + } echo $ste->exectemplate("/usertemplates/" . $section->template); } diff --git a/ratatoeskr/sys/models.php b/ratatoeskr/sys/models.php index f24b71c..cefe79d 100644 --- a/ratatoeskr/sys/models.php +++ b/ratatoeskr/sys/models.php @@ -2366,33 +2366,69 @@ class Article extends BySQLRowEnabled * Get Articles by multiple criterias * * Parameters: - * $criterias - Array that can have these keys: id (int) , urlname (string), section (
object), status (int) + * $criterias - Array that can have these keys: id (int) , urlname (string), section (
object), status (int), onlyvisible, langavail(string), 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 */ - public function by_multi($criterias) + public function by_multi($criterias, $sortby, $sortdir, $count, $offset, $perpage, $page, &$maxpage) { $subqueries = array(); foreach($criterias as $k => $v) { switch($k) { - case "id": $subqueries[] = qdb_fmt("`id` = %d", $v); break; - case "urlname": $subqueries[] = qdb_fmt("`urlname` = '%s'", $v); break; - case "section": $subqueries[] = qdb_fmt("`section` = %d", $v->get_id()); break; - case "status": $subqueries[] = qdb_fmt("`status` = %d", $v); break; + case "id": $subqueries[] = qdb_fmt("`a`.`id` = %d", $v); break; + case "urlname": $subqueries[] = qdb_fmt("`a`.`urlname` = '%s'", $v); break; + case "section": $subqueries[] = qdb_fmt("`a`.`section` = %d", $v->get_id()); break; + case "status": $subqueries[] = qdb_fmt("`a`.`status` = %d", $v); break; + case "onlyvisible": $subqueries[] = "`a`.`status` != 0"; break; + case "langavail": $subqueries[] = qdb_fmt("`b`.`language` = '%s'", $v); break; + case "tag": $subqueries[] = qdb_fmt("`c`.`tag` = %d", $v->get_id()); break; default: continue; } } - if(empty($subqueries)) - return self::all(); /* No limiting criterias, so we take them all... */ + if(($sortdir != "ASC") and ($sortdir != "DESC")) + $sortdir = "ASC"; + $sorting = ""; + switch($sortby) + { + case "id": $sorting = "ORDER BY `a`.`id` $sortdir"; break; + case "urlname": $sorting = "ORDER BY `a`.`urlname` $sortdir"; break; + case "timestamp": $sorting = "ORDER BY `a`.`timestamp` $sortdir"; break; + case "title": $sorting = "ORDER BY `b`.`text` $sortdir"; break; + } - $result = qdb("SELECT `id`, `urlname`, `title`, `text`, `excerpt`, `meta`, `custom`, `article_image`, `status`, `section`, `timestamp`, `allow_comments` FROM `PREFIX_articles` WHERE " . implode(" AND ", $subqueries)); - $rv = array(); + $result = qdb("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"); + + $rows = array(); while($sqlrow = mysql_fetch_assoc($result)) - $rv[] = self::by_sqlrow($sqlrow); + $rows[] = $sqlrow; + + if($count !== NULL) + $rows = array_slice($rows, 0, $count); + if($offset !== NULL) + $rows = array_slice($rows, $offset); + if(($perpage !== NULL) and ($page !== NULL)) + { + $maxpage = ceil(count($rows) / $perpage); + $rows = array_slice($rows, $perpage * ($page - 1), $perpage); + } + + $rv = array(); + foreach($rows as $r) + $rv[] = self::by_sqlrow($r); return $rv; } -- cgit v1.2.3-70-g09d2