root/trunk/common/mvblog_admin.php

Revision 776, 81.7 KB (checked in by michiel, 9 months ago)

update copyright year.

Closes #180

Line 
1<?php
2/**
3 * MvBlog -- An open source no-nosense blogtool
4 *
5 * Copyright (C) 2005-2008, Michiel van Baak
6 * Michiel van Baak <mvanbaak@users.sourceforge.net>
7 *
8 * See http://dev.mvblog.org for more information on MvBlog.
9 * That page also provides Bugtrackers, Filereleases etc.
10 *
11 * This program is free software, distributed under the terms of
12 * the GNU General Public License Version 2. See the LICENSE file
13 * at the top of the source tree.
14 *
15 * @package MvBlog
16 * @author Michiel van Baak
17 * @version %%VERSION%%
18 * @copyright 2005-2008 Michiel van Baak
19 */
20
21/**
22 * Class that holds methods to create admin site.
23 * @package MvBlog
24 */
25Class MvBlog_admin extends MvBlog_common {
26
27    /* constants */
28
29    /* variables */
30    public $lang = "en_US";
31    public $languages = array(
32        "en_US" => "english",
33        "nl_NL" => "dutch",
34        "sv_SE" => "swedish",
35    );
36    private $_selected_menuitem;
37    private $_selected_submenuitem;
38
39    /* methods */
40
41    /* __construct {{{ */
42    /**
43     * Class constructor. Check some defaults etc
44     */
45    public function __construct($basedir="") {
46        /* first do the common construct tasks */
47        parent::__construct($basedir."plugins/", 1);
48        $this->webroot = $this->webroot."admin/";
49        $this->log = new MvBlog_log($basedir, 1);
50
51        if (array_key_exists("action", $_POST))
52            $action = $_POST["action"];
53        else
54            $action = "";
55
56        /* check if we are logged in */
57        if (!array_key_exists("author_id", $_SESSION) && $action != "check_login")
58            $this->show_login();
59        if (array_key_exists("action", $_REQUEST)) {
60            switch($_REQUEST["action"]) {
61            case "show_cats" :
62            case "edit_cat" :
63                $this->_selected_menuitem = "manage";
64                $this->_selected_submenuitem = "categories";
65                break;
66            case "show_dossiers" :
67            case "edit_dossier" :
68                $this->_selected_menuitem = "manage";
69                $this->_selected_submenuitem = "dossiers";
70                break;
71            case "show_userlog":
72                $this->_selected_menuitem = "log";
73                $this->_selected_submenuitem = "users";
74                break;
75            case "show_adminlog":
76                $this->_selected_menuitem = "log";
77                $this->_selected_submenuitem = "admin";
78                break;
79            case "show_authors" :
80            case "edit_author" :
81                $this->_selected_menuitem = "users";
82                if (array_key_exists("id", $_REQUEST) && $_REQUEST["id"] == $_SESSION["author_id"])
83                    $this->_selected_submenuitem = "my";
84                else
85                    $this->_selected_submenuitem = "authors";
86                break;
87            case "show_users" :
88            case "edit_user" :
89                $this->_selected_menuitem = "users";
90                $this->_selected_submenuitem = "users";
91                break;
92            case "show_posts" :
93            case "edit_post" :
94                $this->_selected_menuitem = "manage";
95                $this->_selected_submenuitem = "posts";
96                break;
97            case "show_comments" :
98            case "edit_comment" :
99                $this->_selected_menuitem = "manage";
100                $this->_selected_submenuitem = "comments";
101                break;
102            case "show_plugins" :
103            case "config_plugin" :
104            case "edit_plugin_setting" :
105            case "save_plugin_setting" :
106                $this->_selected_menuitem = "plugins";
107                break;
108            case "show_settings" :
109            case "save_settings" :
110                $this->_selected_menuitem = "settings";
111                $this->_selected_submenuitem = "settings";
112                break;
113            case "show_menuitems" :
114                $this->_selected_menuitem = "settings";
115                $this->_selected_submenuitem = "menuitems";
116                break;
117            case "show_about" :
118                $this->_selected_menuitem = "index";
119                $this->_selected_submenuitem = "about";
120                break;
121            default :
122                $this->_selected_menuitem = "index";
123                $this->_selected_submenuitem = "index";
124                break;
125            }
126        } else {
127            $this->_selected_menuitem = "index";
128            $this->_selected_submenuitem = "index";
129        }
130    }
131    /* }}} */
132    /* _strip_tags {{{ */
133    /**
134     * strip all html tags cept for some tags we like.
135     * The tags we leave will be stripped from attributes we dont like.
136     *
137     * @param string The text to process
138     * @return string The text with only allowed tags.
139     */
140    private function _strip_tags($text) {
141        $allowed_tags  = "<a><abbr><acronym><address><area><b><bdo><big><blockquote><br><caption><center><cite>";
142        $allowed_tags .= "<code><col><dd><del><dir><div><dfn><dl><dt><fieldset><font><h1><h2><h3><h4><h5><h6>";
143        $allowed_tags .= "<hr><i><img><ins><kbd><li><link><menu><ol><p><pre><q><s><samp><small><span><strike>";
144        $allowed_tags .= "<strong><style><sub><sup><table><tbody><td><tfoot><th><thead><tr><tt><u><ul><var><em>";
145        $text = strip_tags($text, $allowed_tags);
146        return @preg_replace('/<(.*?)>/ie', "'<'.$this->_strip_attributes('\\1').'>'", $text);
147    }
148    /* }}} */
149    /* _strip_attributes {{{ */
150    /**
151     * strip evil attributes from tags
152     *
153     * @param string The text to process
154     * @return string The processed text
155     */
156    private function _strip_attributes($text) {
157        $attr_to_strip = array(
158            "javascript:",
159            "onclick",
160            "ondblclick",
161            "onmousedown",
162            "onmouseup",
163            "onmouseover"
164        );
165        foreach ($attr_to_strip as $attribute) {
166            $text = stripslashes(preg_replace("/$attribute/i", "forbidden", $text));
167        }
168        return $text;
169    }
170    /* }}} */
171    /* show_login {{{ */
172    /**
173     * Show admin login screen
174     */
175    public function show_login() {
176        $this->html_header("Admin login");
177        ?>
178        <form name="loginform" method="post" action="index.php">
179        <input type="hidden" name="action" value="check_login" />
180        <div id="if_container">
181            <div id="if_title"></div>
182            <div id="if_bar1"></div>
183            <div id="if_page_header">
184                <h1 class="page_title">login</h1>
185            </div>
186            <div id="if_page">
187                <div class="log_post">
188                    <table border="0" cellspacing="3" cellpadding="0" align="center"><tr>
189                        <td align="right">username:</td><td><input type="text" id="loginname" name="login[name]" /></td>
190                    </tr><tr>
191                        <td align="right">password:</td><td><input type="password" name="login[password]" /></td>
192                    </tr><tr>
193                        <td colspan="2" align="center"><input type="submit" value="login" /></td>
194                    </tr></table>
195                </div>
196        </form>
197        <script language="Javascript" type="text/javascript">
198            document.loginform.loginname.focus();
199        </script>
200        <?php
201        $this->html_footer();
202        exit;
203    }
204    /* }}} */
205    /* check_login {{{ */
206    /**
207     * Check user supplied data against admin database
208     *
209     * @param array name and password to check
210     */
211    public function check_login($login) {
212        $query = sprintf("SELECT * FROM authors WHERE login = '%s' AND password = '%s' AND active = 1",
213            preg_quote($login["name"], "'"),
214            preg_quote($login["password"], "'")
215        );
216        $res =& $this->db->query($query);
217        if (PEAR::isError($res)) {
218            die($res->getUserInfo());
219        }
220        if ($res->numRows()) {
221            $row = $res->fetchRow(MDB2_FETCHMODE_ASSOC);
222            $_SESSION["author_id"]       = $row["id"];
223            $_SESSION["author_name"]     = $row["login"];
224            $_SESSION["author_fullname"] = $row["fullname"];
225            $_SESSION["author_email"]    = $row["email"];
226            $_SESSION["author_website"]  = $row["website"];
227            $_SESSION["blog_user"]       = 1;
228            $this->log->add_log(mktime(), $row["id"], 1, sprintf("Admin %s logged in", $row["login"]));
229            header("Location: index.php");
230        } else {
231            $this->show_login();
232        }
233    }
234    /* }}} */
235    /* logout {{{ */
236    /**
237     * Logout user
238     */
239    public function logout() {
240        $this->log->add_log(mktime(), $_SESSION["author_id"], 1, sprintf("Admin %s logged off", $_SESSION["author_name"]));
241        session_destroy();
242        header("Location: index.php");
243    }
244    /* }}} */
245    /* show_index {{{ */
246    /**
247     * Show nice welcome screen for admin
248     */
249    public function show_index() {
250        ?>
251        <script language="Javascript1.2" type="text/javascript">
252            var reloadinterval = setInterval("document.location.href='index.php';", 60000);
253        </script>
254        <p class="first"><?php echo gettext("Welcome to MvBlog"); ?> "<?php echo $_SESSION["author_fullname"]; ?>".</p>
255        <p class="first">
256            <h3><?php echo gettext("Use these links to get started"); ?>:</h3>
257            <ul>
258                <li><a href="index.php?action=edit_post&id=0"><?php echo gettext("write post"); ?></a></li>
259                <li><a href="index.php?action=edit_author&id=<?php echo $_SESSION["author_id"];?>"><?php echo gettext("update your account settings"); ?></a></li>
260            </ul>
261        </p>
262        <p class="first">
263            <h3><?php echo gettext("5 latest posts"); ?></h3>
264            <ul>
265                <?php
266                $sql = "SELECT id, title, last_modified, modified_by, date, authors_id FROM articles ORDER BY date DESC LIMIT 5";
267                $res =& $this->db->query($sql);
268                while ($row = $res->fetchRow(MDB2_FETCHMODE_ASSOC)) {
269                    if (!$row["last_modified"])
270                        $row["last_modified"] = $row["date"];
271                    if (!$row["modified_by"])
272                        $row["modified_by"] = $row["authors_id"];
273                    echo "<li><a href=\"index.php?action=edit_post&id=".$row["id"]."\">".$row["title"]."</a> (modified ".date("d-m-Y H:i", $row["last_modified"])." by ".$this->authors[$row["modified_by"]]["fullname"].")</li>\n";
274                }
275                ?>
276            </ul>
277        </p>
278        <p class="first">
279            <h3><?php echo gettext("5 latest comments"); ?></h3>
280            <ul>
281                <?php
282                $sql = "SELECT id, title, date, name, articles_id FROM comments ORDER BY date DESC LIMIT 5";
283                $res =& $this->db->query($sql);
284                while ($row = $res->fetchRow(MDB2_FETCHMODE_ASSOC)) {
285                    if (!$row["title"])
286                        $row["title"] = "[".gettext("no title")."]";
287                    $q = sprintf("SELECT title FROM articles WHERE id = %d", $row["articles_id"]);
288                    $r =& $this->db->query($q);
289                    $art = $r->fetchRow(MDB2_FETCHMODE_ASSOC);
290                    echo "<li><a href=\"../index.php?action=view&id=".$row["articles_id"]."#comment".$row["id"]."\">".$row["title"]."</a> - ".$art["title"]." (".date("d-m-Y H:i", $row["date"])." by ".$row["name"].")</li>\n";
291                }
292                ?>
293            </ul>
294        </p>
295        <p class="first">
296            <h3><?php echo gettext("latest mvblog news"); ?></h3>
297            <?php
298            $oldtimeout = ini_set("default_socket_timeout", 5);
299            if (!($rss = file_get_contents("http://www.mvblog.org/blog/common/rdf.php"))) {
300                echo "Your php setup does not allow opening remote files.<br />For the latest news and updates visit <a href=\"http://www.mvblog.org\">http://www.mvblog.org</a>";
301            } else {
302                echo "<ul>";
303                require("rssparser.php");
304                $rssparser = new RSSParser($rss);
305                $rsscount = 0;
306                foreach ($rssparser->rssItems as $rssItem) {
307                    if (strstr($rssItem["dc:subject"], "updates")) {
308                        $rsscount++;
309                        if ($rsscount > 5)
310                            break;
311                        echo "<li><a href=\"".$rssItem["link"]."\" target=\"_new\">".$rssItem["title"]."</a> (".date("d-m-Y H:i", $rssItem["dc:date"])." by ".$rssItem["dc:creator"].")</li>";
312                    }
313                }
314                echo "</ul>";
315            }
316            ini_set("default_socket_timeout", $oldtimeout);
317            ?>
318        </p>
319        <?php
320    }
321    /* }}} */
322    /* show_about {{{ */
323    /**
324     * Show information about the current version etc.
325     */
326    public function show_about() {
327        /* gather some info we want to show */
328        $mvblogversion = $this->version;
329        if (array_key_exists("dbversion", $this->settings))
330            $dbversion = $this->settings["dbversion"];
331        else
332            $dbversion = gettext("Unknown");
333        if (array_key_exists("webroot", $this->settings))
334            $webroot = $this->settings["webroot"];
335        else
336            $webroot = gettext("Unknown");
337        if (is_array($this->active_plugins))
338            $active_plugins = implode(", ", $this->active_plugins);
339        else
340            $active_plugins = gettext("None");
341        ?>
342        <p class="first">
343            <h2>Information about this MvBlog instance</h2>
344            MvBlog version: <?php echo $mvblogversion; ?><br />
345            Database version: <?php echo $dbversion; ?><br />
346            Active plugins: <?php echo $active_plugins; ?> <br />
347        </p>
348        <p class="first">
349            MvBlog is created by Michiel van Baak &lt;michiel@mvblog.org&gt;<br />
350            With the help of Leonieke Aalders, Sofie van Tendeloo en Ferry Boender.<br />
351            Besides those 3 contributers others have helped as well, but those 3 were there from the beginning<br />
352            and without them this project would never be this far.<br /><br />
353            For more information please visit <a href="http://www.mvblog.org">www.mvblog.org</a><br />
354            For documentation please go to the <a href="http://dev.mvblog.org/wiki/EndUserDocumentation">wiki</a><br />
355            If you found a bug or need a new feature please report it on <a href="http://dev.mvblog.org">the developement website</a>.
356        </p>
357        <?php
358    }
359    /* }}} */
360    /* show_admin_menu {{{ */
361    /**
362     * If user is logged in, show menu
363     */
364    public function show_admin_menu() {
365        if (array_key_exists("author_id", $_SESSION)) {
366            ?>
367            <div id="if_menu">
368                <a class="if_menu_item" href="../index.php">Site</a>&nbsp;
369                <a class="if_menu_item<?php if ($this->_selected_menuitem == "index")      { echo "_act"; } ?>" href="./index.php"><?php echo gettext("Main"); ?></a>&nbsp;
370                <a class="if_menu_item<?php if ($this->_selected_menuitem == "manage")     { echo "_act"; } ?>" href="./index.php?action=show_posts"><?php echo gettext("Manage"); ?></a>&nbsp;
371                <a class="if_menu_item<?php if ($this->_selected_menuitem == "users")      { echo "_act"; } ?>" href="./index.php?action=show_userlog"><?php echo gettext("Users"); ?></a>&nbsp;
372                <a class="if_menu_item<?php if ($this->_selected_menuitem == "settings")   { echo "_act"; } ?>" href="./index.php?action=show_settings"><?php echo gettext("Settings"); ?></a>&nbsp;
373                <a class="if_menu_item<?php if ($this->_selected_menuitem == "plugins")    { echo "_act"; } ?>" href="./index.php?action=show_plugins"><?php echo gettext("Plugins"); ?></a>&nbsp;
374                <a class="if_menu_item<?php if ($this->_selected_menuitem == "import")     { echo "_act"; } ?>" href="./index.php?action=show_import"><?php echo gettext("Import"); ?></a>&nbsp;
375                <a class="if_menu_item<?php if ($this->_selected_menuitem == "log")        { echo "_act"; } ?>" href="./index.php?action=show_adminlog"><?php echo gettext("Log"); ?></a>&nbsp;
376                <a class="if_menu_item" href="./index.php?action=logout"><?php echo gettext("Logout"); ?></a>&nbsp;
377            </div>
378            <div id="if_submenu">
379                <?php
380                switch ($this->_selected_menuitem) {
381                case "manage" :
382                    ?>
383                    <a class="if_submenu_item<?php if ($this->_selected_submenuitem == "posts")      { echo "_act"; } ?>" href="./index.php?action=show_posts"><?php echo gettext("Posts"); ?></a>&nbsp;
384                    <a class="if_submenu_item<?php if ($this->_selected_submenuitem == "dossiers")   { echo "_act"; } ?>" href="./index.php?action=show_dossiers"><?php echo gettext("Dossiers"); ?></a>&nbsp;
385                    <a class="if_submenu_item<?php if ($this->_selected_submenuitem == "categories") { echo "_act"; } ?>" href="./index.php?action=show_cats"><?php echo gettext("Categories"); ?></a>&nbsp;
386                    <a class="if_submenu_item<?php if ($this->_selected_submenuitem == "comments")   { echo "_act"; } ?>" href="./index.php?action=show_comments"><?php echo gettext("Comments"); ?></a>&nbsp;
387                    <?php
388                    break;
389                case "users" :
390                    ?>
391                    <a class="if_submenu_item<?php if ($this->_selected_submenuitem == "authors")    { echo "_act"; } ?>" href="./index.php?action=show_authors"><?php echo gettext("Authors"); ?></a>&nbsp;
392                    <a class="if_submenu_item<?php if ($this->_selected_submenuitem == "users")      { echo "_act"; } ?>" href="./index.php?action=show_users"><?php echo gettext("Users"); ?></a>&nbsp;
393                    <a class="if_submenu_item<?php if ($this->_selected_submenuitem == "my")         { echo "_act"; } ?>" href="./index.php?action=edit_author&id=<?php echo $_SESSION["author_id"];?>"><?php echo gettext("Your profile"); ?></a>&nbsp;
394                    <?php
395                    break;
396                case "settings" :
397                    ?>
398                    <a class="if_submenu_item<?php if ($this->_selected_submenuitem == "settings")   { echo "_act"; } ?>" href="./index.php?action=show_settings"><?php echo gettext("Settings"); ?></a>&nbsp;
399                    <a class="if_submenu_item<?php if ($this->_selected_submenuitem == "menuitems")  { echo "_act"; } ?>" href="./index.php?action=show_menuitems"><?php echo gettext("Menu items"); ?></a>&nbsp;
400                    <?php
401                    break;
402                case "index" :
403                    ?>
404                    <a class="if_submenu_item<?php if ($this->_selected_submenuitem == "index")      { echo "_act"; } ?>" href="./index.php"><?php echo gettext("Main"); ?></a>&nbsp;
405                    <a class="if_submenu_item<?php if ($this->_selected_submenuitem == "about")      { echo "_act"; } ?>" href="./index.php?action=show_about"><?php echo gettext("About"); ?></a>&nbsp;
406                    <?php
407                    break;
408                case "log" :
409                    ?>
410                    <a class="if_submenu_item<?php if ($this->_selected_submenuitem == "admin")      { echo "_act"; } ?>" href="./index.php?action=show_adminlog"><?php echo gettext("Backend"); ?></a>&nbsp;
411                    <a class="if_submenu_item<?php if ($this->_selected_submenuitem == "users")      { echo "_act"; } ?>" href="./index.php?action=show_userlog"><?php echo gettext("Frontend"); ?></a>&nbsp;
412                    <?php
413                    break;
414                default:
415                    break;
416                }
417                ?>
418            </div>
419            <?php
420        }
421    }
422    /* }}} */
423    /* show_cats {{{ */
424    /**
425     * Show overview of available categories
426     */
427    public function show_cats() {
428        $count = 0;
429        ?><h1 class="log_post_new"><a href="./index.php?action=edit_cat&amp;id=0"><?php echo gettext("create new"); ?></a></h1><br /><?php
430        foreach ($this->categories as $id => $cat) {
431            if ($id == 0) continue;
432            ?>
433            <div class="log_post">
434                <div class="log_post_head">
435                    <h1 class="log_post_h1"><a href="?action=edit_cat&amp;id=<?php echo $id; ?>"><?php echo stripslashes($cat["name"]); ?></a></h1>
436                    <?php
437                        $r =& $this->db->query(sprintf("SELECT COUNT(*) AS count FROM articles WHERE (categories_ids LIKE '%%,%1\$d' OR categories_ids LIKE '%1\$d,%%' OR categories_ids = '%d' OR categories_ids LIKE '%%,%1\$d,%%')", $id));
438                        if (PEAR::isError($r)) {
439                            die($r->getMessage());
440                        }
441                        $count = $r->fetchRow(MDB2_FETCHMODE_ASSOC);
442                    ?>
443                    <h2 class="log_post_h2"><?php echo sprintf(ngettext("%d article in this category", "%d articles in this category", $count["count"]), $count["count"]); ?></h2>
444                </div>
445                <div class="log_post_body">
446                    <div class="log_post_normal">
447                        <?php echo nl2br(stripslashes($cat["desc"])); ?>
448                    </div>
449                </div>
450                <div class="log_post_foot">
451                    <span class="log_post_date"><?php echo gettext("active"); ?>: <?php echo $cat["active"]; ?></span>
452                    <?php
453                    /*
454                     * TODO: do something with this ?
455                    <span class="log_post_author"><?php echo gettext("public"); ?>: <?php echo $cat["public"]; ?></span>
456                    */
457                    ?>
458                </div>
459            </div>
460            <?php
461        }
462    }
463    /* }}} */
464    /* edit_cat {{{ */
465    /**
466     * Show form to edit a category.
467     *
468     * @param int The category id or 0 to create a new one
469     */
470    function edit_cat($id) {
471        $count = 0;
472        /* check for valid category */
473        if (!array_key_exists($id, $this->categories)) die("no valid category id");
474        /* fetch icons for categories */
475        $allowed_types = array("jpg", "png", "gif");
476        $iconbasedir = "../images/categories/";
477        $icons = array();
478        if ($dh = opendir($iconbasedir)) {
479            while (false !== ($v = readdir($dh))) {
480                if (!is_dir($iconbasedir.$v) && in_array(substr($v, strlen($v)-3), $allowed_types))
481                    $icons[] = $v;
482            }
483        }
484        asort($icons);
485        /* get copy of current category */
486