From 8f431ef8af6c83aa9ebdcd8a2dd6252759127de1 Mon Sep 17 00:00:00 2001 From: Kevin Chabowski Date: Thu, 21 Jul 2011 14:14:40 +0200 Subject: (Almost) finished DB-Models / abstraction layer. --- ratatoeskr/config.php | 11 +- ratatoeskr/languages.php | 189 +++ ratatoeskr/setup/create_tables.php | 139 ++ ratatoeskr/sys/db.php | 103 ++ ratatoeskr/sys/default_settings.php | 10 + ratatoeskr/sys/models.php | 2071 ++++++++++++++++++++++++++++ ratatoeskr/sys/utils.php | 164 +++ ratatoeskr/templates/usertemplates/foo.tpl | 14 + ratatoeskr/translations/de.php | 0 ratatoeskr/translations/en.php | 7 + 10 files changed, 2704 insertions(+), 4 deletions(-) create mode 100644 ratatoeskr/languages.php create mode 100644 ratatoeskr/setup/create_tables.php create mode 100644 ratatoeskr/sys/db.php create mode 100644 ratatoeskr/sys/default_settings.php create mode 100644 ratatoeskr/sys/models.php create mode 100644 ratatoeskr/sys/utils.php create mode 100644 ratatoeskr/templates/usertemplates/foo.tpl create mode 100644 ratatoeskr/translations/de.php create mode 100644 ratatoeskr/translations/en.php diff --git a/ratatoeskr/config.php b/ratatoeskr/config.php index 1691b4a..c8c4acb 100644 --- a/ratatoeskr/config.php +++ b/ratatoeskr/config.php @@ -1,8 +1,11 @@ diff --git a/ratatoeskr/languages.php b/ratatoeskr/languages.php new file mode 100644 index 0000000..1448911 --- /dev/null +++ b/ratatoeskr/languages.php @@ -0,0 +1,189 @@ + array("language" => "аҧсуа", "translation_exist" => False), + "aa" => array("language" => "Afaraf", "translation_exist" => False), + "af" => array("language" => "Afrikaans", "translation_exist" => False), + "ak" => array("language" => "Akan", "translation_exist" => False), + "sq" => array("language" => "Shqip", "translation_exist" => False), + "am" => array("language" => "አማርኛ", "translation_exist" => False), + "ar" => array("language" => "العربية", "translation_exist" => False), + "an" => array("language" => "Aragonés", "translation_exist" => False), + "hy" => array("language" => "Հայերեն", "translation_exist" => False), + "as" => array("language" => "অসমীয়া", "translation_exist" => False), + "av" => array("language" => "авар мацӀ, магӀарул мацӀ", "translation_exist" => False), + "ae" => array("language" => "avesta", "translation_exist" => False), + "ay" => array("language" => "aymar aru", "translation_exist" => False), + "az" => array("language" => "azərbaycan dili", "translation_exist" => False), + "bm" => array("language" => "bamanankan", "translation_exist" => False), + "ba" => array("language" => "башҡорт теле", "translation_exist" => False), + "eu" => array("language" => "euskara, euskera", "translation_exist" => False), + "be" => array("language" => "Беларуская", "translation_exist" => False), + "bn" => array("language" => "বাংলা", "translation_exist" => False), + "bh" => array("language" => "भोजपुरी", "translation_exist" => False), + "bi" => array("language" => "Bislama", "translation_exist" => False), + "bs" => array("language" => "bosanski jezik", "translation_exist" => False), + "br" => array("language" => "brezhoneg", "translation_exist" => False), + "bg" => array("language" => "български език", "translation_exist" => False), + "my" => array("language" => "ဗမာစာ", "translation_exist" => False), + "ca" => array("language" => "Català", "translation_exist" => False), + "ch" => array("language" => "Chamoru", "translation_exist" => False), + "ce" => array("language" => "нохчийн мотт", "translation_exist" => False), + "ny" => array("language" => "chiCheŵa, chinyanja", "translation_exist" => False), + "zh" => array("language" => "中文, 汉语, 漢語", "translation_exist" => False), + "cv" => array("language" => "чӑваш чӗлхи", "translation_exist" => False), + "kw" => array("language" => "Kernewek", "translation_exist" => False), + "co" => array("language" => "corsu, lingua corsa", "translation_exist" => False), + "cr" => array("language" => "ᓀᐦᐃᔭᐍᐏᐣ", "translation_exist" => False), + "hr" => array("language" => "hrvatski", "translation_exist" => False), + "cs" => array("language" => "česky, čeština", "translation_exist" => False), + "da" => array("language" => "dansk", "translation_exist" => False), + "dv" => array("language" => "ދިވެހި", "translation_exist" => False), + "nl" => array("language" => "Nederlands, Vlaams", "translation_exist" => False), + "dz" => array("language" => "རྫོང་ཁ", "translation_exist" => False), + "en" => array("language" => "English", "translation_exist" => True), + "eo" => array("language" => "Esperanto", "translation_exist" => False), + "et" => array("language" => "eesti, eesti keel", "translation_exist" => False), + "ee" => array("language" => "Eʋegbe", "translation_exist" => False), + "fo" => array("language" => "føroyskt", "translation_exist" => False), + "fj" => array("language" => "vosa Vakaviti", "translation_exist" => False), + "fi" => array("language" => "suomi, suomen kieli", "translation_exist" => False), + "fr" => array("language" => "français, langue française", "translation_exist" => False), + "ff" => array("language" => "Fulfulde, Pulaar, Pular", "translation_exist" => False), + "gl" => array("language" => "Galego", "translation_exist" => False), + "ka" => array("language" => "ქართული", "translation_exist" => False), + "de" => array("language" => "Deutsch", "translation_exist" => True), + "el" => array("language" => "Ελληνικά", "translation_exist" => False), + "gn" => array("language" => "Avañe'ẽ", "translation_exist" => False), + "gu" => array("language" => "ગુજરાતી", "translation_exist" => False), + "ht" => array("language" => "Kreyòl ayisyen", "translation_exist" => False), + "ha" => array("language" => "Hausa, هَوُسَ", "translation_exist" => False), + "he" => array("language" => "עברית", "translation_exist" => False), + "hz" => array("language" => "Otjiherero", "translation_exist" => False), + "hi" => array("language" => "हिन्दी, हिंदी", "translation_exist" => False), + "ho" => array("language" => "Hiri Motu", "translation_exist" => False), + "hu" => array("language" => "Magyar", "translation_exist" => False), + "ia" => array("language" => "Interlingua", "translation_exist" => False), + "id" => array("language" => "Bahasa Indonesia", "translation_exist" => False), + "ie" => array("language" => "Originally called ", "translation_exist" => False), + "ga" => array("language" => "Gaeilge", "translation_exist" => False), + "ig" => array("language" => "Asụsụ Igbo", "translation_exist" => False), + "ik" => array("language" => "Iñupiaq, Iñupiatun", "translation_exist" => False), + "io" => array("language" => "Ido", "translation_exist" => False), + "is" => array("language" => "Íslenska", "translation_exist" => False), + "it" => array("language" => "Italiano", "translation_exist" => False), + "iu" => array("language" => "ᐃᓄᒃᑎᑐᑦ", "translation_exist" => False), + "ja" => array("language" => "日本語 (にほんご)", "translation_exist" => False), + "jv" => array("language" => "basa Jawa", "translation_exist" => False), + "kl" => array("language" => "kalaallisut, kalaallit oqaasii", "translation_exist" => False), + "kn" => array("language" => "ಕನ್ನಡ", "translation_exist" => False), + "kr" => array("language" => "Kanuri", "translation_exist" => False), + "ks" => array("language" => "कश्मीरी, كشميري‎", "translation_exist" => False), + "kk" => array("language" => "Қазақ тілі", "translation_exist" => False), + "km" => array("language" => "ភាសាខ្មែរ", "translation_exist" => False), + "ki" => array("language" => "Gĩkũyũ", "translation_exist" => False), + "rw" => array("language" => "Ikinyarwanda", "translation_exist" => False), + "ky" => array("language" => "кыргыз тили", "translation_exist" => False), + "kv" => array("language" => "коми кыв", "translation_exist" => False), + "kg" => array("language" => "KiKongo", "translation_exist" => False), + "ko" => array("language" => "한국어 (韓國語), 조선어 (朝鮮語)", "translation_exist" => False), + "ku" => array("language" => "Kurdî, كوردی‎", "translation_exist" => False), + "kj" => array("language" => "Kuanyama", "translation_exist" => False), + "la" => array("language" => "latine, lingua latina", "translation_exist" => False), + "lb" => array("language" => "Lëtzebuergesch", "translation_exist" => False), + "lg" => array("language" => "Luganda", "translation_exist" => False), + "li" => array("language" => "Limburgs", "translation_exist" => False), + "ln" => array("language" => "Lingála", "translation_exist" => False), + "lo" => array("language" => "ພາສາລາວ", "translation_exist" => False), + "lt" => array("language" => "lietuvių kalba", "translation_exist" => False), + "lu" => array("language" => "Luba-Katanga", "translation_exist" => False), + "lv" => array("language" => "latviešu valoda", "translation_exist" => False), + "gv" => array("language" => "Gaelg, Gailck", "translation_exist" => False), + "mk" => array("language" => "македонски јазик", "translation_exist" => False), + "mg" => array("language" => "Malagasy fiteny", "translation_exist" => False), + "ms" => array("language" => "bahasa Melayu, بهاس ملايو‎", "translation_exist" => False), + "ml" => array("language" => "മലയാളം", "translation_exist" => False), + "mt" => array("language" => "Malti", "translation_exist" => False), + "mi" => array("language" => "te reo Māori", "translation_exist" => False), + "mr" => array("language" => "मराठी", "translation_exist" => False), + "mh" => array("language" => "Kajin M̧ajeļ", "translation_exist" => False), + "mn" => array("language" => "монгол", "translation_exist" => False), + "na" => array("language" => "Ekakairũ Naoero", "translation_exist" => False), + "nv" => array("language" => "Diné bizaad, Dinékʼehǰí", "translation_exist" => False), + "nb" => array("language" => "Norsk bokmål", "translation_exist" => False), + "nd" => array("language" => "isiNdebele", "translation_exist" => False), + "ne" => array("language" => "नेपाली", "translation_exist" => False), + "ng" => array("language" => "Owambo", "translation_exist" => False), + "nn" => array("language" => "Norsk nynorsk", "translation_exist" => False), + "no" => array("language" => "Norsk", "translation_exist" => False), + "ii" => array("language" => "ꆈꌠ꒿ Nuosuhxop", "translation_exist" => False), + "nr" => array("language" => "isiNdebele", "translation_exist" => False), + "oc" => array("language" => "Occitan", "translation_exist" => False), + "oj" => array("language" => "ᐊᓂᔑᓈᐯᒧᐎᓐ", "translation_exist" => False), + "cu" => array("language" => "ѩзыкъ словѣньскъ", "translation_exist" => False), + "om" => array("language" => "Afaan Oromoo", "translation_exist" => False), + "or" => array("language" => "ଓଡ଼ିଆ", "translation_exist" => False), + "os" => array("language" => "ирон æвзаг", "translation_exist" => False), + "pa" => array("language" => "ਪੰਜਾਬੀ, پنجابی‎", "translation_exist" => False), + "pi" => array("language" => "पाऴि", "translation_exist" => False), + "fa" => array("language" => "فارسی", "translation_exist" => False), + "pl" => array("language" => "polski", "translation_exist" => False), + "ps" => array("language" => "پښتو", "translation_exist" => False), + "pt" => array("language" => "Português", "translation_exist" => False), + "qu" => array("language" => "Runa Simi, Kichwa", "translation_exist" => False), + "rm" => array("language" => "rumantsch grischun", "translation_exist" => False), + "rn" => array("language" => "Ikirundi", "translation_exist" => False), + "ro" => array("language" => "română", "translation_exist" => False), + "ru" => array("language" => "русский язык", "translation_exist" => False), + "sa" => array("language" => "संस्कृतम्", "translation_exist" => False), + "sc" => array("language" => "sardu", "translation_exist" => False), + "sd" => array("language" => "yângâ tî sängö", "translation_exist" => False), + "se" => array("language" => "Davvisámegiella", "translation_exist" => False), + "sm" => array("language" => "gagana fa'a Samoa", "translation_exist" => False), + "sg" => array("language" => "yângâ tî sängö", "translation_exist" => False), + "sr" => array("language" => "српски језик", "translation_exist" => False), + "gd" => array("language" => "Gàidhlig", "translation_exist" => False), + "sn" => array("language" => "chiShona", "translation_exist" => False), + "si" => array("language" => "සිංහල", "translation_exist" => False), + "sk" => array("language" => "slovenčina", "translation_exist" => False), + "sl" => array("language" => "slovenščina", "translation_exist" => False), + "so" => array("language" => "Soomaaliga, af Soomaali", "translation_exist" => False), + "st" => array("language" => "Sesotho", "translation_exist" => False), + "es" => array("language" => "español, castellano", "translation_exist" => False), + "su" => array("language" => "Basa Sunda", "translation_exist" => False), + "sw" => array("language" => "Kiswahili", "translation_exist" => False), + "ss" => array("language" => "SiSwati", "translation_exist" => False), + "sv" => array("language" => "svenska", "translation_exist" => False), + "ta" => array("language" => "தமிழ்", "translation_exist" => False), + "te" => array("language" => "తెలుగు", "translation_exist" => False), + "tg" => array("language" => " тоҷикӣ, toğikī, تاجیکی‎", "translation_exist" => False), + "th" => array("language" => "ไทย", "translation_exist" => False), + "ti" => array("language" => "ትግርኛ", "translation_exist" => False), + "bo" => array("language" => "བོད་ཡིག", "translation_exist" => False), + "tk" => array("language" => "Türkmen, Түркмен", "translation_exist" => False), + "tl" => array("language" => "Wikang Tagalog", "translation_exist" => False), + "tn" => array("language" => "Setswana", "translation_exist" => False), + "to" => array("language" => "faka Tonga", "translation_exist" => False), + "tr" => array("language" => "Türkçe", "translation_exist" => False), + "ts" => array("language" => "Xitsonga", "translation_exist" => False), + "tt" => array("language" => "татарча, tatarça, تاتارچا‎", "translation_exist" => False), + "tw" => array("language" => "Twi", "translation_exist" => False), + "ty" => array("language" => "Reo Tahiti", "translation_exist" => False), + "ug" => array("language" => "Uyƣurqə, ئۇيغۇرچە‎", "translation_exist" => False), + "uk" => array("language" => "українська", "translation_exist" => False), + "ur" => array("language" => "اردو", "translation_exist" => False), + "uz" => array("language" => "O'zbek, Ўзбек, أۇزبېك‎", "translation_exist" => False), + "ve" => array("language" => "Tshivenḓa", "translation_exist" => False), + "vi" => array("language" => "Tiếng Việt", "translation_exist" => False), + "vo" => array("language" => "Volapük", "translation_exist" => False), + "wa" => array("language" => "Walon", "translation_exist" => False), + "cy" => array("language" => "Cymraeg", "translation_exist" => False), + "wo" => array("language" => "Wollof", "translation_exist" => False), + "fy" => array("language" => "Frysk", "translation_exist" => False), + "xh" => array("language" => "isiXhosa", "translation_exist" => False), + "yi" => array("language" => "ייִדיש", "translation_exist" => False), + "yo" => array("language" => "Yorùbá", "translation_exist" => False), + "za" => array("language" => "Saɯ cueŋƅ, Saw cuengh", "translation_exist" => False), + "zu" => array("language" => "isiZulu", "translation_exist" => False) +); +?> diff --git a/ratatoeskr/setup/create_tables.php b/ratatoeskr/setup/create_tables.php new file mode 100644 index 0000000..b024d51 --- /dev/null +++ b/ratatoeskr/setup/create_tables.php @@ -0,0 +1,139 @@ + diff --git a/ratatoeskr/sys/db.php b/ratatoeskr/sys/db.php new file mode 100644 index 0000000..0f3357a --- /dev/null +++ b/ratatoeskr/sys/db.php @@ -0,0 +1,103 @@ +, but needs arguments as single array. + * + * Parameters: + * $args - The arguments as an array. + * + * Returns: + * The formatted string. + */ +function qdb_vfmt($args) +{ + global $config; + + if(count($args) < 1) + throw new InvalidArgumentException('Need at least one parameter'); + + $query = $args[0]; + + $data = array_map(function($x) { return is_string($x) ? sqlesc($x) : $x; }, array_slice($args, 1)); + $query = str_replace("PREFIX_", $config["mysql"]["prefix"], $query); + + return vsprintf($query, $data); +} + +/* + * Function: qdb_fmt + * Formats a string like , that means it replaces "PREFIX_" and 's everything before sends everything to vsprintf. + * + * Returns: + * The formatted string. + */ +function qdb_fmt() +{ + return qdb_vfmt(fung_get_args()); +} + +/* + * Function: qdb + * Query Database. + * + * This function replaces mysql_query and should eliminate SQL-Injections. + * Use it like this: + * + * $result = qdb("SELECT `foo` FROM `bar` WHERE `id` = %d AND `baz` = '%s'", 100, "lol"); + * + * It will also replace "PREFIX_" with the prefix defined in 'config.php'. + */ +function qdb() +{ + $query = qdb_vfmt(func_get_args()); + $rv = mysql_query($query); + if($rv === false) + throw new MySQLException(mysql_errno() . ': ' . mysql_error() . (__DEBUG__ ? ("[[FULL QUERY: " . $query . "]]") : "" )); + return $rv; +} + +?> diff --git a/ratatoeskr/sys/default_settings.php b/ratatoeskr/sys/default_settings.php new file mode 100644 index 0000000..7b42028 --- /dev/null +++ b/ratatoeskr/sys/default_settings.php @@ -0,0 +1,10 @@ + False, + "default_language" => "en", + "default_section" => 0/* Must be created */ + "allow_comments_default" => True +); + +?> diff --git a/ratatoeskr/sys/models.php b/ratatoeskr/sys/models.php new file mode 100644 index 0000000..13d5843 --- /dev/null +++ b/ratatoeskr/sys/models.php @@ -0,0 +1,2071 @@ +id = mysql_insert_id(); + $obj->username = $username; + $obj->pwhash = $pwhash; + $obj->mail = $mail; + $obj->fullname = $fullname; + $obj->language = $ratatoeskr_settings["default_language"]; + + return $obj; + } + throw new AlreadyExistsError("\"$name\" is already in database."); + } + + /* DANGER: $result must be valid! The calling function has to check this! */ + private function populate_by_sqlresult($result) + { + $sqlrow = mysql_fetch_assoc($result); + if($sqlrow == False) + throw new DoesNotExistError(); + + $this->id = $sqlrow["id"]; + $this->username = $sqlrow["username"]; + $this->pwhash = $sqlrow["pwhash"]; + $this->mail = $sqlrow["mail"]; + $this->fullname = $sqlrow["fullname"]; + $this->language = $sqlrow["language"]; + } + + /* + * Constructor: by_id + * Get a User object by ID + * + * Parameters: + * $id - The ID. + * + * Returns: + * An User object. + */ + public static function by_id($id) + { + $result = qdb("SELECT `id`, `username`, `pwhash`, `mail`, `fullname`, `language` FROM `PREFIX_users` WHERE `id` = %d", $id); + + $obj = new self; + $obj->populate_by_sqlresult($result); + return $obj; + } + + /* + * Constructor: by_username + * Get a User object by username + * + * Parameters: + * $username - The username. + * + * Returns: + * An User object. + */ + public static function by_name($username) + { + $result = qdb("SELECT `id`, `username`, `pwhash`, `mail`, `fullname`, `language` FROM `PREFIX_users` WHERE `name` = '%s'", $username); + + $obj = new self; + $obj->populate_by_sqlresult($result); + return $obj; + } + + /* + * Function: all_users + * Returns array of all available users. + */ + public static function all_users() + { + $rv = array(); + + $result = qdb("SELECT `id` FROM `PREFIX_users` WHERE 1"); + while($sqlrow = mysql_fetch_assoc($result)) + $rv[] = self::by_id($sqlrow["id"]); + + return $rv; + } + + /* + * Function: get_id + * Returns: + * The user ID. + */ + public function get_id() + { + return $this->id; + } + + /* + * Function: save + * Saves the object to database + */ + public function save() + { + qdb("UPDATE `PREFIX_users` SET `username` = '%s', `pwhash` = '%s', `mail` = '%s', `fullname` = '%s', `language` = '%s' WHERE `id` = %d", + $this->username, $this->pwhash, $this->mail, $this->id, $this->fullname, $this->language); + } + + /* + * Function: delete + * Deletes the user from the database. + * WARNING: Do NOT use this object any longer after you called this function! + */ + public function delete() + { + qdb("DELETE FROM `PREFIX_group_members` WHERE `user` = %d", $this->id); + qdb("DELETE FROM `PREFIX_users` WHERE `id` = %d", $this->id); + } + + /* + * Function: get_groups + * Returns: + * List of all groups where this user is a member (array of objects). + */ + public function get_groups() + { + $rv = array(); + $result = qdb("SELECT `group` FROM `PREFIX_group_members` WHERE `user` = %d", $this->id); + while($sqlrow = mysql_fetch_assoc($result)) + { + try + { + $rv[] = Group::by_id($sqlrow["group"]); + } + catch(DoesNotExistError $e) + { + /* WTF?!? This should be fixed! */ + qdb("DELETE FROM `PREFIX_group_members` WHERE `user` = %d AND `group` = %d", $this->id, $sqlrow["group"]); + } + } + return $rv; + } + + /* + * Function: member_of + * Checks, if the user is a member of a group. + * + * Parameters: + * $group - A Group object + * + * Returns: + * True, if the user is a member of $group. False, if not. + */ + public function member_of($group) + { + $result = qdb("SELECT COUNT(*) AS `num` FROM `PREFIX_group_members` WHERE `user` = %d AND `group` = %d", $this->id, $group->get_id()); + $sqlrow = mysql_fetch_assoc($result); + return ($sqlrow["num"] > 0); + } +} + +/* + * Class: Group + * Data model for groups + */ +class Group +{ + private $id; + + /* + * Variables: Public class properties + * + * $name - Name of the group. + */ + public $name; + + /* Should not be constructed directly. */ + private function __construct() { } + + /* + * Constructor: create + * Creates a new group. + * + * Parameters: + * $name - The name of the group. + * + * Returns: + * An Group object + */ + public static function create($name) + { + try + { + $obj = self::by_username($name); + } + catch(DoesNotExistError $e) + { + qdb("INSERT INTO `PREFIX_groups` (`name`) VALUES ('%s')", $name); + $obj = new self; + + $obj->id = mysql_insert_id(); + $obj->name = $name; + + return $obj; + } + throw new AlreadyExistsError("\"$name\" is already in database."); + } + + /* DANGER: $result must be valid! The calling function has to check this! */ + private function populate_by_sqlresult($result) + { + $sqlrow = mysql_fetch_assoc($result); + if($sqlrow == False) + throw new DoesNotExistError(); + + $this->id = $sqlrow["id"]; + $this->name = $sqlrow["name"]; + } + + /* + * Constructor: by_id + * Get a Group object by ID + * + * Parameters: + * $id - The ID. + * + * Returns: + * A Group object. + */ + public static function by_id($id) + { + $result = qdb("SELECT `id`, `name` FROM `PREFIX_groups` WHERE `id` = %d", $id); + + $obj = new self; + $obj->populate_by_sqlresult($result); + return $obj; + } + + /* + * Constructor: by_name + * Get a Group object by name + * + * Parameters: + * $name - The group name. + * + * Returns: + * A Group object. + */ + public static function by_name($name) + { + $result = qdb("SELECT `id`, `name` FROM `PREFIX_groups` WHERE `name` = '%s'", $name); + + $obj = new self; + $obj->populate_by_sqlresult($result); + return $obj; + } + + /* + * Function: all_groups + * Returns array of all groups + */ + public static function all_groups() + { + $rv = array(); + + $result = qdb("SELECT `id` FROM `PREFIX_groups` WHERE 1"); + while($sqlrow = mysql_fetch_assoc($result)) + $rv[] = self::by_id($sqlrow["id"]); + + return $rv; + } + + /* + * Function: get_id + * Returns: + * The group ID. + */ + public function get_id() + { + return $this->id; + } + + /* + * Function: delete + * Deletes the group from the database. + * WARNING: Do NOT use this object any longer after you called this function! + */ + public function delete() + { + qdb("DELETE FROM `PREFIX_group_members` WHERE `group` = %d", $this->id); + qdb("DELETE FROM `PREFIX_groups` WHERE `id` = %d", $this->id); + } + + /* + * Function: get_members + * Get all members of the group. + * + * Returns: + * Array of objects. + */ + public function get_members() + { + $rv = array(); + $result = qdb("SELECT `user` FROM `PREFIX_group_members` WHERE `group` = %d", $this->id); + while($sqlrow = mysql_fetch_assoc($result)) + { + try + { + $rv[] = User::by_id($sqlrow["user"]); + } + catch(DoesNotExistError $e) + { + /* WTF?!? This should be fixed!*/ + qdb("DELETE FROM `PREFIX_group_members` WHERE `user` = %d AND `group` = %d", $sqlrow["user"], $this->id); + } + } + return $rv; + } + + /* + * Function: exclude_user + * Excludes user from group. + * + * Parameters: + * $user - object. + */ + public function exclude_user($user) + { + qdb("DELETE FROM `PREFIX_group_members` WHERE `user` = %d AND `group` = %d", $user->get_id(), $this->id); + } + + /* + * Function: include_user + * Includes user to group. + * + * Parameters: + * $user - object. + */ + public function include_user($user) + { + if(!$user->member_of($this)) + qdb("INSERT INTO `PREFIX_group_members` (`user`, `group`) VALUES (%d, %d)", $user->get_id(), $this->id); + } +} + +/* + * Class: ACL + * Data model for AccessControlLists + */ +class ACL +{ + private $id; + + /* + * Variables: Public class properties. *_rights are arrays, which can have this elements: "read", "write", "delete". + * + * $users - Array of objects + * $user_rights - User rights + * $groups - Array of objects + * $group_rights - Group rights + * $others_rights - The rights of everyone + */ + public $users; + public $user_rights; + public $groups; + public $group_rights; + public $others_rights; + + /* Should not be constructed directly. */ + private function __construct() + { + $this->users = array(); + $this->user_rights = array(); + $this->groups = array(); + $this->group_rights = array(); + $this->others_rights = array(); + } + + /* + * Function: get_id + * Returns: + * The ACL ID. + */ + public function get_id() + { + return $this->id; + } + + private static function filter_invalid_rights($rights) + { + return array_filter($rights, function($x) { return in_array($x, array("read", "write", "delete")); }); + } + + /* + * Constructor: by_json + * Creates an ACL object from an JSON string. + * + * Parameters: + * json - The JSON string + * + * Returns: + * An ACL object + */ + public static function by_json($json) + { + $obj = new self; + $obj->id = 0; + + $pre = json_decode($json, True); + if($pre === NULL) + return $obj; + + $obj->users = array_filter( + array_map( + function($x){ try{ return User::by_id($x); } catch(DoesNotExistError $e) { return NULL; } }, + $pre["users"]), + function($x) { return $x!==NULL; }); + $obj->groups = array_filter( + array_map( + function($x){ try{ return Group::by_id($x); } catch(DoesNotExistError $e) { return NULL; } }, + $pre["groups"]), + function($x) { return $x!==NULL; }); + $obj->user_rights = self::filter_invalid_rights($pre["rights"]["users"]); + $obj->group_rights = self::filter_invalid_rights($pre["rights"]["groups"]); + $obj->others_rights = self::filter_invalid_rights($pre["rights"]["others"]); + + return $obj; + } + + /* + * Constructor: create + * Creates a new ACL object. + * + * Params: + * $in_db - Should this ACL be stored in the database? (Defaults to True) + * + * Returns: + * ACL object. + */ + public static function create($in_db = True) + { + $obj = new self; + + if($in_db) + { + qdb("INSERT INTO `PREFIX_acl` (`acl_json`) VALUES ('%s')", $obj->to_json()); + $obj->id = mysql_insert_id(); + } + + return $obj; + } + + /* + * Constructor: by_id + * Gets ACL object by id. + * + * Parameters: + * $id - The ID. + * + * Returns: + * An ACL object. + */ + public static function by_id($id) + { + $result = qdb("SELECT `acl_json` FROM `PREFIX_acl` WHERE `id` = %d", $id); + + $sqlrow = mysql_fetch_assoc($result); + if($sqlrow == False) + throw new DoesNotExistError("ACL with ID = \"$id\" does not exist."); + $obj = self::by_json($sqlrow["acl_json"]); + $obj->id = $id; + + return $obj; + } + + /* + * Function: to_json + * Genearets JSON string + * + * Returns: + * JSON string. + */ + public function to_json() + { + return json_encode(array( + "users" => array_map(function($x) { return $x->get_id(); }, $this->users), + "groups" => array_map(function($x) { return $x->get_id(); }, $this->groups), + "rights" => array( + "users" => self::filter_invalid_rights($this->user_rights), + "groups" => self::filter_invalid_rights($this->group_rights), + "others" => self::filter_invalid_rights($this->others_rights) + ) + )); + } + + /* + * Function: save + * If ACL comes from database, save it. Do nothing otherwise. + */ + public function save() + { + if($this->id > 0) + qdb("UPDATE `PREFIX_acl` SET `acl_json` = '%s'", $this->to_json); + } + + /* + * Function: delete + * If ACL comes from database, delete it. Do nothing otherwise. + */ + public function delete() + { + if($this->id > 0) + { + qdb("DELETE FROM `PREFIX_acl` WHERE `id` = %d", $this->id); + $this->id = 0; + } + } + + /* + * Function: user_rights + * Get the rights of $user. + * + * Parameters: + * $user - A object. + * + * Returns: + * An Array of rights. + */ + public function user_rights($user) + { + $get_id_func = function($x) { return $x->get_id(); }; + $rights = $this->others_rights; + if(in_array($user->get_id(), array_map($get_id_func, $this->users))) + $rights = array_merge($rights, $this->user_rights); + $temp = array_intersect(array_map($get_id_func, $user->get_groups()), $this->groups); + if(!empty($temp)) + $rights = array_merge($rights, $this->group_rights); + return self::filter_invalid_rights(array_unique($rights)); + } +} + +/* + * Class: Translation + * A translation. Can only be stored using an object. + */ +class Translation +{ + /* + * Varialbes: Public class variables. + * + * $text - The translated text. + * $texttype - The type of the text. Has only a meaning in a context. + */ + public $text; + public $texttype; + + /* + * Constructor: __construct + * Creates a new Translation object. + * IT WILL NOT BE STORED TO DATABASE! + * + * Parameters: + * $text - The translated text. + * $texttype - The type of the text. Has only a meaning in a context. + * + * See also: + * + */ + public function __construct($text, $texttype) + { + $this->text = $text; + $this->texttype = $texttype; + } +} + +/* + * Class: Multilingual + * Container for objects. + * Translations can be accessed array-like. So, if you want the german translation: $translation = $my_multilingual["de"]; + * + * See also: + * + */ +class Multilingual implements Countable, ArrayAccess, IteratorAggregate +{ + private $translations; + private $id; + private $to_be_deleted; + private $to_be_created; + + private function __construct() + { + $this->translations = array(); + $this->to_be_deleted = array(); + $this->to_be_created = array(); + } + + /* + * Function: get_id + * Retuurns the ID of the object. + */ + public function get_id() + { + return $this->id; + } + + /* + * Constructor: create + * Creates a new Multilingual object + * + * Returns: + * An Multilingual object. + */ + public static function create() + { + $obj = new self; + qdb("INSERT INTO `PREFIX_multilingual` () VALUES ()"); + $obj->id = mysql_insert_id(); + return $obj; + } + + /* + * Constructor: by_id + * Gets an Multilingual object by ID. + * + * Parameters: + * $id - The ID. + * + * Returns: + * An Multilingual object. + */ + public static function by_id($id) + { + $obj = new self; + $result = qdb("SELECT `id` FROM `PREFIX_multilingual` WHERE `id` = %d", $id); + $sqlrow = mysql_fetch_assoc($result); + if($sqlrow == False) + throw new DoesNotExistError(); + $obj->id = $id; + + $result = qdb("SELECT `language`, `text`, `texttype` FROM `PREFIX_translations` WHERE `multilingual` = %d", $id); + while($sqlrow = mysql_fetch_assoc($result)) + $obj->translations[$sqlrow["language"]] = new Translation($sqlrow["text"], $sqlrow["texttype"]); + + return $obj; + } + + /* + * Function: save + * Saves the translations to database. + */ + public function save() + { + foreach($this->to_be_deleted as $deletelang) + qdb("DELETE FROM `PREFIX_translations` WHERE `multilingual` = %d AND `language` = '%s'", $this->id, $deletelang); + $this->to_be_deleted = array(); + + foreach($this->to_be_created as $lang) + qdb("INSERT INTO `PREFIX_translations` (`multilingual`, `language`, `text`, `texttype`) VALUES (%d, '%s', '%s', '%s')", + $this->id, $lang, $this->translations[$lang]->text, $this->translations[$lang]->texttype); + + foreach($this->translations as $lang => $translation) + { + if(!in_array($lang, $this->to_be_created)) + qdb("UPDATE `PREFIX_translations` SET `text` = '%s', `texttype` = '%s' WHERE `multilingual` = %d AND `language` = '%s'", + $translation->text, $translation->texttype, $this->id, $lang); + } + + $this->to_be_created = array(); + } + + /* + * Function: delete + * Deletes the data from database. + */ + public function delete() + { + qdb("DELETE FROM `PREFIX_translations` WHERE `multilingual` = %d", $this->id); + qdb("DELETE FROM `PREFIX_multilingual` WHERE `id` = %d", $this->id); + } + + /* Countable interface implementation */ + public function count() { return count($this->languages); } + + /* ArrayAccess interface implementation */ + public function offsetExists($offset) { return isset($this->translations[$offset]); } + public function offsetGet($offset) + { + if(isset($this->translations[$offset])) + return $this->translations[$offset]; + else + throw new DoesNotExistError(); + } + public function offsetUnset($offset) + { + unset($this->translations[$offset]); + if(in_array($offset, $this->to_be_created)) + unset($this->to_be_created[array_search($offset, $this->to_be_created)]); + else + $this->to_be_deleted[] = $offset; + } + public function offsetSet($offset, $value) + { + if(!isset($this->translations[$offset])) + { + if(in_array($offset, $this->to_be_deleted)) + unset($this->to_be_deleted[array_search($offset, $this->to_be_deleted)]); + else + $this->to_be_created[] = $offset; + } + $this->translations[$offset] = $value; + } + + /* IteratorAggregate interface implementation */ + public function getIterator() { return new ArrayIterator($this->translations); } +} + +/* + * Variable: $global_settings_keys_buffer + * Buffer for settings key. + * NEVER(!) MODIFY DIRECTLY! + */ +$global_settings_keys_buffer = NULL; + +/* DO NOT CONSTRUCT THIS YOURSELF! */ +class SettingsIterator implements Iterator +{ + private $iter_keys_buffer; + private $settings_obj; + private $position = 0; + + public function __construct($settings_obj) + { + global $global_settings_keys_buffer; + $this->settings_obj = $settings_obj; + $this->iter_keys_buffer = array_slice($global_settings_keys_buffer, 0); /* a.k.a. copying */ + } + + function rewind() { return $this->position = 0; } + function current() { return $this->settings_obj->offsetGet($this->iter_keys_buffer[$this->position]); } + function key() { return $this->iter_keys_buffer[$this->position]; } + function next() { ++$this->position; } + function valid() { return isset($this->iter_keys_buffer[$this->position]); } +} + +/* + * Class: Settings + * Representing the settings. + * You can access them like an array. + */ +class Settings implements Countable, ArrayAccess, IteratorAggregate +{ + private $rw; + + /* + * Constructor: __construct + * Creates a new Settings object. + * + * Parameters: + * $mode - "rw" for read-write access, "r" for read-only access (default) + */ + public function __construct($mode="r") + { + global $global_settings_keys_buffer; + if($global_settings_keys_buffer === NULL) + { + $global_settings_keys_buffer = array(); + $result = qdb("SELECT `key` FROM `PREFIX_settings_kvstorage` WHERE 1"); + while($sqlrow = mysql_fetch_assoc($result)) + $global_settings_keys_buffer[] = $sqlrow["key"]; + } + $this->rw = ($mode == "rw"); + } + + /* Countable interface implementation */ + public function count() { global $global_settings_keys_buffer; return count($global_settings_keys_buffer); } + + /* ArrayAccess interface implementation */ + public function offsetExists($offset) { global $global_settings_keys_buffer; return in_array($offset, $global_settings_keys_buffer); } + public function offsetGet($offset) + { + global $global_settings_keys_buffer; + if($this->offsetExists($offset)) + { + $result = qdb("SELECT `value` FROM `PREFIX_settings_kvstorage` WHERE `key` = '%s'", $offset); + $sqlrow = mysql_fetch_assoc($result); + return unserialize(base64_decode($sqlrow["value"])); + } + else + throw new DoesNotExistError(); + } + public function offsetUnset($offset) + { + global $global_settings_keys_buffer; + if(!$this->rw) + throw new NotAllowedError(); + unset($global_settings_keys_buffer[array_search($offset, $global_settings_keys_buffer)]); + qdb("DELETE FROM `PREFIX_settings_kvstorage` WHERE `key` = '%s'", $offset); + } + public function offsetSet($offset, $value) + { + global $global_settings_keys_buffer; + if(!$this->rw) + throw new NotAllowedError(); + if(in_array($offset, $global_settings_keys_buffer)) + qdb("UPDATE `PREFIX_settings_kvstorage` SET `value` = '%s' WHERE `key` = '%s'", base64_encode(serialize($value)), $offset); + else + { + $global_settings_keys_buffer[] = $offset; + qdb("INSERT INTO `PREFIX_settings_kvstorage` (`key`, `value`) VALUES ('%s', '%s')", $offset, base64_encode(serialize($value))); + } + } + + /* IteratorAggregate interface implementation */ + public function getIterator() { return new SettingsIterator($this); } +} + +/* + * Variable: $ratatoeskr_settings + * The global object. For internal use. + */ +$ratatoeskr_settings = new Settings("rw"); + +/* + * Class: PluginKVStorage + * A Key-Value-Storage for Plugins + * Can be accessed like an array. + * Keys are strings and Values can be everything serialize() can process. + */ +class PluginKVStorage implements Countable, ArrayAccess, Iterator +{ + private $plugin_id; + private $keybuffer; + private $counter; + + /* + * Constructor: __construct + * + * Parameters: + * $plugin_id - The ID of the Plugin. + */ + public function __construct($plugin_id) + { + $this->keybuffer = array(); + $this->plugin_id = $plugin_id; + + $result = qdb("SELECT `key` FROM `PREFIX_plugin_kvstorage` WHERE `plugin` = %d", $plugin_id); + while($sqlrow = mysql_fetch_assoc($result)) + $this->keybuffer[] = $sqlrow["key"]; + + $this->counter = 0; + } + + /* Countable interface implementation */ + public function count() { return count($this->keybuffer); } + + /* ArrayAccess interface implementation */ + public function offsetExists($offset) { return in_array($offset, $this->keybuffer); } + public function offsetGet($offset) + { + if($this->offsetExists($offset)) + { + $result = qdb("SELECT `value` FROM `PREFIX_plugin_kvstorage` WHERE `key` = '%s' AND `plugin` = %d", $offset, $this->plugin_id); + $sqlrow = mysql_fetch_assoc($result); + return unserialize(base64_decode($sqlrow["value"])); + } + else + throw new DoesNotExistError(); + } + public function offsetUnset($offset) + { + if($this->offsetExists($offset)) + { + unset($this->keybuffer[array_search($offset, $this->keybuffer)]); + $this->keybuffer = array_merge($this->keybuffer); + qdb("DELETE FROM `PREFIX_plugin_kvstorage` WHERE `key` = '%s' AND `plugin` = %d", $offset, $this->plugin_id); + } + } + public function offsetSet($offset, $value) + { + if($this->offsetExists($offset)) + qdb("UPDATE `PREFIX_plugin_kvstorage` SET `value` = '%s' WHERE `key` = '%s' AND `plugin` = %d", + base64_encode(serialize($value)), $offset, $this->plugin_id); + else + { + qdb("INSERT INTO `PREFIX_plugin_kvstorage` (`plugin`, `key`, `value`) VALUES (%d, '%s', '%s')", + $this->plugin_id, $offset, base64_encode(serialize($value))); + $this->keybuffer[] = $offset; + } + } + + /* Iterator interface implementation */ + function rewind() { return $this->position = 0; } + function current() { return $this->offsetGet($this->keybuffer[$this->position]); } + function key() { return $this->keybuffer[$this->position]; } + function next() { ++$this->position; } + function valid() { return isset($this->keybuffer[$this->position]); } +} + +/* + * Class: Comment + * Representing a user comment + */ +class Comment +{ + private $id; + private $article; + private $language; + private $timestamp; + + /* + * Variables: Public class variables. + * + * $author_name - Name of comment author. + * $author_mail - E-Mail of comment author. + * $text - Comment text. + * $visible - Should the comment be visible? + */ + public $author_name; + public $author_mail; + public $text; + public $visible; + + /* Should not be constructed manually. */ + private function __construct() { } + + /* + * Functions: Getters + * + * get_id - Gets the comment ID. + * get_article - Gets the article. + * get_language - Gets the language. + * get_timestamp - Gets the timestamp. + */ + public function get_id() { return $this->id; } + public function get_article() { return $this->article; } + public function get_language() { return $this->language; } + public function get_timestamp() { return $this->timestamp; } + + /* + * Constructor: create + * Creates a new comment. + * Automatically sets the $timestamp and $visible (default form setting "comment_visible_default"). + * + * Parameters: + * $article - An
Object. + * $language - Which language? (see ) + */ + public static function create($article, $language) + { + global $ratatoeskr_settings; + $obj = new self; + + qdb("INSERT INTO `PREFIX_comments` (`article`, `language`, `author_name`, `author_mail`, `text`, `timestamp`, `visible`) VALUES (%d, '%s', '', '', '', UNIX_TIMESTAMP(NOW()), %d)", + $article->id, $language, $ratatoeskr_settings["comment_visible_default"] ? 1 : 0); + + $obj->id = mysql_insert_id(); + $obj->article = $article; + $obj->language = $language; + $obj->author_name = ""; + $obj->author_mail = ""; + $obj->text = ""; + $obj->timestamp = time(); + $obj->visible = $ratatoeskr_settings["comment_visible_default"]; + } + + /* + * Constructor: by_id + * Gets a Comment by ID. + * + * Parameters: + * $id - The comments ID. + */ + public static function by_id($id) + { + $obj = new self; + + $result = qdb("SELECT `id`, `article`, `language`, `author_name`, `author_mail`, `text`, `timestamp`, visible` FROM `PREFIX_comments` WHERE `id` = %d", + $id); + $sqlrow = mysql_fetch_assoc($result); + if($sqlrow === False) + throw new DoesNotExistError(); + + $obj->id = $sqlrow["id"]; + $obj->article = Article::by_id($sqlrow["article"]); + $obj->language = $sqlrow["language"]; + $obj->author_name = $sqlrow["author_name"]; + $obj->author_mail = $sqlrow["author_mail"]; + $obj->text = $sqlrow["text"]; + $obj->timestamp = $sqlrow["timestamp"]; + $obj->visible = $sqlrow["visible"] == 1; + + return $obj; + } + + /* + * Function: save + * Save changes to database. + */ + public function save() + { + qdb("UPDATE `PREFIX_comments` SET `author_name` = '%s', `author_mail` = '%s', `text` = '%s', `visible` = %d` WHERE `id` = %d`", + $this->author_name, $this->author_mail, $this->text, ($this->visible ? 1 : 0), $this->id); + } + + /* + * Function: delete + */ + public function delete() + { + qdb("DELETE FROM `PREFIX_comments` WHERE `id` = %d", $this->id); + } +} + +/* + * Class: Style + * Represents a Style + */ +class Style +{ + private $id; + + /* + * Variables: Public class variables. + * + * $name - The name of the style. + * $code - The CSS code. + * $acl - An object. + */ + public $name; + public $code; + public $acl; + + /* Should not be constructed manually */ + private function __construct() { } + + private function populate_by_sqlresult($result) + { + $sqlrow = mysql_fetch_assoc($result); + if($sqlrow === False) + throw new DoesNotExistError(); + + $this->id = $sqlrow["id"]; + $this->name = $sqlrow["name"]; + $this->code = $sqlrow["code"]; + $this->acl = ACL::by_id($sqlrow["acl"]); + } + + /* + * Function: get_id + */ + public function get_id() { return $this->id; } + + /* + * Constructor: create + * Create a new style. + * + * Parameters: + * $name - A name for the new style. + */ + public static function create($name) + { + $obj = new self; + $obj->acl = ACL::create(True); + $obj->name = $name; + $obj->code = ""; + + qdb("INSERT INTO `PREFIX_styles` (`name`, `code`, `acl`) VALUES ('%s', '', %d)", + $name, $this->acl->get_id()); + + $obj->id = mysql_insert_id(); + return $obj; + } + + /* + * Constructor: by_id + * Gets a style object by ID. + * + * Parameters: + * $id - The ID + */ + public static function by_id($id) + { + $obj = new seld; + $obj->populate_by_sqlresult(qdb("SELECT `id`, `acl`, `name`, `code` FROM `PREFIX_styles` WHERE `id` = %d", $id)); + return $obj; + } + + /* + * Constructor: by_name + * Gets a style object by name. + * + * Parameters: + * $name - The name. + */ + public static function by_name($id) + { + $obj = new seld; + $obj->populate_by_sqlresult(qdb("SELECT `id`, `acl`, `name`, `code` FROM `PREFIX_styles` WHERE `name` = '%s'", $name)); + return $obj; + } + + /* + * Function: save + * Save changes to database. + */ + public function save() + { + $this->acl->save(); + qdb("UPDATE `PREFIX_styles` SET `name` = '%s', `code` = '%s', `acl` = %d WHERE `id` = %d", + $this->name, $this->code, $this->acl, $this->id); + } + + /* + * Function: delete + */ + public function delete() + { + $this->acl->delete(); + qdb("DELETE FROM `PREFIX_styles` WHERE `id` = %d", $this->id); + } +} + +/* + * Class: PluginDB + * The representation of a plugin in the database. + * See for loader functions and higher-level plugin access. + */ +class PluginDB +{ + private $id; + + /* + * Variables: Public class variables. + * + * $name - Plugin name + * $class - Main class of the plugin + * $version - Plugin version + * $author - Plugin author + * $author_url - Website of author + * $description - Description of plugin + * $help - Help page (HTML) + * $phpcode - The plugin code + * $active - Is the plugin active? + */ + + public $name = ""; + public $class = ""; + public $version = ""; + public $author = ""; + public $author_url = ""; + public $description = ""; + public $help = ""; + public $phpcode = ""; + public $active = False; + + private function __construct() { } + + /* + * Function: get_id + */ + public function get_id() { return $this->id; } + + /* + * Constructor: create + * Creates a new, empty plugin database entry + */ + public static function create() + { + $obj = new self; + qdb("INSERT INTO `PREFIX_plugins` () VALUES ()"); + $obj->id = mysql_insert_id(); + return $obj; + } + + /* + * Constructor: by_id + * Gets plugin by ID. + * + * Parameters: + * $id - The ID + */ + public static function by_id($id) + { + $obj = new self; + + $result = qdb("SELECT `name`, `class`, `version`, `author`, `author_url`, `description`, `help`, `phpcode`, `active` FROM `PREFIX_plugins` WHERE `id` = %d", $id); + $sqlrow = mysql_fetch_assoc($result); + if($sqlrow === False) + throw new DoesNotExistError(); + + $obj->id = $id; + $obj->name = $sqlrow["name"]; + $obj->class = $sqlrow["class"]; + $obj->version = $sqlrow["version"]; + $obj->author = $sqlrow["author"]; + $obj->author_url = $sqlrow["author_url"]; + $obj->description = $sqlrow["description"]; + $obj->help = $sqlrow["help"]; + $obj->phpcode = $sqlrow["phpcode"]; + $obj->active = ($sqlrow["active"] == 1); + + return $obj; + } + + /* + * Constructor: all + * Gets all Plugins + * + * Returns: + * List of objects. + */ + public static function all() + { + $rv = array(); + $result = qdb("SELECT `id` FROM `PREFIX_plugins` WHERE 1"); + while($sqlrow = mysql_fetch_assoc($result)) + $rv[] = self::by_id($sqlrow["id"]); + return $rv; + } + + /* + * Function: save + */ + public function save() + { + qdb("UPDATE `PREFIX_plugins` SET `name` = '%s', `class` = '%s', `version` = '%s', `author` = '%s', `author_url` = '%s', `description` = '%s', `help` = '%s', `phpcode` = '%s', `active` = %d WHERE `id` = %d`", + $this->name, $this->class, $this->version, $this->author, $this->author_url, $this->description, $this->help, $this->phpcode, $this->active ? 1 : 0, $this->id); + } + + /* + * Function: delete + */ + public function delete() + { + qdb("DELETE FROM `PREFIX_plugins` WHERE `id` = %d", $this->id); + } + + /* + * Function get_kvstorage + * Get the KeyValue Storage for the plugin. + * + * Returns: + * An object. + */ + public function get_kvstorage() + { + return new PluginKVStorage($this->id); + } +} + +/* + * Class: Section + * Representing a section + */ +class Section +{ + private $id; + + /* + * Variables: Public class variables + * + * $name - The name of the section. + * $title - The title of the section (a object). + * $template - Name of the template. + * $styles - List of