OSDN Git Service

sync with UTF-8
authorkimitake <kimitake@1ca29b6e-896d-4ea0-84a5-967f57386b96>
Tue, 27 Mar 2007 12:14:48 +0000 (12:14 +0000)
committerkimitake <kimitake@1ca29b6e-896d-4ea0-84a5-967f57386b96>
Tue, 27 Mar 2007 12:14:48 +0000 (12:14 +0000)
git-svn-id: https://svn.sourceforge.jp/svnroot/nucleus-jp/nucleus-jp/trunk@244 1ca29b6e-896d-4ea0-84a5-967f57386b96

27 files changed:
euc/nucleus/bookmarklet.php
euc/nucleus/forgotpassword.html
euc/nucleus/index.php
euc/nucleus/libs/COMMENTS.php
euc/nucleus/libs/ITEM.php
euc/nucleus/libs/KARMA.php
euc/nucleus/libs/MANAGER.php
euc/nucleus/libs/MEDIA.php
euc/nucleus/libs/MEMBER.php
euc/nucleus/libs/NOTIFICATION.php
euc/nucleus/libs/PAGEFACTORY.php
euc/nucleus/libs/PARSER.php
euc/nucleus/libs/PLUGIN.php
euc/nucleus/libs/PLUGINADMIN.php
euc/nucleus/libs/SEARCH.php
euc/nucleus/libs/globalfunctions.php
euc/nucleus/media.php
euc/nucleus/xmlrpc/api_blogger.inc.php
euc/nucleus/xmlrpc/api_metaweblog.inc.php
euc/nucleus/xmlrpc/api_mt.inc.php
euc/nucleus/xmlrpc/api_nucleus.inc.php
euc/nucleus/xmlrpc/server.php
euc/skins/atom/skinbackup.xml
euc/skins/default/sidebar.inc
euc/skins/default/skinbackup.xml
euc/skins/rsd/skinbackup.xml
euc/skins/rss2.0/skinbackup.xml

index 4ab4d61..f0eef98 100755 (executable)
-<?php\r
-/**\r
-  * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/) \r
-  * Copyright (C) 2002-2005 The Nucleus Group\r
-  *\r
-  * This program is free software; you can redistribute it and/or\r
-  * modify it under the terms of the GNU General Public License\r
-  * as published by the Free Software Foundation; either version 2\r
-  * of the License, or (at your option) any later version.\r
-  * (see nucleus/documentation/index.html#license for more info)\r
-  *\r
-  * This script allows adding items to Nucleus through bookmarklets. The member must be logged in\r
-  * in order to use this.\r
-  *\r
-  * $Id: bookmarklet.php,v 1.3 2005-03-16 08:04:14 kimitake Exp $\r
-  * $NucleusJP: bookmarklet.php,v 1.4 2005/03/15 08:24:16 kimitake Exp $\r
-  */\r
-\r
-// bookmarklet is part of admin area (might need XML-RPC)\r
-$CONF = array();\r
-$CONF['UsingAdminArea'] = 1;\r
-\r
-// include all classes and config data \r
-include('../config.php');\r
-\r
-$action = requestVar('action');\r
-\r
-if ($action == 'contextmenucode') {\r
-       bm_doContextMenuCode();\r
-       exit;\r
-}\r
-\r
-if (!$member->isLoggedIn()) {\r
-       bm_loginAndPassThrough();\r
-       exit;\r
-}\r
-\r
-// on successfull login\r
-if (($action == 'login') && ($member->isLoggedIn()))\r
-       $action = requestVar('nextaction');\r
-if ($action == '')\r
-       $action = 'add';\r
-       \r
-sendContentType('application/xhtml+xml', 'bookmarklet-'.$action);      \r
-\r
-// check ticket\r
-$action = strtolower($action);\r
-$aActionsNotToCheck = array('login', 'add', 'edit');\r
-if (!in_array($action, $aActionsNotToCheck))\r
-{\r
-       if (!$manager->checkTicket())\r
-               bm_doError(_ERROR_BADTICKET);\r
-} \r
-\r
-\r
-// find out what to do\r
-switch ($action) {\r
-       case 'additem':\r
-               bm_doAddItem();         // adds the item for real\r
-               break;\r
-       case 'edit':\r
-               bm_doEditForm();        // shows the edit item form\r
-               break;\r
-       case 'edititem':                // edits the item for real\r
-               bm_doEditItem();\r
-               break;\r
-       case 'login':                   // on login, 'action' gets changed to 'nextaction'\r
-               bm_doError('Something went wrong');\r
-               break;\r
-       case 'add':\r
-       default:\r
-               bm_doShowForm();        // shows the fill in form\r
-               break;\r
-}\r
-       \r
-function bm_doAddItem() {\r
-       global $member, $manager, $CONF;\r
-       \r
-       $manager->loadClass('ITEM');\r
-       $result = ITEM::createFromRequest();\r
-       \r
-       if ($result['status'] == 'error')\r
-               bm_doError($result['message']);\r
-\r
-       $blogid = getBlogIDFromItemID($result['itemid']);\r
-       $blog =& $manager->getBlog($blogid);\r
-       \r
-       if ($result['status'] == 'newcategory') {\r
-               $message = '¥¢¥¤¥Æ¥à¤ÏÄɲ䵤졢¿·¤·¤¤¥«¥Æ¥´¥ê¡¼¤¬ºîÀ®¤µ¤ì¤Þ¤·¤¿¡£ <a href="index.php?action=categoryedit&amp;blogid='.$blogid.'&amp;catid='.$result['catid'].'" onclick="if (event &amp;&amp; event.preventDefault) event.preventDefault(); window.open(this.href); return false;" title="Opens in new window">¤³¤³¤ò¥¯¥ê¥Ã¥¯¤·¤Æ¥«¥Æ¥´¥ê¡¼¤Î̾Á°¤ÈÀâÌÀ¤òÊÔ½¸¤·¤Æ¤¯¤À¤µ¤¤¡£</a>';\r
-               $extrahead = '';\r
-       } elseif ((postVar('actiontype') == 'addnow') && $blog->pingUserland()) {\r
-               $message = '¥¢¥¤¥Æ¥à¤ÎÄɲäËÀ®¸ù¤·¤Þ¤·¤¿¡£¸½ºßweblogs.com¤Ëping¤òÁ÷¤Ã¤Æ¤¤¤Þ¤¹¡£¤·¤Ð¤é¤¯¤Î´Ö¤ªÂÔ¤Á¤¯¤À¤µ¤¤...';\r
-               $extrahead = '<meta http-equiv="refresh" content="1; url=index.php?action=sendping&amp;blogid=' . $blogid . '" />';\r
-       } else {\r
-               $message = _ITEM_ADDED;\r
-               $extrahead = '';\r
-       }\r
-       \r
-       bm_message(_ITEM_ADDED, _ITEM_ADDED, $message,$extrahead);\r
-}\r
-\r
-function bm_doEditItem() {\r
-       global $member, $manager, $CONF;\r
-       \r
-       $itemid         = intRequestVar('itemid');\r
-       $catid          = postVar('catid');\r
-       \r
-       // only allow if user is allowed to alter item\r
-       if (!$member->canUpdateItem($itemid, $catid))\r
-               bm_doError(_ERROR_DISALLOWED);\r
-\r
-       $body           = postVar('body');\r
-       $title          = postVar('title');\r
-       $more           = postVar('more');\r
-       $closed         = intPostVar('closed');\r
-       $actiontype = postVar('actiontype');\r
-       \r
-       // redirect to admin area on delete (has delete confirmation)\r
-       if ($actiontype == 'delete') {\r
-               redirect('index.php?action=itemdelete&itemid='.$itemid);\r
-               exit;   \r
-       }\r
-       \r
-       // create new category if needed (only on edit/changedate)\r
-       if (strstr($catid,'newcat')) {\r
-               // get blogid \r
-               list($blogid) = sscanf($catid,"newcat-%d");\r
-\r
-               // create\r
-               $blog =& $manager->getBlog($blogid);\r
-               $catid = $blog->createNewCategory();\r
-\r
-               // show error when sth goes wrong\r
-               if (!$catid) \r
-                       bm_doError('Could not create new category');\r
-       } \r
-\r
-       // only edit action is allowed for bookmarklet edit\r
-       switch ($actiontype) {\r
-               case 'changedate':\r
-                       $publish = 1;\r
-                       $wasdraft = 0;\r
-                       $timestamp = mktime(postVar('hour'), postVar('minutes'), 0, postVar('month'), postVar('day'), postVar('year'));\r
-                       break;\r
-               case 'edit':\r
-                       $publish = 1;\r
-                       $wasdraft = 0;\r
-                       $timestamp = 0;\r
-                       break;\r
-               default:\r
-                       bm_doError('Something went wrong');\r
-       }\r
-       \r
-       // update item for real\r
-       ITEM::update($itemid, $catid, $title, $body, $more, $closed, $wasdraft, $publish, $timestamp);\r
-       \r
-       // show success message\r
-       if ($catid != intPostVar('catid'))\r
-               bm_message(_ITEM_UPDATED, _ITEM_UPDATED, '¥¢¥¤¥Æ¥à¤ÏÄɲ䵤졢¿·¤·¤¤¥«¥Æ¥´¥ê¡¼¤¬ºîÀ®¤µ¤ì¤Þ¤·¤¿¡£<a href="index.php?action=categoryedit&amp;blogid='.$blog->getID().'&amp;catid='.$catid.'" onclick="if (event &amp;&amp; event.preventDefault) event.preventDefault(); window.open(this.href); return false;" title="Opens in new window">¤³¤³¤ò¥¯¥ê¥Ã¥¯¤·¤Æ¥«¥Æ¥´¥ê¡¼¤Î̾Á°¤ÈÀâÌÀ¤òÊÔ½¸¤·¤Æ¤¯¤À¤µ¤¤¡£</a>', '');\r
-       else\r
-               bm_message(_ITEM_UPDATED, _ITEM_UPDATED, _ITEM_UPDATED, '');\r
-}\r
-\r
-function bm_loginAndPassThrough() {\r
-\r
-       $blogid = intRequestVar('blogid');\r
-       $log_text = requestVar('logtext');\r
-       $log_link = requestVar('loglink');\r
-       $log_linktitle = requestVar('loglinktitle');\r
-       \r
-       ?>\r
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">\r
-       <html xmlns="http://www.w3.org/1999/xhtml">\r
-       <head>\r
-               <meta http-equiv="Content-Type" content="text/html; charset=<?php echo _CHARSET ?>" />\r
-               <title>Nucleus</title>\r
-               <?php bm_style(); ?>\r
-       </head>\r
-       <body>\r
-       <h1><?php echo _LOGIN_PLEASE?></h1>\r
-       \r
-       <form method="post" action="bookmarklet.php">\r
-       <p>\r
-               <input name="action" value="login" type="hidden" />\r
-               <input name="blogid" value="<?php echo  htmlspecialchars($blogid) ?>" type="hidden" />\r
-               <input name="logtext" value="<?php echo  htmlspecialchars($log_text) ?>" type="hidden" />\r
-               <input name="loglink" value="<?php echo  htmlspecialchars($log_link) ?>" type="hidden" />\r
-               <input name="loglinktitle" value="<?php echo  htmlspecialchars($log_linktitle) ?>" type="hidden" />\r
-               <?php echo _LOGINFORM_NAME?>:\r
-               <br /><input name="login" />\r
-               <br /><?php echo _LOGINFORM_PWD?>:\r
-               <br /><input name="password" type="password" />\r
-               <br /><br />\r
-               <br /><input type="submit" value="<?php echo _LOGIN?>" />\r
-       </p>\r
-       </form>\r
-       <p><a href="bookmarklet.php" onclick="window.close();"><?php echo _POPUP_CLOSE?></a></p>\r
-       </body>\r
-       </html>\r
-       <?php\r
-}\r
-\r
-function bm_doShowForm() {\r
-       global $member;\r
-       \r
-       $blogid = intRequestVar('blogid');\r
-       $log_text = trim(requestVar('logtext'));\r
-       $log_link = requestVar('loglink');\r
-       $log_linktitle = requestVar('loglinktitle');\r
-\r
-       $log_text = uniDecode($log_text,_CHARSET);\r
-       $log_linktitle = uniDecode($log_linktitle,_CHARSET);\r
-       \r
-       if (!BLOG::existsID($blogid))\r
-               bm_doError(_ERROR_NOSUCHBLOG);\r
-\r
-       if (!$member->isTeamMember($blogid))\r
-               bm_doError(_ERROR_NOTONTEAM);\r
-       \r
-       $logje = '';\r
-       if ($log_text)\r
-               $logje .= '<blockquote><div>"' . htmlspecialchars($log_text) .'"</div></blockquote>' . "\n";\r
-       if (!$log_linktitle)\r
-               $log_linktitle = $log_link;\r
-       if ($log_link) \r
-               $logje .= '<a href="'. htmlspecialchars($log_link) . '">'. htmlspecialchars($log_linktitle).'</a>';\r
-               \r
-\r
-       $item['body'] = $logje;\r
-       $item['title'] = htmlspecialchars($log_linktitle);\r
-\r
-       $factory = new PAGEFACTORY($blogid);\r
-       $factory->createAddForm('bookmarklet',$item);\r
-}\r
-\r
-function bm_doEditForm() {\r
-       global $member, $manager;\r
-       \r
-       $itemid = intRequestVar('itemid');\r
-       \r
-       if (!$manager->existsItem($itemid, 0, 0)) \r
-               bm_doError(_ERROR_NOSUCHITEM);\r
-               \r
-       if (!$member->canAlterItem($itemid))\r
-               bm_doError(_ERROR_DISALLOWED);\r
-               \r
-       $item =& $manager->getItem($itemid,1,1);\r
-       $blog =& $manager->getBlog(getBlogIDFromItemID($itemid));\r
-       \r
-       $manager->notify('PrepareItemForEdit', array('item' => &$item));\r
-\r
-       if ($blog->convertBreaks()) {\r
-               $item['body'] = removeBreaks($item['body']);\r
-               $item['more'] = removeBreaks($item['more']);\r
-       }\r
-\r
-       $formfactory = new PAGEFACTORY($blog->getID());\r
-       $formfactory->createEditForm('bookmarklet',$item);              \r
-\r
-}\r
-\r
-function bm_doError($msg) {\r
-       bm_message(_ERROR,_ERRORMSG,$msg);\r
-       die;\r
-}\r
-\r
-function bm_message($title, $head, $msg, $extrahead = '') {\r
-       ?>\r
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">\r
-       <html xmlns="http://www.w3.org/1999/xhtml">\r
-       <head>\r
-               <meta http-equiv="Content-Type" content="text/html; charset=<?php echo _CHARSET ?>" />\r
-               <title><?php echo  $title ?></title>\r
-               <?php bm_style(); ?>\r
-               <?php echo $extrahead?>\r
-       </head>\r
-       <body>\r
-       <h1><?php echo  $head ?></h1>\r
-       <p><?php echo  $msg ?></p>\r
-       <p><a href="bookmarklet.php" onclick="window.close();"><?php echo _POPUP_CLOSE?></a></p>\r
-       </body>\r
-       </html>\r
-       \r
-       <?php }\r
-\r
-function bm_style() {\r
-       echo '<link rel="stylesheet" type="text/css" href="styles/bookmarklet.css" />';\r
-       echo '<link rel="stylesheet" type="text/css" href="styles/addedit.css" />';     \r
-}\r
-\r
-function bm_doContextMenuCode() {\r
-       global $CONF;\r
-       ?>\r
-<script type="text/javascript" defer="defer">\r
-doc=external.menuArguments.document;\r
-lt=escape(doc.selection.createRange().text);\r
-loglink=escape(external.menuArguments.location.href);\r
-loglinktitle=escape(doc.title);\r
-wingm=window.open('<?php echo $CONF['AdminURL']?>bookmarklet.php?blogid=<?php echo intGetVar('blogid')?>&logtext='+lt+'&loglink='+loglink+'&loglinktitle='+loglinktitle,'nucleusbm','scrollbars=yes,width=600,height=500,left=10,top=10,status=yes,resizable=yes');\r
-wingm.focus();\r
-</script>      \r
-       <?php\r
-}\r
-\r
-function uniDecode($str,$charcode){\r
-  $text = preg_replace_callback("/%u[0-9A-Za-z]{4}/",toUtf8,$str);\r
-  return mb_convert_encoding($text, $charcode, 'UTF-8');\r
-}\r
-function toUtf8($ar){\r
-  foreach($ar as $val){\r
-    $val = intval(substr($val,2),16);\r
-    if($val < 0x7F){        // 0000-007F\r
-        $c .= chr($val);\r
-    }elseif($val < 0x800) { // 0080-0800\r
-        $c .= chr(0xC0 | ($val / 64));\r
-        $c .= chr(0x80 | ($val % 64));\r
-    }else{                // 0800-FFFF\r
-        $c .= chr(0xE0 | (($val / 64) / 64));\r
-        $c .= chr(0x80 | (($val / 64) % 64));\r
-        $c .= chr(0x80 | ($val % 64));\r
-    }\r
-  }\r
-  return $c;\r
-}\r
-\r
-?>\r
+<?php
+/*
+ * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/)
+ * Copyright (C) 2002-2007 The Nucleus Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * (see nucleus/documentation/index.html#license for more info)
+ */
+/**
+ * This script allows adding items to Nucleus through bookmarklets. The member must be logged in
+ * in order to use this.
+ *
+ * @license http://nucleuscms.org/license.txt GNU General Public License
+ * @copyright Copyright (C) 2002-2007 The Nucleus Group
+ * @version $Id: bookmarklet.php,v 1.4 2007-03-27 12:13:47 kimitake Exp $
+ * $NucleusJP: bookmarklet.php,v 1.9 2007/02/04 06:28:45 kimitake Exp $
+ */
+
+// bookmarklet is part of admin area (might need XML-RPC)
+$CONF = array();
+$CONF['UsingAdminArea'] = 1;
+
+// include all classes and config data
+include('../config.php');
+
+$action = requestVar('action');
+
+if ($action == 'contextmenucode') {
+       bm_doContextMenuCode();
+       exit;
+}
+
+if (!$member->isLoggedIn() ) {
+       bm_loginAndPassThrough();
+       exit;
+}
+
+// on successfull login
+if ( ($action == 'login') && ($member->isLoggedIn() ) ) {
+       $action = requestVar('nextaction');
+}
+
+if ($action == '') {
+       $action = 'add';
+}
+
+sendContentType('application/xhtml+xml', 'bookmarklet-' . $action);
+
+// check ticket
+$action = strtolower($action);
+$aActionsNotToCheck = array('login', 'add', 'edit');
+
+if (!in_array($action, $aActionsNotToCheck) ) {
+
+       if (!$manager->checkTicket() ) {
+               bm_doError(_ERROR_BADTICKET);
+       }
+
+}
+
+// find out what to do
+switch ($action) {
+       // adds the item for real
+       case 'additem':
+               bm_doAddItem();
+               break;
+
+       // shows the edit item form
+       case 'edit':
+               bm_doEditForm();
+               break;
+
+       // edits the item for real
+       case 'edititem':
+               bm_doEditItem();
+               break;
+
+       // on login, 'action' gets changed to 'nextaction'
+       case 'login':
+               bm_doError('Something went wrong');
+               break;
+
+       // shows the fill in form
+       case 'add':
+       default:
+               bm_doShowForm();
+               break;
+}
+
+function bm_doAddItem() {
+       global $member, $manager, $CONF;
+
+       $manager->loadClass('ITEM');
+       $result = ITEM::createFromRequest();
+
+       if ($result['status'] == 'error') {
+               bm_doError($result['message']);
+       }
+
+       $blogid = getBlogIDFromItemID($result['itemid']);
+       $blog =& $manager->getBlog($blogid);
+
+       if ($result['status'] == 'newcategory') {
+               $message = '¥¢¥¤¥Æ¥à¤ÏÄɲ䵤졢¿·¤·¤¤¥«¥Æ¥´¥ê¡¼¤¬ºîÀ®¤µ¤ì¤Þ¤·¤¿¡£ <a href="index.php?action=categoryedit&amp;blogid='.$blogid.'&amp;catid='.$result['catid'].'" onclick="if (event &amp;&amp; event.preventDefault) event.preventDefault(); window.open(this.href); return false;" title="Opens in new window">¤³¤³¤ò¥¯¥ê¥Ã¥¯¤·¤Æ¥«¥Æ¥´¥ê¡¼¤Î̾Á°¤ÈÀâÌÀ¤òÊÔ½¸¤·¤Æ¤¯¤À¤µ¤¤¡£</a>';
+               $extrahead = '';
+       } elseif ((postVar('actiontype') == 'addnow') && $blog->pingUserland()) {
+               $message = '¥¢¥¤¥Æ¥à¤ÎÄɲäËÀ®¸ù¤·¤Þ¤·¤¿¡£¸½ºßweblogs.com¤Ëping¤òÁ÷¤Ã¤Æ¤¤¤Þ¤¹¡£¤·¤Ð¤é¤¯¤Î´Ö¤ªÂÔ¤Á¤¯¤À¤µ¤¤...';
+               $pingUrl = $manager->addTicketToUrl($CONF['AdminURL'] . 'index.php?action=sendping&blogid=' . intval($blogid));
+               $extrahead = '<meta http-equiv="refresh" content="1; url=' . htmlspecialchars($pingUrl). '" />';
+       } else {
+               $message = _ITEM_ADDED;
+               $extrahead = '';
+       }
+
+       bm_message(_ITEM_ADDED, _ITEM_ADDED, $message,$extrahead);
+}
+
+function bm_doEditItem() {
+       global $member, $manager, $CONF;
+
+       $itemid = intRequestVar('itemid');
+       $catid = postVar('catid');
+
+       // only allow if user is allowed to alter item
+       if (!$member->canUpdateItem($itemid, $catid) ) {
+               bm_doError(_ERROR_DISALLOWED);
+       }
+
+       $body = postVar('body');
+       $title = postVar('title');
+       $more = postVar('more');
+       $closed = intPostVar('closed');
+       $actiontype = postVar('actiontype');
+       $draftid = intPostVar('draftid');
+
+       // redirect to admin area on delete (has delete confirmation)
+       if ($actiontype == 'delete') {
+               redirect('index.php?action=itemdelete&itemid=' . $itemid);
+               exit;
+       }
+
+       // create new category if needed (only on edit/changedate)
+       if (strstr($catid,'newcat') ) {
+               // get blogid
+               list($blogid) = sscanf($catid, "newcat-%d");
+
+               // create
+               $blog =& $manager->getBlog($blogid);
+               $catid = $blog->createNewCategory();
+
+               // show error when sth goes wrong
+               if (!$catid) {
+                       bm_doError('Could not create new category');
+               }
+       }
+
+       // only edit action is allowed for bookmarklet edit
+       switch ($actiontype) {
+               case 'changedate':
+                       $publish = 1;
+                       $wasdraft = 0;
+                       $timestamp = mktime(postVar('hour'), postVar('minutes'), 0, postVar('month'), postVar('day'), postVar('year') );
+                       break;
+               case 'edit':
+                       $publish = 1;
+                       $wasdraft = 0;
+                       $timestamp = 0;
+                       break;
+               default:
+                       bm_doError('Something went wrong');
+       }
+
+       // update item for real
+       ITEM::update($itemid, $catid, $title, $body, $more, $closed, $wasdraft, $publish, $timestamp);
+
+       if ($draftid > 0) {
+               ITEM::delete($draftid);
+       }
+
+       // show success message
+       if ($catid != intPostVar('catid') ) {
+               bm_message(_ITEM_UPDATED, _ITEM_UPDATED, '¥¢¥¤¥Æ¥à¤ÏÄɲ䵤졢¿·¤·¤¤¥«¥Æ¥´¥ê¡¼¤¬ºîÀ®¤µ¤ì¤Þ¤·¤¿¡£<a href="index.php?action=categoryedit&amp;blogid='.$blog->getID().'&amp;catid='.$catid.'" onclick="if (event &amp;&amp; event.preventDefault) event.preventDefault(); window.open(this.href); return false;" title="Opens in new window">¤³¤³¤ò¥¯¥ê¥Ã¥¯¤·¤Æ¥«¥Æ¥´¥ê¡¼¤Î̾Á°¤ÈÀâÌÀ¤òÊÔ½¸¤·¤Æ¤¯¤À¤µ¤¤¡£</a>', '');
+       } else {
+               bm_message(_ITEM_UPDATED, _ITEM_UPDATED, _ITEM_UPDATED, '');
+       }
+}
+
+function bm_loginAndPassThrough() {
+
+       $blogid = intRequestVar('blogid');
+       $log_text = requestVar('logtext');
+       $log_link = requestVar('loglink');
+       $log_linktitle = requestVar('loglinktitle');
+
+       ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+       <html xmlns="http://www.w3.org/1999/xhtml">
+       <head>
+               <meta http-equiv="Content-Type" content="text/html; charset=<?php echo _CHARSET ?>" />
+               <title>Nucleus</title>
+               <?php bm_style(); ?>
+       </head>
+       <body>
+       <h1><?php echo _LOGIN_PLEASE ?></h1>
+
+       <form method="post" action="bookmarklet.php">
+       <p>
+               <input name="action" value="login" type="hidden" />
+               <input name="blogid" value="<?php echo htmlspecialchars($blogid); ?>" type="hidden" />
+               <input name="logtext" value="<?php echo htmlspecialchars($log_text); ?>" type="hidden" />
+               <input name="loglink" value="<?php echo htmlspecialchars($log_link); ?>" type="hidden" />
+               <input name="loglinktitle" value="<?php echo htmlspecialchars($log_linktitle); ?>" type="hidden" />
+               <?php echo _LOGINFORM_NAME ?>:
+               <br /><input name="login" />
+               <br /><?php echo _LOGINFORM_PWD ?>:
+               <br /><input name="password" type="password" />
+               <br /><br />
+               <br /><input type="submit" value="<?php echo _LOGIN ?>" />
+       </p>
+       </form>
+       <p><a href="bookmarklet.php" onclick="window.close();"><?php echo _POPUP_CLOSE ?></a></p>
+       </body>
+       </html>
+       <?php
+}
+
+function bm_doShowForm() {
+       global $member;
+
+       $blogid = intRequestVar('blogid');
+       $log_text = trim(requestVar('logtext'));
+       $log_link = requestVar('loglink');
+       $log_linktitle = requestVar('loglinktitle');
+
+       $log_text = uniDecode($log_text,_CHARSET);
+       $log_linktitle = uniDecode($log_linktitle,_CHARSET);
+       
+       if (!BLOG::existsID($blogid))
+               bm_doError(_ERROR_NOSUCHBLOG);
+
+       if (!$member->isTeamMember($blogid) ) {
+               bm_doError(_ERROR_NOTONTEAM);
+       }
+
+       $logje = '';
+
+       if ($log_text) {
+               $logje .= '<blockquote><div>"' . htmlspecialchars($log_text) . '"</div></blockquote>' . "\n";
+       }
+
+       if (!$log_linktitle) {
+               $log_linktitle = $log_link;
+       }
+
+       if ($log_link) {
+               $logje .= '<a href="' . htmlspecialchars($log_link) . '">' . htmlspecialchars($log_linktitle) . '</a>';
+       }
+
+       $item['body'] = $logje;
+       $item['title'] = htmlspecialchars($log_linktitle);
+
+       $factory = new PAGEFACTORY($blogid);
+       $factory->createAddForm('bookmarklet', $item);
+}
+
+function bm_doEditForm() {
+       global $member, $manager;
+
+       $itemid = intRequestVar('itemid');
+
+       if (!$manager->existsItem($itemid, 0, 0) ) {
+               bm_doError(_ERROR_NOSUCHITEM);
+       }
+
+       if (!$member->canAlterItem($itemid) ) {
+               bm_doError(_ERROR_DISALLOWED);
+       }
+
+       $item =& $manager->getItem($itemid, 1, 1);
+       $blog =& $manager->getBlog(getBlogIDFromItemID($itemid) );
+
+       $manager->notify('PrepareItemForEdit', array('item' => &$item) );
+
+       if ($blog->convertBreaks() ) {
+               $item['body'] = removeBreaks($item['body']);
+               $item['more'] = removeBreaks($item['more']);
+       }
+
+       $formfactory = new PAGEFACTORY($blog->getID() );
+       $formfactory->createEditForm('bookmarklet', $item);
+}
+
+function bm_doError($msg) {
+       bm_message(_ERROR, _ERRORMSG, $msg);
+       die;
+}
+
+function bm_message($title, $head, $msg, $extrahead = '') {
+       ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+       <html xmlns="http://www.w3.org/1999/xhtml">
+       <head>
+               <meta http-equiv="Content-Type" content="text/html; charset=<?php echo _CHARSET ?>" />
+               <title><?php echo  $title ?></title>
+               <?php bm_style(); ?>
+               <?php echo $extrahead; ?>
+       </head>
+       <body>
+       <h1><?php echo $head; ?></h1>
+       <p><?php echo $msg; ?></p>
+       <p><a href="bookmarklet.php" onclick="window.close();"><?php echo _POPUP_CLOSE ?></a></p>
+       </body>
+       </html>
+
+       <?php
+}
+
+function bm_style() {
+       echo '<link rel="stylesheet" type="text/css" href="styles/bookmarklet.css" />';
+       echo '<link rel="stylesheet" type="text/css" href="styles/addedit.css" />';
+}
+
+function bm_doContextMenuCode() {
+       global $CONF;
+       ?>
+<script type="text/javascript" defer="defer">
+doc = external.menuArguments.document;
+lt = escape(doc.selection.createRange().text);
+loglink = escape(external.menuArguments.location.href);
+loglinktitle = escape(doc.title);
+wingm = window.open('<?php echo $CONF['AdminURL']?>bookmarklet.php?blogid=<?php echo intGetVar('blogid')?>&logtext=' + lt + '&loglink=' + loglink + '&loglinktitle=' + loglinktitle, 'nucleusbm', 'scrollbars=yes,width=600,height=500,left=10,top=10,status=yes,resizable=yes');
+wingm.focus();
+</script>
+       <?php
+}
+
+function uniDecode($str,$charcode){
+  $text = preg_replace_callback("/%u[0-9A-Za-z]{4}/",toUtf8,$str);
+  return mb_convert_encoding($text, $charcode, 'UTF-8');
+}
+function toUtf8($ar){
+  foreach($ar as $val){
+    $val = intval(substr($val,2),16);
+    if($val < 0x7F){        // 0000-007F
+        $c .= chr($val);
+    }elseif($val < 0x800) { // 0080-0800
+        $c .= chr(0xC0 | ($val / 64));
+        $c .= chr(0x80 | ($val % 64));
+    }else{                // 0800-FFFF
+        $c .= chr(0xE0 | (($val / 64) / 64));
+        $c .= chr(0x80 | (($val / 64) % 64));
+        $c .= chr(0x80 | ($val % 64));
+    }
+  }
+  return $c;
+}
+
+?>
index 8738261..a3b3076 100755 (executable)
@@ -1,52 +1,52 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">\r
-<html xmlns="http://www.w3.org/1999/xhtml">\r
-<head>\r
-       <!-- $Id: forgotpassword.html,v 1.6 2005-03-16 08:04:14 kimitake Exp $ -->\r
-       <!-- $NucleusJP: forgotpassword.html,v 1.6 2005/03/15 08:29:27 kimitake Exp $ -->\r
-       <meta http-equiv="content-type" content="application/xhtml+xml; charset=EUC-JP" />\r
-       <title>Nucleus - ¥Ñ¥¹¥ï¡¼¥É¤Îʶ¼º</title>\r
-       <style type="text/css">\r
-       <!--\r
-               @import url(styles/admin.css);\r
-       -->\r
-       </style>\r
-</head>\r
-<body>\r
-               <div class="header">\r
-               <h1>Nucleus CMS</h1>\r
-               </div>\r
-               <div id="content">\r
-\r
-                       <h2>¥Ñ¥¹¥ï¡¼¥É¤ò˺¤ì¤Þ¤·¤¿¤«¡©</h2>\r
-\r
-                       <p>\r
-                       °Ê²¼¤Ë¥æ¡¼¥¶¡¼Ì¾¤È¥á¡¼¥ë¥¢¥É¥ì¥¹¤òÆþÎϤ·¤Æ¤¯¤À¤µ¤¤¡£¿·¤·¤¤¥Ñ¥¹¥ï¡¼¥É¤òÁªÂò¤¹¤ë¥Ú¡¼¥¸¤Ø¤Î¥ê¥ó¥¯¤ÎÆþ¤Ã¤¿¥á¡¼¥ë¤¬Á÷¿®¤µ¤ì¤Þ¤¹¡£\r
-                       </p>\r
-\r
-                       <form method="post" action="../action.php"><p>\r
-                               <input name="action" value="forgotpassword" type="hidden" />\r
-                               ¥æ¡¼¥¶¡¼Ì¾¡§\r
-                               <br />\r
-                               <input name="name" />\r
-                               <br />\r
-                               ¥á¡¼¥ë¥¢¥É¥ì¥¹¡§\r
-                               <br />\r
-                               <input name="email" />\r
-                               <br />\r
-                               <br />\r
-                               <input type="submit" value="¥Ñ¥¹¥ï¡¼¥É¥á¡¼¥ë¤ÎÁ÷¿®" class="transparent" />\r
-                       </p></form>\r
-\r
-                       <p>\r
-                       ¤â¤·¥æ¡¼¥¶¡¼Ì¾¤ò¤ªËº¤ì¤Ê¤é¡¢¤¢¤Ê¤¿¤ÎNucleus¥µ¥¤¥È´ÉÍý¼Ô¤ËÏ¢Íí¤·¤Æ¤¯¤À¤µ¤¤¡£\r
-                       </p>\r
-\r
-\r
-                       <div class="foot">\r
-                               <a href="http://nucleuscms.org/">Nucleus &copy; 2001-2005 The Nucleus Group</a>\r
-                       </div>\r
-\r
-               </div><!-- content -->\r
-\r
-</body>\r
-</html>\r
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+       <!-- $Id: forgotpassword.html,v 1.7 2007-03-27 12:13:47 kimitake Exp $ -->
+       <!-- $NucleusJP: forgotpassword.html,v 1.6 2005/03/16 08:04:14 kimitake Exp $ -->
+       <meta http-equiv="content-type" content="application/xhtml+xml; charset=EUC-JP" />
+       <title>Nucleus - ¥Ñ¥¹¥ï¡¼¥É¤Îʶ¼º</title>
+       <style type="text/css">
+       <!--
+               @import url(styles/admin.css);
+       -->
+       </style>
+</head>
+<body>
+               <div class="header">
+               <h1>Nucleus CMS</h1>
+               </div>
+               <div id="content">
+
+                       <h2>¥Ñ¥¹¥ï¡¼¥É¤ò˺¤ì¤Þ¤·¤¿¤«¡©</h2>
+
+                       <p>
+                       °Ê²¼¤Ë¥æ¡¼¥¶¡¼Ì¾¤È¥á¡¼¥ë¥¢¥É¥ì¥¹¤òÆþÎϤ·¤Æ¤¯¤À¤µ¤¤¡£¿·¤·¤¤¥Ñ¥¹¥ï¡¼¥É¤òÁªÂò¤¹¤ë¥Ú¡¼¥¸¤Ø¤Î¥ê¥ó¥¯¤ÎÆþ¤Ã¤¿¥á¡¼¥ë¤¬Á÷¿®¤µ¤ì¤Þ¤¹¡£
+                       </p>
+
+                       <form method="post" action="../action.php"><p>
+                               <input name="action" value="forgotpassword" type="hidden" />
+                               ¥æ¡¼¥¶¡¼Ì¾¡§
+                               <br />
+                               <input name="name" />
+                               <br />
+                               ¥á¡¼¥ë¥¢¥É¥ì¥¹¡§
+                               <br />
+                               <input name="email" />
+                               <br />
+                               <br />
+                               <input type="submit" value="¥Ñ¥¹¥ï¡¼¥É¥á¡¼¥ë¤ÎÁ÷¿®" class="transparent" />
+                       </p></form>
+
+                       <p>
+                       ¤â¤·¥æ¡¼¥¶¡¼Ì¾¤ò¤ªËº¤ì¤Ê¤é¡¢¤¢¤Ê¤¿¤ÎNucleus¥µ¥¤¥È´ÉÍý¼Ô¤ËÏ¢Íí¤·¤Æ¤¯¤À¤µ¤¤¡£
+                       </p>
+
+
+                       <div class="foot">
+                               <a href="http://nucleuscms.org/">Nucleus &copy; 2001-2007 The Nucleus Group</a>
+                       </div>
+
+               </div><!-- content -->
+
+</body>
+</html>
index 01d342c..ef66765 100755 (executable)
@@ -1,74 +1,77 @@
-<?php\r
-/**\r
-  * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/)\r
-  * Copyright (C) 2002-2005 The Nucleus Group\r
-  *\r
-  * This program is free software; you can redistribute it and/or\r
-  * modify it under the terms of the GNU General Public License\r
-  * as published by the Free Software Foundation; either version 2\r
-  * of the License, or (at your option) any later version.\r
-  * (see nucleus/documentation/index.html#license for more info)\r
-  *\r
-  * $Id: index.php,v 1.3 2005-03-16 08:04:14 kimitake Exp $\r
-  * $NucleusJP$\r
-  */\r
-       // we are using admin stuff:\r
-       $CONF = array();\r
-       $CONF['UsingAdminArea'] = 1;\r
-\r
-       // include the admin code\r
-       include('../config.php');\r
-\r
-       if ($CONF['alertOnSecurityRisk'] == 1)\r
-       {\r
-               // check if files exist and generate an error if so\r
-               $aFiles = array(\r
-                       '../install.sql' => 'install.sql should be deleted',\r
-                       '../install.php' => 'install.php should be deleted',\r
-                       'upgrades' => 'nucleus/upgrades directory should be deleted',\r
-                       'convert' => 'nucleus/convert directory should be deleted'\r
-               );\r
-               $aFound = array();\r
-               foreach($aFiles as $fileName => $fileDesc)\r
-               {\r
-                       if (@file_exists($fileName))\r
-                               array_push($aFound, $fileDesc);\r
-               }\r
-               if (@is_writable('../config.php')) {\r
-                       array_push($aFound, 'config.php should be non-writable (chmod to 444)');\r
-               }\r
-               if (sizeof($aFound) > 0)\r
-               {\r
-                       startUpError(\r
-                               '<p>One or more of the Nucleus installation files are still present on the webserver, or are writable.</p><p>You should remove these files or change their permissions to ensure security. Here are the files that were found by Nucleus</p> <ul><li>'. implode($aFound, '</li><li>').'</li></ul><p>If you don\'t want to see this error message again, without solving the problem, set <code>$CONF[\'alertOnSecurityRisk\']</code> in <code>globalfunctions.php</code> to <code>0</code>, or do this at the end of <code>config.php</code>.</p>',\r
-                               'Security Risk'\r
-                       );\r
-               }\r
-       }\r
-\r
-       $bNeedsLogin = false;\r
-       $bIsActivation = in_array($action, array('activate', 'activatesetpwd'));\r
-       \r
-       if ($action == 'logout') \r
-               $bNeedsLogin = true;    \r
-       \r
-       if (!$member->isLoggedIn() && !$bIsActivation)\r
-               $bNeedsLogin = true;\r
-\r
-       // show error if member cannot login to admin\r
-       if ($member->isLoggedIn() && !$member->canLogin() && !$bIsActivation) {\r
-               $error = _ERROR_LOGINDISALLOWED;\r
-               $bNeedsLogin = true;\r
-       }\r
-       \r
-       if ($bNeedsLogin)\r
-       {\r
-               setOldAction($action);  // see ADMIN::login() (sets old action in POST vars)\r
-               $action = 'showlogin';\r
-       }\r
-\r
-       sendContentType('application/xhtml+xml', 'admin-' . $action);\r
-       \r
-       $admin = new ADMIN();\r
-       $admin->action($action);\r
-?>\r
+<?php
+/*
+ * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/)
+ * Copyright (C) 2002-2007 The Nucleus Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * (see nucleus/documentation/index.html#license for more info)
+ */
+/**
+ * @license http://nucleuscms.org/license.txt GNU General Public License
+ * @copyright Copyright (C) 2002-2007 The Nucleus Group
+ * @version $Id: index.php,v 1.4 2007-03-27 12:13:47 kimitake Exp $
+ * $NucleusJP: index.php,v 1.8 2007/02/04 06:28:45 kimitake Exp $
+ */
+       // we are using admin stuff:
+       $CONF = array();
+       $CONF['UsingAdminArea'] = 1;
+
+       // include the admin code
+       include('../config.php');
+
+       if ($CONF['alertOnSecurityRisk'] == 1)
+       {
+               // check if files exist and generate an error if so
+               $aFiles = array(
+                       '../install.sql' => 'install.sql should be deleted',
+                       '../install.php' => 'install.php should be deleted',
+                       'upgrades' => 'nucleus/upgrades directory should be deleted',
+                       'convert' => 'nucleus/convert directory should be deleted'
+               );
+               $aFound = array();
+               foreach($aFiles as $fileName => $fileDesc)
+               {
+                       if (@file_exists($fileName))
+                               array_push($aFound, $fileDesc);
+               }
+               if (@is_writable('../config.php')) {
+                       array_push($aFound, 'config.php should be non-writable (chmod to 444)');
+               }
+               if (sizeof($aFound) > 0)
+               {
+                       startUpError(
+                               '<p>One or more of the Nucleus installation files are still present on the webserver, or are writable.</p><p>You should remove these files or change their permissions to ensure security. Here are the files that were found by Nucleus</p> <ul><li>'. implode($aFound, '</li><li>').'</li></ul><p>If you don\'t want to see this error message again, without solving the problem, set <code>$CONF[\'alertOnSecurityRisk\']</code> in <code>globalfunctions.php</code> to <code>0</code>, or do this at the end of <code>config.php</code>.</p>',
+                               'Security Risk'
+                       );
+               }
+       }
+
+       $bNeedsLogin = false;
+       $bIsActivation = in_array($action, array('activate', 'activatesetpwd'));
+
+       if ($action == 'logout')
+               $bNeedsLogin = true;
+
+       if (!$member->isLoggedIn() && !$bIsActivation)
+               $bNeedsLogin = true;
+
+       // show error if member cannot login to admin
+       if ($member->isLoggedIn() && !$member->canLogin() && !$bIsActivation) {
+               $error = _ERROR_LOGINDISALLOWED;
+               $bNeedsLogin = true;
+       }
+
+       if ($bNeedsLogin)
+       {
+               setOldAction($action);  // see ADMIN::login() (sets old action in POST vars)
+               $action = 'showlogin';
+       }
+
+       sendContentType('application/xhtml+xml', 'admin-' . $action);
+
+       $admin = new ADMIN();
+       $admin->action($action);
+?>
\ No newline at end of file
index 9e94c78..bb73358 100755 (executable)
-<?php\r
-\r
-/**\r
-  * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/)\r
-  * Copyright (C) 2002-2005 The Nucleus Group\r
-  *\r
-  * This program is free software; you can redistribute it and/or\r
-  * modify it under the terms of the GNU General Public License\r
-  * as published by the Free Software Foundation; either version 2\r
-  * of the License, or (at your option) any later version.\r
-  * (see nucleus/documentation/index.html#license for more info)\r
-  *\r
-  * A class representing the comments (all of them) for a certain post on a ceratin blog\r
-  *\r
-  * $Id: COMMENTS.php,v 1.3 2005-03-16 08:10:35 kimitake Exp $\r
-  * $NucleusJP: COMMENTS.php,v 1.5 2005/03/12 06:19:05 kimitake Exp $\r
-  */\r
-class COMMENTS {\r
-\r
-       // item for which comment are being displayed\r
-       var $itemid;\r
-\r
-       // reference to the itemActions object that is calling the showComments function\r
-       var $itemActions;\r
-\r
-       // total amount of comments displayed\r
-       var $commentcount;\r
-\r
-       /**\r
-        * Creates a new COMMENTS object for the given blog and item\r
-        *\r
-        * @param $itemid\r
-        *              id of the item\r
-        */\r
-       function COMMENTS($itemid) {\r
-               $this->itemid = intval($itemid);\r
-       }\r
-       /**\r
-        * Used when parsing comments\r
-        *\r
-        * @param $itemActions\r
-        *              itemActions object, that will take care of the parsing\r
-        */\r
-       function setItemActions(&$itemActions) {\r
-               $this->itemActions =& $itemActions;\r
-       }\r
-\r
-       /**\r
-        * Shows maximum $max comments to the given item using the given template\r
-        * returns the amount of shown comments (if maxToShow = -1, then there is no limit)\r
-        *\r
-        * @param template\r
-        *              template to use\r
-        * @param maxToShow\r
-        *              max. comments to show\r
-        * @param showNone\r
-        *              indicates if the 'no comments' thingie should be outputted when there are no comments\r
-        *              (useful for closed items)\r
-        * @param highlight\r
-        *              Highlight to use (if any)\r
-        */\r
-       function showComments($template, $maxToShow = -1, $showNone = 1, $highlight = '') {\r
-               global $CONF, $manager;\r
-\r
-               // create parser object & action handler\r
-               $actions =& new COMMENTACTIONS($this);\r
-               $parser =& new PARSER($actions->getDefinedActions(),$actions);\r
-               $actions->setTemplate($template);\r
-               $actions->setParser($parser);\r
-\r
-               if ($maxToShow == 0) {\r
-                       $this->commentcount = $this->amountComments();\r
-               } else {\r
-                       $query =  'SELECT c.cnumber as commentid, c.cbody as body, c.cuser as user, c.cmail as userid, c.cmember as memberid, c.ctime, c.chost as host, c.cip as ip, c.cblog as blogid'\r
-                                  . ' FROM '.sql_table('comment').' as c'\r
-                                  . ' WHERE c.citem=' . $this->itemid\r
-                                  . ' ORDER BY c.ctime';\r
-\r
-                       $comments = sql_query($query);\r
-                       $this->commentcount = mysql_num_rows($comments);\r
-               }\r
-\r
-               // if no result was found\r
-               if ($this->commentcount == 0) {\r
-                       // note: when no reactions, COMMENTS_HEADER and COMMENTS_FOOTER are _NOT_ used\r
-                       if ($showNone) $parser->parse($template['COMMENTS_NONE']);\r
-                       return 0;\r
-               }\r
-\r
-               // if too many comments to show\r
-               if (($maxToShow != -1) && ($this->commentcount > $maxToShow)) {\r
-                       $parser->parse($template['COMMENTS_TOOMUCH']);\r
-                       return 0;\r
-               }\r
-\r
-               $parser->parse($template['COMMENTS_HEADER']);\r
-\r
-               while ( $comment = mysql_fetch_assoc($comments) ) {\r
-                       $comment['timestamp'] = strtotime($comment['ctime']);\r
-                       $actions->setCurrentComment($comment);\r
-                       $actions->setHighlight($highlight);\r
-                       $manager->notify('PreComment', array('comment' => &$comment));\r
-                       $parser->parse($template['COMMENTS_BODY']);\r
-                       $manager->notify('PostComment', array('comment' => &$comment));\r
-               }\r
-\r
-               $parser->parse($template['COMMENTS_FOOTER']);\r
-\r
-               mysql_free_result($comments);\r
-\r
-               return $this->commentcount;\r
-       }\r
-\r
-       /**\r
-        * Returns the amount of comments for this itemid\r
-        */\r
-       function amountComments() {\r
-               $query =  'SELECT COUNT(*)'\r
-                          . ' FROM '.sql_table('comment').' as c'\r
-                          . ' WHERE c.citem='. $this->itemid;\r
-               $res = sql_query($query);\r
-               $arr = mysql_fetch_row($res);\r
-\r
-               return $arr[0];\r
-       }\r
-\r
-\r
-       function addComment($timestamp, $comment) {\r
-               global $CONF, $member, $manager;\r
-\r
-               $blogid = getBlogIDFromItemID($this->itemid);\r
-\r
-               $settings =& $manager->getBlog($blogid);\r
-               $settings->readSettings();\r
-\r
-               if (!$settings->commentsEnabled())\r
-                       return _ERROR_COMMENTS_DISABLED;\r
-\r
-               if (!$settings->isPublic() && !$member->isLoggedIn())\r
-                       return _ERROR_COMMENTS_NONPUBLIC;\r
-\r
-               // member name protection\r
-               if ($CONF['ProtectMemNames'] && !$member->isLoggedIn() && MEMBER::isNameProtected($comment['user']))\r
-                       return _ERROR_COMMENTS_MEMBERNICK;\r
-\r
-               // isValidComment returns either "1" or an error message\r
-               $isvalid = $this->isValidComment($comment);\r
-               if ($isvalid != 1)\r
-                       return $isvalid;\r
-\r
-               $comment['timestamp'] = $timestamp;\r
-               $comment['host'] = gethostbyaddr(serverVar('REMOTE_ADDR'));\r
-               $comment['ip'] = serverVar('REMOTE_ADDR');\r
-\r
-               // if member is logged in, use that data\r
-               if ($member->isLoggedIn()) {\r
-                       $comment['memberid'] = $member->getID();\r
-                       $comment['user'] = '';\r
-                       $comment['userid'] = '';\r
-               } else {\r
-                       $comment['memberid'] = 0;\r
-               }\r
-\r
-\r
-               // send email to notification address, if any\r
-               if ($settings->getNotifyAddress() && $settings->notifyOnComment()) {\r
-\r
-                       $mailto_msg = _NOTIFY_NC_MSG . ' ' . $this->itemid . "\n";\r
-                       $mailto_msg .= $CONF['IndexURL'] . 'index.php?itemid=' . $this->itemid . "\n\n";\r
-                       if ($comment['memberid'] == 0) {\r
-                               $mailto_msg .= _NOTIFY_USER . ' ' . $comment['user'] . "\n";\r
-                               $mailto_msg .= _NOTIFY_USERID . ' ' . $comment['userid'] . "\n";\r
-                       } else {\r
-                               $mailto_msg .= _NOTIFY_MEMBER .' ' . $member->getDisplayName() . ' (ID=' . $member->getID() . ")\n";\r
-                       }\r
-                       $mailto_msg .= _NOTIFY_HOST . ' ' . $comment['host'] . "\n";\r
-                       $mailto_msg .= _NOTIFY_COMMENT . "\n " . $comment['body'] . "\n";\r
-                       $mailto_msg .= getMailFooter();\r
-\r
-                       $item =& $manager->getItem($this->itemid, 0, 0);\r
-                       $mailto_title = _NOTIFY_NC_TITLE . ' ' . strip_tags($item['title']) . ' (' . $this->itemid . ')';\r
-\r
-                       $frommail = $member->getNotifyFromMailAddress($comment['userid']);\r
-\r
-                       $notify =& new NOTIFICATION($settings->getNotifyAddress());\r
-                       $notify->notify($mailto_title, $mailto_msg , $frommail);\r
-               }\r
-\r
-               $comment = COMMENT::prepare($comment);\r
-\r
-               $manager->notify('PreAddComment',array('comment' => &$comment));\r
-\r
-               $name           = addslashes($comment['user']);\r
-               $url            = addslashes($comment['userid']);\r
-               $body           = addslashes($comment['body']);\r
-               $host           = addslashes($comment['host']);\r
-               $ip                     = addslashes($comment['ip']);\r
-               $memberid       = intval($comment['memberid']);\r
-               $timestamp      = date('Y-m-d H:i:s', $comment['timestamp']);\r
-               $itemid         = $this->itemid;\r
-\r
-               $query = 'INSERT INTO '.sql_table('comment').' (CUSER, CMAIL, CMEMBER, CBODY, CITEM, CTIME, CHOST, CIP, CBLOG) '\r
-                          . "VALUES ('$name', '$url', $memberid, '$body', $itemid, '$timestamp', '$host', '$ip', '$blogid')";\r
-\r
-               sql_query($query);\r
-\r
-               // post add comment\r
-               $commentid = mysql_insert_id();\r
-               $manager->notify('PostAddComment',array('comment' => &$comment, 'commentid' => &$commentid));\r
-\r
-               // succeeded !\r
-               return true;\r
-       }\r
-\r
-\r
-       function isValidComment($comment) {\r
-               global $member, $manager;\r
-\r
-               // check if there exists a item for this date\r
-               $item =& $manager->getItem($this->itemid,0,0);\r
-\r
-               if (!$item)\r
-                       return _ERROR_NOSUCHITEM;\r
-\r
-               if ($item['closed'])\r
-                       return _ERROR_ITEMCLOSED;\r
-\r
-               // don't allow words that are too long\r
-               if (eregi('[a-zA-Z0-9|\.,;:!\?=\/\\]{90,90}',$comment['body']) != false)\r
-                       return _ERROR_COMMENT_LONGWORD;\r
-\r
-               // check lengths of comment\r
-               if (strlen($comment['body'])<3)\r
-                       return _ERROR_COMMENT_NOCOMMENT;\r
-\r
-               if (strlen($comment['body'])>5000)\r
-                       return _ERROR_COMMENT_TOOLONG;\r
-\r
-               // only check username if no member logged in\r
-               if (!$member->isLoggedIn())\r
-                       if (strlen($comment['user'])<2)\r
-                               return _ERROR_COMMENT_NOUSERNAME;\r
-\r
-               // let plugins do verification (any plugin which thinks the comment is invalid\r
-               // can change 'error' to something other than '1')\r
-               $result = 1;\r
-               $manager->notify('ValidateForm', array('type' => 'comment', 'comment' => &$comment, 'error' => &$result));\r
-\r
-               return $result;\r
-       }\r
-\r
-\r
-}\r
-\r
-/**\r
-  * This class is used when parsing comment templates\r
-  */\r
-class COMMENTACTIONS extends BaseActions {\r
-\r
-       // ref to COMMENTS object which is using this object to handle\r
-       // its templatevars\r
-       var $commentsObj;\r
-\r
-       // template to use to parse the comments\r
-       var $template;\r
-\r
-       // comment currenlty being handled (mysql result assoc array; see COMMENTS::showComments())\r
-       var $currentComment;\r
-\r
-       function COMMENTACTIONS(&$comments) {\r
-               // call constructor of superclass first\r
-               $this->BaseActions();\r
-\r
-               // reference to the comments object\r
-               $this->setCommentsObj($comments);\r
-       }\r
-\r
-       function getDefinedActions() {\r
-               return array(\r
-                       'commentcount',\r
-                       'commentword',\r
-                       'itemlink',\r
-                       'itemid',\r
-                       'itemtitle',\r
-                       'date',\r
-                       'time',\r
-                       'commentid',\r
-                       'body',\r
-                       'memberid',\r
-                       'timestamp',\r
-                       'host',\r
-                       'ip',\r
-                       'blogid',\r
-                       'authtext',\r
-                       'user',\r
-                       'userid',\r
-                       'userlinkraw',\r
-                       'userlink',\r
-                       'short',\r
-                       'skinfile',\r
-                       'set',\r
-                       'plugin',\r
-                       'include',\r
-                       'phpinclude',\r
-                       'parsedinclude'\r
-               );\r
-       }\r
-\r
-       function setParser(&$parser) {                  $this->parser =& $parser; }\r
-       function setCommentsObj(&$commentsObj) {$this->commentsObj =& $commentsObj; }\r
-       function setTemplate($template) {               $this->template =& $template; }\r
-       function setCurrentComment(&$comment) {\r
-               if ($comment['memberid'] != 0) {\r
-                       $comment['authtext'] = $template['COMMENTS_AUTH'];\r
-\r
-                       $mem = MEMBER::createFromID($comment['memberid']);\r
-                       $comment['user'] = $mem->getDisplayName();\r
-                       if ($mem->getURL())\r
-                               $comment['userid'] = $mem->getURL();\r
-                       else\r
-                               $comment['userid'] = $mem->getEmail();\r
-\r
-                       $comment['userlinkraw'] = createMemberLink(\r
-                                                                               $comment['memberid'],\r
-                                                                               $this->commentsObj->itemActions->linkparams\r
-                                                                         );\r
-\r
-               } else {\r
-\r
-                       // create smart links\r
-                       if (isValidMailAddress($comment['userid']))\r
-                               $comment['userlinkraw'] = 'mailto:'.$comment['userid'];\r
-                       elseif (strstr($comment['userid'],'http://') != false)\r
-                               $comment['userlinkraw'] = $comment['userid'];\r
-                       elseif (strstr($comment['userid'],'www') != false)\r
-                               $comment['userlinkraw'] = 'http://'.$comment['userid'];\r
-               }\r
-\r
-               $this->currentComment =& $comment;\r
-       }\r
-\r
-       function parse_commentcount() {                 echo $this->commentsObj->commentcount; }\r
-       function parse_commentword() {\r
-               if ($this->commentsObj->commentcount == 1)\r
-                       echo $this->template['COMMENTS_ONE'];\r
-               else\r
-                       echo $this->template['COMMENTS_MANY'];\r
-       }\r
-\r
-       function parse_itemlink() {                             echo createItemLink($this->commentsObj->itemid, $this->commentsObj->itemActions->linkparams); }\r
-       function parse_itemid() {                               echo $this->commentsObj->itemid; }\r
-       function parse_itemtitle($maxLength = 0) {\r
-               if ($maxLength == 0)\r
-                       $this->commentsObj->itemActions->parse_title();\r
-               else\r
-                       $this->commentsObj->itemActions->parse_syndicate_title($maxLength);\r
-       }\r
-\r
-       function parse_date($format = '') {\r
-               echo formatDate($format, $this->currentComment['timestamp'], $this->template['FORMAT_DATE']);\r
-       }\r
-       function parse_time($format = '') {\r
-               echo strftime(\r
-                               ($format == '') ? $this->template['FORMAT_TIME'] : $format,\r
-                               $this->currentComment['timestamp']\r
-                       );\r
-       }\r
-\r
-       function parse_commentid() {                    echo $this->currentComment['commentid']; }\r
-       function parse_body() {                                 echo $this->highlight($this->currentComment['body']); }\r
-       function parse_memberid() {                             echo $this->currentComment['memberid']; }\r
-       function parse_timestamp() {                    echo $this->currentComment['timestamp']; }\r
-       function parse_host() {                                 echo $this->currentComment['host']; }\r
-       function parse_ip() {                                   echo $this->currentComment['ip']; }\r
-       function parse_blogid() {                               echo $this->currentComment['blogid']; }\r
-\r
-       function parse_user() {                                 echo $this->currentComment['user']; }\r
-       function parse_userid() {                               echo $this->currentComment['userid']; }\r
-       function parse_userlinkraw() {                  echo $this->currentComment['userlinkraw']; }\r
-       function parse_userlink() {\r
-               if ($this->currentComment['userlinkraw']) {\r
-                       echo '<a href="'.$this->currentComment['userlinkraw'].'" rel="nofollow">'.$this->currentComment['user'].'</a>';\r
-               } else {\r
-                       echo $this->currentComment['user'];\r
-               }\r
-       }\r
-       function parse_short() {\r
-               $tmp = strtok($this->currentComment['body'],"\n");\r
-               $tmp = str_replace('<br />','',$tmp);\r
-               echo $tmp;\r
-               if ($tmp != $this->currentComment['body'])\r
-                       $this->parser->parse($this->template['COMMENTS_CONTINUED']);\r
-       }\r
-       function parse_authtext() {\r
-               if ($this->currentComment['memberid'] != 0)\r
-                       $this->parser->parse($this->template['COMMENTS_AUTH']);\r
-       }\r
-\r
-       /**\r
-         * Executes a plugin templatevar\r
-         *\r
-         * @param pluginName name of plugin (without the NP_)\r
-         *\r
-         * extra parameters can be added\r
-         */\r
-       function parse_plugin($pluginName) {\r
-               global $manager;\r
-\r
-               // only continue when the plugin is really installed\r
-               if (!$manager->pluginInstalled('NP_' . $pluginName))\r
-                       return;\r
-\r
-               $plugin =& $manager->getPlugin('NP_' . $pluginName);\r
-               if (!$plugin) return;\r
-\r
-               // get arguments\r
-               $params = func_get_args();\r
-\r
-               // remove plugin name\r
-               array_shift($params);\r
-\r
-               // pass info on current item and current comment as well\r
-               $params = array_merge(array(&$this->currentComment),$params);\r
-               $params = array_merge(array(&$this->commentsObj->itemActions->currentItem),$params);\r
-\r
-               call_user_func_array(array(&$plugin,'doTemplateCommentsVar'), $params);\r
-       }\r
-}\r
-\r
-?>\r
+<?php
+
+/*
+ * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/)
+ * Copyright (C) 2002-2007 The Nucleus Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * (see nucleus/documentation/index.html#license for more info)
+ */
+/**
+ * A class representing the comments (all of them) for a certain post on a ceratin blog
+ *
+ * @license http://nucleuscms.org/license.txt GNU General Public License
+ * @copyright Copyright (C) 2002-2007 The Nucleus Group
+ * @version $Id: COMMENTS.php,v 1.4 2007-03-27 12:13:56 kimitake Exp $
+ * $NucleusJP: COMMENTS.php,v 1.9 2007/03/20 19:31:29 kmorimatsu Exp $
+ */
+
+if ( !function_exists('requestVar') ) exit;
+require_once dirname(__FILE__) . '/COMMENTACTIONS.php';
+
+class COMMENTS {
+
+       // item for which comment are being displayed
+       var $itemid;
+
+       // reference to the itemActions object that is calling the showComments function
+       var $itemActions;
+
+       // total amount of comments displayed
+       var $commentcount;
+
+       /**
+        * Creates a new COMMENTS object for the given blog and item
+        *
+        * @param $itemid
+        *              id of the item
+        */
+       function COMMENTS($itemid) {
+               $this->itemid = intval($itemid);
+       }
+       /**
+        * Used when parsing comments
+        *
+        * @param $itemActions
+        *              itemActions object, that will take care of the parsing
+        */
+       function setItemActions(&$itemActions) {
+               $this->itemActions =& $itemActions;
+       }
+
+       /**
+        * Shows maximum $max comments to the given item using the given template
+        * returns the amount of shown comments (if maxToShow = -1, then there is no limit)
+        *
+        * @param template
+        *              template to use
+        * @param maxToShow
+        *              max. comments to show
+        * @param showNone
+        *              indicates if the 'no comments' thingie should be outputted when there are no comments
+        *              (useful for closed items)
+        * @param highlight
+        *              Highlight to use (if any)
+        */
+       function showComments($template, $maxToShow = -1, $showNone = 1, $highlight = '') {
+               global $CONF, $manager;
+
+               // create parser object & action handler
+               $actions =& new COMMENTACTIONS($this);
+               $parser =& new PARSER($actions->getDefinedActions(),$actions);
+               $actions->setTemplate($template);
+               $actions->setParser($parser);
+
+               if ($maxToShow == 0) {
+                       $this->commentcount = $this->amountComments();
+               } else {
+                       $query =  'SELECT c.citem as itemid, c.cnumber as commentid, c.cbody as body, c.cuser as user, c.cmail as userid, c.cemail as email, c.cmember as memberid, c.ctime, c.chost as host, c.cip as ip, c.cblog as blogid'
+                                  . ' FROM '.sql_table('comment').' as c'
+                                  . ' WHERE c.citem=' . $this->itemid
+                                  . ' ORDER BY c.ctime';
+
+                       $comments = sql_query($query);
+                       $this->commentcount = mysql_num_rows($comments);
+               }
+
+               // if no result was found
+               if ($this->commentcount == 0) {
+                       // note: when no reactions, COMMENTS_HEADER and COMMENTS_FOOTER are _NOT_ used
+                       if ($showNone) $parser->parse($template['COMMENTS_NONE']);
+                       return 0;
+               }
+
+               // if too many comments to show
+               if (($maxToShow != -1) && ($this->commentcount > $maxToShow)) {
+                       $parser->parse($template['COMMENTS_TOOMUCH']);
+                       return 0;
+               }
+
+               $parser->parse($template['COMMENTS_HEADER']);
+
+               while ( $comment = mysql_fetch_assoc($comments) ) {
+                       $comment['timestamp'] = strtotime($comment['ctime']);
+                       $actions->setCurrentComment($comment);
+                       $actions->setHighlight($highlight);
+                       $manager->notify('PreComment', array('comment' => &$comment));
+                       $parser->parse($template['COMMENTS_BODY']);
+                       $manager->notify('PostComment', array('comment' => &$comment));
+               }
+
+               $parser->parse($template['COMMENTS_FOOTER']);
+
+               mysql_free_result($comments);
+
+               return $this->commentcount;
+       }
+
+       /**
+        * Returns the amount of comments for this itemid
+        */
+       function amountComments() {
+               $query =  'SELECT COUNT(*)'
+                          . ' FROM '.sql_table('comment').' as c'
+                          . ' WHERE c.citem='. $this->itemid;
+               $res = sql_query($query);
+               $arr = mysql_fetch_row($res);
+
+               return $arr[0];
+       }
+
+
+       function addComment($timestamp, $comment) {
+               global $CONF, $member, $manager;
+
+               $blogid = getBlogIDFromItemID($this->itemid);
+
+               $settings =& $manager->getBlog($blogid);
+               $settings->readSettings();
+
+               if (!$settings->commentsEnabled())
+                       return _ERROR_COMMENTS_DISABLED;
+
+               if (!$settings->isPublic() && !$member->isLoggedIn())
+                       return _ERROR_COMMENTS_NONPUBLIC;
+
+               // member name protection
+               if ($CONF['ProtectMemNames'] && !$member->isLoggedIn() && MEMBER::isNameProtected($comment['user']))
+                       return _ERROR_COMMENTS_MEMBERNICK;
+
+               if ($isvalid != 1)
+               if ($settings->emailRequired() && strlen($comment['email']) == 0 && !$member->isLoggedIn()) {
+                       return _ERROR_EMAIL_REQUIRED;
+               }
+
+               $comment['timestamp'] = $timestamp;
+               $comment['host'] = gethostbyaddr(serverVar('REMOTE_ADDR'));
+               $comment['ip'] = serverVar('REMOTE_ADDR');
+
+               // if member is logged in, use that data
+               if ($member->isLoggedIn()) {
+                       $comment['memberid'] = $member->getID();
+                       $comment['user'] = '';
+                       $comment['userid'] = '';
+                       $comment['email'] = '';
+               } else {
+                       $comment['memberid'] = 0;
+               }
+
+               // spam check
+               $continue = false;
+               $plugins = array();
+
+               if (isset($manager->subscriptions['ValidateForm']))
+                       $plugins = array_merge($plugins, $manager->subscriptions['ValidateForm']);
+
+               if (isset($manager->subscriptions['PreAddComment']))
+                       $plugins = array_merge($plugins, $manager->subscriptions['PreAddComment']);
+
+               if (isset($manager->subscriptions['PostAddComment']))
+                       $plugins = array_merge($plugins, $manager->subscriptions['PostAddComment']);
+
+               $plugins = array_unique($plugins);
+
+               while (list(,$plugin) = each($plugins)) {
+                       $p = $manager->getPlugin($plugin);
+                       $continue = $continue || $p->supportsFeature('handleSpam');
+               }
+
+               $spamcheck = array (
+                       'type'          => 'comment',
+                       'body'          => $comment['body'],
+                       'id'        => $comment['itemid'],
+                       'live'          => true,
+                       'return'        => $continue
+               );
+
+               if ($member->isLoggedIn()) {
+                       $spamcheck['author'] = $member->displayname;
+                       $spamcheck['email'] = $member->email;
+               } else {
+                       $spamcheck['author'] = $comment['user'];
+                       $spamcheck['email'] = $comment['email'];
+                       $spamcheck['url'] = $comment['userid'];
+               }
+
+               $manager->notify('SpamCheck', array ('spamcheck' => &$spamcheck));
+
+               if (!$continue && isset($spamcheck['result']) && $spamcheck['result'] == true)
+                       return _ERROR_COMMENTS_SPAM;
+
+
+               // isValidComment returns either "1" or an error message
+               $isvalid = $this->isValidComment($comment, $spamcheck);
+               if ($isvalid != 1)
+                       return $isvalid;
+
+               // send email to notification address, if any
+               if ($settings->getNotifyAddress() && $settings->notifyOnComment()) {
+
+                       $mailto_msg = _NOTIFY_NC_MSG . ' ' . $this->itemid . "\n";
+//                     $mailto_msg .= $CONF['IndexURL'] . 'index.php?itemid=' . $this->itemid . "\n\n";
+                       $temp = parse_url($CONF['Self']);
+                       if ($temp['scheme']) {
+                               $mailto_msg .= createItemLink($this->itemid) . "\n\n";
+                       } else {
+                               $tempurl = $settings->getURL();
+                               if (substr($tempurl, -1) == '/' || substr($tempurl, -4) == '.php') {
+                                       $mailto_msg .= $tempurl . '?itemid=' . $this->itemid . "\n\n";
+                               } else {
+                                       $mailto_msg .= $tempurl . '/?itemid=' . $this->itemid . "\n\n";
+                               }
+                       }
+                       if ($comment['memberid'] == 0) {
+                               $mailto_msg .= _NOTIFY_USER . ' ' . $comment['user'] . "\n";
+                               $mailto_msg .= _NOTIFY_USERID . ' ' . $comment['userid'] . "\n";
+                       } else {
+                               $mailto_msg .= _NOTIFY_MEMBER .' ' . $member->getDisplayName() . ' (ID=' . $member->getID() . ")\n";
+                       }
+                       $mailto_msg .= _NOTIFY_HOST . ' ' . $comment['host'] . "\n";
+                       $mailto_msg .= _NOTIFY_COMMENT . "\n " . $comment['body'] . "\n";
+                       $mailto_msg .= getMailFooter();
+
+                       $item =& $manager->getItem($this->itemid, 0, 0);
+                       $mailto_title = _NOTIFY_NC_TITLE . ' ' . strip_tags($item['title']) . ' (' . $this->itemid . ')';
+
+                       $frommail = $member->getNotifyFromMailAddress($comment['userid']);
+
+                       $notify =& new NOTIFICATION($settings->getNotifyAddress());
+                       $notify->notify($mailto_title, $mailto_msg , $frommail);
+               }
+
+               $comment = COMMENT::prepare($comment);
+
+               $manager->notify('PreAddComment',array('comment' => &$comment, 'spamcheck' => &$spamcheck));
+
+               $name           = addslashes($comment['user']);
+               $url            = addslashes($comment['userid']);
+               $email      = addslashes($comment['email']);
+               $body           = addslashes($comment['body']);
+               $host           = addslashes($comment['host']);
+               $ip                     = addslashes($comment['ip']);
+               $memberid       = intval($comment['memberid']);
+               $timestamp      = date('Y-m-d H:i:s', $comment['timestamp']);
+               $itemid         = $this->itemid;
+
+               $query = 'INSERT INTO '.sql_table('comment').' (CUSER, CMAIL, CEMAIL, CMEMBER, CBODY, CITEM, CTIME, CHOST, CIP, CBLOG) '
+                          . "VALUES ('$name', '$url', '$email', $memberid, '$body', $itemid, '$timestamp', '$host', '$ip', '$blogid')";
+
+               sql_query($query);
+
+               // post add comment
+               $commentid = mysql_insert_id();
+               $manager->notify('PostAddComment',array('comment' => &$comment, 'commentid' => &$commentid, 'spamcheck' => &$spamcheck));
+
+               // succeeded !
+               return true;
+       }
+
+
+       function isValidComment($comment, & $spamcheck) {
+               global $member, $manager;
+
+               // check if there exists a item for this date
+               $item =& $manager->getItem($this->itemid,0,0);
+
+               if (!$item)
+                       return _ERROR_NOSUCHITEM;
+
+               if ($item['closed'])
+                       return _ERROR_ITEMCLOSED;
+
+               // don't allow words that are too long
+               if (eregi('[a-zA-Z0-9|\.,;:!\?=\/\\]{90,90}',$comment['body']) != false)
+                       return _ERROR_COMMENT_LONGWORD;
+
+               // check lengths of comment
+               if (strlen($comment['body'])<3)
+                       return _ERROR_COMMENT_NOCOMMENT;
+
+               if (strlen($comment['body'])>5000)
+                       return _ERROR_COMMENT_TOOLONG;
+
+               // only check username if no member logged in
+               if (!$member->isLoggedIn())
+                       if (strlen($comment['user'])<2)
+                               return _ERROR_COMMENT_NOUSERNAME;
+
+               if ((strlen($comment['email']) != 0) && !(isValidMailAddress($comment['email']))) {
+                       return _ERROR_BADMAILADDRESS;
+               }
+
+               // let plugins do verification (any plugin which thinks the comment is invalid
+               // can change 'error' to something other than '1')
+               $result = 1;
+               $manager->notify('ValidateForm', array('type' => 'comment', 'comment' => &$comment, 'error' => &$result, 'spamcheck' => &$spamcheck));
+
+               return $result;
+       }
+
+}
+
+?>
\ No newline at end of file
index 6662c3c..01ec1d5 100755 (executable)
-<?php\r
-\r
-/**\r
-  * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/) \r
-  * Copyright (C) 2002-2005 The Nucleus Group\r
-  *\r
-  * This program is free software; you can redistribute it and/or\r
-  * modify it under the terms of the GNU General Public License\r
-  * as published by the Free Software Foundation; either version 2\r
-  * of the License, or (at your option) any later version.\r
-  * (see nucleus/documentation/index.html#license for more info)\r
-  *\r
-  * A class representing an item\r
-  *\r
-  * $Id: ITEM.php,v 1.3 2005-03-16 08:10:35 kimitake Exp $\r
-  * $NucleusJP: ITEM.php,v 1.3 2005/03/12 06:19:05 kimitake Exp $\r
-  */\r
-class ITEM {\r
-       \r
-       var $itemid;\r
-       \r
-       function ITEM($itemid) {\r
-               $this->itemid = $itemid;\r
-       }\r
-       \r
-       /**\r
-         * Returns one item with the specific itemid\r
-         * (static)\r
-         */\r
-       function getitem($itemid, $allowdraft, $allowfuture) {\r
-               global $manager;\r
-\r
-               $itemid = intval($itemid);\r
-               \r
-               $query =  'SELECT i.idraft as draft, i.inumber as itemid, i.iclosed as closed, '\r
-                      . ' i.ititle as title, i.ibody as body, m.mname as author, '\r
-                      . ' i.iauthor as authorid, i.itime, i.imore as more, i.ikarmapos as karmapos, '\r
-                      . ' i.ikarmaneg as karmaneg, i.icat as catid, i.iblog as blogid '\r
-                      . ' FROM '.sql_table('item').' as i, '.sql_table('member').' as m, ' . sql_table('blog') . ' as b '\r
-                      . ' WHERE i.inumber=' . $itemid\r
-                      . ' and i.iauthor=m.mnumber '\r
-                      . ' and i.iblog=b.bnumber';\r
-                      \r
-               if (!$allowdraft)\r
-                       $query .= ' and i.idraft=0';\r
-                       \r
-               if (!$allowfuture) {\r
-                       $blog =& $manager->getBlog(getBlogIDFromItemID($itemid));\r
-                       $query .= ' and i.itime <=' . mysqldate($blog->getCorrectTime());               \r
-               }\r
-               \r
-               $query .= ' LIMIT 1';\r
-\r
-               $res = sql_query($query);\r
-\r
-               if (mysql_num_rows($res) == 1)\r
-               {\r
-                       $aItemInfo = mysql_fetch_assoc($res);\r
-                       $aItemInfo['timestamp'] = strtotime($aItemInfo['itime']);       \r
-                       return $aItemInfo;\r
-               } else {\r
-                       return 0;\r
-               }\r
-\r
-       }       \r
-       \r
-       /**\r
-        * Tries to create an item from the data in the current request (comes from\r
-        * bookmarklet or admin area \r
-        *\r
-        * Returns an array with status info (status = 'added', 'error', 'newcategory')\r
-        *\r
-        * (static)\r
-        */\r
-       function createFromRequest() {\r
-                global $member, $manager;\r
-                \r
-                $i_author =            $member->getID();\r
-                $i_body =                      postVar('body');\r
-                $i_title =                     postVar('title');\r
-                $i_more =                      postVar('more');\r
-                $i_actiontype =        postVar('actiontype');           \r
-                $i_closed =            intPostVar('closed');\r
-                $i_hour =                      intPostVar('hour');              \r
-                $i_minutes =           intPostVar('minutes');           \r
-                $i_month =             intPostVar('month');             \r
-                $i_day =                       intPostVar('day');               \r
-                $i_year =                      intPostVar('year');                              \r
-\r
-                $i_catid =             postVar('catid');\r
-                \r
-                if (!$member->canAddItem($i_catid))\r
-                       return array('status' => 'error', 'message' => _ERROR_DISALLOWED);\r
-                \r
-                if (!$i_actiontype) $i_actiontype = 'addnow';\r
-\r
-                switch ($i_actiontype) {\r
-                       case 'adddraft':\r
-                               $i_draft = 1;\r
-                               break;\r
-                       case 'addfuture':\r
-                       case 'addnow':\r
-                       default:\r
-                               $i_draft = 0;\r
-                }\r
-                \r
-                if (!trim($i_body))\r
-                       return array('status' => 'error', 'message' => _ERROR_NOEMPTYITEMS);\r
-                \r
-               // create new category if needed \r
-               if (strstr($i_catid,'newcat')) {\r
-                       // get blogid \r
-                       list($i_blogid) = sscanf($i_catid,"newcat-%d");\r
-                       \r
-                       // create\r
-                       $blog =& $manager->getBlog($i_blogid);\r
-                       $i_catid = $blog->createNewCategory();\r
-\r
-                       // show error when sth goes wrong\r
-                       if (!$i_catid) \r
-                               return array('status' => 'error','message' => 'Could not create new category');\r
-               } else {\r
-                       // force blogid (must be same as category id)\r
-                       $i_blogid = getBlogIDFromCatID($i_catid);\r
-                       $blog =& $manager->getBlog($i_blogid);\r
-               }\r
-               \r
-               if ($i_actiontype == 'addfuture') {\r
-                       $posttime = mktime($i_hour, $i_minutes, 0, $i_month, $i_day, $i_year);\r
-                       \r
-                       // make sure the date is in the future, unless we allow past dates \r
-                       if ((!$blog->allowPastPosting()) && ($posttime < $blog->getCorrectTime()))\r
-                               $posttime = $blog->getCorrectTime();\r
-               } else {\r
-                       // time with offset, or 0 for drafts\r
-                       $posttime = $i_draft ? 0 : $blog->getCorrectTime();     \r
-               }\r
-               \r
-               $itemid = $blog->additem($i_catid, $i_title,$i_body,$i_more,$i_blogid,$i_author,$posttime,$i_closed,$i_draft);  \r
-               \r
-               //Setting the itemOptions\r
-               $aOptions = requestArray('plugoption');\r
-               NucleusPlugin::_applyPluginOptions($aOptions, $itemid);\r
-               $manager->notify('PostPluginOptionsUpdate',array('context' => 'item', 'itemid' => $itemid, 'item' => array('title' => $i_title, 'body' => $i_body, 'more' => $i_more, 'closed' => $i_closed, 'catid' => $i_catid)));\r
-               \r
-               // success\r
-               if ($i_catid != intRequestVar('catid'))\r
-                       return array('status' => 'newcategory', 'itemid' => $itemid, 'catid' => $i_catid);\r
-               else\r
-                       return array('status' => 'added', 'itemid' => $itemid);\r
-       }\r
-       \r
-       \r
-       /**\r
-         * Updates an item (static)\r
-         */\r
-       function update($itemid, $catid, $title, $body, $more, $closed, $wasdraft, $publish, $timestamp = 0) {\r
-               global $manager;\r
-               \r
-               $itemid = intval($itemid);\r
-\r
-               // make sure value is 1 or 0\r
-               if ($closed != 1) $closed = 0;\r
-                       \r
-               // get destination blogid \r
-               $new_blogid = getBlogIDFromCatID($catid);\r
-               $old_blogid = getBlogIDFromItemID($itemid);\r
-               \r
-               // move will be done on end of method\r
-               if ($new_blogid != $old_blogid)\r
-                       $moveNeeded = 1;\r
-               \r
-               // add <br /> before newlines\r
-               $blog =& $manager->getBlog($new_blogid);\r
-               if ($blog->convertBreaks()) {\r
-                       $body = addBreaks($body);\r
-                       $more = addBreaks($more);\r
-               }\r
-       \r
-               // call plugins\r
-               $manager->notify('PreUpdateItem',array('itemid' => $itemid, 'title' => &$title, 'body' => &$body, 'more' => &$more, 'blog' => &$blog, 'closed' => &$closed, 'catid' => &$catid));\r
-       \r
-               // update item itsself\r
-               $query =  'UPDATE '.sql_table('item')\r
-                      . ' SET' \r
-                      . " ibody='". addslashes($body) ."',"\r
-                      . " ititle='" . addslashes($title) . "',"\r
-                      . " imore='" . addslashes($more) . "',"\r
-                      . " iclosed=" . intval($closed) . ","\r
-                      . " icat=" . intval($catid);\r
-\r
-               // if we received an updated timestamp in the past, but past posting is not allowed,\r
-               // reject that date change (timestamp = 0 will make sure the current date is kept)\r
-               if ( (!$blog->allowPastPosting()) && ($timestamp < $blog->getCorrectTime()))\r
-                               $timestamp = 0;\r
-               \r
-               if ($wasdraft && $publish) {\r
-                       $query .= ', idraft=0';\r
-                       \r
-                       // set timestamp to current date only if it's not a future item\r
-                       // draft items have timestamp == 0\r
-                       // don't allow timestamps in the past (unless otherwise defined in blogsettings)\r
-                       if ($timestamp > $blog->getCorrectTime())\r
-                               $isFuture = 1;\r
-                       \r
-                       if ($timestamp == 0)\r
-                               $timestamp = $blog->getCorrectTime();\r
-                       \r
-                       // send new item notification\r
-                       if (!$isFuture && $blog->getNotifyAddress() && $blog->notifyOnNewItem()) \r
-                               $blog->sendNewItemNotification($itemid, $title, $body);\r
-               }\r
-               \r
-               // update timestamp when needed\r
-               if ($timestamp != 0)\r
-                       $query .= ", itime=" . mysqldate($timestamp);   \r
-\r
-               // make sure the correct item is updated                        \r
-               $query .= ' WHERE inumber=' . $itemid;\r
-               \r
-               // off we go!\r
-               sql_query($query);      \r
-               \r
-               // when needed, move item and comments to new blog\r
-               if ($moveNeeded) \r
-                       ITEM::move($itemid, $catid);\r
-               \r
-               //update the itemOptions\r
-               $aOptions = requestArray('plugoption');\r
-               NucleusPlugin::_applyPluginOptions($aOptions);\r
-               $manager->notify('PostPluginOptionsUpdate',array('context' => 'item', 'itemid' => $itemid, 'item' => array('title' => $title, 'body' => $body, 'more' => $more, 'closed' => $closed, 'catid' => $catid)));\r
-               \r
-       }\r
-       \r
-       // move an item to another blog (no checks, static)\r
-       function move($itemid, $new_catid) {\r
-               global $manager;\r
-               \r
-               $itemid = intval($itemid);\r
-               $new_catid = intval($new_catid);\r
-               \r
-               $new_blogid = getBlogIDFromCatID($new_catid);\r
-\r
-               $manager->notify(\r
-                       'PreMoveItem',\r
-                       array(\r
-                               'itemid' => $itemid,\r
-                               'destblogid' => $new_blogid,\r
-                               'destcatid' => $new_catid\r
-                       )\r
-               );\r
-       \r
-       \r
-               // update item table\r
-               $query = 'UPDATE '.sql_table('item')." SET iblog=$new_blogid, icat=$new_catid WHERE inumber=$itemid";\r
-               sql_query($query);              \r
-               \r
-               // update comments\r
-               $query = 'UPDATE '.sql_table('comment')." SET cblog=" . $new_blogid." WHERE citem=" . $itemid;\r
-               sql_query($query);      \r
-               \r
-               $manager->notify(\r
-                       'PostMoveItem',\r
-                       array(\r
-                               'itemid' => $itemid,\r
-                               'destblogid' => $new_blogid,\r
-                               'destcatid' => $new_catid\r
-                       )\r
-               );              \r
-       }\r
-       \r
-       /**\r
-         * Deletes an item\r
-         */\r
-       function delete($itemid) {\r
-               global $manager;\r
-               \r
-               $itemid = intval($itemid);\r
-               \r
-               $manager->notify('PreDeleteItem', array('itemid' => $itemid));\r
-               \r
-               // delete item\r
-               $query = 'DELETE FROM '.sql_table('item').' WHERE inumber=' . $itemid;\r
-               sql_query($query);\r
-\r
-               // delete the comments associated with the item\r
-               $query = 'DELETE FROM '.sql_table('comment').' WHERE citem=' . $itemid;\r
-               sql_query($query);        \r
-               \r
-               // delete all associated plugin options\r
-               NucleusPlugin::_deleteOptionValues('item', $itemid);\r
-               \r
-               $manager->notify('PostDeleteItem', array('itemid' => $itemid));         \r
-       }\r
-       \r
-       // returns true if there is an item with the given ID (static)\r
-       function exists($id,$future,$draft) {\r
-               global $manager;\r
-               \r
-               $id = intval($id);\r
-               \r
-               $r = 'select * FROM '.sql_table('item').' WHERE inumber='.$id;\r
-               if (!$future) {\r
-                       $bid = getBlogIDFromItemID($id);\r
-                       if (!$bid) return 0;\r
-                       $b =& $manager->getBlog($bid);\r
-                       $r .= ' and itime<='.mysqldate($b->getCorrectTime());\r
-               }\r
-               if (!$draft) {\r
-                       $r .= ' and idraft=0';\r
-               }\r
-               $r = sql_query($r);\r
-\r
-               return (mysql_num_rows($r) != 0);\r
-       }       \r
-       \r
-}\r
-\r
-?>\r
+<?php
+
+/*
+ * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/)
+ * Copyright (C) 2002-2007 The Nucleus Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * (see nucleus/documentation/index.html#license for more info)
+ */
+/**
+ * A class representing an item
+ *
+ * @license http://nucleuscms.org/license.txt GNU General Public License
+ * @copyright Copyright (C) 2002-2007 The Nucleus Group
+ * @version $Id: ITEM.php,v 1.4 2007-03-27 12:13:56 kimitake Exp $
+ * $NucleusJP: ITEM.php,v 1.7 2007/02/04 06:28:46 kimitake Exp $
+ */
+class ITEM {
+
+       var $itemid;
+
+       function ITEM($itemid) {
+               $this->itemid = $itemid;
+       }
+
+       /**
+         * Returns one item with the specific itemid
+         * (static)
+         */
+       function getitem($itemid, $allowdraft, $allowfuture) {
+               global $manager;
+
+               $itemid = intval($itemid);
+
+               $query =  'SELECT i.idraft as draft, i.inumber as itemid, i.iclosed as closed, '
+                          . ' i.ititle as title, i.ibody as body, m.mname as author, '
+                          . ' i.iauthor as authorid, i.itime, i.imore as more, i.ikarmapos as karmapos, '
+                          . ' i.ikarmaneg as karmaneg, i.icat as catid, i.iblog as blogid '
+                          . ' FROM '.sql_table('item').' as i, '.sql_table('member').' as m, ' . sql_table('blog') . ' as b '
+                          . ' WHERE i.inumber=' . $itemid
+                          . ' and i.iauthor=m.mnumber '
+                          . ' and i.iblog=b.bnumber';
+
+               if (!$allowdraft)
+                       $query .= ' and i.idraft=0';
+
+               if (!$allowfuture) {
+                       $blog =& $manager->getBlog(getBlogIDFromItemID($itemid));
+                       $query .= ' and i.itime <=' . mysqldate($blog->getCorrectTime());
+               }
+
+               $query .= ' LIMIT 1';
+
+               $res = sql_query($query);
+
+               if (mysql_num_rows($res) == 1)
+               {
+                       $aItemInfo = mysql_fetch_assoc($res);
+                       $aItemInfo['timestamp'] = strtotime($aItemInfo['itime']);
+                       return $aItemInfo;
+               } else {
+                       return 0;
+               }
+
+       }
+
+       /**
+        * Tries to create an item from the data in the current request (comes from
+        * bookmarklet or admin area
+        *
+        * Returns an array with status info (status = 'added', 'error', 'newcategory')
+        *
+        * (static)
+        */
+       function createFromRequest() {
+                global $member, $manager;
+
+                $i_author =            $member->getID();
+                $i_body =                      postVar('body');
+                $i_title =                     postVar('title');
+                $i_more =                      postVar('more');
+                $i_actiontype =        postVar('actiontype');
+                $i_closed =            intPostVar('closed');
+                $i_hour =                      intPostVar('hour');
+                $i_minutes =           intPostVar('minutes');
+                $i_month =             intPostVar('month');
+                $i_day =                       intPostVar('day');
+                $i_year =                      intPostVar('year');
+
+                $i_catid =             postVar('catid');
+
+                $i_draftid =           intPostVar('draftid');
+
+                if (!$member->canAddItem($i_catid))
+                       return array('status' => 'error', 'message' => _ERROR_DISALLOWED);
+
+                if (!$i_actiontype) $i_actiontype = 'addnow';
+
+                switch ($i_actiontype) {
+                       case 'adddraft':
+                               $i_draft = 1;
+                               break;
+                       case 'addfuture':
+                       case 'addnow':
+                       default:
+                               $i_draft = 0;
+                }
+
+                if (!trim($i_body))
+                       return array('status' => 'error', 'message' => _ERROR_NOEMPTYITEMS);
+
+               // create new category if needed
+               if (strstr($i_catid,'newcat')) {
+                       // get blogid
+                       list($i_blogid) = sscanf($i_catid,"newcat-%d");
+
+                       // create
+                       $blog =& $manager->getBlog($i_blogid);
+                       $i_catid = $blog->createNewCategory();
+
+                       // show error when sth goes wrong
+                       if (!$i_catid)
+                               return array('status' => 'error','message' => 'Could not create new category');
+               } else {
+                       // force blogid (must be same as category id)
+                       $i_blogid = getBlogIDFromCatID($i_catid);
+                       $blog =& $manager->getBlog($i_blogid);
+               }
+
+               if ($i_actiontype == 'addfuture') {
+                       $posttime = mktime($i_hour, $i_minutes, 0, $i_month, $i_day, $i_year);
+
+                       // make sure the date is in the future, unless we allow past dates
+                       if ((!$blog->allowPastPosting()) && ($posttime < $blog->getCorrectTime()))
+                               $posttime = $blog->getCorrectTime();
+               } else {
+                       // time with offset, or 0 for drafts
+                       $posttime = $i_draft ? 0 : $blog->getCorrectTime();
+               }
+
+               $itemid = $blog->additem($i_catid, $i_title,$i_body,$i_more,$i_blogid,$i_author,$posttime,$i_closed,$i_draft);
+
+               //Setting the itemOptions
+               $aOptions = requestArray('plugoption');
+               NucleusPlugin::_applyPluginOptions($aOptions, $itemid);
+               $manager->notify('PostPluginOptionsUpdate',array('context' => 'item', 'itemid' => $itemid, 'item' => array('title' => $i_title, 'body' => $i_body, 'more' => $i_more, 'closed' => $i_closed, 'catid' => $i_catid)));
+
+               if ($i_draftid > 0) {
+                       ITEM::delete($i_draftid);
+               }
+
+               // success
+               if ($i_catid != intRequestVar('catid'))
+                       return array('status' => 'newcategory', 'itemid' => $itemid, 'catid' => $i_catid);
+               else
+                       return array('status' => 'added', 'itemid' => $itemid);
+       }
+
+
+       /**
+         * Updates an item (static)
+         */
+       function update($itemid, $catid, $title, $body, $more, $closed, $wasdraft, $publish, $timestamp = 0) {
+               global $manager;
+
+               $itemid = intval($itemid);
+
+               // make sure value is 1 or 0
+               if ($closed != 1) $closed = 0;
+
+               // get destination blogid
+               $new_blogid = getBlogIDFromCatID($catid);
+               $old_blogid = getBlogIDFromItemID($itemid);
+
+               // move will be done on end of method
+               if ($new_blogid != $old_blogid)
+                       $moveNeeded = 1;
+
+               // add <br /> before newlines
+               $blog =& $manager->getBlog($new_blogid);
+               if ($blog->convertBreaks()) {
+                       $body = addBreaks($body);
+                       $more = addBreaks($more);
+               }
+
+               // call plugins
+               $manager->notify('PreUpdateItem',array('itemid' => $itemid, 'title' => &$title, 'body' => &$body, 'more' => &$more, 'blog' => &$blog, 'closed' => &$closed, 'catid' => &$catid));
+
+               // update item itsself
+               $query =  'UPDATE '.sql_table('item')
+                          . ' SET'
+                          . " ibody='". addslashes($body) ."',"
+                          . " ititle='" . addslashes($title) . "',"
+                          . " imore='" . addslashes($more) . "',"
+                          . " iclosed=" . intval($closed) . ","
+                          . " icat=" . intval($catid);
+
+               // if we received an updated timestamp in the past, but past posting is not allowed,
+               // reject that date change (timestamp = 0 will make sure the current date is kept)
+               if ( (!$blog->allowPastPosting()) && ($timestamp < $blog->getCorrectTime()))
+                               $timestamp = 0;
+
+               if ($wasdraft && $publish) {
+                       $query .= ', idraft=0';
+
+                       // set timestamp to current date only if it's not a future item
+                       // draft items have timestamp == 0
+                       // don't allow timestamps in the past (unless otherwise defined in blogsettings)
+                       if ($timestamp > $blog->getCorrectTime())
+                               $isFuture = 1;
+
+                       if ($timestamp == 0)
+                               $timestamp = $blog->getCorrectTime();
+
+                       // send new item notification
+                       if (!$isFuture && $blog->getNotifyAddress() && $blog->notifyOnNewItem())
+                               $blog->sendNewItemNotification($itemid, $title, $body);
+               }
+
+               // update timestamp when needed
+               if ($timestamp != 0)
+                       $query .= ", itime=" . mysqldate($timestamp);
+
+               // make sure the correct item is updated
+               $query .= ' WHERE inumber=' . $itemid;
+
+               // off we go!
+               sql_query($query);
+
+               $manager->notify('PostUpdateItem',array('itemid' => $itemid));
+
+               // when needed, move item and comments to new blog
+               if ($moveNeeded)
+                       ITEM::move($itemid, $catid);
+
+               //update the itemOptions
+               $aOptions = requestArray('plugoption');
+               NucleusPlugin::_applyPluginOptions($aOptions);
+               $manager->notify('PostPluginOptionsUpdate',array('context' => 'item', 'itemid' => $itemid, 'item' => array('title' => $title, 'body' => $body, 'more' => $more, 'closed' => $closed, 'catid' => $catid)));
+
+       }
+
+       // move an item to another blog (no checks, static)
+       function move($itemid, $new_catid) {
+               global $manager;
+
+               $itemid = intval($itemid);
+               $new_catid = intval($new_catid);
+
+               $new_blogid = getBlogIDFromCatID($new_catid);
+
+               $manager->notify(
+                       'PreMoveItem',
+                       array(
+                               'itemid' => $itemid,
+                               'destblogid' => $new_blogid,
+                               'destcatid' => $new_catid
+                       )
+               );
+
+
+               // update item table
+               $query = 'UPDATE '.sql_table('item')." SET iblog=$new_blogid, icat=$new_catid WHERE inumber=$itemid";
+               sql_query($query);
+
+               // update comments
+               $query = 'UPDATE '.sql_table('comment')." SET cblog=" . $new_blogid." WHERE citem=" . $itemid;
+               sql_query($query);
+
+               $manager->notify(
+                       'PostMoveItem',
+                       array(
+                               'itemid' => $itemid,
+                               'destblogid' => $new_blogid,
+                               'destcatid' => $new_catid
+                       )
+               );
+       }
+
+       /**
+         * Deletes an item
+         */
+       function delete($itemid) {
+               global $manager;
+
+               $itemid = intval($itemid);
+
+               $manager->notify('PreDeleteItem', array('itemid' => $itemid));
+
+               // delete item
+               $query = 'DELETE FROM '.sql_table('item').' WHERE inumber=' . $itemid;
+               sql_query($query);
+
+               // delete the comments associated with the item
+               $query = 'DELETE FROM '.sql_table('comment').' WHERE citem=' . $itemid;
+               sql_query($query);
+
+               // delete all associated plugin options
+               NucleusPlugin::_deleteOptionValues('item', $itemid);
+
+               $manager->notify('PostDeleteItem', array('itemid' => $itemid));
+       }
+
+       // returns true if there is an item with the given ID (static)
+       function exists($id,$future,$draft) {
+               global $manager;
+
+               $id = intval($id);
+
+               $r = 'select * FROM '.sql_table('item').' WHERE inumber='.$id;
+               if (!$future) {
+                       $bid = getBlogIDFromItemID($id);
+                       if (!$bid) return 0;
+                       $b =& $manager->getBlog($bid);
+                       $r .= ' and itime<='.mysqldate($b->getCorrectTime());
+               }
+               if (!$draft) {
+                       $r .= ' and idraft=0';
+               }
+               $r = sql_query($r);
+
+               return (mysql_num_rows($r) != 0);
+       }
+
+       /**
+        * Tries to create an draft from the data in the current request (comes from
+        * bookmarklet or admin area
+        *
+        * Returns an array with status info (status = 'added', 'error', 'newcategory')
+        *
+        * (static)
+        *
+        * Used by xmlHTTPRequest AutoDraft
+        */
+       function createDraftFromRequest() {
+               global $member, $manager;
+
+               $i_author = $member->getID();
+               $i_body = postVar('body');
+               $i_title = postVar('title');
+               $i_more = postVar('more');
+               //$i_actiontype = postVar('actiontype');
+               $i_closed = intPostVar('closed');
+               //$i_hour = intPostVar('hour');
+               //$i_minutes = intPostVar('minutes');
+               //$i_month = intPostVar('month');
+               //$i_day = intPostVar('day');
+               //$i_year = intPostVar('year');
+               $i_catid = postVar('catid');
+               $i_draft = 1;
+               $type = postVar('type');
+               if ($type == 'edit') {
+                       $i_blogid = getBlogIDFromItemID(intPostVar('itemid'));
+               }
+               else {
+                       $i_blogid = intPostVar('blogid');
+               }
+               $i_draftid = intPostVar('draftid');
+
+               if (!$member->canAddItem($i_catid)) {
+                       return array('status' => 'error', 'message' => _ERROR_DISALLOWED);
+               }
+
+               if (!trim($i_body)) {
+                       return array('status' => 'error', 'message' => _ERROR_NOEMPTYITEMS);
+               }
+
+               // create new category if needed
+               if (strstr($i_catid, 'newcat')) {
+                       // Set in default category
+                       $blog =& $manager->getBlog($i_blogid);
+                       $i_catid = $blog->getDefaultCategory();
+               }
+               else {
+                       // force blogid (must be same as category id)
+                       $i_blogid = getBlogIDFromCatID($i_catid);
+                       $blog =& $manager->getBlog($i_blogid);
+               }
+
+               $posttime = 0;
+
+               if ($i_draftid > 0) {
+                       ITEM::update($i_draftid, $i_catid, $i_title, $i_body, $i_more, $i_closed, 1, 0, 0);
+                       $itemid = $i_draftid;
+               }
+               else {
+                       $itemid = $blog->additem($i_catid, $i_title, $i_body, $i_more, $i_blogid, $i_author, $posttime, $i_closed, $i_draft);
+               }
+
+               // No plugin support in AutoSaveDraft yet
+               //Setting the itemOptions
+               //$aOptions = requestArray('plugoption');
+               //NucleusPlugin::_applyPluginOptions($aOptions, $itemid);
+               //$manager->notify('PostPluginOptionsUpdate',array('context' => 'item', 'itemid' => $itemid, 'item' => array('title' => $i_title, 'body' => $i_body, 'more' => $i_more, 'closed' => $i_closed, 'catid' => $i_catid)));
+
+               // success
+               return array('status' => 'added', 'draftid' => $itemid);
+       }
+
+}
+
+?>
index d931347..0774f8d 100755 (executable)
-<?php\r
-/**\r
-  * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/) \r
-  * Copyright (C) 2002-2005 The Nucleus Group\r
-  *\r
-  * This program is free software; you can redistribute it and/or\r
-  * modify it under the terms of the GNU General Public License\r
-  * as published by the Free Software Foundation; either version 2\r
-  * of the License, or (at your option) any later version.\r
-  * (see nucleus/documentation/index.html#license for more info)\r
-  *\r
-  * Class representing the karma votes for a certain item\r
-  *\r
-  * $Id: KARMA.php,v 1.3 2005-03-16 08:10:35 kimitake Exp $\r
-  * $NucleusJP: KARMA.php,v 1.3 2005/03/15 07:57:29 kimitake Exp $\r
-  */\r
-class KARMA {\r
-       \r
-       // id of item about which this object contains information\r
-       var $itemid;\r
-       \r
-       // indicates if the karma vote info has already been intialized from the DB\r
-       var $inforead;\r
-       \r
-       // amount of positive/negative votes\r
-       var $karmapos;\r
-       var $karmaneg;\r
-       \r
-       function KARMA($itemid, $initpos = 0, $initneg = 0, $initread = 0) {    \r
-               // itemid\r
-               $this->itemid = intval($itemid);\r
-\r
-               // have we read the karma info yet?\r
-               $this->inforead = intval($initread);    \r
-               \r
-               // number of positive and negative votes\r
-               $this->karmapos = intval($initpos);\r
-               $this->karmaneg = intval($initneg);\r
-       }\r
-       \r
-       function getNbPosVotes() {\r
-               if (!$this->inforead) $this->readFromDatabase();\r
-               return $this->karmapos;\r
-       }\r
-       function getNbNegVotes() {\r
-               if (!$this->inforead) $this->readFromDatabase();\r
-               return $this->karmaneg;\r
-       }\r
-       function getNbOfVotes() {\r
-               if (!$this->inforead) $this->readFromDatabase();\r
-               return ($this->karmapos + $this->karmaneg);\r
-       }\r
-       function getTotalScore() {\r
-               if (!$this->inforead) $this->readFromDatabase();\r
-               return ($this->karmapos - $this->karmaneg);\r
-       }\r
-       \r
-       function setNbPosVotes($val) {\r
-               $this->karmapos = intval($val);\r
-       }\r
-       function setNbNegVotes($val) {\r
-               $this->karmaneg = intval($val);\r
-       }\r
-\r
-\r
-       // adds a positive vote\r
-       function votePositive() {\r
-               $newKarma = $this->getNbPosVotes() + 1;\r
-               $this->setNbPosVotes($newKarma);\r
-               $this->writeToDatabase();\r
-               $this->saveIP();\r
-       }\r
-       \r
-       // adds a negative vote\r
-       function voteNegative() {\r
-               $newKarma = $this->getNbNegVotes() + 1; \r
-               $this->setNbNegVotes($newKarma);                \r
-               $this->writeToDatabase();               \r
-               $this->saveIP();\r
-       }\r
-\r
-\r
-\r
-       // these methods shouldn't be called directly\r
-       function readFromDatabase() {\r
-               $query = 'SELECT ikarmapos, ikarmaneg FROM '.sql_table('item').' WHERE inumber=' . $this->itemid;\r
-               $res = sql_query($query);\r
-               $obj = mysql_fetch_object($res);\r
-               \r
-               $this->karmapos = $obj->ikarmapos;\r
-               $this->karmaneg = $obj->ikarmaneg;              \r
-               $this->inforead = 1;\r
-       }\r
-               \r
-       \r
-       function writeToDatabase() {\r
-               $query = 'UPDATE '.sql_table('item').' SET ikarmapos=' . $this->karmapos . ', ikarmaneg='.$this->karmaneg.' WHERE inumber=' . $this->itemid;\r
-               sql_query($query);\r
-       }\r
-       \r
-       // checks if a vote is still allowed for an IP\r
-       function isVoteAllowed($ip) {\r
-               $query = 'SELECT * FROM '.sql_table('karma')." WHERE itemid=$this->itemid and ip='".addslashes($ip)."'";\r
-               $res = sql_query($query);\r
-               return (mysql_num_rows($res) == 0);\r
-       }\r
-       \r
-       // save IP in database so no multiple votes are possible\r
-       function saveIP() {\r
-               $query = 'INSERT INTO '.sql_table('karma').' (itemid, ip) VALUES ('.$this->itemid.",'".addslashes(serverVar('REMOTE_ADDR'))."')";\r
-               sql_query($query);\r
-       }\r
-}\r
-\r
-?>\r
+<?php
+/*
+ * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/)
+ * Copyright (C) 2002-2007 The Nucleus Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * (see nucleus/documentation/index.html#license for more info)
+ */
+/**
+ * Class representing the karma votes for a certain item
+ *
+ * @license http://nucleuscms.org/license.txt GNU General Public License
+ * @copyright Copyright (C) 2002-2007 The Nucleus Group
+ * @version $Id: KARMA.php,v 1.4 2007-03-27 12:13:56 kimitake Exp $
+ * $NucleusJP: KARMA.php,v 1.6 2007/02/04 06:28:46 kimitake Exp $
+ */
+class KARMA {
+
+       // id of item about which this object contains information
+       var $itemid;
+
+       // indicates if the karma vote info has already been intialized from the DB
+       var $inforead;
+
+       // amount of positive/negative votes
+       var $karmapos;
+       var $karmaneg;
+
+       function KARMA($itemid, $initpos = 0, $initneg = 0, $initread = 0) {
+               // itemid
+               $this->itemid = intval($itemid);
+
+               // have we read the karma info yet?
+               $this->inforead = intval($initread);
+
+               // number of positive and negative votes
+               $this->karmapos = intval($initpos);
+               $this->karmaneg = intval($initneg);
+       }
+
+       function getNbPosVotes() {
+               if (!$this->inforead) $this->readFromDatabase();
+               return $this->karmapos;
+       }
+       function getNbNegVotes() {
+               if (!$this->inforead) $this->readFromDatabase();
+               return $this->karmaneg;
+       }
+       function getNbOfVotes() {
+               if (!$this->inforead) $this->readFromDatabase();
+               return ($this->karmapos + $this->karmaneg);
+       }
+       function getTotalScore() {
+               if (!$this->inforead) $this->readFromDatabase();
+               return ($this->karmapos - $this->karmaneg);
+       }
+
+       function setNbPosVotes($val) {
+               $this->karmapos = intval($val);
+       }
+       function setNbNegVotes($val) {
+               $this->karmaneg = intval($val);
+       }
+
+
+       // adds a positive vote
+       function votePositive() {
+               $newKarma = $this->getNbPosVotes() + 1;
+               $this->setNbPosVotes($newKarma);
+               $this->writeToDatabase();
+               $this->saveIP();
+       }
+
+       // adds a negative vote
+       function voteNegative() {
+               $newKarma = $this->getNbNegVotes() + 1;
+               $this->setNbNegVotes($newKarma);
+               $this->writeToDatabase();
+               $this->saveIP();
+       }
+
+
+
+       // these methods shouldn't be called directly
+       function readFromDatabase() {
+               $query = 'SELECT ikarmapos, ikarmaneg FROM '.sql_table('item').' WHERE inumber=' . $this->itemid;
+               $res = sql_query($query);
+               $obj = mysql_fetch_object($res);
+
+               $this->karmapos = $obj->ikarmapos;
+               $this->karmaneg = $obj->ikarmaneg;
+               $this->inforead = 1;
+       }
+
+
+       function writeToDatabase() {
+               $query = 'UPDATE '.sql_table('item').' SET ikarmapos=' . $this->karmapos . ', ikarmaneg='.$this->karmaneg.' WHERE inumber=' . $this->itemid;
+               sql_query($query);
+       }
+
+       // checks if a vote is still allowed for an IP
+       function isVoteAllowed($ip) {
+               $query = 'SELECT * FROM '.sql_table('karma')." WHERE itemid=$this->itemid and ip='".addslashes($ip)."'";
+               $res = sql_query($query);
+               return (mysql_num_rows($res) == 0);
+       }
+
+       // save IP in database so no multiple votes are possible
+       function saveIP() {
+               $query = 'INSERT INTO '.sql_table('karma').' (itemid, ip) VALUES ('.$this->itemid.",'".addslashes(serverVar('REMOTE_ADDR'))."')";
+               sql_query($query);
+       }
+}
+
+?>
\ No newline at end of file
index 34a3b80..5a0312c 100755 (executable)
-<?php\r
-/**\r
-  * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/) \r
-  * Copyright (C) 2002-2005 The Nucleus Group\r
-  *\r
-  * This program is free software; you can redistribute it and/or\r
-  * modify it under the terms of the GNU General Public License\r
-  * as published by the Free Software Foundation; either version 2\r
-  * of the License, or (at your option) any later version.\r
-  * (see nucleus/documentation/index.html#license for more info)\r
-  *\r
-  *    This class makes sure each item/weblog/comment object gets requested from\r
-  * the database only once, by keeping them in a cache. The class also acts as \r
-  * a dynamic classloader, loading classes _only_ when they are first needed,\r
-  * hoping to diminish execution time\r
-  *\r
-  * The class is a singleton, meaning that there will be only one object of it\r
-  * active at all times. The object can be requested using MANAGER::instance()\r
-  *\r
-  * $Id: MANAGER.php,v 1.3 2005-03-16 08:10:35 kimitake Exp $\r
-  * $NucleusJP: MANAGER.php,v 1.3 2005/03/12 06:19:05 kimitake Exp $\r
-  */\r
-class MANAGER {\r
-\r
-       /**\r
-        * Cached ITEM, BLOG, PLUGIN and KARMA objects. When these objects are requested \r
-        * through the global $manager object (getItem, getBlog, ...), only the first call \r
-        * will create an object. Subsequent calls will return the same object.\r
-        *\r
-        * The $items, $blogs, ... arrays map an id to an object (for plugins, the name is used\r
-        * rather than an ID)\r
-        */\r
-       var $items;\r
-       var $blogs;\r
-       var $plugins;\r
-       var $karma;\r
-       var $templates;\r
-       \r
-       /**\r
-        * cachedInfo to avoid repeated SQL queries (see pidInstalled/pluginInstalled/getPidFromName)\r
-        * e.g. which plugins exists?\r
-        *\r
-        * $cachedInfo['installedPlugins'] = array($pid -> $name)\r
-        */\r
-       var $cachedInfo;\r
-       \r
-       /**\r
-         * The plugin subscriptionlist\r
-         *\r
-         * The subcription array has the following structure\r
-         *             $subscriptions[$EventName] = array containing names of plugin classes to be\r
-         *                                                                      notified when that event happens\r
-         */\r
-       var $subscriptions;     \r
-       \r
-       /**\r
-         * Returns the only instance of this class. Creates the instance if it \r
-         * does not yet exists. Users should use this function as \r
-         * $manager =& MANAGER::instance(); to get a reference to the object\r
-         * instead of a copy\r
-         */\r
-       function &instance() {\r
-               static $instance = '';\r
-               if ($instance == '')\r
-                       $instance =& new MANAGER();\r
-               return $instance;\r
-       }\r
-       \r
-       /**\r
-         * The constructor of this class initializes the object caches \r
-         */\r
-       function MANAGER() {\r
-               $this->items = array();\r
-               $this->blogs = array();\r
-               $this->plugins = array();\r
-               $this->karma = array();\r
-               $this->parserPrefs = array();\r
-               $this->cachedInfo = array();\r
-       }\r
-       \r
-       /**\r
-         * Returns the requested item object. If it is not in the cache, it will\r
-         * first be loaded and then placed in the cache.\r
-         * Intended use: $item =& $manager->getItem(1234)\r
-         */\r
-       function &getItem($itemid, $allowdraft, $allowfuture) {\r
-               $item =& $this->items[$itemid];\r
-               \r
-               // check the draft and future rules if the item was already cached \r
-               if ($item) {\r
-                       if ((!$allowdraft) && ($item['draft']))\r
-                               return 0;\r
-\r
-                       $blog =& $this->getBlog(getBlogIDFromItemID($itemid));\r
-                       if ((!$allowfuture) && ($item['timestamp'] > $blog->getCorrectTime()))\r
-                               return 0;                               \r
-               }\r
-               if (!$item) {\r
-                       // load class if needed\r
-                       $this->loadClass('ITEM');\r
-                       // load item object\r
-                       $item = ITEM::getitem($itemid, $allowdraft, $allowfuture);\r
-                       $this->items[$itemid] = $item;\r
-               }\r
-               return $item;\r
-       }\r
-       \r
-       /**\r
-         * Loads a class if it has not yet been loaded\r
-         */\r
-       function loadClass($name) {\r
-               $this->_loadClass($name, $name . '.php');\r
-       }\r
-       \r
-       /**\r
-         * Checks if an item exists\r
-         */\r
-       function existsItem($id,$future,$draft) {\r
-               $this->_loadClass('ITEM','ITEM.php');   \r
-               return ITEM::exists($id,$future,$draft);\r
-       }\r
-       \r
-       /**\r
-         * Checks if a category exists\r
-         */\r
-       function existsCategory($id) {\r
-               return (quickQuery('SELECT COUNT(*) as result FROM '.sql_table('category').' WHERE catid='.intval($id)) > 0);\r
-       }\r
-       \r
-       function &getBlog($blogid) {\r
-               $blog =& $this->blogs[$blogid];\r
-\r
-               if (!$blog) {\r
-                       // load class if needed\r
-                       $this->_loadClass('BLOG','BLOG.php');\r
-                       // load blog object\r
-                       $blog =& new BLOG($blogid);\r
-                       $this->blogs[$blogid] =& $blog;\r
-               }\r
-               return $blog;\r
-       }\r
-       \r
-       function existsBlog($name) {\r
-               $this->_loadClass('BLOG','BLOG.php');\r
-               return BLOG::exists($name);\r
-       }\r
-\r
-       function existsBlogID($id) {\r
-               $this->_loadClass('BLOG','BLOG.php');\r
-               return BLOG::existsID($id);\r
-       }       \r
-       \r
-       /**\r
-        * Returns a previously read template\r
-        */\r
-       function &getTemplate($templateName) {\r
-               $template =& $this->templates[$templateName];\r
-\r
-               if (!$template) {\r
-                       $template = TEMPLATE::read($templateName);\r
-                       $this->templates[$templateName] =& $template;\r
-               }\r
-               return $template;\r
-       }       \r
-\r
-       /**\r
-        * Returns a KARMA object (karma votes)\r
-        */\r
-       function &getKarma($itemid) {\r
-               $karma =& $this->karma[$itemid];\r
-\r
-               if (!$karma) {\r
-                       // load class if needed\r
-                       $this->_loadClass('KARMA','KARMA.php');\r
-                       // create KARMA object\r
-                       $karma =& new KARMA($itemid);\r
-                       $this->karma[$itemid] =& $karma;\r
-               }\r
-               return $karma;\r
-       }       \r
-       \r
-       /**\r
-        * Global parser preferences\r
-        */\r
-       function setParserProperty($name, $value) {\r
-               $this->parserPrefs[$name] = $value;\r
-       }\r
-       function getParserProperty($name) {\r
-               return $this->parserPrefs[$name];\r
-       }\r
-\r
-       /**\r
-         * A private helper class to load classes\r
-         */\r
-       function _loadClass($name, $filename) {\r
-               if (!class_exists($name)) {\r
-                               global $DIR_LIBS;\r
-                               include($DIR_LIBS . $filename);\r
-               }       \r
-       }\r
-       \r
-       function _loadPlugin($name) {\r
-               if (!class_exists($name)) {\r
-                               global $DIR_PLUGINS;\r
-                               \r
-                               $fileName = $DIR_PLUGINS . $name . '.php';\r
-                               \r
-                               if (!file_exists($fileName))\r
-                               {\r
-                                       ACTIONLOG::add(WARNING, 'Plugin ' . $name . ' was not loaded (File not found)');\r
-                                       return 0;\r
-                               }\r
-                               \r
-                               // load plugin\r
-                               include($fileName);\r
-                               \r
-                               // check if class exists (avoid errors in eval'd code)\r
-                               if (!class_exists($name))\r
-                               {\r
-                                       ACTIONLOG::add(WARNING, 'Plugin ' . $name . ' was not loaded (Class not found in file, possible parse error)');                         \r
-                                       return 0;\r
-                               }\r
-                               \r
-                               // add to plugin array\r
-                               eval('$this->plugins[$name] =& new ' . $name . '();');\r
-                               \r
-                               // get plugid\r
-                               $this->plugins[$name]->plugid = $this->getPidFromName($name);\r
-                               \r
-                               // unload plugin if a prefix is used and the plugin cannot handle this^\r
-                               global $MYSQL_PREFIX;\r
-                               if (($MYSQL_PREFIX != '') && !$this->plugins[$name]->supportsFeature('SqlTablePrefix')) \r
-                               {\r
-                                       unset($this->plugins[$name]);\r
-                                       ACTIONLOG::add(WARNING, 'Plugin ' . $name . ' was not loaded (does not support SqlTablePrefix)');\r
-                                       return 0;\r
-                               }\r
-                               \r
-                               // call init method\r
-                               $this->plugins[$name]->init();\r
-                               \r
-               }       \r
-       }\r
-       \r
-       function &getPlugin($name) {\r
-               $plugin =& $this->plugins[$name];\r
-\r
-               if (!$plugin) {\r
-                       // load class if needed\r
-                       $this->_loadPlugin($name);\r
-                       $plugin =& $this->plugins[$name];                       \r
-               }\r
-               return $plugin;\r
-       }\r
-\r
-       /**\r
-         * checks if the given plugin IS installed or not\r
-         */\r
-       function pluginInstalled($name) {\r
-               $this->_initCacheInfo('installedPlugins');\r
-               return ($this->getPidFromName($name) != -1);\r
-       }\r
-       function pidInstalled($pid) {\r
-               $this->_initCacheInfo('installedPlugins');\r
-               return ($this->cachedInfo['installedPlugins'][$pid] != '');\r
-       }\r
-       function getPidFromName($name) {\r
-               $this->_initCacheInfo('installedPlugins');\r
-               foreach ($this->cachedInfo['installedPlugins'] as $pid => $pfile)\r
-               {\r
-                       if ($pfile == $name)\r
-                               return $pid;\r
-               }\r
-               return -1;\r
-       }\r
-       function clearCachedInfo($what) {\r
-               unset($this->cachedInfo[$what]);\r
-       }\r
-       \r
-       /**\r
-        * Loads some info on the first call only\r
-        */\r
-       function _initCacheInfo($what)\r
-       {\r
-               if (is_array($this->cachedInfo[$what]))\r
-                       return;\r
-               switch ($what)\r
-               {\r
-                       // 'installedPlugins' = array ($pid => $name)\r
-                       case 'installedPlugins':\r
-                               $this->cachedInfo['installedPlugins'] = array();\r
-                               $res = sql_query('SELECT pid, pfile FROM ' . sql_table('plugin'));\r
-                               while ($o = mysql_fetch_object($res))\r
-                               {\r
-                                       $this->cachedInfo['installedPlugins'][$o->pid] = $o->pfile;\r
-                               }\r
-                               break;\r
-               }\r
-       }\r
-       \r
-       /**\r
-         * A function to notify plugins that something has happened. Only the plugins\r
-         * that are subscribed to the event will get notified.\r
-         * Upon the first call, the list of subscriptions will be fetched from the \r
-         * database. The plugins itsself will only get loaded when they are first needed\r
-         *\r
-         * @param $eventName\r
-         *             Name of the event (method to be called on plugins)\r
-         * @param $data\r
-         *             Can contain any type of data, depending on the event type. Usually this is\r
-         *             an itemid, blogid, ... but it can also be an array containing multiple values\r
-         */\r
-       function notify($eventName, $data) {\r
-               // load subscription list if needed\r
-               if (!is_array($this->subscriptions)) \r
-                       $this->_loadSubscriptions();\r
-                       \r
-\r
-               // get listening objects\r
-               $listeners = $this->subscriptions[$eventName];\r
-               \r
-               // notify all of them\r
-               if (is_array($listeners)) {\r
-                       foreach($listeners as $listener) {\r
-                               // load class if needed\r
-                               $this->_loadPlugin($listener);\r
-                               // do notify (if method exists)\r
-                               if (method_exists($this->plugins[$listener], 'event_' . $eventName))\r
-                                       call_user_func(array(&$this->plugins[$listener],'event_' . $eventName), $data);\r
-                       }\r
-               }\r
-               \r
-       }\r
-       \r
-       /**\r
-         * Loads plugin subscriptions\r
-         */\r
-       function _loadSubscriptions() {\r
-               // initialize as array\r
-               $this->subscriptions = array();\r
-\r
-               $res = sql_query('SELECT p.pfile as pfile, e.event as event FROM '.sql_table('plugin_event').' as e, '.sql_table('plugin').' as p WHERE e.pid=p.pid ORDER BY p.porder ASC');\r
-               while ($o = mysql_fetch_object($res)) {\r
-                       $pluginName = $o->pfile;\r
-                       $eventName = $o->event;\r
-                       $this->subscriptions[$eventName][] = $pluginName;\r
-               }\r
-               \r
-       }\r
-\r
-       /*\r
-               Ticket functions. These are uses by the admin area to make it impossible to simulate certain GET/POST\r
-               requests. tickets are user specific\r
-       */\r
-\r
-       var $currentRequestTicket = '';\r
-       \r
-       /**\r
-        * GET requests: Adds ticket to URL (URL should NOT be html-encoded!, ticket is added at the end)\r
-        */\r
-       function addTicketToUrl($url)\r
-       {\r
-               $ticketCode = 'ticket=' . $this->_generateTicket();\r
-               if (strstr($url, '?'))\r
-                       return $url . '&' . $ticketCode;\r
-               else \r
-                       return $url . '?' . $ticketCode;\r
-       }\r
-       \r
-       /**\r
-        * POST requests: Adds ticket as hidden formvar\r
-        */\r
-       function addTicketHidden()\r
-       {\r
-               $ticket = $this->_generateTicket();\r
-               \r
-               echo '<input type="hidden" name="ticket" value="', htmlspecialchars($ticket), '" />';\r
-       }\r
-       \r
-       /**\r
-        * Checks the ticket that was passed along with the current request\r
-        */\r
-       function checkTicket() \r
-       {\r
-               global $member;\r
-               \r
-               // get ticket from request\r
-               $ticket = requestVar('ticket');\r
-               \r
-               // no ticket -> don't allow\r
-               if ($ticket == '')\r
-                       return false;\r
-                       \r
-               // remove expired tickets first\r
-               $this->_cleanUpExpiredTickets();\r
-               \r
-               // get member id\r
-               if (!$member->isLoggedIn())\r
-                       $memberId = -1;\r
-               else\r
-                       $memberId = $member->getID();\r
-               \r
-               // check if ticket is a valid one\r
-               $query = 'SELECT COUNT(*) as result FROM ' . sql_table('tickets') . ' WHERE member=' . intval($memberId). ' and ticket=\''.addslashes($ticket).'\'';\r
-               if (quickQuery($query) == 1)\r
-               {\r
-                       // [in the original implementation, the checked ticket was deleted. This would lead to invalid\r
-                       //  tickets when using the browsers back button and clicking another link/form\r
-                       //  leaving the keys in the database is not a real problem, since they're member-specific and \r
-                       //  only valid for a period of one hour\r
-                       // ]\r
-                       // sql_query('DELETE FROM '.sql_table('tickets').' WHERE member=' . intval($memberId). ' and ticket=\''.addslashes($ticket).'\'');\r
-                       return true;                    \r
-               } else {\r
-                       // not a valid ticket\r
-                       return false;\r
-               }\r
-\r
-       }\r
-       \r
-       /**\r
-        * (internal method) Removes the expired tickets \r
-        */\r
-       function _cleanUpExpiredTickets()\r
-       {\r
-               // remove tickets older than 1 hour\r
-               $oldTime = time() - 60 * 60;\r
-               $query = 'DELETE FROM ' . sql_table('tickets'). ' WHERE ctime < \'' . date('Y-m-d H:i:s',$oldTime) .'\'';\r
-               sql_query($query);\r
-       }\r
-\r
-       /**\r
-        * (internal method) Generates/returns a ticket (one ticket per page request)\r
-        */\r
-       function _generateTicket()\r
-       {\r
-               if ($this->currentRequestTicket == '')\r
-               {\r
-                       // generate new ticket (only one ticket will be generated per page request)\r
-                       // and store in database \r
-                       global $member;\r
-                       // get member id\r
-                       if (!$member->isLoggedIn())\r
-                               $memberId = -1;\r
-                       else\r
-                               $memberId = $member->getID();\r
-                       \r
-                       $ok = false;\r
-                       while (!$ok)\r
-                       {\r
-                               // generate a random token\r
-                               srand((double)microtime()*1000000);\r
-                               $ticket = md5(uniqid(rand(), true));\r
-\r
-                               // add in database as non-active\r
-                               $query = 'INSERT INTO ' . sql_table('tickets') . ' (ticket, member, ctime) ';\r
-                               $query .= 'VALUES (\'' . addslashes($ticket). '\', \'' . intval($memberId). '\', \'' . date('Y-m-d H:i:s',time()) . '\')';\r
-                               if (sql_query($query))\r
-                                       $ok = true;\r
-                       }\r
-                       \r
-                       $this->currentRequestTicket = $ticket;\r
-               }\r
-               return $this->currentRequestTicket;\r
-       }\r
-       \r
-}\r
-\r
-?>\r
+<?php
+/*
+ * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/)
+ * Copyright (C) 2002-2007 The Nucleus Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * (see nucleus/documentation/index.html#license for more info)
+ */
+/**
+ * This class makes sure each item/weblog/comment object gets requested from
+ * the database only once, by keeping them in a cache. The class also acts as
+ * a dynamic classloader, loading classes _only_ when they are first needed,
+ * hoping to diminish execution time
+ *
+ * The class is a singleton, meaning that there will be only one object of it
+ * active at all times. The object can be requested using MANAGER::instance()
+ *
+ * @license http://nucleuscms.org/license.txt GNU General Public License
+ * @copyright Copyright (C) 2002-2007 The Nucleus Group
+ * @version $Id: MANAGER.php,v 1.4 2007-03-27 12:13:56 kimitake Exp $
+ * $NucleusJP: MANAGER.php,v 1.7 2007/02/04 06:28:46 kimitake Exp $
+ */
+class MANAGER {
+
+       /**
+        * Cached ITEM, BLOG, PLUGIN, KARMA and MEMBER objects. When these objects are requested
+        * through the global $manager object (getItem, getBlog, ...), only the first call
+        * will create an object. Subsequent calls will return the same object.
+        *
+        * The $items, $blogs, ... arrays map an id to an object (for plugins, the name is used
+        * rather than an ID)
+        */
+       var $items;
+       var $blogs;
+       var $plugins;
+       var $karma;
+       var $templates;
+       var $members;
+
+       /**
+        * cachedInfo to avoid repeated SQL queries (see pidInstalled/pluginInstalled/getPidFromName)
+        * e.g. which plugins exists?
+        *
+        * $cachedInfo['installedPlugins'] = array($pid -> $name)
+        */
+       var $cachedInfo;
+
+       /**
+         * The plugin subscriptionlist
+         *
+         * The subcription array has the following structure
+         *             $subscriptions[$EventName] = array containing names of plugin classes to be
+         *                                                                      notified when that event happens
+         */
+       var $subscriptions;
+
+       /**
+         * Returns the only instance of this class. Creates the instance if it
+         * does not yet exists. Users should use this function as
+         * $manager =& MANAGER::instance(); to get a reference to the object
+         * instead of a copy
+         */
+       function &instance() {
+               static $instance = array();
+               if (empty($instance)) {
+                       $instance[0] =& new MANAGER();
+               }
+               return $instance[0];
+       }
+
+       /**
+         * The constructor of this class initializes the object caches
+         */
+       function MANAGER() {
+               $this->items = array();
+               $this->blogs = array();
+               $this->plugins = array();
+               $this->karma = array();
+               $this->parserPrefs = array();
+               $this->cachedInfo = array();
+       }
+
+       /**
+         * Returns the requested item object. If it is not in the cache, it will
+         * first be loaded and then placed in the cache.
+         * Intended use: $item =& $manager->getItem(1234)
+         */
+       function &getItem($itemid, $allowdraft, $allowfuture) {
+               $item =& $this->items[$itemid];
+
+               // check the draft and future rules if the item was already cached
+               if ($item) {
+                       if ((!$allowdraft) && ($item['draft']))
+                               return 0;
+
+                       $blog =& $this->getBlog(getBlogIDFromItemID($itemid));
+                       if ((!$allowfuture) && ($item['timestamp'] > $blog->getCorrectTime()))
+                               return 0;
+               }
+               if (!$item) {
+                       // load class if needed
+                       $this->loadClass('ITEM');
+                       // load item object
+                       $item = ITEM::getitem($itemid, $allowdraft, $allowfuture);
+                       $this->items[$itemid] = $item;
+               }
+               return $item;
+       }
+
+       /**
+         * Loads a class if it has not yet been loaded
+         */
+       function loadClass($name) {
+               $this->_loadClass($name, $name . '.php');
+       }
+
+       /**
+         * Checks if an item exists
+         */
+       function existsItem($id,$future,$draft) {
+               $this->_loadClass('ITEM','ITEM.php');
+               return ITEM::exists($id,$future,$draft);
+       }
+
+       /**
+         * Checks if a category exists
+         */
+       function existsCategory($id) {
+               return (quickQuery('SELECT COUNT(*) as result FROM '.sql_table('category').' WHERE catid='.intval($id)) > 0);
+       }
+
+       function &getBlog($blogid) {
+               $blog =& $this->blogs[$blogid];
+
+               if (!$blog) {
+                       // load class if needed
+                       $this->_loadClass('BLOG','BLOG.php');
+                       // load blog object
+                       $blog =& new BLOG($blogid);
+                       $this->blogs[$blogid] =& $blog;
+               }
+               return $blog;
+       }
+
+       function existsBlog($name) {
+               $this->_loadClass('BLOG','BLOG.php');
+               return BLOG::exists($name);
+       }
+
+       function existsBlogID($id) {
+               $this->_loadClass('BLOG','BLOG.php');
+               return BLOG::existsID($id);
+       }
+
+       /**
+        * Returns a previously read template
+        */
+       function &getTemplate($templateName) {
+               $template =& $this->templates[$templateName];
+
+               if (!$template) {
+                       $template = TEMPLATE::read($templateName);
+                       $this->templates[$templateName] =& $template;
+               }
+               return $template;
+       }
+
+       /**
+        * Returns a KARMA object (karma votes)
+        */
+       function &getKarma($itemid) {
+               $karma =& $this->karma[$itemid];
+
+               if (!$karma) {
+                       // load class if needed
+                       $this->_loadClass('KARMA','KARMA.php');
+                       // create KARMA object
+                       $karma =& new KARMA($itemid);
+                       $this->karma[$itemid] =& $karma;
+               }
+               return $karma;
+       }
+
+       /**
+        * Returns a MEMBER object
+        */
+       function &getMember($memberid) {
+               $mem =& $this->members[$memberid];
+
+               if (!$mem) {
+                       // load class if needed
+                       $this->_loadClass('MEMBER','MEMBER.php');
+                       // create MEMBER object
+                       $mem =& MEMBER::createFromID($memberid);
+                       $this->members[$memberid] =& $mem;
+               }
+               return $mem;
+       }
+
+       /**
+        * Global parser preferences
+        */
+       function setParserProperty($name, $value) {
+               $this->parserPrefs[$name] = $value;
+       }
+       function getParserProperty($name) {
+               return $this->parserPrefs[$name];
+       }
+
+       /**
+         * A private helper class to load classes
+         */
+       function _loadClass($name, $filename) {
+               if (!class_exists($name)) {
+                               global $DIR_LIBS;
+                               include($DIR_LIBS . $filename);
+               }
+       }
+
+       function _loadPlugin($name) {
+               if (!class_exists($name)) {
+                               global $DIR_PLUGINS;
+
+                               $fileName = $DIR_PLUGINS . $name . '.php';
+
+                               if (!file_exists($fileName))
+                               {
+                                       ACTIONLOG::add(WARNING, 'Plugin ' . $name . ' was not loaded (File not found)');
+                                       return 0;
+                               }
+
+                               // load plugin
+                               include($fileName);
+
+                               // check if class exists (avoid errors in eval'd code)
+                               if (!class_exists($name))
+                               {
+                                       ACTIONLOG::add(WARNING, 'Plugin ' . $name . ' was not loaded (Class not found in file, possible parse error)');
+                                       return 0;
+                               }
+
+                               // add to plugin array
+                               eval('$this->plugins[$name] =& new ' . $name . '();');
+
+                               // get plugid
+                               $this->plugins[$name]->plugid = $this->getPidFromName($name);
+
+                               // unload plugin if a prefix is used and the plugin cannot handle this^
+                               global $MYSQL_PREFIX;
+                               if (($MYSQL_PREFIX != '') && !$this->plugins[$name]->supportsFeature('SqlTablePrefix'))
+                               {
+                                       unset($this->plugins[$name]);
+                                       ACTIONLOG::add(WARNING, 'Plugin ' . $name . ' was not loaded (does not support SqlTablePrefix)');
+                                       return 0;
+                               }
+
+                               // call init method
+                               $this->plugins[$name]->init();
+
+               }
+       }
+
+       function &getPlugin($name) {
+               $plugin =& $this->plugins[$name];
+
+               if (!$plugin) {
+                       // load class if needed
+                       $this->_loadPlugin($name);
+                       $plugin =& $this->plugins[$name];
+               }
+               return $plugin;
+       }
+
+       /**
+         * checks if the given plugin IS installed or not
+         */
+       function pluginInstalled($name) {
+               $this->_initCacheInfo('installedPlugins');
+               return ($this->getPidFromName($name) != -1);
+       }
+       function pidInstalled($pid) {
+               $this->_initCacheInfo('installedPlugins');
+               return ($this->cachedInfo['installedPlugins'][$pid] != '');
+       }
+       function getPidFromName($name) {
+               $this->_initCacheInfo('installedPlugins');
+               foreach ($this->cachedInfo['installedPlugins'] as $pid => $pfile)
+               {
+                       if ($pfile == $name)
+                               return $pid;
+               }
+               return -1;
+       }
+       function clearCachedInfo($what) {
+               unset($this->cachedInfo[$what]);
+       }
+
+       /**
+        * Loads some info on the first call only
+        */
+       function _initCacheInfo($what)
+       {
+               if (isset($this->cachedInfo[$what]) && is_array($this->cachedInfo[$what]))
+                       return;
+               switch ($what)
+               {
+                       // 'installedPlugins' = array ($pid => $name)
+                       case 'installedPlugins':
+                               $this->cachedInfo['installedPlugins'] = array();
+                               $res = sql_query('SELECT pid, pfile FROM ' . sql_table('plugin'));
+                               while ($o = mysql_fetch_object($res))
+                               {
+                                       $this->cachedInfo['installedPlugins'][$o->pid] = $o->pfile;
+                               }
+                               break;
+               }
+       }
+
+       /**
+         * A function to notify plugins that something has happened. Only the plugins
+         * that are subscribed to the event will get notified.
+         * Upon the first call, the list of subscriptions will be fetched from the
+         * database. The plugins itsself will only get loaded when they are first needed
+         *
+         * @param $eventName
+         *             Name of the event (method to be called on plugins)
+         * @param $data
+         *             Can contain any type of data, depending on the event type. Usually this is
+         *             an itemid, blogid, ... but it can also be an array containing multiple values
+         */
+       function notify($eventName, $data) {
+               // load subscription list if needed
+               if (!is_array($this->subscriptions))
+                       $this->_loadSubscriptions();
+
+
+               // get listening objects
+               $listeners = false;
+               if (isset($this->subscriptions[$eventName])) {
+                       $listeners = $this->subscriptions[$eventName];
+               }
+
+               // notify all of them
+               if (is_array($listeners)) {
+                       foreach($listeners as $listener) {
+                               // load class if needed
+                               $this->_loadPlugin($listener);
+                               // do notify (if method exists)
+                               if (method_exists($this->plugins[$listener], 'event_' . $eventName))
+                                       call_user_func(array(&$this->plugins[$listener],'event_' . $eventName), $data);
+                       }
+               }
+
+       }
+
+       /**
+         * Loads plugin subscriptions
+         */
+       function _loadSubscriptions() {
+               // initialize as array
+               $this->subscriptions = array();
+
+               $res = sql_query('SELECT p.pfile as pfile, e.event as event FROM '.sql_table('plugin_event').' as e, '.sql_table('plugin').' as p WHERE e.pid=p.pid ORDER BY p.porder ASC');
+               while ($o = mysql_fetch_object($res)) {
+                       $pluginName = $o->pfile;
+                       $eventName = $o->event;
+                       $this->subscriptions[$eventName][] = $pluginName;
+               }
+
+       }
+
+       /*
+               Ticket functions. These are uses by the admin area to make it impossible to simulate certain GET/POST
+               requests. tickets are user specific
+       */
+
+       var $currentRequestTicket = '';
+
+       /**
+        * GET requests: Adds ticket to URL (URL should NOT be html-encoded!, ticket is added at the end)
+        */
+       function addTicketToUrl($url)
+       {
+               $ticketCode = 'ticket=' . $this->_generateTicket();
+               if (strstr($url, '?'))
+                       return $url . '&' . $ticketCode;
+               else
+                       return $url . '?' . $ticketCode;
+       }
+
+       /**
+        * POST requests: Adds ticket as hidden formvar
+        */
+       function addTicketHidden()
+       {
+               $ticket = $this->_generateTicket();
+
+               echo '<input type="hidden" name="ticket" value="', htmlspecialchars($ticket), '" />';
+       }
+
+       /**
+        * Get a new ticket
+        * (xmlHTTPRequest AutoSaveDraft uses this to refresh the ticket)
+        */
+       function getNewTicket()
+       {
+               $this->currentRequestTicket = '';
+               return $this->_generateTicket();
+       }
+
+       /**
+        * Checks the ticket that was passed along with the current request
+        */
+       function checkTicket()
+       {
+               global $member;
+
+               // get ticket from request
+               $ticket = requestVar('ticket');
+
+               // no ticket -> don't allow
+               if ($ticket == '')
+                       return false;
+
+               // remove expired tickets first
+               $this->_cleanUpExpiredTickets();
+
+               // get member id
+               if (!$member->isLoggedIn())
+                       $memberId = -1;
+               else
+                       $memberId = $member->getID();
+
+               // check if ticket is a valid one
+               $query = 'SELECT COUNT(*) as result FROM ' . sql_table('tickets') . ' WHERE member=' . intval($memberId). ' and ticket=\''.addslashes($ticket).'\'';
+               if (quickQuery($query) == 1)
+               {
+                       // [in the original implementation, the checked ticket was deleted. This would lead to invalid
+                       //  tickets when using the browsers back button and clicking another link/form
+                       //  leaving the keys in the database is not a real problem, since they're member-specific and
+                       //  only valid for a period of one hour
+                       // ]
+                       // sql_query('DELETE FROM '.sql_table('tickets').' WHERE member=' . intval($memberId). ' and ticket=\''.addslashes($ticket).'\'');
+                       return true;
+               } else {
+                       // not a valid ticket
+                       return false;
+               }
+
+       }
+
+       /**
+        * (internal method) Removes the expired tickets
+        */
+       function _cleanUpExpiredTickets()
+       {
+               // remove tickets older than 1 hour
+               $oldTime = time() - 60 * 60;
+               $query = 'DELETE FROM ' . sql_table('tickets'). ' WHERE ctime < \'' . date('Y-m-d H:i:s',$oldTime) .'\'';
+               sql_query($query);
+       }
+
+       /**
+        * (internal method) Generates/returns a ticket (one ticket per page request)
+        */
+       function _generateTicket()
+       {
+               if ($this->currentRequestTicket == '')
+               {
+                       // generate new ticket (only one ticket will be generated per page request)
+                       // and store in database
+                       global $member;
+                       // get member id
+                       if (!$member->isLoggedIn())
+                               $memberId = -1;
+                       else
+                               $memberId = $member->getID();
+
+                       $ok = false;
+                       while (!$ok)
+                       {
+                               // generate a random token
+                               srand((double)microtime()*1000000);
+                               $ticket = md5(uniqid(rand(), true));
+
+                               // add in database as non-active
+                               $query = 'INSERT INTO ' . sql_table('tickets') . ' (ticket, member, ctime) ';
+                               $query .= 'VALUES (\'' . addslashes($ticket). '\', \'' . intval($memberId). '\', \'' . date('Y-m-d H:i:s',time()) . '\')';
+                               if (sql_query($query))
+                                       $ok = true;
+                       }
+
+                       $this->currentRequestTicket = $ticket;
+               }
+               return $this->currentRequestTicket;
+       }
+
+}
+
+?>
\ No newline at end of file
index de0cfb0..09bd58a 100755 (executable)
-<?php\r
-/**\r
-  * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/) \r
-  * Copyright (C) 2002-2005 The Nucleus Group\r
-  *\r
-  * This program is free software; you can redistribute it and/or\r
-  * modify it under the terms of the GNU General Public License\r
-  * as published by the Free Software Foundation; either version 2\r
-  * of the License, or (at your option) any later version.\r
-  * (see nucleus/documentation/index.html#license for more info)\r
-  *\r
-  * Media classes for nucleus\r
-  *\r
-  * $Id: MEDIA.php,v 1.3 2005-03-16 08:10:35 kimitake Exp $\r
-  * $NucleusJP: MEDIA.php,v 1.3 2005/03/12 06:19:05 kimitake Exp $\r
-  */\r
-\r
-\r
-/**\r
-  * Represents the media objects for a certain member\r
-  */\r
-class MEDIA {\r
-       \r
-       /**\r
-         * Gets the list of collections available to the currently logged\r
-         * in member \r
-         *\r
-         * @returns array of dirname => display name\r
-         */\r
-       function getCollectionList() {\r
-               global $member, $DIR_MEDIA;\r
-               \r
-               $collections = array();\r
-               \r
-               // add private directory for member\r
-               $collections[$member->getID()] = 'Private Collection';\r
-               \r
-               // add global collections\r
-               if (!is_dir($DIR_MEDIA)) return $collections;\r
-               \r
-               $dirhandle = opendir($DIR_MEDIA);\r
-               while ($dirname = readdir($dirhandle)) {\r
-                       // only add non-numeric (numeric=private) dirs\r
-                       if (@is_dir($DIR_MEDIA . $dirname) && ($dirname != '.') && ($dirname != '..') && ($dirname != 'CVS') && (!is_numeric($dirname)))  {\r
-                               $collections[$dirname] = $dirname;\r
-                       }\r
-               }\r
-               closedir($dirhandle);\r
-               \r
-               return $collections;\r
-               \r
-       }\r
-\r
-       /**\r
-         * Returns an array of MEDIAOBJECT objects for a certain collection\r
-         *\r
-         * @param $collection\r
-         *             name of the collection\r
-         * @param $filter\r
-         *             filter on filename (defaults to none)     \r
-         */\r
-       function getMediaListByCollection($collection, $filter = '') {\r
-               global $DIR_MEDIA;\r
-\r
-               $filelist = array();    \r
-               \r
-               // 1. go through all objects and add them to the filelist\r
-\r
-               $mediadir = $DIR_MEDIA . $collection . '/';\r
-               \r
-               // return if dir does not exist\r
-               if (!is_dir($mediadir)) return $filelist;\r
-               \r
-               $dirhandle = opendir($mediadir);\r
-               while ($filename = readdir($dirhandle)) {\r
-                       // only add files that match the filter\r
-                       if (!@is_dir($filename) && MEDIA::checkFilter($filename, $filter))\r
-                               array_push($filelist, new MEDIAOBJECT($collection, $filename, filemtime($mediadir . $filename)));\r
-               }\r
-               closedir($dirhandle);\r
-\r
-               // sort array so newer files are shown first\r
-               usort($filelist, 'sort_media');\r
-               \r
-               return $filelist;\r
-       }\r
-       \r
-       function checkFilter($strText, $strFilter) {\r
-               if ($strFilter == '')\r
-                       return 1;\r
-               else \r
-                       return is_integer(strpos(strtolower($strText), strtolower($strFilter)));\r
-       }\r
-\r
-       /**\r
-         * checks if a collection exists with the given name, and if it's \r
-         * allowed for the currently logged in member to upload files to it\r
-         */ \r
-       function isValidCollection($collectionName) {\r
-               global $member, $DIR_MEDIA;\r
-               \r
-               // private collections only accept uploads from their owners\r
-               if (is_numeric($collectionName))\r
-                       return ($member->getID() == $collectionName);\r
-                       \r
-               // other collections should exists and be writable\r
-               $collectionDir = $DIR_MEDIA . $collectionName;\r
-               return (@is_dir($collectionDir) || @is_writable($collectionDir));\r
-       }\r
-\r
-       /**\r
-         * Adds an uploaded file to the media archive\r
-         *\r
-         * @param collection\r
-         *             collection\r
-         * @param uploadfile\r
-         *             the postFileInfo(..) array \r
-         * @param filename\r
-         *             the filename that should be used to save the file as\r
-         *             (date prefix should be already added here)\r
-         */\r
-       function addMediaObject($collection, $uploadfile, $filename) {\r
-               global $DIR_MEDIA;\r
-               \r
-               // don't allow uploads to unknown or forbidden collections\r
-               if (!MEDIA::isValidCollection($collection))\r
-                       return _ERROR_DISALLOWED;\r
-\r
-               // check dir permissions (try to create dir if it does not exist)\r
-               $mediadir = $DIR_MEDIA . $collection;\r
-\r
-               // try to create new private media directories if needed\r
-               if (!@is_dir($mediadir) && is_numeric($collection)) {\r
-                       $oldumask = umask(0000);\r
-                       if (!@mkdir($mediadir, 0777))\r
-                               return _ERROR_BADPERMISSIONS;\r
-                       umask($oldumask);                               \r
-               } \r
-               \r
-               // if dir still not exists, the action is disallowed\r
-               if (!@is_dir($mediadir))\r
-                       return _ERROR_DISALLOWED;\r
-               \r
-               if (!is_writeable($mediadir))\r
-                       return _ERROR_BADPERMISSIONS;\r
-                       \r
-               // add trailing slash (don't add it earlier since it causes mkdir to fail on some systems)\r
-               $mediadir .= '/';\r
-                       \r
-               if (file_exists($mediadir . $filename))\r
-                       return _ERROR_UPLOADDUPLICATE;\r
-\r
-               // move file to directory\r
-               if (is_uploaded_file($uploadfile)) {\r
-                       if (!@move_uploaded_file($uploadfile, $mediadir . $filename))\r
-                               return _ERROR_UPLOADMOVEP;\r
-               } else {\r
-                       if (!copy($uploadfile, $mediadir . $filename))\r
-                               return _ERROR_UPLOADCOPY ;\r
-               }\r
-               \r
-               // chmod uploaded file\r
-               $oldumask = umask(0000);\r
-               @chmod($mediadir . $filename, 0644); \r
-               umask($oldumask);               \r
-               \r
-               return '';\r
-       \r
-       }\r
-       \r
-       /**\r
-        * Adds an uploaded file to the media dir. \r
-        *\r
-        * @param $collection\r
-        *              collection to use\r
-        * @param $filename\r
-        *              the filename that should be used to save the file as\r
-        *              (date prefix should be already added here)\r
-        * @param &$data\r
-        *              File data (binary)\r
-        *\r
-        * NOTE: does not check if $collection is valid.\r
-        */\r
-       function addMediaObjectRaw($collection, $filename, &$data) {\r
-               global $DIR_MEDIA;\r
-               \r
-               // check dir permissions (try to create dir if it does not exist)\r
-               $mediadir = $DIR_MEDIA . $collection;\r
-\r
-               // try to create new private media directories if needed\r
-               if (!@is_dir($mediadir) && is_numeric($collection)) {\r
-                       $oldumask = umask(0000);\r
-                       if (!@mkdir($mediadir, 0777))\r
-                               return _ERROR_BADPERMISSIONS;\r
-                       umask($oldumask);                               \r
-               } \r
-               \r
-               // if dir still not exists, the action is disallowed\r
-               if (!@is_dir($mediadir))\r
-                       return _ERROR_DISALLOWED;\r
-               \r
-               if (!is_writeable($mediadir))\r
-                       return _ERROR_BADPERMISSIONS;\r
-                       \r
-               // add trailing slash (don't add it earlier since it causes mkdir to fail on some systems)\r
-               $mediadir .= '/';\r
-                       \r
-               if (file_exists($mediadir . $filename))\r
-                       return _ERROR_UPLOADDUPLICATE;\r
-\r
-               // create file\r
-               $fh = @fopen($mediadir . $filename, 'wb');\r
-               if (!$fh) \r
-                       return _ERROR_UPLOADFAILED;\r
-               $ok = @fwrite($fh, $data);\r
-               @fclose($fh);\r
-               if (!$ok)\r
-                       return _ERROR_UPLOADFAILED;\r
-               \r
-               // chmod uploaded file\r
-               $oldumask = umask(0000);\r
-               @chmod($mediadir . $filename, 0644); \r
-               umask($oldumask);               \r
-               \r
-               return '';\r
-       \r
-       }\r
-\r
-}\r
-\r
-/**\r
-  * Represents the characteristics of one single media-object\r
-  *\r
-  * Description of properties:\r
-  *  - filename: filename, without paths\r
-  *  - timestamp: last modification (unix timestamp)\r
-  *  - collection: collection to which the file belongs (can also be a owner ID, for private collections)\r
-  *  - private: true if the media belongs to a private member collection\r
-  */\r
-class MEDIAOBJECT {\r
-\r
-       var $private;\r
-       var $collection;\r
-       var $filename;\r
-       var $timestamp;\r
-\r
-       function MEDIAOBJECT($collection, $filename, $timestamp) {\r
-               $this->private = is_numeric($collection);\r
-               $this->collection = $collection;\r
-               $this->filename = $filename;\r
-               $this->timestamp = $timestamp;\r
-       }\r
-       \r
-}\r
-\r
-/**\r
-  * User-defined sort method to sort an array of MEDIAOBJECTS\r
-  */\r
-function sort_media($a, $b) {\r
-    if ($a->timestamp == $b->timestamp) return 0;\r
-    return ($a->timestamp > $b->timestamp) ? -1 : 1;\r
-}\r
-\r
-?>\r
+<?php
+/*
+ * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/)
+ * Copyright (C) 2002-2007 The Nucleus Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * (see nucleus/documentation/index.html#license for more info)
+ */
+/**
+ * Media classes for nucleus
+ *
+ * @license http://nucleuscms.org/license.txt GNU General Public License
+ * @copyright Copyright (C) 2002-2007 The Nucleus Group
+ * @version $Id: MEDIA.php,v 1.4 2007-03-27 12:13:56 kimitake Exp $
+ * $NucleusJP: MEDIA.php,v 1.6 2007/02/04 06:28:46 kimitake Exp $
+ */
+
+
+/**
+  * Represents the media objects for a certain member
+  */
+class MEDIA {
+
+       /**
+         * Gets the list of collections available to the currently logged
+         * in member
+         *
+         * @returns array of dirname => display name
+         */
+       function getCollectionList() {
+               global $member, $DIR_MEDIA;
+
+               $collections = array();
+
+               // add private directory for member
+               $collections[$member->getID()] = 'Private Collection';
+
+               // add global collections
+               if (!is_dir($DIR_MEDIA)) return $collections;
+
+               $dirhandle = opendir($DIR_MEDIA);
+               while ($dirname = readdir($dirhandle)) {
+                       // only add non-numeric (numeric=private) dirs
+                       if (@is_dir($DIR_MEDIA . $dirname) && ($dirname != '.') && ($dirname != '..') && ($dirname != 'CVS') && (!is_numeric($dirname)))  {
+                               $collections[$dirname] = $dirname;
+                       }
+               }
+               closedir($dirhandle);
+
+               return $collections;
+
+       }
+
+       /**
+         * Returns an array of MEDIAOBJECT objects for a certain collection
+         *
+         * @param $collection
+         *             name of the collection
+         * @param $filter
+         *             filter on filename (defaults to none)
+         */
+       function getMediaListByCollection($collection, $filter = '') {
+               global $DIR_MEDIA;
+
+               $filelist = array();
+
+               // 1. go through all objects and add them to the filelist
+
+               $mediadir = $DIR_MEDIA . $collection . '/';
+
+               // return if dir does not exist
+               if (!is_dir($mediadir)) return $filelist;
+
+               $dirhandle = opendir($mediadir);
+               while ($filename = readdir($dirhandle)) {
+                       // only add files that match the filter
+                       if (!@is_dir($filename) && MEDIA::checkFilter($filename, $filter))
+                               array_push($filelist, new MEDIAOBJECT($collection, $filename, filemtime($mediadir . $filename)));
+               }
+               closedir($dirhandle);
+
+               // sort array so newer files are shown first
+               usort($filelist, 'sort_media');
+
+               return $filelist;
+       }
+
+       function checkFilter($strText, $strFilter) {
+               if ($strFilter == '')
+                       return 1;
+               else
+                       return is_integer(strpos(strtolower($strText), strtolower($strFilter)));
+       }
+
+       /**
+         * checks if a collection exists with the given name, and if it's
+         * allowed for the currently logged in member to upload files to it
+         */
+       function isValidCollection($collectionName) {
+               global $member, $DIR_MEDIA;
+
+               // private collections only accept uploads from their owners
+               if (is_numeric($collectionName))
+                       return ($member->getID() == $collectionName);
+
+               // other collections should exists and be writable
+               $collectionDir = $DIR_MEDIA . $collectionName;
+               return (@is_dir($collectionDir) || @is_writable($collectionDir));
+       }
+
+       /**
+         * Adds an uploaded file to the media archive
+         *
+         * @param collection
+         *             collection
+         * @param uploadfile
+         *             the postFileInfo(..) array
+         * @param filename
+         *             the filename that should be used to save the file as
+         *             (date prefix should be already added here)
+         */
+       function addMediaObject($collection, $uploadfile, $filename) {
+               global $DIR_MEDIA, $manager;
+
+               $manager->notify('PreMediaUpload',array('collection' => &$collection, 'uploadfile' => $uploadfile, 'filename' => &$filename));
+
+               // don't allow uploads to unknown or forbidden collections
+               if (!MEDIA::isValidCollection($collection))
+                       return _ERROR_DISALLOWED;
+
+               // check dir permissions (try to create dir if it does not exist)
+               $mediadir = $DIR_MEDIA . $collection;
+
+               // try to create new private media directories if needed
+               if (!@is_dir($mediadir) && is_numeric($collection)) {
+                       $oldumask = umask(0000);
+                       if (!@mkdir($mediadir, 0777))
+                               return _ERROR_BADPERMISSIONS;
+                       umask($oldumask);
+               }
+
+               // if dir still not exists, the action is disallowed
+               if (!@is_dir($mediadir))
+                       return _ERROR_DISALLOWED;
+
+               if (!is_writeable($mediadir))
+                       return _ERROR_BADPERMISSIONS;
+
+               // add trailing slash (don't add it earlier since it causes mkdir to fail on some systems)
+               $mediadir .= '/';
+
+               if (file_exists($mediadir . $filename))
+                       return _ERROR_UPLOADDUPLICATE;
+
+               // move file to directory
+               if (is_uploaded_file($uploadfile)) {
+                       if (!@move_uploaded_file($uploadfile, $mediadir . $filename))
+                               return _ERROR_UPLOADMOVEP;
+               } else {
+                       if (!copy($uploadfile, $mediadir . $filename))
+                               return _ERROR_UPLOADCOPY ;
+               }
+
+               // chmod uploaded file
+               $oldumask = umask(0000);
+               @chmod($mediadir . $filename, 0644);
+               umask($oldumask);
+
+               $manager->notify('PostMediaUpload',array('collection' => $collection, 'mediadir' => $mediadir, 'filename' => $filename));
+
+               return '';
+
+       }
+
+       /**
+        * Adds an uploaded file to the media dir.
+        *
+        * @param $collection
+        *              collection to use
+        * @param $filename
+        *              the filename that should be used to save the file as
+        *              (date prefix should be already added here)
+        * @param &$data
+        *              File data (binary)
+        *
+        * NOTE: does not check if $collection is valid.
+        */
+       function addMediaObjectRaw($collection, $filename, &$data) {
+               global $DIR_MEDIA;
+
+               // check dir permissions (try to create dir if it does not exist)
+               $mediadir = $DIR_MEDIA . $collection;
+
+               // try to create new private media directories if needed
+               if (!@is_dir($mediadir) && is_numeric($collection)) {
+                       $oldumask = umask(0000);
+                       if (!@mkdir($mediadir, 0777))
+                               return _ERROR_BADPERMISSIONS;
+                       umask($oldumask);
+               }
+
+               // if dir still not exists, the action is disallowed
+               if (!@is_dir($mediadir))
+                       return _ERROR_DISALLOWED;
+
+               if (!is_writeable($mediadir))
+                       return _ERROR_BADPERMISSIONS;
+
+               // add trailing slash (don't add it earlier since it causes mkdir to fail on some systems)
+               $mediadir .= '/';
+
+               if (file_exists($mediadir . $filename))
+                       return _ERROR_UPLOADDUPLICATE;
+
+               // create file
+               $fh = @fopen($mediadir . $filename, 'wb');
+               if (!$fh)
+                       return _ERROR_UPLOADFAILED;
+               $ok = @fwrite($fh, $data);
+               @fclose($fh);
+               if (!$ok)
+                       return _ERROR_UPLOADFAILED;
+
+               // chmod uploaded file
+               $oldumask = umask(0000);
+               @chmod($mediadir . $filename, 0644);
+               umask($oldumask);
+
+               return '';
+
+       }
+
+}
+
+/**
+  * Represents the characteristics of one single media-object
+  *
+  * Description of properties:
+  *  - filename: filename, without paths
+  *  - timestamp: last modification (unix timestamp)
+  *  - collection: collection to which the file belongs (can also be a owner ID, for private collections)
+  *  - private: true if the media belongs to a private member collection
+  */
+class MEDIAOBJECT {
+
+       var $private;
+       var $collection;
+       var $filename;
+       var $timestamp;
+
+       function MEDIAOBJECT($collection, $filename, $timestamp) {
+               $this->private = is_numeric($collection);
+               $this->collection = $collection;
+               $this->filename = $filename;
+               $this->timestamp = $timestamp;
+       }
+
+}
+
+/**
+  * User-defined sort method to sort an array of MEDIAOBJECTS
+  */
+function sort_media($a, $b) {
+       if ($a->timestamp == $b->timestamp) return 0;
+       return ($a->timestamp > $b->timestamp) ? -1 : 1;
+}
+
+?>
index 3119324..a6de188 100755 (executable)
-<?php\r
-\r
-/**\r
-  * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/) \r
-  * Copyright (C) 2002-2005 The Nucleus Group\r
-  *\r
-  * This program is free software; you can redistribute it and/or\r
-  * modify it under the terms of the GNU General Public License\r
-  * as published by the Free Software Foundation; either version 2\r
-  * of the License, or (at your option) any later version.\r
-  * (see nucleus/documentation/index.html#license for more info)\r
-  *\r
-  * A class representing site members\r
-  *\r
-  * $Id: MEMBER.php,v 1.5 2005-03-16 08:10:35 kimitake Exp $\r
-  * $NucleusJP: MEMBER.php,v 1.4 2005/03/12 06:19:05 kimitake Exp $\r
-  */\r
-class MEMBER {\r
-\r
-       // 1 when authenticated, 0 when not\r
-       var $loggedin;\r
-       var $password;          // not the actual password, but rather a MD5 hash       \r
-\r
-       var $cookiekey;         // value that should also be in the client cookie to allow authentication\r
-       \r
-       // member info\r
-       var $id;\r
-       var $realname;\r
-       var $displayname;\r
-       var $email;\r
-       var $url;\r
-       var $language;          // name of the language file to use (e.g. 'english' -> english.php)\r
-       var $admin;                     // (either 0 or 1)\r
-       var $canlogin;          // (either 0 or 1)\r
-       var $notes;\r
-\r
-       // (private)\r
-       function MEMBER() {\r
-\r
-       }\r
-       \r
-       // (static)\r
-       function createFromName($displayname) {\r
-               $mem =& new MEMBER();\r
-               $mem->readFromName($displayname);\r
-               return $mem;\r
-       }\r
-       \r
-       // (static)\r
-       function createFromID($id) {\r
-               $mem =& new MEMBER();\r
-               $mem->readFromID($id);\r
-               return $mem;\r
-       }\r
-       \r
-       function readFromName($displayname) {\r
-               return $this->read("mname='".addslashes($displayname)."'");\r
-       }\r
-       \r
-       function readFromID($id) {\r
-               return $this->read("mnumber=" . intval($id));\r
-       }\r
-       \r
-       /**\r
-         * Tries to login as a given user. Returns true when succeeded, \r
-         * returns false when failed\r
-         */\r
-       function login($login, $password) {\r
-               $this->loggedin = 0;\r
-               if (!$this->readFromName($login))\r
-                       return 0;\r
-               if (!$this->checkPassword($password)) \r
-                       return 0;\r
-               $this->loggedin = 1;\r
-               return $this->isLoggedIn();\r
-       }\r
-       \r
-       // login using cookie key\r
-       function cookielogin($login, $cookiekey) {\r
-               $this->loggedin = 0;\r
-               if (!$this->readFromName($login))\r
-                       return 0;\r
-               if (!$this->checkCookieKey($cookiekey))\r
-                       return 0;\r
-               $this->loggedin = 1;\r
-               return $this->isLoggedIn();\r
-       }\r
-       \r
-       function logout() {\r
-               $this->loggedin=0;\r
-       }\r
-       \r
-       function isLoggedIn() {\r
-               return $this->loggedin;\r
-       }\r
-       \r
-       function read($where) {\r
-               // read info\r
-               $query =  'SELECT * FROM '.sql_table('member') . ' WHERE ' . $where;\r
-               \r
-               $res = sql_query($query);\r
-               $obj = mysql_fetch_object($res);\r
-               \r
-               $this->setRealName($obj->mrealname);\r
-               $this->setEmail($obj->memail);\r
-               $this->password = $obj->mpassword;\r
-               $this->setCookieKey($obj->mcookiekey);          \r
-               $this->setURL($obj->murl);\r
-               $this->setDisplayName($obj->mname);\r
-               $this->setAdmin($obj->madmin);\r
-               $this->id = $obj->mnumber;\r
-               $this->setCanLogin($obj->mcanlogin);\r
-               $this->setNotes($obj->mnotes);\r
-               $this->setLanguage($obj->deflang);              \r
-                       \r
-               return mysql_num_rows($res);\r
-       }\r
-       \r
-       \r
-       /**\r
-         * Returns true if member is an admin for the given blog\r
-         * (returns false if not a team member)\r
-         */\r
-       function isBlogAdmin($blogid) {\r
-               $query = 'SELECT tadmin FROM '.sql_table('team').' WHERE'\r
-                      . ' tblog=' . intval($blogid)\r
-                      . ' and tmember='. $this->getID();\r
-               $res = sql_query($query);\r
-               if (mysql_num_rows($res) == 0)\r
-                       return 0;\r
-               else\r
-                       return (mysql_result($res,0,0) == 1) ;                 \r
-       }\r
-       \r
-       function blogAdminRights($blogid) {\r
-               return ($this->isAdmin() || $this->isBlogAdmin($blogid));\r
-       }\r
-\r
-               \r
-       function teamRights($blogid) {\r
-               return ($this->isAdmin() || $this->isTeamMember($blogid));\r
-       }\r
-       \r
-       /**\r
-         * Returns true if this member is a team member of the given blog\r
-         */\r
-       function isTeamMember($blogid) {\r
-               $query = 'SELECT * FROM '.sql_table('team').' WHERE'\r
-                      . ' tblog=' . intval($blogid)\r
-                      . ' and tmember='. $this->getID();\r
-               return (mysql_num_rows(sql_query($query)) != 0);\r
-       }\r
-       \r
-       /**\r
-         * Returns true if this member can edit/delete a commentitem. This can be in the\r
-         * following cases:\r
-         *       - member is a super-admin\r
-         *   - member is the author of the comment\r
-         *   - member is admin of the blog associated with the comment\r
-         *   - member is author of the item associated with the comment\r
-         */\r
-       function canAlterComment($commentid) {\r
-               if ($this->isAdmin()) return 1;\r
-       \r
-               $query =  'SELECT citem as itemid, iblog as blogid, cmember as cauthor, iauthor'\r
-                      . ' FROM '.sql_table('comment') .', '.sql_table('item').', '.sql_table('blog')\r
-                      . ' WHERE citem=inumber and iblog=bnumber and cnumber=' . intval($commentid);\r
-               $obj = mysql_fetch_object(sql_query($query));\r
-               \r
-               return ($obj->cauthor == $this->getID()) or $this->isBlogAdmin($obj->blogid) or ($obj->iauthor == $this->getID());\r
-       }       \r
-       \r
-       /**\r
-         * Returns true if this member can edit/delete an item. This is true in the following\r
-         * cases: - member is a super-admin\r
-         *            - member is the author of the item\r
-         *        - member is admin of the the associated blog\r
-         */\r
-       function canAlterItem($itemid) {\r
-               if ($this->isAdmin()) return 1;\r
-               \r
-               $query =  'SELECT iblog, iauthor FROM '.sql_table('item').' WHERE inumber=' . intval($itemid);\r
-               $obj = mysql_fetch_object(sql_query($query));\r
-               return ($obj->iauthor == $this->getID()) or $this->isBlogAdmin($obj->iblog);\r
-       }\r
-       \r
-       /**\r
-         * returns true if this member can move/update an item to a given category, \r
-         * false if not (see comments fot the tests that are executed)\r
-         *\r
-         * @param itemid\r
-         * @param newcat (can also be of form 'newcat-x' with x=blogid)\r
-         */\r
-       function canUpdateItem($itemid, $newcat) {\r
-               global $manager;\r
-               \r
-               // item does not exists -> NOK\r
-               if (!$manager->existsItem($itemid,1,1)) return 0;\r
-               \r
-               // cannot alter item -> NOK\r
-               if (!$this->canAlterItem($itemid)) return 0;\r
-               \r
-               // if this is a 'newcat' style newcat\r
-               // no blog admin of destination blog -> NOK\r
-               // blog admin of destination blog -> OK\r
-               if (strstr($newcat,'newcat')) {\r
-                       // get blogid \r
-                       list($blogid) = sscanf($newcat,'newcat-%d');\r
-                       return $this->blogAdminRights($blogid);\r
-               } \r
-\r
-               // category does not exist -> NOK\r
-               if (!$manager->existsCategory($newcat)) return 0;\r
-\r
-               \r
-               // get item\r
-               $item =& $manager->getItem($itemid,1,1);\r
-               \r
-               // old catid = new catid -> OK\r
-               if ($item['catid'] == $newcat) return 1;\r
-\r
-               // not a valid category -> NOK\r
-               $validCat = quickQuery('SELECT COUNT(*) AS result FROM '.sql_table('category').' WHERE catid='.intval($newcat));\r
-               if (!$validCat) return 0;\r
-               \r
-               // get destination blog\r
-               $source_blogid = getBlogIDFromItemID($itemid);\r
-               $dest_blogid = getBlogIDFromCatID($newcat);\r
-               \r
-               // not a team member of destination blog -> NOK\r
-               if (!$this->teamRights($dest_blogid)) return 0;\r
-\r
-               // if member is author of item -> OK\r
-               if ($item['authorid'] == $this->getID()) return 1;\r
-               \r
-               // if member has admin rights on both blogs: OK\r
-               if (($this->blogAdminRights($dest_blogid)) && ($this->blogAdminRights($source_blogid))) return 1;\r
-               \r
-               // all other cases: NOK\r
-               return 0;\r
-               \r
-       }\r
-       \r
-       function canAddItem($catid) {\r
-               global $manager;\r
-               \r
-               // if this is a 'newcat' style newcat\r
-               // no blog admin of destination blog -> NOK\r
-               // blog admin of destination blog -> OK\r
-               if (strstr($catid,'newcat')) {\r
-                       // get blogid \r
-                       list($blogid) = sscanf($catid,"newcat-%d");\r
-                       return $this->blogAdminRights($blogid);\r
-               } \r
-               \r
-               // category does not exist -> NOK\r
-               if (!$manager->existsCategory($catid)) return 0;\r
-\r
-               $blogid = getBlogIDFromCatID($catid);\r
-\r
-               // no team rights for blog -> NOK\r
-               if (!$this->teamRights($blogid)) return 0;\r
-\r
-               // all other cases: OK\r
-               return 1;\r
-       }\r
-       \r
-       /** \r
-         * Return true if member can be deleted. This means that there are no items or comments\r
-         * posted by the member\r
-         */\r
-       function canBeDeleted() {\r
-               $res = sql_query('SELECT * FROM '.sql_table('item').' WHERE iauthor=' . $this->getID());\r
-               $res2 = sql_query('SELECT * FROM '.sql_table('comment').' WHERE cmember=' . $this->getID());\r
-               return ((mysql_num_rows($res) == 0) and (mysql_num_rows($res2)==0));\r
-       }\r
-\r
-       /** \r
-         * Sets the cookies for the member\r
-         *\r
-         * @param shared\r
-         *             set this to 1 when using a shared computer. Cookies will expire\r
-         *             at the end of the session in this case.\r
-         */\r
-       function setCookies($shared = 0) {\r
-               global $CONF;\r
-               \r
-               if ($CONF['SessionCookie'] || $shared)\r
-                       $lifetime = 0;\r
-               else\r
-                       $lifetime = (time()+2592000);\r
-                       \r
-               setcookie($CONF['CookiePrefix'] .'user',$this->getDisplayName(),$lifetime,$CONF['CookiePath'],$CONF['CookieDomain'],$CONF['CookieSecure']);\r
-               setcookie($CONF['CookiePrefix'] .'loginkey', $this->getCookieKey(),$lifetime,$CONF['CookiePath'],$CONF['CookieDomain'],$CONF['CookieSecure']);\r
-\r
-               // make sure cookies on shared pcs don't get renewed\r
-               if ($shared)\r
-                       setcookie($CONF['CookiePrefix'] .'sharedpc', '1',$lifetime,$CONF['CookiePath'],$CONF['CookieDomain'],$CONF['CookieSecure']);\r
-       }\r
-       \r
-       function sendActivationLink($type, $extra='') \r
-       {\r
-               global $CONF;\r
-               \r
-               // generate key and URL\r
-               $key = $this->generateActivationEntry($type, $extra);\r
-               $url = $CONF['AdminURL'] . 'index.php?action=activate&key=' . $key;\r
-               \r
-               // choose text to use in mail\r
-               switch ($type)\r
-               {\r
-                       case 'register':\r
-                               $message = _ACTIVATE_REGISTER_MAIL;                     \r
-                               $title = _ACTIVATE_REGISTER_MAILTITLE;\r
-                               break;\r
-                       case 'forgot':\r
-                               $message = _ACTIVATE_FORGOT_MAIL;                       \r
-                               $title = _ACTIVATE_FORGOT_MAILTITLE;\r
-                               break;\r
-                       case 'addresschange':\r
-                               $message = _ACTIVATE_CHANGE_MAIL;\r
-                               $title = _ACTIVATE_CHANGE_MAILTITLE;                            \r
-                               break;\r
-                       default;\r
-               }\r
-\r
-               // fill out variables in text\r
-               \r
-               $aVars = array(\r
-                       'siteName' => $CONF['SiteName'],\r
-                       'siteUrl' => $CONF['IndexURL'],\r
-                       'memberName' => $this->getDisplayName(),\r
-                       'activationUrl' => $url\r
-               );\r
-\r
-               $message = TEMPLATE::fill($message, $aVars);            \r
-               $title = TEMPLATE::fill($title, $aVars);                \r
-               \r
-               // send mail\r
-               \r
-               mb_language('ja');\r
-               mb_internal_encoding(_CHARSET);\r
-               @mb_send_mail($this->getEmail(), $title ,$message,'From: ' . $CONF['AdminEmail']);\r
-               \r
-               ACTIONLOG::add(INFO, _ACTIONLOG_ACTIVATIONLINK . ' (' . $this->getDisplayName() . ' / type: ' . $type . ')'); \r
-               \r
-\r
-       }\r
-       \r
-       /** \r
-         * Returns an array of all blogids for which member has admin rights\r
-         */\r
-       function getAdminBlogs() {\r
-               $blogs = array();\r
-               \r
-               if ($this->isAdmin())\r
-                       $query = 'SELECT bnumber as blogid from '.sql_table('blog');\r
-               else\r
-                       $query = 'SELECT tblog as blogid from '.sql_table('team').' where tadmin=1 and tmember=' . $this->getID();\r
-                       \r
-               $res = sql_query($query);\r
-               if (mysql_num_rows($res) > 0) {\r
-                       while ($obj = mysql_fetch_object($res)) {\r
-                               array_push($blogs, $obj->blogid);\r
-                       }\r
-               }\r
-               \r
-               return $blogs;\r
-       }\r
-       \r
-       /**\r
-         * Returns an email address from which notification of commenting/karma voting can\r
-         * be sent. A suggestion can be given for when the member is not logged in\r
-         */\r
-       function getNotifyFromMailAddress($suggest = "") {\r
-               global $CONF;\r
-               if ($this->isLoggedIn()) {\r
-                       return $this->getDisplayName() . " <" . $this->getEmail() . ">"; \r
-               } else if (isValidMailAddress($suggest)) {\r
-                       return $suggest;\r
-               } else {\r
-                       return $CONF['AdminEmail'];\r
-               }\r
-       }\r
-\r
-       /**\r
-         * Write data to database\r
-         */\r
-       function write() {\r
-\r
-               $query =  'UPDATE '.sql_table('member')\r
-                      . " SET mname='" . addslashes($this->getDisplayName()) . "',"\r
-                      . "     mrealname='". addslashes($this->getRealName()) . "',"\r
-                      . "     mpassword='". addslashes($this->getPassword()) . "',"\r
-                      . "     mcookiekey='". addslashes($this->getCookieKey()) . "',"                 \r
-                      . "     murl='" . addslashes($this->getURL()) . "',"\r
-                      . "     memail='" . addslashes($this->getEmail()) . "',"\r
-                      . "     madmin=" . $this->isAdmin() . ","\r
-                      . "     mnotes='" . addslashes($this->getNotes()) . "',"\r
-                      . "     mcanlogin=" . $this->canLogin() . ","\r
-                      . "         deflang='" . addslashes($this->getLanguage()) . "'"\r
-                      . " WHERE mnumber=" . $this->getID();\r
-               sql_query($query);\r
-       }\r
-       \r
-       function checkPassword($pw) {\r
-               return (md5($pw) == $this->getPassword());\r
-       }\r
-       \r
-       function checkCookieKey($key) {\r
-               return (($key != '') && ($key == $this->getCookieKey()));\r
-       }\r
-       \r
-       function getRealName() {\r
-               return $this->realname;\r
-       }\r
-       \r
-       function setRealName($name) {\r
-               $this->realname = $name;\r
-       }\r
-       \r
-       function getEmail() {\r
-               return $this->email;\r
-       }\r
-       \r
-       function setEmail($email) {\r
-               $this->email = $email;\r
-       }\r
-       \r
-       function getPassword() {\r
-               return $this->password;\r
-       }\r
-       \r
-       function setPassword($pwd) {\r
-               $this->password = md5($pwd);\r
-       }\r
-       \r
-       function getCookieKey() {\r
-               return $this->cookiekey;\r
-       }\r
-       \r
-       /**\r
-         * Generate new cookiekey, save it, and return it\r
-         */\r
-       function newCookieKey() {\r
-               mt_srand( (double) microtime() * 1000000);\r
-               $this->cookiekey = md5(uniqid(mt_rand()));\r
-               $this->write();\r
-               return $this->cookiekey;\r
-       }\r
-       \r
-       function setCookieKey($val) {\r
-               $this->cookiekey = $val;\r
-       }\r
-\r
-       function getURL() {\r
-               return $this->url;\r
-       }\r
-       \r
-       function setURL($site) {\r
-               $this->url = $site;\r
-       }\r
-       \r
-       function getLanguage() {\r
-               return $this->language;\r
-       }\r
-       \r
-       function setLanguage($lang) {\r
-               $this->language = $lang;\r
-       }\r
-       \r
-       function setDisplayName($nick) {\r
-               $this->displayname = $nick;\r
-       }\r
-       \r
-       function getDisplayName() {\r
-               return $this->displayname;\r
-       }\r
-       \r
-       function isAdmin() {\r
-               return $this->admin;\r
-       }\r
-       \r
-       function setAdmin($val) {\r
-               $this->admin = $val;\r
-       }\r
-       \r
-       function canLogin() {\r
-               return $this->canlogin;\r
-       }\r
-       \r
-       function setCanLogin($val) {\r
-               $this->canlogin = $val;\r
-       }\r
-\r
-       function getNotes() {\r
-               return $this->notes;\r
-       }\r
-       \r
-       function setNotes($val) {\r
-               $this->notes = $val;\r
-       }\r
-       \r
-       function getID() {\r
-               return $this->id;\r
-       }\r
-\r
-       // returns true if there is a member with the given login name (static)\r
-       function exists($name) {\r
-               $r = sql_query('select * FROM '.sql_table('member')." WHERE mname='".addslashes($name)."'");\r
-               return (mysql_num_rows($r) != 0);\r
-       }\r
-\r
-       // returns true if there is a member with the given ID (static)\r
-       function existsID($id) {\r
-               $r = sql_query('select * FROM '.sql_table('member')." WHERE mnumber='".intval($id)."'");\r
-               return (mysql_num_rows($r) != 0);\r
-       }\r
-       \r
-       // checks if a username is protected. If so, it can not be used on anonymous comments\r
-       function isNameProtected($name) {\r
-               \r
-               // extract name\r
-               $name = strip_tags($name);      \r
-               $name = trim($name);            \r
-               \r
-               return MEMBER::exists($name);\r
-       }\r
-       \r
-       // adds a new member (static)\r
-       function create($name, $realname, $password, $email, $url, $admin, $canlogin, $notes) {\r
-               if (!isValidMailAddress($email))\r
-                       return _ERROR_BADMAILADDRESS;\r
-\r
-               if (!isValidDisplayName($name))\r
-                       return _ERROR_BADNAME;\r
-\r
-               if (MEMBER::exists($name))\r
-                       return _ERROR_NICKNAMEINUSE;    \r
-\r
-               if (!$realname)\r
-                       return _ERROR_REALNAMEMISSING;\r
-\r
-               if (!$password)\r
-                       return _ERROR_PASSWORDMISSING;                  \r
-\r
-               // Sometimes user didn't prefix the URL with http://, this cause a malformed URL. Let's fix it.\r
-               if (!eregi("^https?://", $url))\r
-                       $url = "http://".$url;\r
-\r
-               $name = addslashes($name);\r
-               $realname = addslashes($realname);\r
-               $password = addslashes(md5($password));\r
-               $email = addslashes($email);\r
-               $url = addslashes($url);\r
-               $admin = intval($admin);\r
-               $canlogin = intval($canlogin);\r
-               $notes = addslashes($notes);\r
-\r
-               $query = 'INSERT INTO '.sql_table('member')." (MNAME,MREALNAME,MPASSWORD,MEMAIL,MURL, MADMIN, MCANLOGIN, MNOTES) "\r
-                      . "VALUES ('$name','$realname','$password','$email','$url',$admin, $canlogin, '$notes')";\r
-               sql_query($query);\r
-               \r
-               ACTIONLOG::add(INFO, _ACTIONLOG_NEWMEMBER . ' ' . $name);               \r
-\r
-               return 1;\r
-       }       \r
-       \r
-       /**\r
-        * Returns activation info for a certain key (an object with properties vkey, vmember, ...)\r
-        * (static)\r
-        *\r
-        * @author karma\r
-        */\r
-       function getActivationInfo($key)\r
-       {\r
-               $query = 'SELECT * FROM ' . sql_table('activation') . ' WHERE vkey=\'' . addslashes($key). '\'';\r
-               $res = sql_query($query);\r
-\r
-               if (!$res || (mysql_num_rows($res) == 0))\r
-                       return 0;\r
-               else\r
-                       return mysql_fetch_object($res);\r
-       }\r
-       \r
-       /**\r
-        * Creates an account activation key\r
-        *\r
-        * @param $type one of the following values (determines what to do when activation expires)\r
-        *                'register' (new member registration)\r
-        *                'forgot' (forgotton password)\r
-        *                'addresschange' (member address has changed)\r
-        * @param $extra extra info (needed when validation link expires)\r
-        *                                addresschange -> old email address\r
-        * @author dekarma\r
-        */\r
-       function generateActivationEntry($type, $extra = '') \r
-       {\r
-               // clean up old entries\r
-               $this->cleanupActivationTable();\r
-       \r
-               // kill any existing entries for the current member (delete is ok)\r
-               // (only one outstanding activation key can be present for a member)\r
-               sql_query('DELETE FROM ' . sql_table('activation') . ' WHERE vmember=' . intval($this->getID()));\r
-\r
-               $canLoginWhileActive = false; // indicates if the member can log in while the link is active \r
-               switch ($type)\r
-               {\r
-                       case 'forgot':\r
-                               $canLoginWhileActive = true;\r
-                               break;\r
-                       case 'register':\r
-                               break;\r
-                       case 'addresschange':\r
-                               $extra = $extra . '/' . ($this->canLogin() ? '1' : '0');\r
-                               break;\r
-               }\r
-               \r
-               $ok = false;\r
-               while (!$ok)\r
-               {\r
-                       // generate a random key\r
-                       srand((double)microtime()*1000000);\r
-                       $key = md5(uniqid(rand(), true));\r
-                       \r
-                       // attempt to add entry in database\r
-                       // add in database as non-active\r
-                       $query = 'INSERT INTO ' . sql_table('activation'). ' (vkey, vtime, vmember, vtype, vextra) ';\r
-                       $query .= 'VALUES (\'' . addslashes($key). '\', \'' . date('Y-m-d H:i:s',time()) . '\', \'' . intval($this->getID()). '\', \'' . addslashes($type). '\', \'' . addslashes($extra). '\')';\r
-                       if (sql_query($query))\r
-                               $ok = true;\r
-               }\r
-               \r
-               // mark member as not allowed to log in\r
-               if (!$canLoginWhileActive)\r
-               {\r
-                       $this->setCanLogin(0);\r
-                       $this->write(); \r
-               }\r
-               \r
-               // return the key\r
-               return $key;\r
-       }\r
-       \r
-       /**\r
-        * Inidicates that an activation link has been clicked and any forms displayed\r
-        * there have been successfully filled out.\r
-        * @author dekarma\r
-        */\r
-       function activate($key) \r
-       {\r
-               // get activate info\r
-               $info = MEMBER::getActivationInfo($key);\r
-               \r
-               // no active key\r
-               if (!$info)\r
-                       return false;\r
-                       \r
-               switch ($info->vtype) \r
-               {\r
-                       case 'forgot':\r
-                               // nothing to do\r
-                               break;\r
-                       case 'register':\r
-                               // set canlogin value\r
-                               global $CONF;\r
-                               sql_query('UPDATE ' . sql_table('member') . ' SET mcanlogin=' . intval($CONF['NewMemberCanLogon']). ' WHERE mnumber=' . intval($info->vmember));\r
-                               break;\r
-                       case 'addresschange':\r
-                               // reset old 'canlogin' value\r
-                               list($oldEmail, $oldCanLogin) = explode('/', $info->vextra);\r
-                               sql_query('UPDATE ' . sql_table('member') . ' SET mcanlogin=' . intval($oldCanLogin). ' WHERE mnumber=' . intval($info->vmember));\r
-                               break;\r
-               }\r
-               \r
-               // delete from activation table\r
-               sql_query('DELETE FROM ' . sql_table('activation') . ' WHERE vkey=\'' . addslashes($key) . '\'');\r
-               \r
-               // success!\r
-               return true;\r
-       }\r
-       \r
-       /**\r
-        * Cleans up entries in the activation table. All entries older than 2 days are removed.\r
-        * (static)\r
-        *\r
-        * @author dekarma\r
-        */\r
-       function cleanupActivationTable() \r
-       {\r
-               $boundary = time() - (60 * 60 * 24 * 2);\r
-               \r
-               // 1. walk over all entries, and see if special actions need to be performed\r
-               $res = sql_query('SELECT * FROM ' . sql_table('activation') . ' WHERE vtime < \'' . date('Y-m-d H:i:s',$boundary) . '\'');\r
-               \r
-               while ($o = mysql_fetch_object($res))\r
-               {\r
-                       switch ($o->vtype)\r
-                       {\r
-                               case 'register':\r
-                                       // delete all information about this site member. registration is undone because there was\r
-                                       // no timely activation\r
-                                       include_once($DIR_LIBS . 'ADMIN.php');\r
-                                       ADMIN::deleteOneMember(intval($o->vmember));\r
-                                       break;\r
-                               case 'addresschange':\r
-                                       // revert the e-mail address of the member back to old address\r
-                                       list($oldEmail, $oldCanLogin) = explode('/', $o->vextra);\r
-                                       sql_query('UPDATE ' . sql_table('member') . ' SET mcanlogin=' . intval($oldCanLogin). ', memail=\'' . addslashes($oldEmail). '\' WHERE mnumber=' . intval($o->vmember));\r
-                                       break;                                  \r
-                               case 'forgot':\r
-                                       // delete the activation link and ignore. member can request a new password using the \r
-                                       // forgot password link\r
-                                       break;\r
-                       }\r
-               }\r
-               \r
-               // 2. delete activation entries for real\r
-               sql_query('DELETE FROM ' . sql_table('activation') . ' WHERE vtime < \'' . date('Y-m-d H:i:s',$boundary) . '\'');\r
-       }\r
-\r
-}\r
-\r
-?>\r
+<?php
+
+/*
+ * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/)
+ * Copyright (C) 2002-2007 The Nucleus Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * (see nucleus/documentation/index.html#license for more info)
+ */
+/**
+ * A class representing site members
+ *
+ * @license http://nucleuscms.org/license.txt GNU General Public License
+ * @copyright Copyright (C) 2002-2007 The Nucleus Group
+ * @version $Id: MEMBER.php,v 1.6 2007-03-27 12:13:56 kimitake Exp $
+ * $NucleusJP: MEMBER.php,v 1.7 2007/02/04 06:28:46 kimitake Exp $
+ */
+class MEMBER {
+
+       // 1 when authenticated, 0 when not
+       var $loggedin = 0;
+       var $password;          // not the actual password, but rather a MD5 hash
+
+       var $cookiekey;         // value that should also be in the client cookie to allow authentication
+
+       // member info
+       var $id = -1;
+       var $realname;
+       var $displayname;
+       var $email;
+       var $url;
+       var $language = '';             // name of the language file to use (e.g. 'english' -> english.php)
+       var $admin = 0;                 // (either 0 or 1)
+       var $canlogin = 0;              // (either 0 or 1)
+       var $notes;
+
+       // (private)
+       function MEMBER() {
+
+       }
+
+       // (static)
+       function &createFromName($displayname) {
+               $mem =& new MEMBER();
+               $mem->readFromName($displayname);
+               return $mem;
+       }
+
+       // (static)
+       function &createFromID($id) {
+               $mem =& new MEMBER();
+               $mem->readFromID($id);
+               return $mem;
+       }
+
+       function readFromName($displayname) {
+               return $this->read("mname='".addslashes($displayname)."'");
+       }
+
+       function readFromID($id) {
+               return $this->read("mnumber=" . intval($id));
+       }
+
+       /**
+         * Tries to login as a given user. Returns true when succeeded,
+         * returns false when failed
+         */
+       function login($login, $password) {
+               $this->loggedin = 0;
+               if (!$this->readFromName($login))
+                       return 0;
+               if (!$this->checkPassword($password))
+                       return 0;
+               $this->loggedin = 1;
+               return $this->isLoggedIn();
+       }
+
+       // login using cookie key
+       function cookielogin($login, $cookiekey) {
+               $this->loggedin = 0;
+               if (!$this->readFromName($login))
+                       return 0;
+               if (!$this->checkCookieKey($cookiekey))
+                       return 0;
+               $this->loggedin = 1;
+               return $this->isLoggedIn();
+       }
+
+       function logout() {
+               $this->loggedin=0;
+       }
+
+       function isLoggedIn() {
+               return $this->loggedin;
+       }
+
+       function read($where) {
+               // read info
+               $query =  'SELECT * FROM '.sql_table('member') . ' WHERE ' . $where;
+
+               $res = sql_query($query);
+               $obj = mysql_fetch_object($res);
+
+               $this->setRealName($obj->mrealname);
+               $this->setEmail($obj->memail);
+               $this->password = $obj->mpassword;
+               $this->setCookieKey($obj->mcookiekey);
+               $this->setURL($obj->murl);
+               $this->setDisplayName($obj->mname);
+               $this->setAdmin($obj->madmin);
+               $this->id = $obj->mnumber;
+               $this->setCanLogin($obj->mcanlogin);
+               $this->setNotes($obj->mnotes);
+               $this->setLanguage($obj->deflang);
+
+               return mysql_num_rows($res);
+       }
+
+
+       /**
+         * Returns true if member is an admin for the given blog
+         * (returns false if not a team member)
+         */
+       function isBlogAdmin($blogid) {
+               $query = 'SELECT tadmin FROM '.sql_table('team').' WHERE'
+                          . ' tblog=' . intval($blogid)
+                          . ' and tmember='. $this->getID();
+               $res = sql_query($query);
+               if (mysql_num_rows($res) == 0)
+                       return 0;
+               else
+                       return (mysql_result($res,0,0) == 1) ;
+       }
+
+       function blogAdminRights($blogid) {
+               return ($this->isAdmin() || $this->isBlogAdmin($blogid));
+       }
+
+
+       function teamRights($blogid) {
+               return ($this->isAdmin() || $this->isTeamMember($blogid));
+       }
+
+       /**
+         * Returns true if this member is a team member of the given blog
+         */
+       function isTeamMember($blogid) {
+               $query = 'SELECT * FROM '.sql_table('team').' WHERE'
+                          . ' tblog=' . intval($blogid)
+                          . ' and tmember='. $this->getID();
+               $res = sql_query($query);
+               return (mysql_num_rows($res) != 0);
+       }
+
+       /**
+         * Returns true if this member can edit/delete a commentitem. This can be in the
+         * following cases:
+         *       - member is a super-admin
+         *   - member is the author of the comment
+         *   - member is admin of the blog associated with the comment
+         *   - member is author of the item associated with the comment
+         */
+       function canAlterComment($commentid) {
+               if ($this->isAdmin()) return 1;
+
+               $query =  'SELECT citem as itemid, iblog as blogid, cmember as cauthor, iauthor'
+                          . ' FROM '.sql_table('comment') .', '.sql_table('item').', '.sql_table('blog')
+                          . ' WHERE citem=inumber and iblog=bnumber and cnumber=' . intval($commentid);
+               $res = sql_query($query);
+               $obj = mysql_fetch_object($res);
+
+               return ($obj->cauthor == $this->getID()) or $this->isBlogAdmin($obj->blogid) or ($obj->iauthor == $this->getID());
+       }
+
+       /**
+         * Returns true if this member can edit/delete an item. This is true in the following
+         * cases: - member is a super-admin
+         *            - member is the author of the item
+         *        - member is admin of the the associated blog
+         */
+       function canAlterItem($itemid) {
+               if ($this->isAdmin()) return 1;
+
+               $query =  'SELECT iblog, iauthor FROM '.sql_table('item').' WHERE inumber=' . intval($itemid);
+               $res = sql_query($query);
+               $obj = mysql_fetch_object($res);
+               return ($obj->iauthor == $this->getID()) or $this->isBlogAdmin($obj->iblog);
+       }
+
+       /**
+         * returns true if this member can move/update an item to a given category,
+         * false if not (see comments fot the tests that are executed)
+         *
+         * @param itemid
+         * @param newcat (can also be of form 'newcat-x' with x=blogid)
+         */
+       function canUpdateItem($itemid, $newcat) {
+               global $manager;
+
+               // item does not exists -> NOK
+               if (!$manager->existsItem($itemid,1,1)) return 0;
+
+               // cannot alter item -> NOK
+               if (!$this->canAlterItem($itemid)) return 0;
+
+               // if this is a 'newcat' style newcat
+               // no blog admin of destination blog -> NOK
+               // blog admin of destination blog -> OK
+               if (strstr($newcat,'newcat')) {
+                       // get blogid
+                       list($blogid) = sscanf($newcat,'newcat-%d');
+                       return $this->blogAdminRights($blogid);
+               }
+
+               // category does not exist -> NOK
+               if (!$manager->existsCategory($newcat)) return 0;
+
+
+               // get item
+               $item =& $manager->getItem($itemid,1,1);
+
+               // old catid = new catid -> OK
+               if ($item['catid'] == $newcat) return 1;
+
+               // not a valid category -> NOK
+               $validCat = quickQuery('SELECT COUNT(*) AS result FROM '.sql_table('category').' WHERE catid='.intval($newcat));
+               if (!$validCat) return 0;
+
+               // get destination blog
+               $source_blogid = getBlogIDFromItemID($itemid);
+               $dest_blogid = getBlogIDFromCatID($newcat);
+
+               // not a team member of destination blog -> NOK
+               if (!$this->teamRights($dest_blogid)) return 0;
+
+               // if member is author of item -> OK
+               if ($item['authorid'] == $this->getID()) return 1;
+
+               // if member has admin rights on both blogs: OK
+               if (($this->blogAdminRights($dest_blogid)) && ($this->blogAdminRights($source_blogid))) return 1;
+
+               // all other cases: NOK
+               return 0;
+
+       }
+
+       function canAddItem($catid) {
+               global $manager;
+
+               // if this is a 'newcat' style newcat
+               // no blog admin of destination blog -> NOK
+               // blog admin of destination blog -> OK
+               if (strstr($catid,'newcat')) {
+                       // get blogid
+                       list($blogid) = sscanf($catid,"newcat-%d");
+                       return $this->blogAdminRights($blogid);
+               }
+
+               // category does not exist -> NOK
+               if (!$manager->existsCategory($catid)) return 0;
+
+               $blogid = getBlogIDFromCatID($catid);
+
+               // no team rights for blog -> NOK
+               if (!$this->teamRights($blogid)) return 0;
+
+               // all other cases: OK
+               return 1;
+       }
+
+       /**
+         * Return true if member can be deleted. This means that there are no items
+         * posted by the member left
+         */
+       function canBeDeleted() {
+               $res = sql_query('SELECT * FROM '.sql_table('item').' WHERE iauthor=' . $this->getID());
+               return (mysql_num_rows($res) == 0);
+       }
+
+       /**
+         * Sets the cookies for the member
+         *
+         * @param shared
+         *             set this to 1 when using a shared computer. Cookies will expire
+         *             at the end of the session in this case.
+         */
+       function setCookies($shared = 0) {
+               global $CONF;
+
+               if ($CONF['SessionCookie'] || $shared)
+                       $lifetime = 0;
+               else
+                       $lifetime = (time()+2592000);
+
+               setcookie($CONF['CookiePrefix'] .'user',$this->getDisplayName(),$lifetime,$CONF['CookiePath'],$CONF['CookieDomain'],$CONF['CookieSecure']);
+               setcookie($CONF['CookiePrefix'] .'loginkey', $this->getCookieKey(),$lifetime,$CONF['CookiePath'],$CONF['CookieDomain'],$CONF['CookieSecure']);
+
+               // make sure cookies on shared pcs don't get renewed
+               if ($shared)
+                       setcookie($CONF['CookiePrefix'] .'sharedpc', '1',$lifetime,$CONF['CookiePath'],$CONF['CookieDomain'],$CONF['CookieSecure']);
+       }
+
+       function sendActivationLink($type, $extra='')
+       {
+               global $CONF;
+
+               // generate key and URL
+               $key = $this->generateActivationEntry($type, $extra);
+               $url = $CONF['AdminURL'] . 'index.php?action=activate&key=' . $key;
+
+               // choose text to use in mail
+               switch ($type)
+               {
+                       case 'register':
+                               $message = _ACTIVATE_REGISTER_MAIL;
+                               $title = _ACTIVATE_REGISTER_MAILTITLE;
+                               break;
+                       case 'forgot':
+                               $message = _ACTIVATE_FORGOT_MAIL;
+                               $title = _ACTIVATE_FORGOT_MAILTITLE;
+                               break;
+                       case 'addresschange':
+                               $message = _ACTIVATE_CHANGE_MAIL;
+                               $title = _ACTIVATE_CHANGE_MAILTITLE;
+                               break;
+                       default;
+               }
+
+               // fill out variables in text
+
+               $aVars = array(
+                       'siteName' => $CONF['SiteName'],
+                       'siteUrl' => $CONF['IndexURL'],
+                       'memberName' => $this->getDisplayName(),
+                       'activationUrl' => $url
+               );
+
+               $message = TEMPLATE::fill($message, $aVars);
+               $title = TEMPLATE::fill($title, $aVars);
+
+               // send mail
+
+               mb_language('ja');
+               mb_internal_encoding(_CHARSET);
+               @mb_send_mail($this->getEmail(), $title ,$message,'From: ' . $CONF['AdminEmail']);
+
+               ACTIONLOG::add(INFO, _ACTIONLOG_ACTIVATIONLINK . ' (' . $this->getDisplayName() . ' / type: ' . $type . ')');
+
+
+       }
+
+       /**
+         * Returns an array of all blogids for which member has admin rights
+         */
+       function getAdminBlogs() {
+               $blogs = array();
+
+               if ($this->isAdmin())
+                       $query = 'SELECT bnumber as blogid from '.sql_table('blog');
+               else
+                       $query = 'SELECT tblog as blogid from '.sql_table('team').' where tadmin=1 and tmember=' . $this->getID();
+
+               $res = sql_query($query);
+               if (mysql_num_rows($res) > 0) {
+                       while ($obj = mysql_fetch_object($res)) {
+                               array_push($blogs, $obj->blogid);
+                       }
+               }
+
+               return $blogs;
+       }
+
+       /**
+         * Returns an email address from which notification of commenting/karma voting can
+         * be sent. A suggestion can be given for when the member is not logged in
+         */
+       function getNotifyFromMailAddress($suggest = "") {
+               global $CONF;
+               if ($this->isLoggedIn()) {
+                       return $this->getDisplayName() . " <" . $this->getEmail() . ">";
+               } else if (isValidMailAddress($suggest)) {
+                       return $suggest;
+               } else {
+                       return $CONF['AdminEmail'];
+               }
+       }
+
+       /**
+         * Write data to database
+         */
+       function write() {
+
+               $query =  'UPDATE '.sql_table('member')
+                          . " SET mname='" . addslashes($this->getDisplayName()) . "',"
+                          . "     mrealname='". addslashes($this->getRealName()) . "',"
+                          . "     mpassword='". addslashes($this->getPassword()) . "',"
+                          . "     mcookiekey='". addslashes($this->getCookieKey()) . "',"
+                          . "     murl='" . addslashes($this->getURL()) . "',"
+                          . "     memail='" . addslashes($this->getEmail()) . "',"
+                          . "     madmin=" . $this->isAdmin() . ","
+                          . "     mnotes='" . addslashes($this->getNotes()) . "',"
+                          . "     mcanlogin=" . $this->canLogin() . ","
+                          . "     deflang='" . addslashes($this->getLanguage()) . "'"
+                          . " WHERE mnumber=" . $this->getID();
+               sql_query($query);
+       }
+
+       function checkPassword($pw) {
+               return (md5($pw) == $this->getPassword());
+       }
+
+       function checkCookieKey($key) {
+               return (($key != '') && ($key == $this->getCookieKey()));
+       }
+
+       function getRealName() {
+               return $this->realname;
+       }
+
+       function setRealName($name) {
+               $this->realname = $name;
+       }
+
+       function getEmail() {
+               return $this->email;
+       }
+
+       function setEmail($email) {
+               $this->email = $email;
+       }
+
+       function getPassword() {
+               return $this->password;
+       }
+
+       function setPassword($pwd) {
+               $this->password = md5($pwd);
+       }
+
+       function getCookieKey() {
+               return $this->cookiekey;
+       }
+
+       /**
+         * Generate new cookiekey, save it, and return it
+         */
+       function newCookieKey() {
+               mt_srand( (double) microtime() * 1000000);
+               $this->cookiekey = md5(uniqid(mt_rand()));
+               $this->write();
+               return $this->cookiekey;
+       }
+
+       function setCookieKey($val) {
+               $this->cookiekey = $val;
+       }
+
+       function getURL() {
+               return $this->url;
+       }
+
+       function setURL($site) {
+               $this->url = $site;
+       }
+
+       function getLanguage() {
+               return $this->language;
+       }
+
+       function setLanguage($lang) {
+               $this->language = $lang;
+       }
+
+       function setDisplayName($nick) {
+               $this->displayname = $nick;
+       }
+
+       function getDisplayName() {
+               return $this->displayname;
+       }
+
+       function isAdmin() {
+               return $this->admin;
+       }
+
+       function setAdmin($val) {
+               $this->admin = $val;
+       }
+
+       function canLogin() {
+               return $this->canlogin;
+       }
+
+       function setCanLogin($val) {
+               $this->canlogin = $val;
+       }
+
+       function getNotes() {
+               return $this->notes;
+       }
+
+       function setNotes($val) {
+               $this->notes = $val;
+       }
+
+       function getID() {
+               return $this->id;
+       }
+
+       // returns true if there is a member with the given login name (static)
+       function exists($name) {
+               $r = sql_query('select * FROM '.sql_table('member')." WHERE mname='".addslashes($name)."'");
+               return (mysql_num_rows($r) != 0);
+       }
+
+       // returns true if there is a member with the given ID (static)
+       function existsID($id) {
+               $r = sql_query('select * FROM '.sql_table('member')." WHERE mnumber='".intval($id)."'");
+               return (mysql_num_rows($r) != 0);
+       }
+
+       // checks if a username is protected. If so, it can not be used on anonymous comments
+       function isNameProtected($name) {
+
+               // extract name
+               $name = strip_tags($name);
+               $name = trim($name);
+
+               return MEMBER::exists($name);
+       }
+
+       // adds a new member (static)
+       function create($name, $realname, $password, $email, $url, $admin, $canlogin, $notes) {
+               if (!isValidMailAddress($email))
+                       return _ERROR_BADMAILADDRESS;
+
+               if (!isValidDisplayName($name))
+                       return _ERROR_BADNAME;
+
+               if (MEMBER::exists($name))
+                       return _ERROR_NICKNAMEINUSE;
+
+               if (!$realname)
+                       return _ERROR_REALNAMEMISSING;
+
+               if (!$password)
+                       return _ERROR_PASSWORDMISSING;
+
+               // Sometimes user didn't prefix the URL with http://, this cause a malformed URL. Let's fix it.
+               if (!eregi("^https?://", $url))
+                       $url = "http://".$url;
+
+               $name = addslashes($name);
+               $realname = addslashes($realname);
+               $password = addslashes(md5($password));
+               $email = addslashes($email);
+               $url = addslashes($url);
+               $admin = intval($admin);
+               $canlogin = intval($canlogin);
+               $notes = addslashes($notes);
+
+               $query = 'INSERT INTO '.sql_table('member')." (MNAME,MREALNAME,MPASSWORD,MEMAIL,MURL, MADMIN, MCANLOGIN, MNOTES) "
+                          . "VALUES ('$name','$realname','$password','$email','$url',$admin, $canlogin, '$notes')";
+               sql_query($query);
+
+               ACTIONLOG::add(INFO, _ACTIONLOG_NEWMEMBER . ' ' . $name);
+
+               return 1;
+       }
+
+       /**
+        * Returns activation info for a certain key (an object with properties vkey, vmember, ...)
+        * (static)
+        *
+        * @author karma
+        */
+       function getActivationInfo($key)
+       {
+               $query = 'SELECT * FROM ' . sql_table('activation') . ' WHERE vkey=\'' . addslashes($key). '\'';
+               $res = sql_query($query);
+
+               if (!$res || (mysql_num_rows($res) == 0))
+                       return 0;
+               else
+                       return mysql_fetch_object($res);
+       }
+
+       /**
+        * Creates an account activation key
+        *
+        * @param $type one of the following values (determines what to do when activation expires)
+        *                'register' (new member registration)
+        *                'forgot' (forgotton password)
+        *                'addresschange' (member address has changed)
+        * @param $extra extra info (needed when validation link expires)
+        *                                addresschange -> old email address
+        * @author dekarma
+        */
+       function generateActivationEntry($type, $extra = '')
+       {
+               // clean up old entries
+               $this->cleanupActivationTable();
+
+               // kill any existing entries for the current member (delete is ok)
+               // (only one outstanding activation key can be present for a member)
+               sql_query('DELETE FROM ' . sql_table('activation') . ' WHERE vmember=' . intval($this->getID()));
+
+               $canLoginWhileActive = false; // indicates if the member can log in while the link is active
+               switch ($type)
+               {
+                       case 'forgot':
+                               $canLoginWhileActive = true;
+                               break;
+                       case 'register':
+                               break;
+                       case 'addresschange':
+                               $extra = $extra . '/' . ($this->canLogin() ? '1' : '0');
+                               break;
+               }
+
+               $ok = false;
+               while (!$ok)
+               {
+                       // generate a random key
+                       srand((double)microtime()*1000000);
+                       $key = md5(uniqid(rand(), true));
+
+                       // attempt to add entry in database
+                       // add in database as non-active
+                       $query = 'INSERT INTO ' . sql_table('activation'). ' (vkey, vtime, vmember, vtype, vextra) ';
+                       $query .= 'VALUES (\'' . addslashes($key). '\', \'' . date('Y-m-d H:i:s',time()) . '\', \'' . intval($this->getID()). '\', \'' . addslashes($type). '\', \'' . addslashes($extra). '\')';
+                       if (sql_query($query))
+                               $ok = true;
+               }
+
+               // mark member as not allowed to log in
+               if (!$canLoginWhileActive)
+               {
+                       $this->setCanLogin(0);
+                       $this->write();
+               }
+
+               // return the key
+               return $key;
+       }
+
+       /**
+        * Inidicates that an activation link has been clicked and any forms displayed
+        * there have been successfully filled out.
+        * @author dekarma
+        */
+       function activate($key)
+       {
+               // get activate info
+               $info = MEMBER::getActivationInfo($key);
+
+               // no active key
+               if (!$info)
+                       return false;
+
+               switch ($info->vtype)
+               {
+                       case 'forgot':
+                               // nothing to do
+                               break;
+                       case 'register':
+                               // set canlogin value
+                               global $CONF;
+                               sql_query('UPDATE ' . sql_table('member') . ' SET mcanlogin=' . intval($CONF['NewMemberCanLogon']). ' WHERE mnumber=' . intval($info->vmember));
+                               break;
+                       case 'addresschange':
+                               // reset old 'canlogin' value
+                               list($oldEmail, $oldCanLogin) = explode('/', $info->vextra);
+                               sql_query('UPDATE ' . sql_table('member') . ' SET mcanlogin=' . intval($oldCanLogin). ' WHERE mnumber=' . intval($info->vmember));
+                               break;
+               }
+
+               // delete from activation table
+               sql_query('DELETE FROM ' . sql_table('activation') . ' WHERE vkey=\'' . addslashes($key) . '\'');
+
+               // success!
+               return true;
+       }
+
+       /**
+        * Cleans up entries in the activation table. All entries older than 2 days are removed.
+        * (static)
+        *
+        * @author dekarma
+        */
+       function cleanupActivationTable()
+       {
+               $boundary = time() - (60 * 60 * 24 * 2);
+
+               // 1. walk over all entries, and see if special actions need to be performed
+               $res = sql_query('SELECT * FROM ' . sql_table('activation') . ' WHERE vtime < \'' . date('Y-m-d H:i:s',$boundary) . '\'');
+
+               while ($o = mysql_fetch_object($res))
+               {
+                       switch ($o->vtype)
+                       {
+                               case 'register':
+                                       // delete all information about this site member. registration is undone because there was
+                                       // no timely activation
+                                       include_once($DIR_LIBS . 'ADMIN.php');
+                                       ADMIN::deleteOneMember(intval($o->vmember));
+                                       break;
+                               case 'addresschange':
+                                       // revert the e-mail address of the member back to old address
+                                       list($oldEmail, $oldCanLogin) = explode('/', $o->vextra);
+                                       sql_query('UPDATE ' . sql_table('member') . ' SET mcanlogin=' . intval($oldCanLogin). ', memail=\'' . addslashes($oldEmail). '\' WHERE mnumber=' . intval($o->vmember));
+                                       break;
+                               case 'forgot':
+                                       // delete the activation link and ignore. member can request a new password using the
+                                       // forgot password link
+                                       break;
+                       }
+               }
+
+               // 2. delete activation entries for real
+               sql_query('DELETE FROM ' . sql_table('activation') . ' WHERE vtime < \'' . date('Y-m-d H:i:s',$boundary) . '\'');
+       }
+
+}
+
+?>
index 88c328f..71513c5 100755 (executable)
@@ -1,66 +1,69 @@
-<?php\r
-/**\r
-  * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/) \r
-  * Copyright (C) 2002-2005 The Nucleus Group\r
-  *\r
-  * This program is free software; you can redistribute it and/or\r
-  * modify it under the terms of the GNU General Public License\r
-  * as published by the Free Software Foundation; either version 2\r
-  * of the License, or (at your option) any later version.\r
-  * (see nucleus/documentation/index.html#license for more info)\r
-  *\r
-  * Class used to represent a collection of e-mail addresses, to which a\r
-  * message can be sent (e.g. comment or karma vote notification).\r
-  *\r
-  * $Id: NOTIFICATION.php,v 1.3 2005-03-16 08:10:35 kimitake Exp $\r
-  * $NucleusJP: NOTIFICATION.php,v 1.3 2005/03/12 06:19:05 kimitake Exp $\r
-  */\r
-class NOTIFICATION {\r
-\r
-       // array of addresses that need to get a notification\r
-       var $addresses = array();\r
-\r
-       /**\r
-         * takes one string as argument, containing multiple e-mail addresses\r
-         * separated by semicolons\r
-         * eg: site@demuynck.org;nucleus@demuynck.org;foo@bar.com\r
-         */\r
-       function NOTIFICATION($addresses) {\r
-               $this->addresses = explode(';' , $addresses);\r
-       }\r
-\r
-       /**\r
-         * returns true if all addresses are valid\r
-         */\r
-       function validAddresses() {\r
-               foreach ( $this->addresses as $address ) {\r
-                       if (!isValidMailAddress(trim($address))) \r
-                               return 0;\r
-               }\r
-               return 1;\r
-       }\r
-       \r
-       /**\r
-         * Sends email messages to all the email addresses\r
-         */\r
-       function notify($title, $message, $from) {\r
-               global $member;\r
-                       \r
-               foreach ( $this->addresses as $address ) {\r
-                       $address = trim($address);\r
-                       \r
-                       if (!$address)\r
-                               continue;\r
-                       \r
-                       // don't send messages to yourself\r
-                       if ($member->isLoggedIn() && ($member->getEmail() == $address))\r
-                               continue;\r
-               \r
-                       @mb_language('ja');\r
-                       @mb_internal_encoding(_CHARSET);\r
-                       @mb_send_mail($address, $title, $message, "From: ". $from);\r
-               }\r
-       }\r
-}\r
-\r
-?>\r
+<?php
+/*
+ * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/)
+ * Copyright (C) 2002-2007 The Nucleus Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * (see nucleus/documentation/index.html#license for more info)
+ */
+/**
+ * Class used to represent a collection of e-mail addresses, to which a
+ * message can be sent (e.g. comment or karma vote notification).
+ *
+ * @license http://nucleuscms.org/license.txt GNU General Public License
+ * @copyright Copyright (C) 2002-2007 The Nucleus Group
+ * @version $Id: NOTIFICATION.php,v 1.4 2007-03-27 12:13:56 kimitake Exp $
+ * $NucleusJP: NOTIFICATION.php,v 1.7 2007/02/04 06:28:46 kimitake Exp $
+ */
+class NOTIFICATION {
+
+       // array of addresses that need to get a notification
+       var $addresses = array();
+
+       /**
+         * takes one string as argument, containing multiple e-mail addresses
+         * separated by semicolons
+         * eg: site@demuynck.org;nucleus@demuynck.org;foo@bar.com
+         */
+       function NOTIFICATION($addresses) {
+               $this->addresses = explode(';' , $addresses);
+       }
+
+       /**
+         * returns true if all addresses are valid
+         */
+       function validAddresses() {
+               foreach ( $this->addresses as $address ) {
+                       if (!isValidMailAddress(trim($address)))
+                               return 0;
+               }
+               return 1;
+       }
+
+       /**
+         * Sends email messages to all the email addresses
+         */
+       function notify($title, $message, $from) {
+               global $member;
+
+               foreach ( $this->addresses as $address ) {
+                       $address = trim($address);
+
+                       if (!$address)
+                               continue;
+
+                       // don't send messages to yourself
+                       if ($member->isLoggedIn() && ($member->getEmail() == $address))
+                               continue;
+
+                       @mb_language('ja');
+                       @mb_internal_encoding(_CHARSET);
+                       @mb_send_mail($address, $title, $message, "From: ". $from);
+               }
+       }
+}
+
+?>
\ No newline at end of file
index a1efc4b..76acbdb 100755 (executable)
-<?php\r
-/**\r
-  * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/) \r
-  * Copyright (C) 2002-2005 The Nucleus Group\r
-  *\r
-  * This program is free software; you can redistribute it and/or\r
-  * modify it under the terms of the GNU General Public License\r
-  * as published by the Free Software Foundation; either version 2\r
-  * of the License, or (at your option) any later version.\r
-  * (see nucleus/documentation/index.html#license for more info)\r
-  *\r
-  * $Id: PAGEFACTORY.php,v 1.3 2005-03-16 08:10:35 kimitake Exp $\r
-  * $NucleusJP$\r
-  */\r
-\r
-/**\r
- * The formfactory class can be used to insert add/edit item forms into \r
- * admin area, bookmarklet, skins or any other places where such a form\r
- * might be needed\r
- */\r
-class PAGEFACTORY extends BaseActions {\r
-\r
-       // ref to the blog object for which an add:edit form is created\r
-       var $blog;\r
-       \r
-       // allowed actions (for parser)\r
-       var $actions;\r
-       \r
-       // allowed types of forms (bookmarklet/admin)\r
-       var $allowedTypes;\r
-       var $type;              // one of the types in $allowedTypes\r
-       \r
-       // 'add' or 'edit'\r
-       var $method;\r
-       \r
-       // info to fill out in the form (e.g. catid, itemid, ...)\r
-       var $variables;\r
-\r
-       /**\r
-        * creates a new PAGEFACTORY object\r
-        */\r
-       function PAGEFACTORY($blogid) {\r
-               // call constructor of superclass first\r
-               $this->BaseActions();                   \r
-               \r
-               global $manager;\r
-               $this->blog =& $manager->getBlog($blogid);\r
-               \r
-               // TODO: move the definition of actions to the createXForm \r
-               // methods\r
-               $this->actions = Array(\r
-                       'actionurl', \r
-                       'title',\r
-                       'body',\r
-                       'more',\r
-                       'blogid',\r
-                       'bloglink',\r
-                       'blogname',\r
-                       'authorname',\r
-                       'checkedonval',\r
-                       'helplink',\r
-                       'currenttime',\r
-                       'itemtime',\r
-                       'init',\r
-                       'text',\r
-                       'jsinput',\r
-                       'jsbuttonbar',\r
-                       'categories',\r
-                       'contents',\r
-                       'ifblogsetting',\r
-                       'ifitemproperty',\r
-                       'else',\r
-                       'endif',\r
-                       'pluginextras',\r
-                       'itemoptions',\r
-                       'extrahead',\r
-                       'ticket'\r
-               );\r
-               \r
-               // TODO: maybe add 'skin' later on?\r
-               // TODO: maybe add other pages from admin area\r
-               $this->allowedTypes = Array('bookmarklet','admin');     \r
-       }\r
-\r
-       /**\r
-        * creates a "add item" form for a given type of page\r
-        *\r
-        * @param type\r
-        *              'admin' or 'bookmarklet' \r
-        */\r
-       function createAddForm($type, $contents = array()) {\r
-               if (!in_array($type, $this->allowedTypes))\r
-                       return;\r
-               $this->type = $type;\r
-               $this->method = 'add';\r
-               \r
-               global $manager;\r
-               $manager->notify('PreAddItemForm', array('contents' => &$contents, 'blog' => &$this->blog));\r
-               \r
-               $this->createForm($contents);\r
-       }\r
-       \r
-       /**\r
-        * creates a "add item" form for a given type of page\r
-        *\r
-        * @param type\r
-        *              'admin' or 'bookmarklet' \r
-        * @param contents\r
-        *              An associative array\r
-        *                      'author' => author\r
-        *                      '' => \r
-        */\r
-       function createEditForm($type, $contents) {\r
-               if (!in_array($type, $this->allowedTypes))\r
-                       return;\r
-               $this->type = $type;\r
-               $this->method = 'edit';\r
-               $this->createForm($contents);\r
-       }\r
-       \r
-       /**\r
-        * (private) creates a form for a given type of page\r
-        */\r
-       function createForm($contents) {\r
-               // save contents\r
-               $this->variables = $contents;\r
-               \r
-               // get template to use\r
-               $template = $this->getTemplateFor($this->type);\r
-               \r
-               // use the PARSER engine to parse that template\r
-               $parser =& new PARSER($this->actions, $this);\r
-               $parser->parse($template);\r
-       }\r
-       \r
-       /**\r
-        * returns an appropriate template\r
-        */\r
-       function getTemplateFor($type) {\r
-               global $DIR_LIBS;\r
-               \r
-               $filename = $DIR_LIBS . 'include/' . $this->type . '-' . $this->method . '.template';\r
-               \r
-               if (!file_exists($filename)) \r
-                       return '';\r
-\r
-               $fsize = filesize($filename);\r
-               if ($fsize <= 0)\r
-                       return '';\r
-                       \r
-               // read file and return it\r
-               $fd = fopen ($filename, 'r');\r
-               $contents = fread ($fd, $fsize);\r
-               fclose ($fd);\r
-               \r
-               return $contents;\r
-               \r
-       }\r
-       \r
-       // create category dropdown box\r
-       function parse_categories($startidx = 0) {\r
-                       if ($this->variables['catid']) \r
-                               $catid = $this->variables['catid'];                             // on edit item\r
-                       else\r
-                               $catid = $this->blog->getDefaultCategory();             // on add item\r
-                       \r
-                       ADMIN::selectBlogCategory('catid',$catid,$startidx,1,$this->blog->getID());\r
-       }\r
-       \r
-       function parse_blogid() {\r
-               echo $this->blog->getID();\r
-       }\r
-       \r
-       function parse_blogname() {\r
-               echo $this->blog->getName();\r
-       }\r
-       \r
-       function parse_bloglink() {\r
-               echo '<a href="'.htmlspecialchars($this->blog->getURL()).'">'.$this->blog->getName().'</a>';\r
-       }\r
-       \r
-       function parse_authorname() {\r
-               // don't use on add item?\r
-               global $member;\r
-               echo $member->getDisplayName();\r
-       }\r
-\r
-       function parse_title() {\r
-               echo $this->contents['title'];\r
-       }\r
-\r
-       /**\r
-        * Indicates the start of a conditional block of data. It will be added to\r
-        * the output only if the blogsetting with the given name equals the \r
-        * given value (default for value = 1 = true)\r
-        *\r
-        * the name of the blogsetting is the column name in the nucleus_blog table\r
-        *\r
-        * the conditional block ends with an <endif> var\r
-        */\r
-       function parse_ifblogsetting($name,$value=1) {\r
-               $this->_addIfCondition(($this->blog->getSetting($name) == $value));\r
-       }\r
-       \r
-       function parse_ifitemproperty($name,$value=1) {\r
-               $this->_addIfCondition(($this->variables[$name] == $value));\r
-       }\r
-       \r
-       function parse_helplink($topic) {\r
-               help($topic);\r
-       }\r
-       \r
-       // for future items\r
-       function parse_currenttime($what) {\r
-               $nu = getdate($this->blog->getCorrectTime());\r
-               echo $nu[$what];\r
-       }\r
-       \r
-       // date change on edit item\r
-       function parse_itemtime($what) {\r
-               $itemtime = getdate($this->variables['timestamp']);\r
-               echo $itemtime[$what];\r
-       }\r
-       \r
-       // some init stuff for all forms\r
-       function parse_init() {\r
-               $authorid = ($this->method == 'edit') ? $this->variables['authorid'] : '';\r
-               $this->blog->insertJavaScriptInfo($authorid);           \r
-       }\r
-       \r
-       // on bookmarklets only: insert extra html header information (by plugins)\r
-       function parse_extrahead() {\r
-               global $manager;\r
-               \r
-               $extrahead = '';\r
-               \r
-               $manager->notify(\r
-                       'BookmarkletExtraHead',\r
-                       array(\r
-                               'extrahead' => &$extrahead\r
-                       )\r
-               );\r
-               \r
-               echo $extrahead;\r
-       }\r
-       \r
-       // inserts some localized text\r
-       function parse_text($which) {\r
-               // constant($which) only available from 4.0.4 :(\r
-               if (defined($which)) {  \r
-                       eval("echo $which;");\r
-               } else {\r
-                       echo $which;    // this way we see where definitions are missing\r
-               }\r
-               \r
-       }\r
-       \r
-       function parse_contents($which) {\r
-               echo htmlspecialchars($this->variables[$which]);\r
-       }\r
-       \r
-       function parse_checkedonval($value, $name) {\r
-               if ($this->variables[$name] == $value)\r
-                       echo "checked='checked'";\r
-       }\r
-       \r
-       // extra javascript for input and textarea fields\r
-       function parse_jsinput($which) {\r
-               global $CONF;\r
-       ?>\r
-                       name="<?php echo $which?>" \r
-                       id="input<?php echo $which?>" \r
-       <?php\r
-               if ($CONF['DisableJsTools'] != 1) {\r
-       ?>\r
-                       onkeyup="storeCaret(this); updPreview('<?php echo $which?>');"\r
-                       onclick="storeCaret(this);"\r
-                       onselect="storeCaret(this);" \r
-\r
-       <?php           \r
-               } \r
-               \r
-               if ($CONF['DisableJsTools'] == 0) {\r
-       ?>\r
-                   onkeypress="shortCuts();"                   \r
-       <?php           }\r
-       }\r
-       \r
-       // shows the javascript button bar\r
-       function parse_jsbuttonbar($extrabuttons = "") {\r
-               global $CONF;\r
-               switch($CONF['DisableJsTools']) {\r
-\r
-                       case "0":       \r
-                               echo '<div class="jsbuttonbar">';\r
-\r
-                                       $this->_jsbutton('cut','cutThis()',_ADD_CUT_TT . " (Ctrl + X)");\r
-                                       $this->_jsbutton('copy','copyThis()',_ADD_COPY_TT . " (Ctrl + C)");\r
-                                       $this->_jsbutton('paste','pasteThis()',_ADD_PASTE_TT . " (Ctrl + V)");\r
-                                       $this->_jsbuttonspacer();\r
-                                       $this->_jsbutton('bold',"boldThis()",_ADD_BOLD_TT ." (Ctrl + Shift + B)");\r
-                                       $this->_jsbutton('italic',"italicThis()",_ADD_ITALIC_TT ." (Ctrl + Shift + I)");\r
-                                       $this->_jsbutton('link',"ahrefThis()",_ADD_HREF_TT ." (Ctrl + Shift + A)");\r
-                                       $this->_jsbuttonspacer();                                       \r
-                                       $this->_jsbutton('alignleft',"alignleftThis()",_ADD_ALIGNLEFT_TT);\r
-                                       $this->_jsbutton('alignright',"alignrightThis()",_ADD_ALIGNRIGHT_TT);\r
-                                       $this->_jsbutton('aligncenter',"aligncenterThis()",_ADD_ALIGNCENTER_TT);\r
-                                       $this->_jsbuttonspacer();                                       \r
-                                       $this->_jsbutton('left',"leftThis()",_ADD_LEFT_TT);\r
-                                       $this->_jsbutton('right',"rightThis()",_ADD_RIGHT_TT);\r
-\r
-                               \r
-                                       if ($extrabuttons) {\r
-                                               $btns = explode('+',$extrabuttons);\r
-                                               $this->_jsbuttonspacer();\r
-                                               foreach ($btns as $button) {\r
-                                                       switch($button) {\r
-                                                               case "media":\r
-                                                                       $this->_jsbutton('media',"addMedia()",_ADD_MEDIA_TT .   " (Ctrl + Shift + M)");                                                 \r
-                                                                       break;\r
-                                                               case "preview":\r
-                                                                       $this->_jsbutton('preview',"showedit()",_ADD_PREVIEW_TT);\r
-                                                                       break;\r
-                                                       }\r
-                                               }\r
-                                       } \r
-                                       \r
-                               echo '</div>';\r
-                               \r
-                               break;\r
-                       case "2":\r
-                               echo '<div class="jsbuttonbar">';\r
-\r
-                                       $this->_jsbutton('bold',"boldThis()",'');\r
-                                       $this->_jsbutton('italic',"italicThis()",'');\r
-                                       $this->_jsbutton('link',"ahrefThis()",'');\r
-                                       $this->_jsbuttonspacer();                                                                               \r
-                                       $this->_jsbutton('alignleft',"alignleftThis()",_ADD_ALIGNLEFT_TT);\r
-                                       $this->_jsbutton('alignright',"alignrightThis()",_ADD_ALIGNRIGHT_TT);\r
-                                       $this->_jsbutton('aligncenter',"aligncenterThis()",_ADD_ALIGNCENTER_TT);\r
-                                       $this->_jsbuttonspacer();                                       \r
-                                       $this->_jsbutton('left',"leftThis()",_ADD_LEFT_TT);\r
-                                       $this->_jsbutton('right',"rightThis()",_ADD_RIGHT_TT);\r
-                                       \r
-\r
-                                       if ($extrabuttons) {\r
-                                               $btns = explode('+',$extrabuttons);\r
-                                               $this->_jsbuttonspacer();\r
-                                               foreach ($btns as $button) {\r
-                                                       switch($button) {\r
-                                                               case "media":\r
-                                                                       $this->_jsbutton('media',"addMedia()",'');                                                      \r
-                                                                       break;\r
-                                                       }\r
-                                               }\r
-                                       } \r
-                                       \r
-                               echo '</div>';\r
-                               \r
-                               break;                  \r
-               }\r
-       }\r
-       \r
-       /**\r
-        * Allows plugins to add their own custom fields\r
-        */\r
-       function parse_pluginextras() {\r
-               global $manager;\r
-                       \r
-               switch ($this->method) {\r
-                       case 'add':\r
-                               $manager->notify('AddItemFormExtras', \r
-                                               array(\r
-                                                       'blog' => &$this->blog\r
-                                               )\r
-                               );\r
-                               break;\r
-                       case 'edit':\r
-                               $manager->notify('EditItemFormExtras', \r
-                                               array(\r
-                                                       'variables' => $this->variables,\r
-                                                       'blog' => &$this->blog,\r
-                                                       'itemid' => $this->variables['itemid']\r
-                                               )\r
-                               );\r
-                               break;\r
-               }\r
-       }\r
-       \r
-       /**\r
-        * Adds the itemOptions of a plugin to a page\r
-        * @author TeRanEX\r
-        */\r
-    function parse_itemoptions() {\r
-               global $itemid;\r
-               ADMIN::_insertPluginOptions('item', $itemid);\r
-    }\r
-    \r
-    function parse_ticket() {\r
-       global $manager;\r
-       $manager->addTicketHidden();\r
-    }\r
-       \r
-       /**\r
-        * convenience method\r
-        */\r
-       function _jsbutton($type, $code ,$tooltip) {\r
-       ?>\r
-                       <span class="jsbutton"\r
-                               onmouseover="BtnHighlight(this);" \r
-                               onmouseout="BtnNormal(this);" \r
-                               onclick="<?php echo $code?>" >                  \r
-                               <img src="images/button-<?php echo $type?>.gif" alt="<?php echo $tooltip?>" width="16" height="16"/>\r
-                       </span>                         \r
-       <?php   }\r
-       \r
-       function _jsbuttonspacer() {\r
-               echo '<span class="jsbuttonspacer"></span>';\r
-       }\r
-       \r
-}\r
\r
- ?>\r
+<?php
+/*
+ * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/)
+ * Copyright (C) 2002-2007 The Nucleus Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * (see nucleus/documentation/index.html#license for more info)
+ */
+/**
+ * @license http://nucleuscms.org/license.txt GNU General Public License
+ * @copyright Copyright (C) 2002-2007 The Nucleus Group
+ * @version $Id: PAGEFACTORY.php,v 1.4 2007-03-27 12:13:56 kimitake Exp $
+ * $NucleusJP: PAGEFACTORY.php,v 1.8 2007/03/22 03:30:14 kmorimatsu Exp $
+ */
+
+/**
+ * The formfactory class can be used to insert add/edit item forms into
+ * admin area, bookmarklet, skins or any other places where such a form
+ * might be needed
+ */
+class PAGEFACTORY extends BaseActions {
+
+       // ref to the blog object for which an add:edit form is created
+       var $blog;
+
+       // allowed actions (for parser)
+       var $actions;
+
+       // allowed types of forms (bookmarklet/admin)
+       var $allowedTypes;
+       var $type;              // one of the types in $allowedTypes
+
+       // 'add' or 'edit'
+       var $method;
+
+       // info to fill out in the form (e.g. catid, itemid, ...)
+       var $variables;
+
+       /**
+        * creates a new PAGEFACTORY object
+        */
+       function PAGEFACTORY($blogid) {
+               // call constructor of superclass first
+               $this->BaseActions();
+
+               global $manager;
+               $this->blog =& $manager->getBlog($blogid);
+
+               // TODO: move the definition of actions to the createXForm
+               // methods
+               $this->actions = Array(
+                       'actionurl',
+                       'title',
+                       'body',
+                       'more',
+                       'blogid',
+                       'bloglink',
+                       'blogname',
+                       'authorname',
+                       'checkedonval',
+                       'helplink',
+                       'currenttime',
+                       'itemtime',
+                       'init',
+                       'text',
+                       'jsinput',
+                       'jsbuttonbar',
+                       'categories',
+                       'contents',
+                       'ifblogsetting',
+                       'ifitemproperty',
+                       'else',
+                       'endif',
+                       'pluginextras',
+                       'itemoptions',
+                       'extrahead',
+                       'ticket'
+               );
+
+               // TODO: maybe add 'skin' later on?
+               // TODO: maybe add other pages from admin area
+               $this->allowedTypes = Array('bookmarklet','admin');
+       }
+
+       /**
+        * creates a "add item" form for a given type of page
+        *
+        * @param type
+        *              'admin' or 'bookmarklet'
+        */
+       function createAddForm($type, $contents = array()) {
+               if (!in_array($type, $this->allowedTypes))
+                       return;
+               $this->type = $type;
+               $this->method = 'add';
+
+               global $manager;
+               $manager->notify('PreAddItemForm', array('contents' => &$contents, 'blog' => &$this->blog));
+
+               $this->createForm($contents);
+       }
+
+       /**
+        * creates a "add item" form for a given type of page
+        *
+        * @param type
+        *              'admin' or 'bookmarklet'
+        * @param contents
+        *              An associative array
+        *                      'author' => author
+        *                      '' =>
+        */
+       function createEditForm($type, $contents) {
+               if (!in_array($type, $this->allowedTypes))
+                       return;
+               $this->type = $type;
+               $this->method = 'edit';
+               $this->createForm($contents);
+       }
+
+       /**
+        * (private) creates a form for a given type of page
+        */
+       function createForm($contents) {
+               // save contents
+               $this->variables = $contents;
+
+               // get template to use
+               $template = $this->getTemplateFor($this->type);
+
+               // use the PARSER engine to parse that template
+               $parser =& new PARSER($this->actions, $this);
+               $parser->parse($template);
+       }
+
+       /**
+        * returns an appropriate template
+        */
+       function getTemplateFor($type) {
+               global $DIR_LIBS;
+
+               $filename = $DIR_LIBS . 'include/' . $this->type . '-' . $this->method . '.template';
+
+               if (!file_exists($filename))
+                       return '';
+
+               $fsize = filesize($filename);
+               if ($fsize <= 0)
+                       return '';
+
+               // read file and return it
+               $fd = fopen ($filename, 'r');
+               $contents = fread ($fd, $fsize);
+               fclose ($fd);
+
+               return $contents;
+
+       }
+
+       // create category dropdown box
+       function parse_categories($startidx = 0) {
+                       if ($this->variables['catid'])
+                               $catid = $this->variables['catid'];                             // on edit item
+                       else
+                               $catid = $this->blog->getDefaultCategory();             // on add item
+
+                       ADMIN::selectBlogCategory('catid',$catid,$startidx,1,$this->blog->getID());
+       }
+
+       function parse_blogid() {
+               echo $this->blog->getID();
+       }
+
+       function parse_blogname() {
+               echo $this->blog->getName();
+       }
+
+       function parse_bloglink() {
+               echo '<a href="'.htmlspecialchars($this->blog->getURL()).'">'.$this->blog->getName().'</a>';
+       }
+
+       function parse_authorname() {
+               // don't use on add item?
+               global $member;
+               echo $member->getDisplayName();
+       }
+
+       function parse_title() {
+               echo $this->contents['title'];
+       }
+
+       /**
+        * Indicates the start of a conditional block of data. It will be added to
+        * the output only if the blogsetting with the given name equals the
+        * given value (default for value = 1 = true)
+        *
+        * the name of the blogsetting is the column name in the nucleus_blog table
+        *
+        * the conditional block ends with an <endif> var
+        */
+       function parse_ifblogsetting($name,$value=1) {
+               $this->_addIfCondition(($this->blog->getSetting($name) == $value));
+       }
+
+       function parse_ifitemproperty($name,$value=1) {
+               $this->_addIfCondition(($this->variables[$name] == $value));
+       }
+
+       function parse_helplink($topic) {
+               help($topic);
+       }
+
+       // for future items
+       function parse_currenttime($what) {
+               $nu = getdate($this->blog->getCorrectTime());
+               echo $nu[$what];
+       }
+
+       // date change on edit item
+       function parse_itemtime($what) {
+               $itemtime = getdate($this->variables['timestamp']);
+               echo $itemtime[$what];
+       }
+
+       // some init stuff for all forms
+       function parse_init() {
+               $authorid = ($this->method == 'edit') ? $this->variables['authorid'] : '';
+               $this->blog->insertJavaScriptInfo($authorid);
+       }
+
+       // on bookmarklets only: insert extra html header information (by plugins)
+       function parse_extrahead() {
+               global $manager;
+
+               $extrahead = '';
+
+               $manager->notify(
+                       'BookmarkletExtraHead',
+                       array(
+                               'extrahead' => &$extrahead
+                       )
+               );
+
+               echo $extrahead;
+       }
+
+       // inserts some localized text
+       function parse_text($which) {
+               // constant($which) only available from 4.0.4 :(
+               if (defined($which)) {
+                       eval("echo $which;");
+               } else {
+                       echo $which;    // this way we see where definitions are missing
+               }
+
+       }
+
+       function parse_contents($which) {
+               echo htmlspecialchars($this->variables[$which],ENT_QUOTES);
+       }
+
+       function parse_checkedonval($value, $name) {
+               if ($this->variables[$name] == $value)
+                       echo "checked='checked'";
+       }
+
+       // extra javascript for input and textarea fields
+       function parse_jsinput($which) {
+               global $CONF;
+       ?>
+                       name="<?php echo $which?>"
+                       id="input<?php echo $which?>"
+       <?php
+               if ($CONF['DisableJsTools'] != 1) {
+       ?>
+                       onkeyup="storeCaret(this); updPreview('<?php echo $which?>'); doMonitor();"
+                       onclick="storeCaret(this);"
+                       onselect="storeCaret(this);"
+
+       <?php
+               }
+               else if ($CONF['DisableJsTools'] == 0) {
+       ?>
+                       onkeyup="doMonitor();"
+                       onkeypress="shortCuts();"
+       <?php
+               }
+               else {
+       ?>
+                       onkeyup="doMonitor();"
+       <?php
+               }
+       }
+
+       // shows the javascript button bar
+       function parse_jsbuttonbar($extrabuttons = "") {
+               global $CONF;
+               switch($CONF['DisableJsTools']) {
+
+                       case "0":
+                               echo '<div class="jsbuttonbar">';
+
+                                       $this->_jsbutton('cut','cutThis()',_ADD_CUT_TT . " (Ctrl + X)");
+                                       $this->_jsbutton('copy','copyThis()',_ADD_COPY_TT . " (Ctrl + C)");
+                                       $this->_jsbutton('paste','pasteThis()',_ADD_PASTE_TT . " (Ctrl + V)");
+                                       $this->_jsbuttonspacer();
+                                       $this->_jsbutton('bold',"boldThis()",_ADD_BOLD_TT ." (Ctrl + Shift + B)");
+                                       $this->_jsbutton('italic',"italicThis()",_ADD_ITALIC_TT ." (Ctrl + Shift + I)");
+                                       $this->_jsbutton('link',"ahrefThis()",_ADD_HREF_TT ." (Ctrl + Shift + A)");
+                                       $this->_jsbuttonspacer();
+                                       $this->_jsbutton('alignleft',"alignleftThis()",_ADD_ALIGNLEFT_TT);
+                                       $this->_jsbutton('alignright',"alignrightThis()",_ADD_ALIGNRIGHT_TT);
+                                       $this->_jsbutton('aligncenter',"aligncenterThis()",_ADD_ALIGNCENTER_TT);
+                                       $this->_jsbuttonspacer();
+                                       $this->_jsbutton('left',"leftThis()",_ADD_LEFT_TT);
+                                       $this->_jsbutton('right',"rightThis()",_ADD_RIGHT_TT);
+
+
+                                       if ($extrabuttons) {
+                                               $btns = explode('+',$extrabuttons);
+                                               $this->_jsbuttonspacer();
+                                               foreach ($btns as $button) {
+                                                       switch($button) {
+                                                               case "media":
+                                                                       $this->_jsbutton('media',"addMedia()",_ADD_MEDIA_TT .   " (Ctrl + Shift + M)");
+                                                                       break;
+                                                               case "preview":
+                                                                       $this->_jsbutton('preview',"showedit()",_ADD_PREVIEW_TT);
+                                                                       break;
+                                                       }
+                                               }
+                                       }
+
+                               echo '</div>';
+
+                               break;
+                       case "2":
+                               echo '<div class="jsbuttonbar">';
+
+                                       $this->_jsbutton('bold',"boldThis()",'');
+                                       $this->_jsbutton('italic',"italicThis()",'');
+                                       $this->_jsbutton('link',"ahrefThis()",'');
+                                       $this->_jsbuttonspacer();
+                                       $this->_jsbutton('alignleft',"alignleftThis()",_ADD_ALIGNLEFT_TT);
+                                       $this->_jsbutton('alignright',"alignrightThis()",_ADD_ALIGNRIGHT_TT);
+                                       $this->_jsbutton('aligncenter',"aligncenterThis()",_ADD_ALIGNCENTER_TT);
+                                       $this->_jsbuttonspacer();
+                                       $this->_jsbutton('left',"leftThis()",_ADD_LEFT_TT);
+                                       $this->_jsbutton('right',"rightThis()",_ADD_RIGHT_TT);
+
+
+                                       if ($extrabuttons) {
+                                               $btns = explode('+',$extrabuttons);
+                                               $this->_jsbuttonspacer();
+                                               foreach ($btns as $button) {
+                                                       switch($button) {
+                                                               case "media":
+                                                                       $this->_jsbutton('media',"addMedia()",'');
+                                                                       break;
+                                                       }
+                                               }
+                                       }
+
+                               echo '</div>';
+
+                               break;
+               }
+       }
+
+       /**
+        * Allows plugins to add their own custom fields
+        */
+       function parse_pluginextras() {
+               global $manager;
+
+               switch ($this->method) {
+                       case 'add':
+                               $manager->notify('AddItemFormExtras',
+                                               array(
+                                                       'blog' => &$this->blog
+                                               )
+                               );
+                               break;
+                       case 'edit':
+                               $manager->notify('EditItemFormExtras',
+                                               array(
+                                                       'variables' => $this->variables,
+                                                       'blog' => &$this->blog,
+                                                       'itemid' => $this->variables['itemid']
+                                               )
+                               );
+                               break;
+               }
+       }
+
+       /**
+        * Adds the itemOptions of a plugin to a page
+        * @author TeRanEX
+        */
+       function parse_itemoptions() {
+               global $itemid;
+               ADMIN::_insertPluginOptions('item', $itemid);
+       }
+
+       function parse_ticket() {
+               global $manager;
+               $manager->addTicketHidden();
+       }
+
+       /**
+        * convenience method
+        */
+       function _jsbutton($type, $code ,$tooltip) {
+       ?>
+                       <span class="jsbutton"
+                               onmouseover="BtnHighlight(this);"
+                               onmouseout="BtnNormal(this);"
+                               onclick="<?php echo $code?>" >
+                               <img src="images/button-<?php echo $type?>.gif" alt="<?php echo $tooltip?>" width="16" height="16"/>
+                       </span>
+       <?php   }
+
+       function _jsbuttonspacer() {
+               echo '<span class="jsbuttonspacer"></span>';
+       }
+
+}
+
+ ?>
\ No newline at end of file
index 5703252..2540635 100755 (executable)
-<?php\r
-/**\r
-  * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/) \r
-  * Copyright (C) 2002-2005 The Nucleus Group\r
-  *\r
-  * This program is free software; you can redistribute it and/or\r
-  * modify it under the terms of the GNU General Public License\r
-  * as published by the Free Software Foundation; either version 2\r
-  * of the License, or (at your option) any later version.\r
-  * (see nucleus/documentation/index.html#license for more info)\r
-  *\r
-  * $Id: PARSER.php,v 1.3 2005-03-16 08:10:35 kimitake Exp $\r
-  * $NucleusJP: PARSER.php,v 1.3 2005/03/12 06:19:05 kimitake Exp $\r
-  */\r
\r
-/**\r
- * This is the parser class of Nucleus. It is used for various things (skin parsing,\r
- * form generation, ...)\r
- */\r
-class PARSER {\r
-\r
-       // array with the names of all allowed actions\r
-       var $actions;\r
-       \r
-       // reference to actions handler\r
-       var $handler;\r
-       \r
-       // delimiters that can be used for skin/templatevars\r
-       var $delim;\r
-       \r
-       // parameter delimiter (to separate skinvar params)\r
-       var $pdelim;\r
-       \r
-       // usually set to 0. When set to 1, all skinvars are allowed regardless of $actions\r
-       var $norestrictions;\r
-       \r
-       /**\r
-        * Creates a new parser object with the given allowed actions \r
-        * and the given handler\r
-        *\r
-        * @param $allowedActions array\r
-        * @param $handler class object with functions for each action (reference)\r
-        * @param $delim optional delimiter\r
-        * @param $paramdelim optional parameterdelimiter        \r
-        */\r
-       function PARSER($allowedActions, &$handler, $delim = '(<%|%>)', $pdelim = ',') {\r
-               $this->actions = $allowedActions;\r
-               $this->handler =& $handler;\r
-               $this->delim = $delim;\r
-               $this->pdelim = $pdelim;\r
-               $this->norestrictions = 0;      // set this to 1 to disable checking for allowedActions\r
-       }\r
-       \r
-       /**\r
-        * Parses the given contents and outputs it\r
-        */\r
-       function parse(&$contents) {\r
-       \r
-               $pieces = preg_split('/'.$this->delim.'/',$contents);\r
-               \r
-               $maxidx = sizeof($pieces);\r
-               for ($idx = 0;$idx<$maxidx;$idx++) {\r
-                       echo $pieces[$idx];             \r
-                       $idx++;\r
-                       $this->doAction($pieces[$idx]);\r
-               }\r
-       }\r
-       \r
-\r
-       /**\r
-         * handle an action \r
-         */\r
-       function doAction($action) {\r
-               global $manager;\r
-\r
-               if (!$action) return;\r
-               \r
-               // split into action name + arguments\r
-               if (strstr($action,'(')) {\r
-                       $paramStartPos = strpos($action, '(');\r
-                       $params = substr($action, $paramStartPos + 1, strlen($action) - $paramStartPos - 2);\r
-                       $action = substr($action, 0, $paramStartPos);\r
-                       $params = explode ($this->pdelim, $params);\r
-                       \r
-                       // trim parameters \r
-                       // for PHP versions lower than 4.0.6:\r
-                       //   - add // before '$params = ...' \r
-                       //   - remove // before 'foreach'\r
-                       $params = array_map('trim',$params);\r
-                       // foreach ($params as $key => $value) { $params[$key] = trim($value); }                        \r
-               } else {\r
-                       // no parameters\r
-                       $params = array();\r
-               }\r
-       \r
-               $actionlc = strtolower($action);\r
-               \r
-               // skip execution of skinvars while inside an if condition which hides this part of the page\r
-               if (!$this->handler->if_currentlevel && ($actionlc != 'else') && ($actionlc != 'endif') && (substr($actionlc,0,2) != 'if'))\r
-                       return;\r
-       \r
-               if (in_array($actionlc, $this->actions) || $this->norestrictions ) {\r
-                       // when using PHP versions lower than 4.0.5, uncomment the line before\r
-                       // and comment the call_user_func_array call\r
-                       //$this->call_using_array($action, $this->handler, $params);\r
-                       call_user_func_array(array(&$this->handler,'parse_' . $actionlc), $params);\r
-               } else {\r
-                       // redirect to plugin action if possible\r
-                       if (in_array('plugin', $this->actions) && $manager->pluginInstalled('NP_'.$action))\r
-                               $this->doAction('plugin('.$action.$this->pdelim.implode($this->pdelim,$params).')');\r
-                       else\r
-                               echo '<b>DISALLOWED (' , $action , ')</b>';\r
-               }\r
-               \r
-       }\r
-       \r
-       /**\r
-         * Calls a method using an array of parameters (for use with PHP versions lower than 4.0.5)\r
-         * ( = call_user_func_array() function )\r
-         */\r
-       function call_using_array($methodname, &$handler, $paramarray) {\r
-\r
-               $methodname = 'parse_' . $methodname;\r
-               \r
-               if (!method_exists($handler, $methodname)) {\r
-                       return;\r
-               }\r
-\r
-               $command = 'call_user_func(array(&$handler,$methodname)';\r
-               for ($i = 0; $i<count($paramarray); $i++)\r
-                       $command .= ',$paramarray[' . $i . ']';\r
-               $command .= ');';\r
-               eval($command); // execute the correct method\r
-       }\r
-       \r
-       function setProperty($property, $value) {\r
-               global $manager;\r
-               $manager->setParserProperty($property, $value);\r
-       }\r
-       \r
-       function getProperty($name) {\r
-               global $manager;\r
-               return $manager->getParserProperty($name);\r
-       }\r
-       \r
-       \r
-}\r
-\r
-/**\r
- * This class contains parse actions that are available in all ACTION classes\r
- * e.g. include, phpinclude, parsedinclude, skinfile, ...\r
- *\r
- * It should never be used on it's own\r
- */\r
-class BaseActions {\r
-       \r
-       // depth level for includes (max. level is 3)\r
-       var $level;\r
-       \r
-       // array of evaluated conditions (true/false). The element at the end is the one for the most nested\r
-       // if block.\r
-       var $if_conditions;\r
-       \r
-       // at all times, can be evaluated to either true if the current block needs to be displayed. This \r
-       // variable is used to decide to skip skinvars in parts that will never be outputted.\r
-       var $if_currentlevel;\r
-       \r
-       // contains a search string with keywords that need to be highlighted. These get parsed into $aHighlight\r
-       var $strHighlight;\r
-       \r
-       // array of keywords that need to be highlighted in search results (see the highlight() \r
-       // and parseHighlight() methods)\r
-       var $aHighlight;\r
-       \r
-\r
-       // reference to the parser object that is using this object as actions-handler\r
-\r
-       var $parser;\r
-       \r
-\r
-       function BaseActions() {\r
-               $this->level = 0; \r
-               \r
-               // if nesting level\r
-               $this->if_conditions = array(); // array on which condition values are pushed/popped\r
-               $this->if_currentlevel = 1;             // 1 = current level is displayed; 0 = current level not displayed\r
-\r
-               // highlights           \r
-               $this->strHighlight = '';                       // full highlight\r
-               $this->aHighlight = array();            // parsed highlight\r
-               \r
-       }\r
-\r
-       // include file (no parsing of php)\r
-       function parse_include($filename) {\r
-               @readfile($this->getIncludeFileName($filename));\r
-       }\r
-       \r
-       // php-include file \r
-       function parse_phpinclude($filename) {\r
-               includephp($this->getIncludeFileName($filename));\r
-       }       \r
-       // parsed include\r
-       function parse_parsedinclude($filename) {\r
-               // check current level\r
-               if ($this->level > 3) return;   // max. depth reached (avoid endless loop)\r
-               $filename = $this->getIncludeFileName($filename);\r
-               if (!file_exists($filename)) return '';\r
-               \r
-               $fsize = filesize($filename);\r
-               \r
-               // nothing to include\r
-               if ($fsize <= 0)\r
-                       return;\r
-               \r
-               $this->level = $this->level + 1;\r
-               \r
-               // read file \r
-               $fd = fopen ($filename, 'r');\r
-               $contents = fread ($fd, $fsize);\r
-               fclose ($fd);           \r
-               \r
-               // parse file contents\r
-               $this->parser->parse($contents);\r
-               \r
-               $this->level = $this->level - 1;                \r
-       }\r
-       \r
-       /**\r
-        * Returns the correct location of the file to be included, according to\r
-        * parser properties\r
-        *\r
-        * IF IncludeMode = 'skindir' => use skindir\r
-        */\r
-       function getIncludeFileName($filename) {\r
-               // leave absolute filenames and http urls as they are\r
-               if (\r
-                               (substr($filename,0,1) == '/')\r
-                       ||      (substr($filename,0,7) == 'http://')\r
-                       ||      (substr($filename,0,6) == 'ftp://')                     \r
-                       )\r
-                       return $filename;\r
-       \r
-               $filename = PARSER::getProperty('IncludePrefix') . $filename;\r
-               if (PARSER::getProperty('IncludeMode') == 'skindir') {\r
-                       global $DIR_SKINS;\r
-                       return $DIR_SKINS . $filename;\r
-               } else {\r
-                       return $filename;\r
-               }\r
-       }\r
-       \r
-       /**\r
-        * Inserts an url relative to the skindir (useful when doing import/export)\r
-        *\r
-        * e.g. <skinfile(default/myfile.sth)>\r
-        */\r
-       function parse_skinfile($filename) {\r
-               global $CONF;\r
-               \r
-               echo $CONF['SkinsURL'] . PARSER::getProperty('IncludePrefix') . $filename;\r
-       }\r
-       \r
-       /**\r
-        * Sets a property for the parser\r
-        */\r
-       function parse_set($property, $value) {\r
-               PARSER::setProperty($property, $value);\r
-       }\r
-       \r
-       /**\r
-        * Helper function: add if condition\r
-        */\r
-       function _addIfCondition($condition) {\r
-       \r
-               array_push($this->if_conditions,$condition);\r
-       \r
-               $this->_updateTopIfCondition();\r
-                       \r
-               ob_start();             \r
-       }\r
-       \r
-       function _updateTopIfCondition() {\r
-               if (sizeof($this->if_conditions) == 0) \r
-                       $this->if_currentlevel = 1;\r
-               else\r
-                       $this->if_currentlevel = $this->if_conditions[sizeof($this->if_conditions) - 1];\r
-       }\r
-       \r
-       /**\r
-        * returns the currently top if condition\r
-        */\r
-       function _getTopIfCondition() {\r
-               return $this->if_currentlevel;\r
-       }\r
-       \r
-       /**\r
-        * else\r
-        */\r
-       function parse_else() {\r
-               if (sizeof($this->if_conditions) == 0) return;\r
-               $old = $this->if_currentlevel;\r
-               if (array_pop($this->if_conditions)) {\r
-                       ob_end_flush();\r
-                       $this->_addIfCondition(0);\r
-               } else {\r
-                       ob_end_clean();\r
-                       $this->_addIfCondition(1);\r
-               }\r
-       }\r
-       \r
-       /**\r
-        * Ends a conditional if-block \r
-        * see e.g. ifcat (BLOG), ifblogsetting (PAGEFACTORY)\r
-        */\r
-       function parse_endif() {\r
-               // we can only close what has been opened\r
-               if (sizeof($this->if_conditions) == 0) return;\r
-               \r
-               if (array_pop($this->if_conditions)) {\r
-                       ob_end_flush();\r
-               } else {\r
-                       ob_end_clean();\r
-               }\r
-               \r
-               $this->_updateTopIfCondition();\r
-       }\r
-       \r
-       \r
-       /** \r
-        * Sets the search terms to be highlighted\r
-        *\r
-        * @param $highlight\r
-        *              A series of search terms\r
-        */\r
-       function setHighlight($highlight) {     \r
-               $this->strHighlight = $highlight;\r
-               if ($highlight) {\r
-                       $this->aHighlight = parseHighlight($highlight); \r
-               }\r
-       }\r
-       \r
-       /**\r
-        * Applies the highlight to the given piece of text\r
-        *\r
-        * @param &$data\r
-        *              Data that needs to be highlighted\r
-        * @see setHighlight\r
-        */\r
-       function highlight(&$data) {\r
-               if ($this->aHighlight)\r
-                       return highlight($data,$this->aHighlight,$this->template['SEARCH_HIGHLIGHT']);\r
-               else\r
-                       return $data;\r
-       }\r
-       \r
-       \r
-\r
-}\r
\r
-?>\r
+<?php
+/*
+ * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/)
+ * Copyright (C) 2002-2007 The Nucleus Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * (see nucleus/documentation/index.html#license for more info)
+ */
+/**
+ * @license http://nucleuscms.org/license.txt GNU General Public License
+ * @copyright Copyright (C) 2002-2007 The Nucleus Group
+ * @version $Id: PARSER.php,v 1.4 2007-03-27 12:13:56 kimitake Exp $
+ * $NucleusJP: PARSER.php,v 1.7 2007/03/20 19:31:29 kmorimatsu Exp $
+ */
+
+if ( !function_exists('requestVar') ) exit;
+require_once dirname(__FILE__) . '/BaseActions.php';
+
+/**
+ * This is the parser class of Nucleus. It is used for various things (skin parsing,
+ * form generation, ...)
+ */
+class PARSER {
+
+       // array with the names of all allowed actions
+       var $actions;
+
+       // reference to actions handler
+       var $handler;
+
+       // delimiters that can be used for skin/templatevars
+       var $delim;
+
+       // parameter delimiter (to separate skinvar params)
+       var $pdelim;
+
+       // usually set to 0. When set to 1, all skinvars are allowed regardless of $actions
+       var $norestrictions;
+
+       /**
+        * Creates a new parser object with the given allowed actions
+        * and the given handler
+        *
+        * @param $allowedActions array
+        * @param $handler class object with functions for each action (reference)
+        * @param $delim optional delimiter
+        * @param $paramdelim optional parameterdelimiter
+        */
+       function PARSER($allowedActions, &$handler, $delim = '(<%|%>)', $pdelim = ',') {
+               $this->actions = $allowedActions;
+               $this->handler =& $handler;
+               $this->delim = $delim;
+               $this->pdelim = $pdelim;
+               $this->norestrictions = 0;      // set this to 1 to disable checking for allowedActions
+       }
+
+       /**
+        * Parses the given contents and outputs it
+        */
+       function parse(&$contents) {
+
+               $pieces = preg_split('/'.$this->delim.'/',$contents);
+
+               $maxidx = sizeof($pieces);
+               for ($idx = 0; $idx < $maxidx; $idx++) {
+                       echo $pieces[$idx];
+                       $idx++;
+                       if ($idx < $maxidx) {
+                               $this->doAction($pieces[$idx]);
+                       }
+               }
+       }
+
+
+       /**
+         * handle an action
+         */
+       function doAction($action) {
+               global $manager;
+
+               if (!$action) return;
+
+               // split into action name + arguments
+               if (strstr($action,'(')) {
+                       $paramStartPos = strpos($action, '(');
+                       $params = substr($action, $paramStartPos + 1, strlen($action) - $paramStartPos - 2);
+                       $action = substr($action, 0, $paramStartPos);
+                       $params = explode ($this->pdelim, $params);
+
+                       // trim parameters
+                       // for PHP versions lower than 4.0.6:
+                       //   - add // before '$params = ...'
+                       //   - remove // before 'foreach'
+                       $params = array_map('trim',$params);
+                       // foreach ($params as $key => $value) { $params[$key] = trim($value); }
+               } else {
+                       // no parameters
+                       $params = array();
+               }
+
+               $actionlc = strtolower($action);
+
+               // skip execution of skinvars while inside an if condition which hides this part of the page
+               if (!$this->handler->if_currentlevel && ($actionlc != 'else') && ($actionlc != 'elseif') && ($actionlc != 'endif') && ($actionlc != 'ifnot') && ($actionlc != 'elseifnot') && (substr($actionlc,0,2) != 'if'))
+                       return;
+
+               if (in_array($actionlc, $this->actions) || $this->norestrictions ) {
+                       // when using PHP versions lower than 4.0.5, uncomment the line before
+                       // and comment the call_user_func_array call
+                       //$this->call_using_array($action, $this->handler, $params);
+                       call_user_func_array(array(&$this->handler,'parse_' . $actionlc), $params);
+               } else {
+                       // redirect to plugin action if possible
+                       if (in_array('plugin', $this->actions) && $manager->pluginInstalled('NP_'.$action))
+                               $this->doAction('plugin('.$action.$this->pdelim.implode($this->pdelim,$params).')');
+                       else
+                               echo '&lt;%' , $action , '(', implode($this->pdelim, $params), ')%&gt;';
+               }
+
+       }
+
+       /**
+         * Calls a method using an array of parameters (for use with PHP versions lower than 4.0.5)
+         * ( = call_user_func_array() function )
+         */
+       function call_using_array($methodname, &$handler, $paramarray) {
+
+               $methodname = 'parse_' . $methodname;
+
+               if (!method_exists($handler, $methodname)) {
+                       return;
+               }
+
+               $command = 'call_user_func(array(&$handler,$methodname)';
+               for ($i = 0; $i<count($paramarray); $i++)
+                       $command .= ',$paramarray[' . $i . ']';
+               $command .= ');';
+               eval($command); // execute the correct method
+       }
+
+       function setProperty($property, $value) {
+               global $manager;
+               $manager->setParserProperty($property, $value);
+       }
+
+       function getProperty($name) {
+               global $manager;
+               return $manager->getParserProperty($name);
+       }
+
+
+}
+
+?>
\ No newline at end of file
index c86975b..35a0690 100755 (executable)
@@ -1,7 +1,7 @@
 <?php
        /*
         * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/)
-        * Copyright (C) 2002-2006 The Nucleus Group
+        * Copyright (C) 2002-2007 The Nucleus Group
         *
         * This program is free software; you can redistribute it and/or
         * modify it under the terms of the GNU General Public License
@@ -16,9 +16,9 @@
         * plugins.html file that is included with the Nucleus documenation
         *
         * @license http://nucleuscms.org/license.txt GNU General Public License
-        * @copyright Copyright (C) 2002-2005 The Nucleus Group
-        * @version $Id: PLUGIN.php,v 1.4 2006-12-07 03:18:54 kmorimatsu Exp $
-        * @version $NucleusJP: PLUGIN.php,v 1.3.2.1 2005/08/23 08:08:38 kimitake Exp $
+        * @copyright Copyright (C) 2002-2007 The Nucleus Group
+        * @version $Id: PLUGIN.php,v 1.5 2007-03-27 12:13:56 kimitake Exp $
+        * $NucleusJP: PLUGIN.php,v 1.9 2007/03/13 05:03:23 shizuki Exp $
         */
        class NucleusPlugin {
 
@@ -58,6 +58,8 @@
                        call_user_func_array(array(&$this,'doSkinVar'),$args);
                }
                function doAction($type) { return 'No Such Action'; }
+               function doIf($key,$value) { return false; }
+               function doItemVar () {}
 
                /**
                 * Checks if a plugin supports a certain feature.
                /**
                  * Retrieves the current value for an option
                  */
-               function getOption($name) {
+               function getOption($name)
+               {
+                       // only request the options the very first time. On subsequent requests
+                       // the static collection is used to save SQL queries.
+                       if ($this->plugin_options == 0)
+                       {
+                               $this->plugin_options = array();
+                               $query = mysql_query(
+                                        'SELECT d.oname as name, o.ovalue as value '.
+                                        'FROM '.
+                                        sql_table('plugin_option').' o, '.
+                                        sql_table('plugin_option_desc').' d '.
+                                        'WHERE d.opid='. intval($this->getID()).' AND d.oid=o.oid'
+                               );
+                               while ($row = mysql_fetch_object($query))
+                                       $this->plugin_options[strtolower($row->name)] = $row->value;
+                 }
+                 if (isset($this->plugin_options[strtolower($name)]))
+                               return $this->plugin_options[strtolower($name)];
+                 else
                        return $this->_getOption('global', 0, $name);
                }
                function getBlogOption($blogid, $name) {
 
                var $_aOptionValues;    // oid_contextid => value
                var $_aOptionToInfo;    // context_name => array('oid' => ..., 'default' => ...)
+               var $plugin_options;    // see getOption()
                var $plugid;                    // plugin id
 
 
                function NucleusPlugin() {
                        $this->_aOptionValues = array();        // oid_contextid => value
                        $this->_aOptionToInfo = array();        // context_name => array('oid' => ..., 'default' => ...)
+                       $this->plugin_options = 0;
                }
 
                // private
 
                        // update plugin_option
                        sql_query('DELETE FROM ' . sql_table('plugin_option') . ' WHERE oid='.intval($oid) . ' and ocontextid='. intval($contextid));
-                       sql_query('INSERT INTO ' . sql_table('plugin_option') . ' (ovalue, oid, ocontextid) VALUES (\''.addslashes($value).'\', '. intval($oid) . ', ' . intval($contextid) . ')');
+                       @mysql_query('INSERT INTO ' . sql_table('plugin_option') . ' (ovalue, oid, ocontextid) VALUES (\''.addslashes($value).'\', '. intval($oid) . ', ' . intval($contextid) . ')');
 
                        // update cache
                        $this->_aOptionValues[$oid . '_' . $contextid] = $value;
                                case 'member':
                                        $r = sql_query('SELECT mnumber as contextid FROM ' . sql_table('member'));
                                        break;
+                               case 'item':
+                                       $r = sql_query('SELECT inumber as contextid FROM ' . sql_table('item'));
+                                       break;
                        }
                        if ($r) {
                                while ($o = mysql_fetch_object($r))
 
                                                        // delete the old value for the option
                                                        sql_query('DELETE FROM '.sql_table('plugin_option').' WHERE oid='.intval($oid).' AND ocontextid='.intval($contextid));
-                                                       sql_query('INSERT INTO '.sql_table('plugin_option')." (oid, ocontextid, ovalue) VALUES (".intval($oid).",".intval($contextid).",'" . addslashes($value) . "')");
+                                                       @mysql_query('INSERT INTO '.sql_table('plugin_option')." (oid, ocontextid, ovalue) VALUES (".intval($oid).",".intval($contextid).",'" . addslashes($value) . "')");
                                                }
                                        }
                                }
                }
 
        }
-?>
+?>
\ No newline at end of file
index cd57eb8..d562ef3 100755 (executable)
-<?php\r
-\r
-/**\r
-  * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/) \r
-  * Copyright (C) 2002-2005 The Nucleus Group\r
-  *\r
-  * This program is free software; you can redistribute it and/or\r
-  * modify it under the terms of the GNU General Public License\r
-  * as published by the Free Software Foundation; either version 2\r
-  * of the License, or (at your option) any later version.\r
-  * (see nucleus/documentation/index.html#license for more info)\r
-  *\r
-  * code to make it easier to create plugin admin areas\r
-  *\r
-  * $Id: PLUGINADMIN.php,v 1.3 2005-03-16 08:10:35 kimitake Exp $\r
-  * $NucleusJP: PLUGINADMIN.php,v 1.3 2005/03/12 06:19:05 kimitake Exp $\r
-  */\r
-\r
-global $HTTP_GET_VARS, $HTTP_POST_VARS, $HTTP_COOKIE_VARS, $HTTP_ENV_VARS, $HTTP_POST_FILES, $HTTP_SESSION_VARS;\r
-$aVarsToCheck = array('DIR_LIBS');\r
-foreach ($aVarsToCheck as $varName)\r
-{\r
-       if (phpversion() >= '4.1.0')\r
-       {\r
-               if (   isset($_GET[$varName]) \r
-                       || isset($_POST[$varName]) \r
-                       || isset($_COOKIE[$varName])\r
-                       || isset($_ENV[$varName])\r
-                       || isset($_SESSION[$varName])\r
-                       || isset($_FILES[$varName])\r
-               ){\r
-                       die('Sorry. An error occurred.');\r
-               }\r
-       } else {\r
-               if (   isset($HTTP_GET_VARS[$varName]) \r
-                       || isset($HTTP_POST_VARS[$varName]) \r
-                       || isset($HTTP_COOKIE_VARS[$varName])\r
-                       || isset($HTTP_ENV_VARS[$varName])\r
-                       || isset($HTTP_SESSION_VARS[$varName])\r
-                       || isset($HTTP_POST_FILES[$varName])\r
-               ){\r
-                       die('Sorry. An error occurred.');\r
-               }               \r
-       }\r
-}\r
-\r
-\r
-include($DIR_LIBS . 'ADMIN.php');\r
-\r
-class PluginAdmin {\r
-       \r
-       var $strFullName;               // NP_SomeThing\r
-       var $plugin;                    // ref. to plugin object\r
-       var $bValid;                    // evaluates to true when object is considered valid\r
-       var $admin;                             // ref to an admin object\r
-       \r
-       function PluginAdmin($pluginName)\r
-       {\r
-               global $manager;\r
-               \r
-               $this->strFullName = 'NP_' . $pluginName;\r
-               \r
-               // check if plugin exists and is installed\r
-               if (!$manager->pluginInstalled($this->strFullName))\r
-                       doError('Invalid plugin');\r
-               \r
-               $this->plugin =& $manager->getPlugin($this->strFullName);\r
-               $this->bValid = $this->plugin;\r
-       \r
-               if (!$this->bValid)\r
-                       doError('Invalid plugin');\r
-               \r
-               $this->admin = new ADMIN();\r
-               $this->admin->action = 'plugin_' . $pluginName;\r
-       }\r
-       \r
-       function start($extraHead = '')\r
-       {\r
-               global $CONF;\r
-               $strBaseHref  = '<base href="' . htmlspecialchars($CONF['AdminURL']) . '" />';  \r
-               $extraHead .= $strBaseHref;\r
-               \r
-               $this->admin->pagehead($extraHead);\r
-       }\r
-       \r
-       function end()\r
-       {\r
-               $this->admin->pagefoot();\r
-       }       \r
-}\r
-\r
-\r
-\r
-?>\r
+<?php
+
+/*
+ * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/)
+ * Copyright (C) 2002-2007 The Nucleus Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * (see nucleus/documentation/index.html#license for more info)
+ */
+/**
+ * code to make it easier to create plugin admin areas
+ *
+ * @license http://nucleuscms.org/license.txt GNU General Public License
+ * @copyright Copyright (C) 2002-2007 The Nucleus Group
+ * @version $Id: PLUGINADMIN.php,v 1.4 2007-03-27 12:13:56 kimitake Exp $
+ * $NucleusJP: PLUGINADMIN.php,v 1.8 2007/03/22 03:30:14 kmorimatsu Exp $
+ */
+
+global $HTTP_GET_VARS, $HTTP_POST_VARS, $HTTP_COOKIE_VARS, $HTTP_ENV_VARS, $HTTP_POST_FILES, $HTTP_SESSION_VARS;
+$aVarsToCheck = array('HTTP_GET_VARS', 'HTTP_POST_VARS', 'HTTP_COOKIE_VARS', 'HTTP_ENV_VARS', 'HTTP_SESSION_VARS', 'HTTP_POST_FILES', 'HTTP_SERVER_VARS', 'GLOBALS', 'argv', 'argc', '_GET', '_POST', '_COOKIE', '_ENV', '_SESSION', '_SERVER', '_FILES', 'DIR_LIBS');
+
+foreach ($aVarsToCheck as $varName)
+{
+       if (phpversion() >= '4.1.0')
+       {
+               if (   isset($_GET[$varName])
+                       || isset($_POST[$varName])
+                       || isset($_COOKIE[$varName])
+                       || isset($_ENV[$varName])
+                       || isset($_SESSION[$varName])
+                       || isset($_FILES[$varName])
+               ){
+                       die('Sorry. An error occurred.');
+               }
+       } else {
+               if (   isset($HTTP_GET_VARS[$varName])
+                       || isset($HTTP_POST_VARS[$varName])
+                       || isset($HTTP_COOKIE_VARS[$varName])
+                       || isset($HTTP_ENV_VARS[$varName])
+                       || isset($HTTP_SESSION_VARS[$varName])
+                       || isset($HTTP_POST_FILES[$varName])
+               ){
+                       die('Sorry. An error occurred.');
+               }
+       }
+}
+
+if (!isset($DIR_LIBS)) {
+       die('Sorry.');
+}
+
+include($DIR_LIBS . 'ADMIN.php');
+
+class PluginAdmin {
+
+       var $strFullName;               // NP_SomeThing
+       var $plugin;                    // ref. to plugin object
+       var $bValid;                    // evaluates to true when object is considered valid
+       var $admin;                             // ref to an admin object
+
+       function PluginAdmin($pluginName)
+       {
+               global $manager;
+
+               $this->strFullName = 'NP_' . $pluginName;
+
+               // check if plugin exists and is installed
+               if (!$manager->pluginInstalled($this->strFullName))
+                       doError('Invalid plugin');
+
+               $this->plugin =& $manager->getPlugin($this->strFullName);
+               $this->bValid = $this->plugin;
+
+               if (!$this->bValid)
+                       doError('Invalid plugin');
+
+               $this->admin = new ADMIN();
+               $this->admin->action = 'plugin_' . $pluginName;
+       }
+
+       function start($extraHead = '')
+       {
+               global $CONF;
+               $strBaseHref  = '<base href="' . htmlspecialchars($CONF['AdminURL']) . '" />';
+               $extraHead .= $strBaseHref;
+
+               $this->admin->pagehead($extraHead);
+       }
+
+       function end()
+       {
+               $this->_AddTicketByJS();
+               $this->admin->pagefoot();
+       }
+
+/** 
+ * Add ticket when not used in plugin's admin page
+ * to avoid CSRF.
+ */
+       function _AddTicketByJS(){
+               global $CONF,$ticketforplugin;
+               if (!($ticket=$ticketforplugin['ticket'])) {
+                       //echo "\n<!--TicketForPlugin skipped-->\n";
+                       return;
+               }
+               $ticket=htmlspecialchars($ticket,ENT_QUOTES);
+?><script type="text/javascript">
+/*<![CDATA[*/
+/* Add tickets for available links (outside blog excluded) */
+for (i=0;document.links[i];i++){
+  if (document.links[i].href.indexOf('<?php echo $CONF['PluginURL']; ?>',0)<0
+    && !(document.links[i].href.indexOf('//',0)<0)) continue;
+  if ((j=document.links[i].href.indexOf('?',0))<0) continue;
+  if (document.links[i].href.indexOf('ticket=',j)>=0) continue;
+  document.links[i].href=document.links[i].href.substring(0,j+1)+'ticket=<?php echo $ticket; ?>&'+document.links[i].href.substring(j+1);
+}
+/* Add tickets for forms (outside blog excluded) */
+for (i=0;document.forms[i];i++){
+  /* check if ticket is already used */
+  for (j=0;document.forms[i].elements[j];j++) {
+    if (document.forms[i].elements[j].name=='ticket') {
+      j=-1;
+      break;
+    }
+  }
+  if (j==-1) continue;
+  /* check if the modification works */
+  try{document.forms[i].innerHTML+='';}catch(e){
+    /* Modificaion falied: this sometime happens on IE */
+    if (!document.forms[i].action.name && document.forms[i].method.toUpperCase()=="POST") {
+      /* <input name="action"/> is not used for POST method*/
+      if (document.forms[i].action.indexOf('<?php echo $CONF['PluginURL']; ?>',0)<0
+        && !(document.forms[i].action.indexOf('//',0)<0)) continue;
+      if (0<(j=document.forms[i].action.indexOf('?',0))) if (0<document.forms[i].action.indexOf('ticket=',j)) continue;
+      if (j<0) document.forms[i].action+='?'+'ticket=<?php echo $ticket; ?>';
+      else document.forms[i].action+='&'+'ticket=<?php echo $ticket; ?>';
+      continue;
+    }
+    document.write('<p><b>Error occured druing automatic addition of tickets.</b></p>');
+    j=document.forms[i].outerHTML;
+    while (j!=j.replace('<','&lt;')) j=j.replace('<','&lt;');
+    document.write('<p>'+j+'</p>');
+    continue;
+  }
+  /* check the action paramer in form tag */
+  /* note that <input name="action"/> may be used here */
+  j=document.forms[i].innerHTML;
+  document.forms[i].innerHTML='';
+  if ((document.forms[i].action+'').indexOf('<?php echo $CONF['PluginURL']; ?>',0)<0
+      && !((document.forms[i].action+'').indexOf('//',0)<0)) {
+    document.forms[i].innerHTML=j;
+    continue;
+  }
+  /* add ticket */
+  document.forms[i].innerHTML=j+'<input type="hidden" name="ticket" value="<?php echo $ticket; ?>"/>';
+}
+/*]]>*/
+</script><?php
+       }
+}
+
+
+
+?>
\ No newline at end of file
index 599c293..0814c3e 100755 (executable)
-<?php\r
-\r
-/**\r
-  * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/) \r
-  * Copyright (C) 2003-2005 The Nucleus Group\r
-  *\r
-  * This program is free software; you can redistribute it and/or\r
-  * modify it under the terms of the GNU General Public License\r
-  * as published by the Free Software Foundation; either version 2\r
-  * of the License, or (at your option) any later version.\r
-  * (see nucleus/documentation/index.html#license for more info)\r
-  *\r
-  * SEARCH(querystring) offers different functionality to create an\r
-  * SQL query to find certain items. (and comments)\r
-  *\r
-  * based on code by David Altherr:\r
-  * http://www.evolt.org/article/Boolean_Fulltext_Searching_with_PHP_and_MySQL/18/15665/\r
-  * http://davidaltherr.net/web/php_functions/boolean/funcs.mysql.boolean.txt\r
-  * \r
-  *\r
-  * $Id: SEARCH.php,v 1.5 2005-03-16 08:10:35 kimitake Exp $\r
-  $ $NucleusJP: SEARCH.php,v 1.4 2005/03/12 06:19:05 kimitake Exp $\r
-  */\r
-\r
-\r
-class SEARCH {\r
-       \r
-       var $querystring;\r
-       var $marked;\r
-       var $inclusive;\r
-       var $blogs;\r
-\r
-\r
-    function SEARCH($text) {\r
-        global $blogid;\r
-\r
-//       $text = preg_replace ("/[<,>,=,?,!,#,^,(,),[,\],:,;,\\\,%]/","",$text);\r
-\r
-     /* * * for jp * * * * * * * * * * */\r
-        $text = $this->zenspace_replace($text);\r
-        $text = preg_replace ("/[<>=?!#^()[\]:;\\%]/","",$text);\r
-\r
-        $this->ascii = '[\x00-\x7F]';\r
-        $this->two = '[\x8E\xA1-\xFE][\xA1-\xFE]';\r
-        $this->three = '\x8F[\xA1-\xFE][\xA1-\xFE]';\r
-\r
-        $this->jpmarked      = $this->boolean_mark_atoms_jp($text);\r
-     /* * * * * * * * * * * * * * * * */\r
-\r
-        $this->querystring     = $text;\r
-//        $this->marked                = $this->boolean_mark_atoms($text);\r
-        $this->inclusive       = $this->boolean_inclusive_atoms($text);\r
-        $this->blogs           = array();\r
-\r
-        // get all public searchable blogs, no matter what, include the current blog allways.\r
-               $res = sql_query('SELECT bnumber FROM '.sql_table('blog').' WHERE bincludesearch=1 ');\r
-               while ($obj = mysql_fetch_object($res)) \r
-                   $this->blogs[] = intval($obj->bnumber);\r
-        }\r
-/***********************************************\r
-  zenkaku space to space\r
-***********************************************/\r
-\r
-    function zenspace_replace($text){\r
-        $ta = unpack("C*",$text);\r
-        $len = count($ta);\r
-        $temp = '';\r
-        for($i=1; $i<=$len; $i++){\r
-                       if($ta[$i]>= 0x8e){ // ja\r
-                       if($ta[$i]>0xa0 || $ta[$i]<0x8f){ // 2byte\r
-                                       $char = chr($ta[$i]).chr($ta[$i+1]);\r
-                               if($char == "\xA1\xA1") $char = "\x20";\r
-                               $temp .= $char;\r
-                               $i ++;\r
-                       }else{ // 3byte\r
-                                       $temp .= chr($ta[$i]).chr($ta[$i+1]).chr($ta[$i+2]);\r
-                               $i += 2;\r
-                       }\r
-               }else{ //ascii\r
-                       $temp .= chr($ta[$i]);\r
-               }\r
-        }\r
-      return $temp;\r
-   }\r
-/***********************************************/\r
-\r
-    function  boolean_sql_select($match){\r
-//        $string = $this->inclusive;\r
-//        if (strlen($string) > 0) {\r
-          /* build sql for determining score for each record */\r
-/*\r
-              preg_match_all(\r
-                                  "([A-Za-z0-9]{1,}[A-Za-z0-9\-\.\_]{0,})",\r
-                              $string,\r
-                              $result);\r
-           $result = $result[0];\r
-                for($cth=0;$cth<count($result);$cth++){\r
-             if(strlen($result[$cth])>=4){\r
-                   $stringsum_long .=  " $result[$cth] ";\r
-                    }else{\r
-                      $stringsum_a[] = ' '.$this->boolean_sql_select_short($result[$cth],$match).' ';\r
-                    }\r
-                }\r
-            if(strlen($stringsum_long)>0){\r
-                               $stringsum_long = addslashes($stringsum_long);\r
-                       $stringsum_a[] = " match ($match) against ('$stringsum_long') ";\r
-            }\r
-                $stringsum .= implode("+",$stringsum_a);\r
-            return $stringsum;\r
-           }\r
-*/\r
-    }\r
-\r
-    \r
-\r
-    function boolean_inclusive_atoms($string){\r
-       $result=trim($string);\r
-       $result=preg_replace("/([[:space:]]{2,})/",' ',$result);\r
-\r
-       /* convert normal boolean operators to shortened syntax */\r
-       $result=eregi_replace(' not ',' -',$result);\r
-       $result=eregi_replace(' and ',' ',$result);\r
-       $result=eregi_replace(' or ',',',$result);\r
-\r
-       /* drop unnecessary spaces */\r
-       $result=str_replace(' ,',',',$result);\r
-       $result=str_replace(', ',',',$result);\r
-       $result=str_replace('- ','-',$result);\r
-       $result=str_replace('+','',$result);\r
-\r
-       /* strip exlusive atoms */\r
-       $result=preg_replace(\r
-//             "(\-\([A-Za-z0-9]{1,}[A-Za-z0-9\-\.\_\,]{0,}\))",\r
-               "(\-\(([A-Za-z0-9]|$this->two|$this->three){1,}([A-Za-z0-9\-\.\_\,]|$this->two|$this->three){0,}\))",\r
-               '',\r
-               $result);\r
-\r
-       $result=preg_replace(\r
-//             "(\-[A-Za-z0-9]{1,}[A-Za-z0-9\-\.\_]{0,})",\r
-               "(\-([A-Za-z0-9]|$this->two|$this->three){1,}([A-Za-z0-9\-\.\_\,]|$this->two|$this->three){0,})",\r
-               '',\r
-               $result);\r
-\r
-       $result=str_replace('(',' ',$result);\r
-       $result=str_replace(')',' ',$result);\r
-       $result=str_replace(',',' ',$result);\r
-\r
-       return $result;\r
-    }\r
-\r
-    function boolean_sql_where($match){\r
-/*\r
-        $result = $this->marked;\r
-       $result = preg_replace(\r
-               "/foo\[\(\'([^\)]{4,})\'\)\]bar/e",\r
-               " 'match ('.\$match.') against (\''.\$this->copyvalue(\"$1\").'\') > 0 ' ",\r
-               $result);\r
-\r
-       $result = preg_replace(                 \r
-            "/foo\[\(\'([^\)]{1,3})\'\)\]bar/e",\r
-            " '('.\$this->boolean_sql_where_short(\"$1\",\"$match\").')' ",                    \r
-            $result);\r
-*/\r
-      $result = $this->jpmarked; /* for jp */\r
-       $result = $this->boolean_sql_where_jp_short($result,$match);/* for jp */\r
-       return $result;\r
-    }\r
-\r
-    // there must be a simple way to simply copy a value with backslashes in it through\r
-    // the preg_replace, but I cannot currently find it (karma 2003-12-30)\r
-    function copyvalue($foo) {\r
-       return $foo;\r
-    }\r
-\r
-/***********************************************\r
-  Make "WHERE" (jp)\r
-***********************************************/\r
-\r
-    function boolean_mark_atoms_jp($string){\r
-\r
-       $result=trim($string);\r
-       $result=preg_replace("/([[:space:]]{2,})/",' ',$result);\r
-       \r
-       /* convert normal boolean operators to shortened syntax */\r
-       $result=eregi_replace(' not ',' -',$result);\r
-       $result=eregi_replace(' and ',' ',$result);\r
-       $result=eregi_replace(' or ',',',$result);\r
-\r
-       /* strip excessive whitespace */\r
-       $result=str_replace(', ',',',$result);\r
-       $result=str_replace(' ,',',',$result);\r
-       $result=str_replace('- ','-',$result);\r
-       $result=str_replace('+','',$result);\r
-       \r
-       $result=str_replace(',',' ,',$result);\r
-\r
-       return $result;\r
-    }\r
-    \r
-\r
-    function boolean_sql_where_jp_short($string,$match){\r
-       $match_a = explode(',',$match);\r
-                       $key_a = explode(' ',$string);\r
-                       \r
-       for($ith=0;$ith<count($match_a);$ith++){\r
-               $temp_a[$ith] = "(i.$match_a[$ith] LIKE '%" . addslashes($key_a[0]) . "%') ";\r
-       }\r
-       $like = '('.implode(' or ',$temp_a).')';\r
-\r
-                       for($kn=1; $kn<count($key_a); $kn++){\r
-               if(substr($key_a[$kn],0,1) == ","){\r
-                       for($ith=0;$ith<count($match_a);$ith++){\r
-                               $temp_a[$ith] = " (i.$match_a[$ith] LIKE '%" . addslashes(substr($key_a[$kn],1)) . "%') ";\r
-                       }\r
-                       $like .=' OR ('. implode(' or ',$temp_a).')';\r
-               }elseif(substr($key_a[$kn],0,1) != '-'){\r
-                       for($ith=0;$ith<count($match_a);$ith++){\r
-                               $temp_a[$ith] = " (i.$match_a[$ith] LIKE '%" . addslashes($key_a[$kn]) . "%') ";\r
-                       }\r
-                       $like .=' AND ('. implode(' or ',$temp_a).')';\r
-               }else{\r
-                       for($ith=0;$ith<count($match_a);$ith++){\r
-                               $temp_a[$ith] = " NOT(i.$match_a[$ith] LIKE '%" . addslashes(substr($key_a[$kn],1)) . "%') ";\r
-                       }\r
-                       $like .=' AND ('. implode(' and ',$temp_a).')';\r
-               }\r
-       }\r
-       \r
-       $like = '('.$like.')';\r
-       return $like;\r
-    }\r
-\r
-/***********************************************/\r
-\r
-\r
-/*\r
-    function boolean_mark_atoms($string){\r
-       $result=trim($string);\r
-       $result=preg_replace("/([[:space:]]{2,})/",' ',$result);\r
-\r
-       //convert normal boolean operators to shortened syntax\r
-       $result=eregi_replace(' not ',' -',$result);\r
-       $result=eregi_replace(' and ',' ',$result);\r
-       $result=eregi_replace(' or ',',',$result);\r
-\r
-\r
-       //strip excessive whitespace\r
-       $result=str_replace('( ','(',$result);\r
-       $result=str_replace(' )',')',$result);\r
-       $result=str_replace(', ',',',$result);\r
-       $result=str_replace(' ,',',',$result);\r
-       $result=str_replace('- ','-',$result);\r
-       $result=str_replace('+','',$result);\r
-\r
-       // remove double spaces (we might have introduced some new ones above)\r
-       $result=trim($result);\r
-       $result=preg_replace("/([[:space:]]{2,})/",' ',$result);\r
-\r
-       // apply arbitrary function to all 'word' atoms\r
-\r
-        $result_a = explode(" ",$result);\r
-        for($word=0;$word<count($result_a);$word++){\r
-            $result_a[$word] = "foo[('".$result_a[$word]."')]bar";\r
-        }\r
-        $result = implode(" ",$result_a);\r
-        \r
-       // dispatch ' ' to ' AND '\r
-       $result=str_replace(' ',' AND ',$result);\r
-\r
-       // dispatch ',' to ' OR '\r
-       $result=str_replace(',',' OR ',$result);\r
-\r
-       // dispatch '-' to ' NOT '\r
-       $result=str_replace(' -',' NOT ',$result);\r
-       return $result;\r
-    }\r
-    \r
-    function boolean_sql_where_short($string,$match){\r
-       $match_a = explode(',',$match);\r
-       for($ith=0;$ith<count($match_a);$ith++){\r
-               $like_a[$ith] = " $match_a[$ith] LIKE '% $string %' ";\r
-       }\r
-       $like = implode(" OR ",$like_a);\r
-\r
-       return $like;\r
-    }\r
-    function boolean_sql_select_short($string,$match){\r
-        $match_a = explode(',',$match);\r
-        $score_unit_weight = .2;\r
-        for($ith=0;$ith<count($match_a);$ith++){\r
-            $score_a[$ith] =\r
-                           " $score_unit_weight*(\r
-                           LENGTH(" . addslashes($match_a[$ith]) . ") -\r
-                           LENGTH(REPLACE(LOWER(" . addslashes($match_a[$ith]) . "),LOWER('" . addslashes($string) . "'),'')))\r
-                                      /LENGTH('" . addslashes($string) . "') ";\r
-        }\r
-           $score = implode(" + ",$score_a);\r
-\r
-        return $score;\r
-    }\r
-*/\r
-\r
-}\r
-?>\r
+<?php
+
+/*
+ * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/)
+ * Copyright (C) 2003-2007 The Nucleus Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * (see nucleus/documentation/index.html#license for more info)
+ */
+/**
+ * SEARCH(querystring) offers different functionality to create an
+ * SQL query to find certain items. (and comments)
+ *
+ * based on code by David Altherr:
+ * http://www.evolt.org/article/Boolean_Fulltext_Searching_with_PHP_and_MySQL/18/15665/
+ * http://davidaltherr.net/web/php_functions/boolean/funcs.mysql.boolean.txt
+ *
+ * @license http://nucleuscms.org/license.txt GNU General Public License
+ * @copyright Copyright (C) 2002-2007 The Nucleus Group
+ * @version $Id: SEARCH.php,v 1.6 2007-03-27 12:13:56 kimitake Exp $
+ * @version $NucleusJP: SEARCH.php,v 1.8 2007/02/04 06:28:46 kimitake Exp $
+ */
+
+
+
+class SEARCH {
+
+       var $querystring;
+       var $marked;
+       var $inclusive;
+       var $blogs;
+
+
+       function SEARCH($text) {
+               global $blogid;
+//             $text = preg_replace ("/[<,>,=,?,!,#,^,(,),[,\],:,;,\\\,%]/","",$text);
+
+
+     /* * * for jp * * * * * * * * * * */
+        $text = $this->zenspace_replace($text);
+        $text = preg_replace ("/[<>=?!#^()[\]:;\\%]/","",$text);
+
+        $this->ascii = '[\x00-\x7F]';
+        $this->two = '[\x8E\xA1-\xFE][\xA1-\xFE]';
+        $this->three = '\x8F[\xA1-\xFE][\xA1-\xFE]';
+
+        $this->jpmarked      = $this->boolean_mark_atoms_jp($text);
+     /* * * * * * * * * * * * * * * * */
+
+        $this->querystring     = $text;
+//             $this->marked           = $this->boolean_mark_atoms($text);
+        $this->inclusive       = $this->boolean_inclusive_atoms($text);
+        $this->blogs           = array();
+
+        // get all public searchable blogs, no matter what, include the current blog allways.
+               $res = sql_query('SELECT bnumber FROM '.sql_table('blog').' WHERE bincludesearch=1 ');
+               while ($obj = mysql_fetch_object($res)) 
+                   $this->blogs[] = intval($obj->bnumber);
+        }
+/***********************************************
+  zenkaku space to space
+***********************************************/
+
+    function zenspace_replace($text){
+        $ta = unpack("C*",$text);
+        $len = count($ta);
+        $temp = '';
+        for($i=1; $i<=$len; $i++){
+                       if($ta[$i]>= 0x8e){ // ja
+                       if($ta[$i]>0xa0 || $ta[$i]<0x8f){ // 2byte
+                                       $char = chr($ta[$i]).chr($ta[$i+1]);
+                               if($char == "\xA1\xA1") $char = "\x20";
+                               $temp .= $char;
+                               $i ++;
+                       }else{ // 3byte
+                                       $temp .= chr($ta[$i]).chr($ta[$i+1]).chr($ta[$i+2]);
+                               $i += 2;
+                       }
+               }else{ //ascii
+                       $temp .= chr($ta[$i]);
+               }
+        }
+      return $temp;
+   }
+/***********************************************/
+
+    function  boolean_sql_select($match){
+//        $string = $this->inclusive;
+//        if (strlen($string) > 0) {
+          /* build sql for determining score for each record */
+/*
+              preg_match_all(
+                                  "([A-Za-z0-9]{1,}[A-Za-z0-9\-\.\_]{0,})",
+                              $string,
+                              $result);
+           $result = $result[0];
+                for($cth=0;$cth<count($result);$cth++){
+             if(strlen($result[$cth])>=4){
+                   $stringsum_long .=  " $result[$cth] ";
+                    }else{
+                      $stringsum_a[] = ' '.$this->boolean_sql_select_short($result[$cth],$match).' ';
+                    }
+                }
+            if(strlen($stringsum_long)>0){
+                               $stringsum_long = addslashes($stringsum_long);
+                       $stringsum_a[] = " match ($match) against ('$stringsum_long') ";
+            }
+                $stringsum .= implode("+",$stringsum_a);
+            return $stringsum;
+           }
+*/
+    }
+
+    
+
+    function boolean_inclusive_atoms($string){
+       $result=trim($string);
+       $result=preg_replace("/([[:space:]]{2,})/",' ',$result);
+
+       /* convert normal boolean operators to shortened syntax */
+       $result=eregi_replace(' not ',' -',$result);
+       $result=eregi_replace(' and ',' ',$result);
+       $result=eregi_replace(' or ',',',$result);
+
+       /* drop unnecessary spaces */
+       $result=str_replace(' ,',',',$result);
+       $result=str_replace(', ',',',$result);
+       $result=str_replace('- ','-',$result);
+       $result=str_replace('+','',$result);
+
+       /* strip exlusive atoms */
+       $result=preg_replace(
+//             "(\-\([A-Za-z0-9]{1,}[A-Za-z0-9\-\.\_\,]{0,}\))",
+               "(\-\(([A-Za-z0-9]|$this->two|$this->three){1,}([A-Za-z0-9\-\.\_\,]|$this->two|$this->three){0,}\))",
+               '',
+               $result);
+
+       $result=preg_replace(
+//             "(\-[A-Za-z0-9]{1,}[A-Za-z0-9\-\.\_]{0,})",
+               "(\-([A-Za-z0-9]|$this->two|$this->three){1,}([A-Za-z0-9\-\.\_\,]|$this->two|$this->three){0,})",
+               '',
+               $result);
+
+       $result=str_replace('(',' ',$result);
+       $result=str_replace(')',' ',$result);
+       $result=str_replace(',',' ',$result);
+
+       return $result;
+    }
+
+    function boolean_sql_where($match){
+/*
+        $result = $this->marked;
+       $result = preg_replace(
+               "/foo\[\(\'([^\)]{4,})\'\)\]bar/e",
+               " 'match ('.\$match.') against (\''.\$this->copyvalue(\"$1\").'\') > 0 ' ",
+               $result);
+
+       $result = preg_replace(                 
+            "/foo\[\(\'([^\)]{1,3})\'\)\]bar/e",
+            " '('.\$this->boolean_sql_where_short(\"$1\",\"$match\").')' ",                    
+            $result);
+*/
+      $result = $this->jpmarked; /* for jp */
+       $result = $this->boolean_sql_where_jp_short($result,$match);/* for jp */
+       return $result;
+    }
+
+    // there must be a simple way to simply copy a value with backslashes in it through
+    // the preg_replace, but I cannot currently find it (karma 2003-12-30)
+    function copyvalue($foo) {
+       return $foo;
+    }
+
+/***********************************************
+  Make "WHERE" (jp)
+***********************************************/
+
+    function boolean_mark_atoms_jp($string){
+
+       $result=trim($string);
+       $result=preg_replace("/([[:space:]]{2,})/",' ',$result);
+       
+       /* convert normal boolean operators to shortened syntax */
+       $result=eregi_replace(' not ',' -',$result);
+       $result=eregi_replace(' and ',' ',$result);
+       $result=eregi_replace(' or ',',',$result);
+
+       /* strip excessive whitespace */
+       $result=str_replace(', ',',',$result);
+       $result=str_replace(' ,',',',$result);
+       $result=str_replace('- ','-',$result);
+       $result=str_replace('+','',$result);
+       
+       $result=str_replace(',',' ,',$result);
+
+       return $result;
+    }
+    
+
+    function boolean_sql_where_jp_short($string,$match){
+       $match_a = explode(',',$match);
+                       $key_a = explode(' ',$string);
+                       
+       for($ith=0;$ith<count($match_a);$ith++){
+               $temp_a[$ith] = "(i.$match_a[$ith] LIKE '%" . addslashes($key_a[0]) . "%') ";
+       }
+       $like = '('.implode(' or ',$temp_a).')';
+
+                       for($kn=1; $kn<count($key_a); $kn++){
+               if(substr($key_a[$kn],0,1) == ","){
+                       for($ith=0;$ith<count($match_a);$ith++){
+                               $temp_a[$ith] = " (i.$match_a[$ith] LIKE '%" . addslashes(substr($key_a[$kn],1)) . "%') ";
+                       }
+                       $like .=' OR ('. implode(' or ',$temp_a).')';
+               }elseif(substr($key_a[$kn],0,1) != '-'){
+                       for($ith=0;$ith<count($match_a);$ith++){
+                               $temp_a[$ith] = " (i.$match_a[$ith] LIKE '%" . addslashes($key_a[$kn]) . "%') ";
+                       }
+                       $like .=' AND ('. implode(' or ',$temp_a).')';
+               }else{
+                       for($ith=0;$ith<count($match_a);$ith++){
+                               $temp_a[$ith] = " NOT(i.$match_a[$ith] LIKE '%" . addslashes(substr($key_a[$kn],1)) . "%') ";
+                       }
+                       $like .=' AND ('. implode(' and ',$temp_a).')';
+               }
+       }
+       
+       $like = '('.$like.')';
+       return $like;
+    }
+
+/***********************************************/
+
+
+/*
+    function boolean_mark_atoms($string){
+       $result=trim($string);
+       $result=preg_replace("/([[:space:]]{2,})/",' ',$result);
+
+       //convert normal boolean operators to shortened syntax
+       $result=eregi_replace(' not ',' -',$result);
+       $result=eregi_replace(' and ',' ',$result);
+       $result=eregi_replace(' or ',',',$result);
+
+
+       //strip excessive whitespace
+       $result=str_replace('( ','(',$result);
+       $result=str_replace(' )',')',$result);
+       $result=str_replace(', ',',',$result);
+       $result=str_replace(' ,',',',$result);
+       $result=str_replace('- ','-',$result);
+       $result=str_replace('+','',$result);
+
+       // remove double spaces (we might have introduced some new ones above)
+       $result=trim($result);
+       $result=preg_replace("/([[:space:]]{2,})/",' ',$result);
+
+       // apply arbitrary function to all 'word' atoms
+
+        $result_a = explode(" ",$result);
+        for($word=0;$word<count($result_a);$word++){
+            $result_a[$word] = "foo[('".$result_a[$word]."')]bar";
+        }
+        $result = implode(" ",$result_a);
+        
+       // dispatch ' ' to ' AND '
+       $result=str_replace(' ',' AND ',$result);
+
+       // dispatch ',' to ' OR '
+       $result=str_replace(',',' OR ',$result);
+
+       // dispatch '-' to ' NOT '
+       $result=str_replace(' -',' NOT ',$result);
+       return $result;
+    }
+    
+    function boolean_sql_where_short($string,$match){
+       $match_a = explode(',',$match);
+       for($ith=0;$ith<count($match_a);$ith++){
+               $like_a[$ith] = " $match_a[$ith] LIKE '% $string %' ";
+       }
+       $like = implode(" OR ",$like_a);
+
+       return $like;
+    }
+    function boolean_sql_select_short($string,$match){
+        $match_a = explode(',',$match);
+        $score_unit_weight = .2;
+        for($ith=0;$ith<count($match_a);$ith++){
+            $score_a[$ith] =
+                           " $score_unit_weight*(
+                           LENGTH(" . addslashes($match_a[$ith]) . ") -
+                           LENGTH(REPLACE(LOWER(" . addslashes($match_a[$ith]) . "),LOWER('" . addslashes($string) . "'),'')))
+                                      /LENGTH('" . addslashes($string) . "') ";
+        }
+           $score = implode(" + ",$score_a);
+
+        return $score;
+    }
+*/
+
+}
+?>
index eb2cead..8a2c70b 100755 (executable)
@@ -1,31 +1,42 @@
 <?php
 
+/*
+ * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/)
+ * Copyright (C) 2002-2007 The Nucleus Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * (see nucleus/documentation/index.html#license for more info)
+ */
 /**
-  * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/)
-  * Copyright (C) 2002-2005 The Nucleus Group
-  *
-  * This program is free software; you can redistribute it and/or
-  * modify it under the terms of the GNU General Public License
-  * as published by the Free Software Foundation; either version 2
-  * of the License, or (at your option) any later version.
-  * (see nucleus/documentation/index.html#license for more info)
-  *
-  * $Id: globalfunctions.php,v 1.8 2007-03-22 08:32:11 kimitake Exp $
-  * $NucleusJP: globalfunctions.php,v 1.7 2005/08/13 07:21:03 kimitake Exp $
-  */
+ * @license http://nucleuscms.org/license.txt GNU General Public License
+ * @copyright Copyright (C) 2002-2007 The Nucleus Group
+ * @version $Id: globalfunctions.php,v 1.9 2007-03-27 12:13:56 kimitake Exp $
+ * $NucleusJP: globalfunctions.php,v 1.19 2007/03/22 03:30:14 kmorimatsu Exp $
+ */
 
 // needed if we include globalfunctions from install.php
-global $nucleus, $CONF, $DIR_LIBS, $DIR_LANG, $manager, $member; 
+global $nucleus, $CONF, $DIR_LIBS, $DIR_LANG, $manager, $member;
 
+//$nucleus['version'] = 'v3.3SVN';
+//$nucleus['codename'] = 'Lithium';
+$nucleus['version'] = 'v3.3';
+$nucleus['codename'] = '';
 
-checkVars(array('nucleus', 'CONF', 'DIR_LIBS', 'MYSQL_HOST', 'MYSQL_USER', 'MYSQL_PASSWORD', 'MYSQL_DATABASE', 'DIR_LANG', 'DIR_PLUGINS'));
+checkVars(array('nucleus', 'CONF', 'DIR_LIBS', 'MYSQL_HOST', 'MYSQL_USER', 'MYSQL_PASSWORD', 'MYSQL_DATABASE', 'DIR_LANG', 'DIR_PLUGINS', 'HTTP_GET_VARS', 'HTTP_POST_VARS', 'HTTP_COOKIE_VARS', 'HTTP_ENV_VARS', 'HTTP_SESSION_VARS', 'HTTP_POST_FILES', 'HTTP_SERVER_VARS', 'GLOBALS', 'argv', 'argc', '_GET', '_POST', '_COOKIE', '_ENV', '_SESSION', '_SERVER', '_FILES'));
 
 $CONF['debug'] = 0;
+if ($CONF['debug']) {
+       error_reporting(E_ALL); // report all errors!
+} else {
+       error_reporting(E_ERROR | E_WARNING | E_PARSE);
+}
 
-$nucleus['version'] = 'v3.21';
-if (getNucleusPatchLevel() > 0)
-{
-       $nucleus['version'] .= '/' . getNucleusPatchLevel();
+// Avoid notices
+if (!isset($CONF['Self'])) {
+       $CONF['Self'] = $_SERVER['PHP_SELF'];
 }
 
 /*
@@ -44,67 +55,71 @@ if (getNucleusPatchLevel() > 0)
 */
 $CONF['alertOnHeadersSent'] = 1;
 $CONF['alertOnSecurityRisk'] = 1;
+$CONF['ItemURL'] = $CONF['Self'];
+$CONF['ArchiveURL'] = $CONF['Self'];
+$CONF['ArchiveListURL'] = $CONF['Self'];
+$CONF['MemberURL'] = $CONF['Self'];
+$CONF['SearchURL'] = $CONF['Self'];
+$CONF['BlogURL'] = $CONF['Self'];
+$CONF['CategoryURL'] = $CONF['Self'];
 
-/**
-  * returns the currently used version (100 = 1.00, 101 = 1.01, etc...)
-  */
-function getNucleusVersion() {
-       return 321;
+// switch URLMode back to normal when $CONF['Self'] ends in .php
+// this avoids urls like index.php/item/13/index.php/item/15
+if (!isset($CONF['URLMode']) || (($CONF['URLMode'] == 'pathinfo') && (substr($CONF['Self'], strlen($CONF['Self']) - 4) == '.php'))) {
+       $CONF['URLMode'] = 'normal';
 }
 
-/**
- * power users can install patches in between nucleus releases. These patches
- * usually add new functionality in the plugin API and allow those to
- * be tested without having to install CVS.
- */
-function getNucleusPatchLevel() {
-       return 0;
+if (getNucleusPatchLevel() > 0) {
+       $nucleus['version'] .= '/' . getNucleusPatchLevel();
 }
 
-
-if ($CONF['debug']) {
-       error_reporting(E_ALL & ~E_NOTICE);     // report almost all errors!
-                                                                               // (no uninitialized vars and such)
-} else {
-       error_reporting(E_ERROR | E_WARNING | E_PARSE);
+// Avoid notices
+if (!isset($CONF['installscript'])) {
+       $CONF['installscript'] = 0;
 }
 
 // we will use postVar, getVar, ... methods instead of HTTP_GET_VARS or _GET
-if ($CONF['installscript']!=1){ // vars were already included in install.php
-  if (phpversion() >= '4.1.0')
-         include_once($DIR_LIBS . 'vars4.1.0.php');
-  else
-         include_once($DIR_LIBS . 'vars4.0.6.php');
+if ($CONF['installscript'] != 1) { // vars were already included in install.php
+       if (phpversion() >= '4.1.0') {
+               include_once($DIR_LIBS . 'vars4.1.0.php');
+       } else {
+               include_once($DIR_LIBS . 'vars4.0.6.php');
+       }
 }
 
-function intPostVar($name) { return intval(postVar($name));}
-function intGetVar($name) { return intval(getVar($name));}
-function intRequestVar($name) { return intval(requestVar($name)); }
-function intCookieVar($name) { return intval(cookieVar($name)); }
+// sanitize option
+$bLoggingSanitizedResult=0;
+$bSanitizeAndContinue=0;
+
+$orgRequestURI = serverVar('REQUEST_URI');
+sanitizeParams();
 
 // get all variables that can come from the request and put them in the global scope
-$blogid                        = requestVar('blogid');
-$itemid                        = intRequestVar('itemid');
-$catid                 = intRequestVar('catid');
-$skinid                        = requestVar('skinid');
-$memberid              = requestVar('memberid');
-$archivelist   = requestVar('archivelist');
-$imagepopup            = requestVar('imagepopup');
-$archive               = requestVar('archive');
-$query                 = requestVar('query');
-$highlight             = requestVar('highlight');
-$amount                        = requestVar('amount');
-$action                        = requestVar('action');
-$nextaction            = requestVar('nextaction');
-$maxresults     = requestVar('maxresults');
-$startpos       = intRequestVar('startpos');
-$errormessage  = '';
-$error                 = '';
-
-if (!headers_sent())
+$blogid        = requestVar('blogid');
+$itemid        = intRequestVar('itemid');
+$catid = intRequestVar('catid');
+$skinid        = requestVar('skinid');
+$memberid = requestVar('memberid');
+$archivelist = requestVar('archivelist');
+$imagepopup = requestVar('imagepopup');
+$archive = requestVar('archive');
+$query = requestVar('query');
+$highlight = requestVar('highlight');
+$amount = requestVar('amount');
+$action = requestVar('action');
+$nextaction = requestVar('nextaction');
+$maxresults = requestVar('maxresults');
+$startpos = intRequestVar('startpos');
+$errormessage = '';
+$error = '';
+$virtualpath = ((getVar('virtualpath') != null) ? getVar('virtualpath') : serverVar('PATH_INFO'));
+
+if (!headers_sent() ) {
        header('Generator: Nucleus CMS ' . $nucleus['version']);
+}
 
 // include core classes that are needed for login & plugin handling
+include($DIR_LIBS . 'mysql.php');
 include($DIR_LIBS . 'MEMBER.php');
 include($DIR_LIBS . 'ACTIONLOG.php');
 include($DIR_LIBS . 'MANAGER.php');
@@ -115,15 +130,32 @@ $manager =& MANAGER::instance();
 // make sure there's no unnecessary escaping:
 set_magic_quotes_runtime(0);
 
+// Avoid notices
+if (!isset($CONF['UsingAdminArea'])) {
+       $CONF['UsingAdminArea'] = 0;
+}
+
 // only needed when updating logs
 if ($CONF['UsingAdminArea']) {
        include($DIR_LIBS . 'xmlrpc.inc.php');  // XML-RPC client classes
        include_once($DIR_LIBS . 'ADMIN.php');
 }
 
-
-// connect to sql
+// connect to database
 sql_connect();
+$SQLCount = 0;
+
+// logs sanitized result if need
+if ($orgRequestURI!==serverVar('REQUEST_URI')) {
+       $msg = "Sanitized [" . serverVar('REMOTE_ADDR') . "] ";
+       $msg .= $orgRequestURI . " -> " . serverVar('REQUEST_URI');
+    if ($bLoggingSanitizedResult) {
+        addToLog(WARNING, $msg);
+    }
+    if (!$bSanitizeAndContinue) {
+        die("");
+    }
+}
 
 // makes sure database connection gets closed on script termination
 register_shutdown_function('sql_disconnect');
@@ -132,34 +164,39 @@ register_shutdown_function('sql_disconnect');
 getConfig();
 
 // automatically use simpler toolbar for mozilla
-if (($CONF['DisableJsTools'] == 0) && strstr(serverVar('HTTP_USER_AGENT'),'Mozilla/5.0') && strstr(serverVar('HTTP_USER_AGENT'),'Gecko'))
+if (($CONF['DisableJsTools'] == 0) && strstr(serverVar('HTTP_USER_AGENT'), 'Mozilla/5.0') && strstr(serverVar('HTTP_USER_AGENT'), 'Gecko') ) {
        $CONF['DisableJsTools'] = 2;
+}
 
 // login if cookies set
-
-$member =& new MEMBER();
+$member = new MEMBER();
 
 // login/logout when required or renew cookies
 if ($action == 'login') {
        // Form Authentication
-       $login  = postVar('login');
-       $pw     = postVar('password');
+       $login = postVar('login');
+       $pw = postVar('password');
        $shared = intPostVar('shared'); // shared computer or not
 
-       if ($member->login($login,$pw)) {
+       if ($member->login($login, $pw) ) {
 
                $member->newCookieKey();
                $member->setCookies($shared);
 
                // allows direct access to parts of the admin area after logging in
-               if ($nextaction)
+               if ($nextaction) {
                        $action = $nextaction;
+               }
 
-               $manager->notify('LoginSuccess',array('member' => &$member));
+               $manager->notify('LoginSuccess', array('member' => &$member) );
+               $errormessage = '';
                ACTIONLOG::add(INFO, "Login successful for $login (sharedpc=$shared)");
        } else {
-               $manager->notify('LoginFailed',array('username' => $login));
-               ACTIONLOG::add(INFO, 'Login failed for ' . $login);
+               // errormessage for [%errordiv%]
+               $errormessage = 'Login failed for ' . $login;
+
+               $manager->notify('LoginFailed', array('username' => $login) );
+               ACTIONLOG::add(INFO, $errormessage);
        }
 /*
 
@@ -167,43 +204,45 @@ Backed out for now: See http://forum.nucleuscms.org/viewtopic.php?t=3684 for det
 
 } elseif (serverVar('PHP_AUTH_USER') && serverVar('PHP_AUTH_PW')) {
        // HTTP Authentication
-       $login  = serverVar('PHP_AUTH_USER');
-       $pw     = serverVar('PHP_AUTH_PW');
-
-       if ($member->login($login,$pw)) {
-               $manager->notify('LoginSuccess',array('member' => &$member));
-               ACTIONLOG::add(INFO, "HTTP authentication successful for $login");
-       } else {
-               $manager->notify('LoginFailed',array('username' => $login));
-               ACTIONLOG::add(INFO, 'HTTP authentication failed for ' . $login);
-
-               //Since bad credentials, generate an apropriate error page
-               header("WWW-Authenticate: Basic realm=\"Nucleus CMS {$nucleus['version']}\"");
-               header('HTTP/1.0 401 Unauthorized');
-               echo 'Invalid username or password';
-               exit;
-       }
+       $login  = serverVar('PHP_AUTH_USER');
+       $pw     = serverVar('PHP_AUTH_PW');
+
+       if ($member->login($login, $pw) ) {
+               $manager->notify('LoginSuccess',array('member' => &$member));
+               ACTIONLOG::add(INFO, "HTTP authentication successful for $login");
+       } else {
+               $manager->notify('LoginFailed',array('username' => $login));
+               ACTIONLOG::add(INFO, 'HTTP authentication failed for ' . $login);
+
+               //Since bad credentials, generate an apropriate error page
+               header("WWW-Authenticate: Basic realm=\"Nucleus CMS {$nucleus['version']}\"");
+               header('HTTP/1.0 401 Unauthorized');
+               echo 'Invalid username or password';
+               exit;
+       }
 */
 
-} elseif (($action == 'logout') && (!headers_sent()) && cookieVar($CONF['CookiePrefix'] . 'user')){
+} elseif (($action == 'logout') && (!headers_sent() ) && cookieVar($CONF['CookiePrefix'] . 'user') ) {
        // remove cookies on logout
-       setcookie($CONF['CookiePrefix'] .'user','',(time()-2592000),$CONF['CookiePath'],$CONF['CookieDomain'],$CONF['CookieSecure']);
-       setcookie($CONF['CookiePrefix'] .'loginkey','',(time()-2592000),$CONF['CookiePath'],$CONF['CookieDomain'],$CONF['CookieSecure']);
-       $manager->notify('Logout',array('username' => cookieVar($CONF['CookiePrefix'] .'user')));
-} elseif (cookieVar($CONF['CookiePrefix'] .'user')) {
+       setcookie($CONF['CookiePrefix'] . 'user', '', (time() - 2592000), $CONF['CookiePath'], $CONF['CookieDomain'], $CONF['CookieSecure']);
+       setcookie($CONF['CookiePrefix'] . 'loginkey', '', (time() - 2592000), $CONF['CookiePath'], $CONF['CookieDomain'], $CONF['CookieSecure']);
+       $manager->notify('Logout', array('username' => cookieVar($CONF['CookiePrefix'] . 'user') ) );
+} elseif (cookieVar($CONF['CookiePrefix'] . 'user') ) {
        // Cookie Authentication
-       $res = $member->cookielogin(cookieVar($CONF['CookiePrefix'] .'user'), cookieVar($CONF['CookiePrefix'] .'loginkey'));
+       $res = $member->cookielogin(cookieVar($CONF['CookiePrefix'] . 'user'), cookieVar($CONF['CookiePrefix'] . 'loginkey') );
 
        // renew cookies when not on a shared computer
-       if ($res && (cookieVar($CONF['CookiePrefix'] .'sharedpc') != 1) && (!headers_sent()))
+       if ($res && (cookieVar($CONF['CookiePrefix'] . 'sharedpc') != 1) && (!headers_sent() ) ) {
                $member->setCookies();
+       }
 }
 
 // login completed
-$manager->notify('PostAuthentication',array('loggedIn' => $member->isLoggedIn()));
+ticketForPlugin();
+$manager->notify('PostAuthentication', array('loggedIn' => $member->isLoggedIn() ) );
 
-// first, let's see if the site is disabled or not
-if ($CONF['DisableSite'] && !$member->isAdmin()) {
+// first, let's see if the site is disabled or not. always allow admin area access.
+if ($CONF['DisableSite'] && !$member->isAdmin() && !$CONF['UsingAdminArea']) {
        redirect($CONF['DisableSiteURL']);
        exit;
 }
@@ -213,6 +252,7 @@ include($DIR_LIBS . 'PARSER.php');
 include($DIR_LIBS . 'SKIN.php');
 include($DIR_LIBS . 'TEMPLATE.php');
 include($DIR_LIBS . 'BLOG.php');
+include($DIR_LIBS . 'BODYACTIONS.php');
 include($DIR_LIBS . 'COMMENTS.php');
 include($DIR_LIBS . 'COMMENT.php');
 //include($DIR_LIBS . 'ITEM.php');
@@ -220,14 +260,16 @@ include($DIR_LIBS . 'NOTIFICATION.php');
 include($DIR_LIBS . 'BAN.php');
 include($DIR_LIBS . 'PAGEFACTORY.php');
 include($DIR_LIBS . 'SEARCH.php');
+include($DIR_LIBS . 'entity.php');
 
 
 // set lastVisit cookie (if allowed)
-if (!headers_sent()) {
-       if ($CONF['LastVisit'])
-               setcookie($CONF['CookiePrefix'] .'lastVisit',time(),time()+2592000,$CONF['CookiePath'],$CONF['CookieDomain'],$CONF['CookieSecure']);
-       else
-               setcookie($CONF['CookiePrefix'] .'lastVisit','',(time()-2592000),$CONF['CookiePath'],$CONF['CookieDomain'],$CONF['CookieSecure']);
+if (!headers_sent() ) {
+       if ($CONF['LastVisit']) {
+               setcookie($CONF['CookiePrefix'] . 'lastVisit', time(), time() + 2592000, $CONF['CookiePath'], $CONF['CookieDomain'], $CONF['CookieSecure']);
+       } else {
+               setcookie($CONF['CookiePrefix'] . 'lastVisit', '', (time() - 2592000), $CONF['CookiePath'], $CONF['CookieDomain'], $CONF['CookieSecure']);
+       }
 }
 
 // read language file, only after user has been initialized
@@ -236,8 +278,8 @@ include($DIR_LANG . ereg_replace( '[\\|/]', '', $language) . '.php');
 
 /*
        Backed out for now: See http://forum.nucleuscms.org/viewtopic.php?t=3684 for details
-       
-// To remove after v2.5 is released and language files have been updated. 
+
+// To remove after v2.5 is released and language files have been updated.
 // Including this makes sure that language files for v2.5beta can still be used for v2.5final
 // without having weird _SETTINGS_EXTAUTH string showing up in the admin area.
 if (!defined('_MEMBERS_BYPASS'))
@@ -250,87 +292,208 @@ if (!defined('_MEMBERS_BYPASS'))
 */
 
 // make sure the archivetype skinvar keeps working when _ARCHIVETYPE_XXX not defined
-if (!defined('_ARCHIVETYPE_MONTH'))
-{
-       define('_ARCHIVETYPE_DAY','day');
-       define('_ARCHIVETYPE_MONTH','month');
+if (!defined('_ARCHIVETYPE_MONTH') ) {
+       define('_ARCHIVETYPE_DAY', 'day');
+       define('_ARCHIVETYPE_MONTH', 'month');
 }
 
-
 // decode path_info
 if ($CONF['URLMode'] == 'pathinfo') {
-       $data = explode("/",serverVar('PATH_INFO'));
-       for ($i=0;$i<sizeof($data);$i++) {
-               switch ($data[$i]) {
-                       case 'item':                    // item/1 (blogid)
-                               $i++;
-                               if ($i<sizeof($data)) $itemid = intval($data[$i]);
-                               break;
-                       case 'archives':                // archives/1 (blogid)
-                               $i++;
-                               if ($i<sizeof($data)) $archivelist = intval($data[$i]);
-                               break;
-                       case 'archive':                 // two possibilities: archive/yyyy-mm or archive/1/yyyy-mm (with blogid)
-                               if ((($i+1)<sizeof($data)) && (!strstr($data[$i+1],'-')) ){
-                                       $blogid = intval($data[++$i]);
-                               }
-                               $i++;
-                               if ($i<sizeof($data)) $archive = $data[$i];
-                               break;
-                       case 'blogid':                  // blogid/1
-                       case 'blog':                    // blog/1
-                               $i++;
-                               if ($i<sizeof($data)) $blogid = intval($data[$i]);
-                               break;
-                       case 'category':                // category/1 (catid)
-                       case 'catid':
-                               $i++;
-                               if ($i<sizeof($data)) $catid = intval($data[$i]);
-                               break;
-                       case 'member':
-                               $i++;
-                               if ($i<sizeof($data)) $memberid = intval($data[$i]);
-                               break;
-                       default:
-                               // skip...
+       // initialize keywords if this hasn't been done before
+       if ($CONF['ItemKey'] == '') {
+               $CONF['ItemKey'] = 'item';
+       }
+
+       if ($CONF['ArchiveKey'] == '') {
+               $CONF['ArchiveKey'] = 'archive';
+       }
+
+       if ($CONF['ArchivesKey'] == '') {
+               $CONF['ArchivesKey'] = 'archives';
+       }
+
+       if ($CONF['MemberKey'] == '') {
+               $CONF['MemberKey'] = 'member';
+       }
+
+       if ($CONF['BlogKey'] == '') {
+               $CONF['BlogKey'] = 'blog';
+       }
+
+       if ($CONF['CategoryKey'] == '') {
+               $CONF['CategoryKey'] = 'category';
+       }
+
+       if ($CONF['SpecialskinKey'] == '') {
+               $CONF['SpecialskinKey'] = 'special';
+       }
+
+       $parsed = false;
+       $manager->notify(
+               'ParseURL',
+               array(
+                       'type' => basename(serverVar('SCRIPT_NAME') ), // e.g. item, blog, ...
+                       'info' => $virtualpath,
+                       'complete' => &$parsed
+               )
+       );
+
+       if (!$parsed) {
+               // default implementation
+               $data = explode("/", $virtualpath );
+               for ($i = 0; $i < sizeof($data); $i++) {
+                       switch ($data[$i]) {
+                               case $CONF['ItemKey']: // item/1 (blogid)
+                                       $i++;
+
+                                       if ($i < sizeof($data) ) {
+                                               $itemid = intval($data[$i]);
+                                       }
+                                       break;
+
+                               case $CONF['ArchivesKey']: // archives/1 (blogid)
+                                       $i++;
+
+                                       if ($i < sizeof($data) ) {
+                                               $archivelist = intval($data[$i]);
+                                       }
+                                       break;
+
+                               case $CONF['ArchiveKey']: // two possibilities: archive/yyyy-mm or archive/1/yyyy-mm (with blogid)
+                                       if ((($i + 1) < sizeof($data) ) && (!strstr($data[$i + 1], '-') ) ) {
+                                               $blogid = intval($data[++$i]);
+                                       }
+
+                                       $i++;
+
+                                       if ($i < sizeof($data) ) {
+                                               $archive = $data[$i];
+                                       }
+                                       break;
+
+                               case 'blogid': // blogid/1
+                               case $CONF['BlogKey']: // blog/1
+                                       $i++;
+
+                                       if ($i < sizeof($data) ) {
+                                               $blogid = intval($data[$i]);
+                                       }
+                                       break;
+
+                               case $CONF['CategoryKey']: // category/1 (catid)
+                               case 'catid':
+                                       $i++;
+
+                                       if ($i < sizeof($data) ) {
+                                               $catid = intval($data[$i]);
+                                       }
+                                       break;
+
+                               case $CONF['MemberKey']:
+                                       $i++;
+
+                                       if ($i < sizeof($data) ) {
+                                               $memberid = intval($data[$i]);
+                                       }
+                                       break;
+
+                case $CONF['SpecialskinKey']:
+                    $i++;
+
+                                       if ($i < sizeof($data) ) {
+                       $_REQUEST['special'] = $data[$i];
+                    }
+                    break;
+
+                               default:
+                                       // skip...
+                       }
                }
        }
 }
 
+function intPostVar($name) {
+       return intval(postVar($name) );
+}
+
+function intGetVar($name) {
+       return intval(getVar($name) );
+}
+
+function intRequestVar($name) {
+       return intval(requestVar($name) );
+}
+
+function intCookieVar($name) {
+       return intval(cookieVar($name) );
+}
+
+/**
+  * returns the currently used version (100 = 1.00, 101 = 1.01, etc...)
+  */
+function getNucleusVersion() {
+       return 330;
+}
+
+/**
+ * power users can install patches in between nucleus releases. These patches
+ * usually add new functionality in the plugin API and allow those to
+ * be tested without having to install CVS.
+ */
+function getNucleusPatchLevel() {
+       return 0;
+}
+
 /**
   * Connects to mysql server
   */
 function sql_connect() {
-       global $MYSQL_HOST, $MYSQL_USER, $MYSQL_PASSWORD, $MYSQL_DATABASE;
+       global $MYSQL_HOST, $MYSQL_USER, $MYSQL_PASSWORD, $MYSQL_DATABASE, $MYSQL_CONN;
 
-       $connection = @mysql_connect($MYSQL_HOST, $MYSQL_USER, $MYSQL_PASSWORD) or startUpError('<p>Could not connect to MySQL database.</p>','Connect Error');
-       mysql_select_db($MYSQL_DATABASE) or startUpError('<p>Could not select database: '. mysql_error().'</p>', 'Connect Error');
+       $MYSQL_CONN = @mysql_connect($MYSQL_HOST, $MYSQL_USER, $MYSQL_PASSWORD) or startUpError('<p>Could not connect to MySQL database.</p>', 'Connect Error');
+       mysql_select_db($MYSQL_DATABASE) or startUpError('<p>Could not select database: ' . mysql_error() . '</p>', 'Connect Error');
 
-       return $connection;
+       return $MYSQL_CONN;
 }
 
 /**
  * returns a prefixed nucleus table name
  */
-function sql_table($name)
-{
+function sql_table($name) {
        global $MYSQL_PREFIX;
 
-       if ($MYSQL_PREFIX)
+       if ($MYSQL_PREFIX) {
                return $MYSQL_PREFIX . 'nucleus_' . $name;
-       else
+       } else {
                return 'nucleus_' . $name;
+       }
 }
 
 function sendContentType($contenttype, $pagetype = '', $charset = _CHARSET) {
        global $manager, $CONF;
-       
-       if (!headers_sent()) {
+
+       if (!headers_sent() ) {
                // if content type is application/xhtml+xml, only send it to browsers
                // that can handle it (IE6 cannot). Otherwise, send text/html
-               
+
                // v2.5: For admin area pages, keep sending text/html (unless it's a debug version)
                //       application/xhtml+xml still causes too much problems with the javascript implementations
+
+               // v3.3: ($CONF['UsingAdminArea'] && !$CONF['debug']) gets removed,
+               //       application/xhtml+xml seems to be working, so we're going to use it if we can.
+               //
+               // Note: reverted the following function in JP version
+               //
+       /*
+               // v3.3 code
+               if (
+                               ($contenttype == 'application/xhtml+xml')
+                       &&      (!stristr(serverVar('HTTP_ACCEPT'), 'application/xhtml+xml') )
+                       ) {
+                       $contenttype = 'text/html';
+               }
+       */
+               // v3.2x code
                if (
                                ($contenttype == 'application/xhtml+xml')
                        &&      (($CONF['UsingAdminArea'] && !$CONF['debug']) || !stristr(serverVar('HTTP_ACCEPT'),'application/xhtml+xml'))
@@ -338,7 +501,7 @@ function sendContentType($contenttype, $pagetype = '', $charset = _CHARSET) {
                {
                        $contenttype = 'text/html';
                }
-                       
+
                $manager->notify(
                        'PreSendContentType',
                        array(
@@ -351,13 +514,13 @@ function sendContentType($contenttype, $pagetype = '', $charset = _CHARSET) {
                // strip strange characters
                $contenttype = preg_replace('|[^a-z0-9-+./]|i', '', $contenttype);
                $charset = preg_replace('|[^a-z0-9-_]|i', '', $charset);
-               
-               header('Content-Type: ' . $contenttype . '; charset=' . $charset);                      
-       }
-       
-       
 
-       
+               if ($charset != '') {
+                       header('Content-Type: ' . $contenttype . '; charset=' . $charset);
+               } else {
+                       header('Content-Type: ' . $contenttype);
+               }
+       }
 }
 
 /**
@@ -366,7 +529,8 @@ function sendContentType($contenttype, $pagetype = '', $charset = _CHARSET) {
 function startUpError($msg, $title) {
        ?>
        <html xmlns="http://www.w3.org/1999/xhtml">
-               <head><meta http-equiv="Content-Type" content="text/html; charset=EUC-JP" /><title><?php echo htmlspecialchars($title)?></title></head>
+               <head><meta http-equiv="Content-Type" content="text/html; charset=EUC-JP" />
+               <title><?php echo htmlspecialchars($title)?></title></head>
                <body>
                        <h1><?php echo htmlspecialchars($title)?></h1>
                        <?php echo $msg?>
@@ -386,6 +550,8 @@ function sql_disconnect() {
   * executes an SQL query
   */
 function sql_query($query) {
+       global $SQLCount;
+       $SQLCount++;
        $res = mysql_query($query) or print("mySQL error with query $query: " . mysql_error() . '<p />');
        return $res;
 }
@@ -403,12 +569,16 @@ function sql_query($query) {
  *
  */
 function highlight($text, $expression, $highlight) {
-       if (!$highlight || !$expression) return $text;
-       if (is_array($expression) && (count($expression) == 0))
+       if (!$highlight || !$expression) {
                return $text;
+       }
+
+       if (is_array($expression) && (count($expression) == 0) ) {
+               return $text;
+       }
 
        // add a tag in front (is needed for preg_match_all to work correct)
-       $text = '<!--h-->'.$text;
+       $text = '<!--h-->' . $text;
 
        // split the HTML up so we have HTML tags
        // $matches[0][i] = HTML + text
@@ -419,15 +589,20 @@ function highlight($text, $expression, $highlight) {
        // throw it all together again while applying the highlight to the text pieces
        $result = '';
        for ($i = 0; $i < sizeof($matches[2]); $i++) {
-               if ($i != 0) $result .= $matches[1][$i];
+               if ($i != 0) {
+                       $result .= $matches[1][$i];
+               }
+
+               if (is_array($expression) ) {
+                       foreach ($expression as $regex) {
+                               if ($regex) {
+                                       $matches[2][$i] = @eregi_replace($regex, $highlight, $matches[2][$i]);
+                               }
+                       }
 
-               if (is_array($expression)) {
-                       foreach ($expression as $regex)
-                               if ($regex)
-                                       $matches[2][$i] = @eregi_replace($regex,$highlight,$matches[2][$i]);
                        $result .= $matches[2][$i];
                } else {
-                       $result .= @eregi_replace($expression,$highlight,$matches[2][$i]);
+                       $result .= @eregi_replace($expression, $highlight, $matches[2][$i]);
                }
        }
 
@@ -441,54 +616,66 @@ function parseHighlight($query) {
        // TODO: add more intelligent splitting logic
 
        // get rid of quotes
-       $query = preg_replace('/\'|"/','',$query);
+       $query = preg_replace('/\'|"/', '', $query);
 
-       if (!query) return array();
+       if (!query) {
+               return array();
+       }
 
        $aHighlight = explode(' ', $query);
 
-       for ($i = 0; $i<count($aHighlight); $i++) {
+       for ($i = 0; $i < count($aHighlight); $i++) {
                $aHighlight[$i] = trim($aHighlight[$i]);
-               if (strlen($aHighlight[$i]) < 3)
+
+               if (strlen($aHighlight[$i]) < 3) {
                        unset($aHighlight[$i]);
+               }
        }
 
-       if (count($aHighlight) == 1)
+       if (count($aHighlight) == 1) {
                return $aHighlight[0];
-       else
+       } else {
                return $aHighlight;
+       }
 }
 
 /**
   * Checks if email address is valid
   */
 function isValidMailAddress($address) {
-       if (preg_match('/^[a-zA-Z0-9\._-]+@[a-zA-Z0-9\._-]+\.[A-Za-z]{2,5}$/', $address))
+       if (preg_match('/^[a-zA-Z+0-9\._-]+@[a-zA-Z0-9\._-]+\.[A-Za-z]{2,5}$/', $address)) {
                return 1;
-       else
+       } else {
                return 0;
+       }
 }
 
 
 // some helper functions
 function getBlogIDFromName($name) {
-       return quickQuery('SELECT bnumber as result FROM '.sql_table('blog').' WHERE bshortname="'.addslashes($name).'"');
+       return quickQuery('SELECT bnumber as result FROM ' . sql_table('blog') . ' WHERE bshortname="' . addslashes($name) . '"');
 }
+
 function getBlogNameFromID($id) {
-       return quickQuery('SELECT bname as result FROM '.sql_table('blog').' WHERE bnumber='.intval($id));
+       return quickQuery('SELECT bname as result FROM ' . sql_table('blog') . ' WHERE bnumber=' . intval($id) );
 }
+
 function getBlogIDFromItemID($itemid) {
-       return quickQuery('SELECT iblog as result FROM '.sql_table('item').' WHERE inumber='.intval($itemid));
+       return quickQuery('SELECT iblog as result FROM ' . sql_table('item') . ' WHERE inumber=' . intval($itemid) );
 }
+
 function getBlogIDFromCommentID($commentid) {
-       return quickQuery('SELECT cblog as result FROM '.sql_table('comment').' WHERE cnumber='.intval($commentid));
+       return quickQuery('SELECT cblog as result FROM ' . sql_table('comment') . ' WHERE cnumber=' . intval($commentid) );
 }
+
 function getBlogIDFromCatID($catid) {
-       return quickQuery('SELECT cblog as result FROM '.sql_table('category').' WHERE catid='.intval($catid));
+       return quickQuery('SELECT cblog as result FROM ' . sql_table('category') . ' WHERE catid=' . intval($catid) );
 }
+
 function getCatIDFromName($name) {
-       return quickQuery('SELECT catid as result FROM '.sql_table('category').' WHERE cname="'.addslashes($name).'"');
+       return quickQuery('SELECT catid as result FROM ' . sql_table('category') . ' WHERE cname="' . addslashes($name) . '"');
 }
+
 function quickQuery($q) {
        $res = sql_query($q);
        $obj = mysql_fetch_object($res);
@@ -496,7 +683,8 @@ function quickQuery($q) {
 }
 
 function getPluginNameFromPid($pid) {
-       $obj = mysql_fetch_object(sql_query('SELECT pfile FROM '.sql_table('plugin').' WHERE pid='.intval($pid)));
+       $res = sql_query('SELECT pfile FROM ' . sql_table('plugin') . ' WHERE pid=' . intval($pid) );
+       $obj = mysql_fetch_object($res);
        return $obj->pfile;
 }
 
@@ -508,30 +696,31 @@ function selector() {
 
        $actionNames = array('addcomment', 'sendmessage', 'createaccount', 'forgotpassword', 'votepositive', 'votenegative', 'plugin');
        $action = requestVar('action');
-       if (in_array($action, $actionNames))
-       {
+
+       if (in_array($action, $actionNames) ) {
                global $DIR_LIBS, $errormessage;
                include_once($DIR_LIBS . 'ACTION.php');
-               $a =& new ACTION();
+               $a = new ACTION();
                $errorInfo = $a->doAction($action);
-               if ($errorInfo)
+
+               if ($errorInfo) {
                        $errormessage = $errorInfo['message'];
-       }       
+               }
+       }
 
        // show error when headers already sent out
        if (headers_sent() && $CONF['alertOnHeadersSent']) {
 
                // try to get line number/filename (extra headers_sent params only exists in PHP 4.3+)
-               if (function_exists('version_compare') && version_compare('4.3.0', phpversion(), '<=')) {
+               if (function_exists('version_compare') && version_compare('4.3.0', phpversion(), '<=') ) {
                        headers_sent($hsFile, $hsLine);
-                       $extraInfo = ' in <code>'.$hsFile.'</code> line <code>'.$hsLine.'</code>';
+                       $extraInfo = ' in <code>' . $hsFile . '</code> line <code>' . $hsLine . '</code>';
                } else {
                        $extraInfo = '';
                }
 
-
                startUpError(
-                       '<p>The page headers have already been sent out'.$extraInfo.'. This could cause Nucleus not to work in the expected way.</p><p>Usually, this is caused by spaces or newlines at the end of the <code>config.php</code> file, at the end of the language file or at the end of a plugin file. Please check this and try again.</p><p>If you don\'t want to see this error message again, without solving the problem, set <code>$CONF[\'alertOnHeadersSent\']</code> in <code>globalfunctions.php</code> to <code>0</code></p>',
+                       '<p>The page headers have already been sent out' . $extraInfo . '. This could cause Nucleus not to work in the expected way.</p><p>Usually, this is caused by spaces or newlines at the end of the <code>config.php</code> file, at the end of the language file or at the end of a plugin file. Please check this and try again.</p><p>If you don\'t want to see this error message again, without solving the problem, set <code>$CONF[\'alertOnHeadersSent\']</code> in <code>globalfunctions.php</code> to <code>0</code></p>',
                        'Page headers already sent'
                );
                exit;
@@ -539,70 +728,77 @@ function selector() {
 
        // make is so ?archivelist without blogname or blogid shows the archivelist
        // for the default weblog
-       if (serverVar('QUERY_STRING') == 'archivelist')
+       if (serverVar('QUERY_STRING') == 'archivelist') {
                $archivelist = $CONF['DefaultBlog'];
+       }
 
        // now decide which type of skin we need
        if ($itemid) {
                // itemid given -> only show that item
                $type = 'item';
-               if (!$manager->existsItem($itemid,0,0))
-                       doError(_ERROR_NOSUCHITEM);
 
+               if (!$manager->existsItem($itemid,0,0) ) {
+                       doError(_ERROR_NOSUCHITEM);
+               }
 
                global $itemidprev, $itemidnext, $catid, $itemtitlenext, $itemtitleprev;
 
-               // 1. get timestamp and blogid for item
-               $query = 'SELECT itime, iblog FROM '.sql_table('item').' WHERE inumber=' . intval($itemid);
+               // 1. get timestamp, blogid and catid for item
+               $query = 'SELECT itime, iblog, icat FROM ' . sql_table('item') . ' WHERE inumber=' . intval($itemid);
                $res = sql_query($query);
                $obj = mysql_fetch_object($res);
 
                // if a different blog id has been set through the request or selectBlog(),
-               // jump to correct url
-//             if ($blogid && (intval($blogid) != $obj->iblog))
+               // deny access
+//             if ($blogid && (intval($blogid) != $obj->iblog) ) {
 //                     doError(_ERROR_NOSUCHITEM);
+//             }
                if ($blogid && (intval($blogid) != $obj->iblog)) {
-                  if (!headers_sent()) {
-                         $b =& $manager->getBlog($obj->iblog);
-                         $correctURL = $b->getURL();
-
-                         if ($CONF['URLMode'] == 'pathinfo') {
-                                if (substr($correctURL,strlen($correctURL)-1,1)=='/')
-                                       $correctURL .= 'item/' . $itemid;
-                                else
-                                       $correctURL .= '/item/' . $itemid;
-                         }
-                         else
-                                $correctURL .= '?itemid=' . $itemid;
-
-                         redirect($correctURL);
-                         exit;
-                  }
-                  else doError(_ERROR_NOSUCHITEM);
+                       if (!headers_sent()) {
+                               $b =& $manager->getBlog($obj->iblog);
+                               $CONF['ItemURL'] = $b->getURL();
+                               if ($CONF['URLMode'] == 'pathinfo' and substr($CONF['ItemURL'],-1) == '/')
+                                       $CONF['ItemURL'] = substr($CONF['ItemURL'], 0, -1);
+                               $correctURL = createItemLink($itemid, '');
+                               redirect($correctURL);
+                               exit;
+                       } else {
+                               doError(_ERROR_NOSUCHITEM);
+                       }
+               }
+
+               // if a category has been selected which doesn't match the item, ignore the
+               // category. #85
+               if (($catid != 0) && ($catid != $obj->icat) ) {
+                       $catid = 0;
                }
 
                $blogid = $obj->iblog;
                $timestamp = strtotime($obj->itime);
 
                $b =& $manager->getBlog($blogid);
-               if ($b->isValidCategory($catid))
+
+               if ($b->isValidCategory($catid) ) {
                        $catextra = ' and icat=' . $catid;
+               }
 
                // get previous itemid and title
-               $query = 'SELECT inumber, ititle FROM '.sql_table('item').' WHERE itime<' . mysqldate($timestamp) . ' and idraft=0 and iblog=' . $blogid . $catextra . ' ORDER BY itime DESC LIMIT 1';
+               $query = 'SELECT inumber, ititle FROM ' . sql_table('item') . ' WHERE itime<' . mysqldate($timestamp) . ' and idraft=0 and iblog=' . $blogid . $catextra . ' ORDER BY itime DESC LIMIT 1';
                $res = sql_query($query);
 
                $obj = mysql_fetch_object($res);
+
                if ($obj) {
                        $itemidprev = $obj->inumber;
                        $itemtitleprev = $obj->ititle;
-       }
+               }
 
                // get next itemid and title
-               $query = 'SELECT inumber, ititle FROM '.sql_table('item').' WHERE itime>' . mysqldate($timestamp) . ' and itime <= ' . mysqldate(time()) . ' and idraft=0 and iblog=' . $blogid . $catextra . ' ORDER BY itime ASC LIMIT 1';
+               $query = 'SELECT inumber, ititle FROM ' . sql_table('item') . ' WHERE itime>' . mysqldate($timestamp) . ' and itime <= ' . mysqldate($b->getCorrectTime()) . ' and idraft=0 and iblog=' . $blogid . $catextra . ' ORDER BY itime ASC LIMIT 1';
                $res = sql_query($query);
 
                $obj = mysql_fetch_object($res);
+
                if ($obj) {
                        $itemidnext = $obj->inumber;
                        $itemtitlenext = $obj->ititle;
@@ -612,33 +808,80 @@ function selector() {
                // show archive
                $type = 'archive';
 
-               // get next and prev month links
-               global $archivenext, $archiveprev, $archivetype;
+               // get next and prev month links ...
+               global $archivenext, $archiveprev, $archivetype, $archivenextexists, $archiveprevexists;
+
+               // sql queries for the timestamp of the first and the last published item
+               $query = "SELECT UNIX_TIMESTAMP(itime) as result FROM ".sql_table('item')." WHERE idraft=0 ORDER BY itime ASC";
+               $first_timestamp=quickQuery ($query); 
+               $query = "SELECT UNIX_TIMESTAMP(itime) as result FROM ".sql_table('item')." WHERE idraft=0 ORDER BY itime DESC";
+               $last_timestamp=quickQuery ($query); 
+
+               sscanf($archive, '%d-%d-%d', $y, $m, $d);
 
-               sscanf($archive,'%d-%d-%d',$y,$m,$d);
                if ($d != 0) {
                        $archivetype = _ARCHIVETYPE_DAY;
-                       $t = mktime(0,0,0,$m,$d,$y);
-                       $archiveprev = strftime('%Y-%m-%d',$t - (24*60*60));
-                       $archivenext = strftime('%Y-%m-%d',$t + (24*60*60));
+                       $t = mktime(0, 0, 0, $m, $d, $y);
+
+                       $archiveprev = strftime('%Y-%m-%d', $t - (24 * 60 * 60) );
+                       // check for published items                    
+                       if ($t > $first_timestamp) {
+                               $archiveprevexists = true;
+                       }
+                       else {
+                               $archiveprevexists = false;
+                       }
+
+                       // one day later
+//                     $t += 86400; 
+//                     $archivenext = strftime('%Y-%m-%d', $t);
+                       $archivenext = strftime('%Y-%m-%d', $t + (24 * 60 * 60) );
+                       if ($t + (24 * 60 * 60) < $last_timestamp) {
+                               $archivenextexists = true;
+                       }
+                       else {
+                               $archivenextexists = false;
+                       }
 
                } else {
                        $archivetype = _ARCHIVETYPE_MONTH;
-                       $t = mktime(0,0,0,$m,1,$y);
-                       $archiveprev = strftime('%Y-%m',$t - (1*24*60*60));
-                       $archivenext = strftime('%Y-%m',$t + (32*24*60*60));
-               }
+                       $t = mktime(0, 0, 0, $m, 1, $y);
+
+                       $archiveprev = strftime('%Y-%m', $t - (1 * 24 * 60 * 60) );
+                       if ($t > $first_timestamp) {
+                               $archiveprevexists = true;
+                       }
+                       else {
+                               $archiveprevexists = false;
+                       }
 
+//                     $archivenext = strftime('%Y-%m', $t + (32 * 24 * 60 * 60) );
+                       // timestamp for the next month                 
+                       $t = mktime(0, 0, 0, $m+1, 1, $y);
+                       $archivenext = strftime('%Y-%m', $t);
+                       if ($t < $last_timestamp) {
+                               $archivenextexists = true;
+                       }
+                       else {
+                               $archivenextexists = false;
+                       }
+               }
 
        } elseif ($archivelist) {
                $type = 'archivelist';
-               if (intval($archivelist) != 0)
-                       $blogid = $archivelist;
-               else
+
+               if (is_numeric($archivelist)) {
+                       $blogid = intVal($archivelist);
+               } else {
                        $blogid = getBlogIDFromName($archivelist);
-               if (!$blogid) doError(_ERROR_NOSUCHBLOG);
+               }
+
+               if (!$blogid) {
+                       doError(_ERROR_NOSUCHBLOG);
+               }
+
        } elseif ($query) {
-           global $startpos;
+               global $startpos;
                $type = 'search';
                $query = stripslashes($query);
                if(preg_match("/^(\xA1{2}|\xe3\x80{2}|\x20)+$/",$query)){
@@ -646,14 +889,24 @@ function selector() {
                }
                $order = (_CHARSET == 'EUC-JP') ? 'EUC-JP, UTF-8,' : 'UTF-8, EUC-JP,';
                $query = mb_convert_encoding($query, _CHARSET, $order.' JIS, SJIS, ASCII');
-               if (intval($blogid)==0)
+               if (is_numeric($blogid)) {
+                       $blogid = intVal($blogid);
+               } else {
                        $blogid = getBlogIDFromName($blogid);
-               if (!$blogid) doError(_ERROR_NOSUCHBLOG);
+               }
+
+               if (!$blogid) {
+                       doError(_ERROR_NOSUCHBLOG);
+               }
+
        } elseif ($memberid) {
                $type = 'member';
-               if (!MEMBER::existsID($memberid))
+
+               if (!MEMBER::existsID($memberid) ) {
                        doError(_ERROR_NOSUCHMEMBER);
-               $memberinfo = MEMBER::createFromID($memberid);
+               }
+
+               $memberinfo = $manager->getMember($memberid);
 
        } elseif ($imagepopup) {
                // media object (images etc.)
@@ -663,33 +916,46 @@ function selector() {
                // TODO: set some vars?
        } else {
                // show regular index page
-           global $startpos;
+               global $startpos;
                $type = 'index';
        }
 
        // decide which blog should be displayed
-       if (!$blogid)
+       if (!$blogid) {
                $blogid = $CONF['DefaultBlog'];
+       }
 
        $b =& $manager->getBlog($blogid);
        $blog = $b;     // references can't be placed in global variables?
-       if (!$blog->isValid)
+
+       if (!$blog->isValid) {
                doError(_ERROR_NOSUCHBLOG);
+       }
 
        // set catid if necessary
-       if ($catid)
+       if ($catid) {
                $blog->setSelectedCategory($catid);
+       }
 
        // decide which skin should be used
-       if ($skinid != '' && ($skinid == 0))
+       if ($skinid != '' && ($skinid == 0) ) {
                selectSkin($skinid);
-       if (!$skinid)
+       }
+
+       if (!$skinid) {
                $skinid = $blog->getDefaultSkin();
+       }
 
-       
-       $skin =& new SKIN($skinid);
-       if (!$skin->isValid)
+       $special = requestVar('special');
+       if (!empty($special) && isValidShortName($special)) {
+               $type = strtolower($special);
+       }
+
+       $skin = new SKIN($skinid);
+
+       if (!$skin->isValid) {
                doError(_ERROR_NOSUCHSKIN);
+       }
 
        // parse the skin
        $skin->parse($type);
@@ -702,18 +968,20 @@ function doError($msg, $skin = '') {
        global $errormessage, $CONF, $skinid, $blogid, $manager;
 
        if ($skin == '') {
-               if (SKIN::existsID($skinid)) {
-                       $skin =& new SKIN($skinid);
-               } elseif ($manager->existsBlogID($blogid)) {
+
+               if (SKIN::existsID($skinid) ) {
+                       $skin = new SKIN($skinid);
+               } elseif ($manager->existsBlogID($blogid) ) {
                        $blog =& $manager->getBlog($blogid);
-                       $skin =& new SKIN($blog->getDefaultSkin());
+                       $skin = new SKIN($blog->getDefaultSkin() );
                } elseif ($CONF['DefaultBlog']) {
                        $blog =& $manager->getBlog($CONF['DefaultBlog']);
-                       $skin =& new SKIN($blog->getDefaultSkin());
+                       $skin = new SKIN($blog->getDefaultSkin() );
                } else {
                        // this statement should actually never be executed
-                       $skin =& new SKIN($CONF['BaseSkin']);
+                       $skin = new SKIN($CONF['BaseSkin']);
                }
+
        }
 
        $errormessage = $msg;
@@ -724,31 +992,53 @@ function doError($msg, $skin = '') {
 function getConfig() {
        global $CONF;
 
-       $query = 'SELECT * FROM '.sql_table('config');
+       $query = 'SELECT * FROM ' . sql_table('config');
        $res = sql_query($query);
-       while ($obj = mysql_fetch_object($res)) {
+
+       while ($obj = mysql_fetch_object($res) ) {
                $CONF[$obj->name] = $obj->value;
        }
 }
 
 // some checks for names of blogs, categories, templates, members, ...
-function isValidShortName($name) {             return eregi('^[a-z0-9]+$', $name); }
-function isValidDisplayName($name) {   return eregi('^[a-z0-9]+[a-z0-9 ]*[a-z0-9]+$', $name); }
-function isValidCategoryName($name) {  return 1; } 
-function isValidTemplateName($name) {  return eregi('^[a-z0-9/]+$', $name); }
-function isValidSkinName($name) {              return eregi('^[a-z0-9/]+$', $name); }
+function isValidShortName($name) {
+       return eregi('^[a-z0-9]+$', $name);
+}
+
+function isValidDisplayName($name) {
+       return eregi('^[a-z0-9]+[a-z0-9 ]*[a-z0-9]+$', $name);
+}
+
+function isValidCategoryName($name) {
+       return 1;
+}
+
+function isValidTemplateName($name) {
+       return eregi('^[a-z0-9/]+$', $name);
+}
+
+function isValidSkinName($name) {
+       return eregi('^[a-z0-9/]+$', $name);
+}
 
 // add and remove linebreaks
-function addBreaks($var) {                             return nl2br($var); }
-function removeBreaks($var) {                  return preg_replace("/<br \/>([\r\n])/","$1",$var); }
+function addBreaks($var) {
+       return nl2br($var);
+}
+
+function removeBreaks($var) {
+       return preg_replace("/<br \/>([\r\n])/", "$1", $var);
+}
 
 // shortens a text string to maxlength ($toadd) is what needs to be added
 // at the end (end length is <= $maxlength)
 function shorten($text, $maxlength, $toadd) {
        // 1. remove entities...
-       $trans = get_html_translation_table(HTML_ENTITIES);
+//     $trans = get_html_translation_table(HTML_ENTITIES);
+       $trans = get_html_translation_table(HTML_SPECIALCHARS); // for Japanese
        $trans = array_flip($trans);
        $text = strtr($text, $trans);
+
        // 2. the actual shortening
        if (strlen($text) > $maxlength)
                $text = mb_strimwidth($text, 0, $maxlength, $toadd, _CHARSET);
@@ -760,7 +1050,7 @@ function shorten($text, $maxlength, $toadd) {
   * quotes around it.
   */
 function mysqldate($timestamp) {
-       return '"' . date('Y-m-d H:i:s',$timestamp) . '"';
+       return '"' . date('Y-m-d H:i:s', $timestamp) . '"';
 }
 
 /**
@@ -771,8 +1061,9 @@ function selectBlog($shortname) {
        $blogid = getBlogIDFromName($shortname);
 
        // also force archivelist variable, if it is set
-       if ($archivelist)
+       if ($archivelist) {
                $archivelist = $blogid;
+       }
 }
 
 function selectSkin($skinname) {
@@ -786,13 +1077,14 @@ function selectSkin($skinname) {
  */
 function selectCategory($cat) {
        global $catid;
-       if (is_numeric($cat))
+       if (is_numeric($cat) ) {
                $catid = intval($cat);
-       else
+       } else {
                $catid = getCatIDFromName($cat);
+       }
 }
 
-function selectItem($id){
+function selectItem($id) {
        global $itemid;
        $itemid = intval($id);
 }
@@ -803,16 +1095,24 @@ function selectLanguage($language) {
        include($DIR_LANG . ereg_replace( '[\\|/]', '', $language) . '.php');
 }
 
-function parseFile($filename) {
-       $handler =& new ACTIONS('fileparser');
-       $parser =& new PARSER(SKIN::getAllowedActionsForType('fileparser'), $handler);
+function parseFile($filename, $includeMode = 'normal', $includePrefix = '') {
+       $handler = new ACTIONS('fileparser');
+       $parser = new PARSER(SKIN::getAllowedActionsForType('fileparser'), $handler);
        $handler->parser =& $parser;
 
-       if (!file_exists($filename)) doError('A file is missing');
+       // set IncludeMode properties of parser
+       PARSER::setProperty('IncludeMode', $includeMode);
+       PARSER::setProperty('IncludePrefix', $includePrefix);
+
+       if (!file_exists($filename) ) {
+               doError('A file is missing');
+       }
 
        $fsize = filesize($filename);
-       if ($fsize <= 0)
+
+       if ($fsize <= 0) {
                return;
+       }
 
        // read file
        $fd = fopen ($filename, 'r');
@@ -831,7 +1131,9 @@ function debug($msg) {
 }
 
 // shortcut
-function addToLog($level, $msg) { ACTIONLOG::add($level, $msg); }
+function addToLog($level, $msg) {
+       ACTIONLOG::add($level, $msg);
+}
 
 // shows a link to help file
 function help($id) {
@@ -839,7 +1141,7 @@ function help($id) {
 }
 
 function helpHtml($id) {
-       return helplink($id) . '<img src="documentation/icon-help.gif" width="15" height="15" alt="'._HELP_TT.'" /></a>';
+       return helplink($id) . '<img src="documentation/icon-help.gif" width="15" height="15" alt="' . _HELP_TT . '" /></a>';
 }
 
 function helplink($id) {
@@ -863,19 +1165,21 @@ function getMailFooter() {
 function getLanguageName() {
        global $CONF, $member;
 
-       if ($member) {
+       if ($member && $member->isLoggedIn() ) {
                // try to use members language
                $memlang = $member->getLanguage();
 
-               if (($memlang != '') && (checkLanguage($memlang)))
+               if (($memlang != '') && (checkLanguage($memlang) ) ) {
                        return $memlang;
+               }
        }
 
        // use default language
-       if (checkLanguage($CONF['Language']))
+       if (checkLanguage($CONF['Language']) ) {
                return $CONF['Language'];
-       else
+       } else {
                return 'english';
+       }
 }
 
 /**
@@ -900,7 +1204,9 @@ function includephp($filename) {
        // other
        global $PATH_INFO, $HTTPS, $HTTP_RAW_POST_DATA, $HTTP_X_FORWARDED_FOR;
 
-       if (@file_exists($filename)) include($filename);
+       if (@file_exists($filename) ) {
+               include($filename);
+       }
 }
 
 /**
@@ -910,99 +1216,158 @@ function checkLanguage($lang) {
        global $DIR_LANG ;
        return file_exists($DIR_LANG . ereg_replace( '[\\|/]', '', $lang) . '.php');
 }
+
 function checkPlugin($plug) {
        global $DIR_PLUGINS;
        return file_exists($DIR_PLUGINS . ereg_replace( '[\\|/]', '', $plug) . '.php');
 }
 
-
-$CONF['ItemURL'] = $CONF['Self'];
-$CONF['ArchiveURL'] = $CONF['Self'];
-$CONF['ArchiveListURL'] = $CONF['Self'];
-$CONF['MemberURL'] = $CONF['Self'];
-$CONF['SearchURL'] = $CONF['Self'];
-$CONF['BlogURL'] = $CONF['Self'];
-$CONF['CategoryURL'] = $CONF['Self'];
-
-// switch URLMode back to normal when $CONF['Self'] ends in .php
-// this avoids urls like index.php/item/13/index.php/item/15
-if (   ($CONF['URLMode'] == 'pathinfo')
-       &&      (substr($CONF['Self'], strlen($CONF['Self']) - 4) == '.php')
-       ) {
-       $CONF['URLMode'] = 'normal';
-}
-
 /**
   * Centralisation of the functions that generate links
   */
 function createItemLink($itemid, $extra = '') {
-       global $CONF;
-       if ($CONF['URLMode'] == 'pathinfo')
-               $link = $CONF['ItemURL'] . '/item/' . $itemid;
-       else
-               $link = $CONF['ItemURL'] . '?itemid=' . $itemid;
-       return addLinkParams($link, $extra);
+       return createLink('item', array('itemid' => $itemid, 'extra' => $extra) );
 }
+
 function createMemberLink($memberid, $extra = '') {
-       global $CONF;
-       if ($CONF['URLMode'] == 'pathinfo')
-               $link = $CONF['MemberURL'] . '/member/' . $memberid;
-       else
-               $link = $CONF['MemberURL'] . '?memberid=' . $memberid;
-       return addLinkParams($link, $extra);
+       return createLink('member', array('memberid' => $memberid, 'extra' => $extra) );
 }
+
 function createCategoryLink($catid, $extra = '') {
-       global $CONF;
-       if ($CONF['URLMode'] == 'pathinfo')
-               $link = $CONF['CategoryURL'] . '/category/' . $catid;
-       else
-               $link = $CONF['CategoryURL'] . '?catid=' . $catid;
-       return addLinkParams($link, $extra);
+       return createLink('category', array('catid' => $catid, 'extra' => $extra) );
 }
+
 function createArchiveListLink($blogid = '', $extra = '') {
-       global $CONF;
-       if (!$blogid)
-               $blogid = $CONF['DefaultBlog'];
-       if ($CONF['URLMode'] == 'pathinfo')
-               $link = $CONF['ArchiveListURL'] . '/archives/' . $blogid;
-       else
-               $link = $CONF['ArchiveListURL'] . '?archivelist=' . $blogid;
-       return addLinkParams($link, $extra);
+       return createLink('archivelist', array('blogid' => $blogid, 'extra' => $extra) );
 }
+
 function createArchiveLink($blogid, $archive, $extra = '') {
-       global $CONF;
-       if ($CONF['URLMode'] == 'pathinfo')
-               $link = $CONF['ArchiveURL'] . '/archive/'.$blogid.'/' . $archive;
-       else
-               $link = $CONF['ArchiveURL'] . '?blogid='.$blogid.'&amp;archive=' . $archive;
-       return addLinkParams($link, $extra);
-}
-function createBlogLink($url, $params) {
-       return addLinkParams($url . '?', $params);
+       return createLink('archive', array('blogid' => $blogid, 'archive' => $archive, 'extra' => $extra) );
 }
+
 function createBlogidLink($blogid, $params = '') {
-       global $CONF;
-       if ($CONF['URLMode'] == 'pathinfo')
-               $link = $CONF['BlogURL'] . '/blog/' . $blogid;
-       else
-               $link = $CONF['BlogURL'] . '?blogid=' . $blogid;
-       return addLinkParams($link, $params);
+       return createLink('blog', array('blogid' => $blogid, 'extra' => $params) );
+}
+
+function createLink($type, $params) {
+       global $manager, $CONF;
+
+       $generatedURL = '';
+       $usePathInfo = ($CONF['URLMode'] == 'pathinfo');
+
+       // ask plugins first
+       $created = false;
+
+       if ($usePathInfo) {
+               $manager->notify(
+                       'GenerateURL',
+                       array(
+                               'type' => $type,
+                               'params' => $params,
+                               'completed' => &$created,
+                               'url' => &$url
+                       )
+               );
+       }
+
+       // if a plugin created the URL, return it
+       if ($created) {
+               return $url;
+       }
+
+       // default implementation
+       switch ($type) {
+               case 'item':
+                       if ($usePathInfo) {
+                               $url = $CONF['ItemURL'] . '/' . $CONF['ItemKey'] . '/' . $params['itemid'];
+                       } else {
+                               $url = $CONF['ItemURL'] . '?itemid=' . $params['itemid'];
+                       }
+                       break;
+
+               case 'member':
+                       if ($usePathInfo) {
+                               $url = $CONF['MemberURL'] . '/' . $CONF['MemberKey'] . '/' . $params['memberid'];
+                       } else {
+                               $url = $CONF['MemberURL'] . '?memberid=' . $params['memberid'];
+                       }
+                       break;
+
+               case 'category':
+                       if ($usePathInfo) {
+                               $url = $CONF['CategoryURL'] . '/' . $CONF['CategoryKey'] . '/' . $params['catid'];
+                       } else {
+                               $url = $CONF['CategoryURL'] . '?catid=' . $params['catid'];
+                       }
+                       break;
+
+               case 'archivelist':
+                       if (!$params['blogid']) {
+                               $params['blogid'] = $CONF['DefaultBlog'];
+                       }
+
+                       if ($usePathInfo) {
+                               $url = $CONF['ArchiveListURL'] . '/' . $CONF['ArchivesKey'] . '/' . $params['blogid'];
+                       } else {
+                               $url = $CONF['ArchiveListURL'] . '?archivelist=' . $params['blogid'];
+                       }
+                       break;
+
+               case 'archive':
+                       if ($usePathInfo) {
+                               $url = $CONF['ArchiveURL'] . '/' . $CONF['ArchiveKey'] . '/'.$params['blogid'].'/' . $params['archive'];
+                       } else {
+                               $url = $CONF['ArchiveURL'] . '?blogid='.$params['blogid'].'&amp;archive=' . $params['archive'];
+                       }
+                       break;
+
+               case 'blog':
+                       if ($usePathInfo) {
+                               $url = $CONF['BlogURL'] . '/' . $CONF['BlogKey'] . '/' . $params['blogid'];
+                       } else {
+                               $url = $CONF['BlogURL'] . '?blogid=' . $params['blogid'];
+                       }
+                       break;
+       }
+
+       return addLinkParams($url, (isset($params['extra'])? $params['extra'] : null));
 }
 
+function createBlogLink($url, $params) {
+    global $CONF;
+    if ($CONF['URLMode'] == 'normal') {
+        if (strpos($url, '?') === FALSE && is_array($params)) {
+            $fParam = reset($params);
+            $fKey   = key($params);
+            array_shift($params);
+            $url .= '?' . $fKey . '=' . $fParam;
+        }
+    } elseif ($CONF['URLMode'] == 'pathinfo' && substr($url, -1) == '/') {
+        $url = substr($url, 0, -1);
+    }
+       return addLinkParams($url, $params);
+}
 
 function addLinkParams($link, $params) {
        global $CONF;
-       if (is_array($params)) {
+
+       if (is_array($params) ) {
+
                if ($CONF['URLMode'] == 'pathinfo')     {
+
                        foreach ($params as $param => $value) {
                                $link .= '/' . $param . '/' . urlencode($value);
                        }
+
                } else {
+
                        foreach ($params as $param => $value) {
                                $link .= '&amp;' . $param . '=' . urlencode($value);
                        }
+
                }
        }
+
        return $link;
 }
 
@@ -1013,99 +1378,574 @@ function addLinkParams($link, $params) {
  *             name of parameter to change (e.g. 'foo')
  * @param $value
  *             New value for that parameter (e.g. 3)
- * @result 
+ * @result
  *             altered query string (for the examples above: foo=3&bar=2&x=y)
  */
 function alterQueryStr($querystr, $param, $value) {
-    $vars = explode("&", $querystr);
-    $set  = false;
-    for ($i=0;$i<count($vars);$i++) {
-        $v = explode('=',$vars[$i]);
-        if ($v[0] == $param) {
-            $v[1]     = $value;
-            $vars[$i] = implode('=', $v);
-            $set      = true;
-            break;
-        }
-    }
-    if (!$set) {$vars[] = $param . '=' . $value;}
-    return ltrim(implode('&', $vars), '&');
+       $vars = explode('&', $querystr);
+       $set  = false;
+
+       for ($i = 0; $i < count($vars); $i++) {
+               $v = explode('=', $vars[$i]);
+
+               if ($v[0] == $param) {
+                       $v[1] = $value;
+                       $vars[$i] = implode('=', $v);
+                       $set = true;
+                       break;
+               }
+       }
+
+       if (!$set) {
+               $vars[] = $param . '=' . $value;
+       }
+
+       return ltrim(implode('&', $vars), '&');
 }
 
 // passes one variable as hidden input field (multiple fields for arrays)
 // @see passRequestVars in varsx.x.x.php
 function passVar($key, $value) {
        // array ?
-       if (is_array($value)) {
-               for ($i=0;$i<sizeof($value);$i++)
-                       passVar($key.'['.$i.']',$value[$i]);
-                       return;
+       if (is_array($value) ) {
+               for ($i = 0; $i < sizeof($value); $i++) {
+                       passVar($key . '[' . $i . ']', $value[$i]);
+               }
+
+               return;
        }
 
        // other values: do stripslashes if needed
-       ?><input type="hidden" name="<?php echo htmlspecialchars($key)?>" value="<?php echo htmlspecialchars(undoMagic($value))?>" /><?php
+       ?><input type="hidden" name="<?php echo htmlspecialchars($key)?>" value="<?php echo htmlspecialchars(undoMagic($value) )?>" /><?php
 }
 
 /*
        Date format functions (to be used from [%date(..)%] skinvars
 */
-function formatDate($format, $timestamp, $defaultFormat) {
-       if ($format == 'rfc822') { 
-               return date('r', $timestamp); 
-       } else if ($format == 'rfc822GMT') { 
-               return gmdate('r', $timestamp); 
-       } else if ($format == 'utc') { 
-               return gmdate('Y-m-d\TH:i:s\Z', $timestamp); 
-       } else if ($format == 'iso8601') {
-               $tz = date('O', $timestamp);
-        $tz = substr($tz, 0, 3) . ':' . substr($tz, 3, 2);     
-               return gmdate('Y-m-d\TH:i:s', $timestamp) . $tz;
-       } else {  
-               return strftime($format ? $format : $defaultFormat,$timestamp); 
-       }  
-
-}
-
-function checkVars($aVars)
-{
+function formatDate($format, $timestamp, $defaultFormat, &$blog) {
+       // apply blog offset (#42)
+       $boffset = $blog ? $blog->getTimeOffset() * 3600 : 0;
+       $offset = date('Z', $timestamp) + $boffset;
+
+       switch ($format) {
+               case 'rfc822':
+                       if ($offset >= 0) {
+                               $tz = '+';
+                       } else {
+                               $tz = '-';
+                               $offset = -$offset;
+                       }
+
+                       $tz .= sprintf("%02d%02d", floor($offset / 3600), round(($offset % 3600) / 60) );
+                       return date('D, j M Y H:i:s ', $timestamp) . $tz;
+
+               case 'rfc822GMT':
+                       $timestamp -= $offset;
+                       return date('D, j M Y H:i:s ', $timestamp) . 'GMT';
+
+               case 'utc':
+                       $timestamp -= $offset;
+                       return date('Y-m-d\TH:i:s\Z', $timestamp);
+
+               case 'iso8601':
+                       if ($offset >= 0) {
+                               $tz = '+';
+                       } else {
+                               $tz = '-';
+                               $offset = -$offset;
+                       }
+
+                       $tz .= sprintf("%02d:%02d", floor($offset / 3600), round(($offset % 3600) / 60) );
+                       return date('Y-m-d\TH:i:s', $timestamp) . $tz;
+
+               default :
+                       return strftime($format ? $format : $defaultFormat, $timestamp);
+       }
+}
+
+function checkVars($aVars) {
        global $HTTP_GET_VARS, $HTTP_POST_VARS, $HTTP_COOKIE_VARS, $HTTP_ENV_VARS, $HTTP_POST_FILES, $HTTP_SESSION_VARS;
-       foreach ($aVars as $varName)
-       {
-               if (phpversion() >= '4.1.0')
-               {
-                       if (   isset($_GET[$varName]) 
-                               || isset($_POST[$varName]) 
+
+       foreach ($aVars as $varName) {
+
+               if (phpversion() >= '4.1.0') {
+
+                       if (   isset($_GET[$varName])
+                               || isset($_POST[$varName])
                                || isset($_COOKIE[$varName])
                                || isset($_ENV[$varName])
                                || isset($_SESSION[$varName])
                                || isset($_FILES[$varName])
-                       ){
+                       ) {
                                die('Sorry. An error occurred.');
                        }
+
                } else {
-                       if (   isset($HTTP_GET_VARS[$varName]) 
-                               || isset($HTTP_POST_VARS[$varName]) 
+
+                       if (   isset($HTTP_GET_VARS[$varName])
+                               || isset($HTTP_POST_VARS[$varName])
                                || isset($HTTP_COOKIE_VARS[$varName])
                                || isset($HTTP_ENV_VARS[$varName])
                                || isset($HTTP_SESSION_VARS[$varName])
                                || isset($HTTP_POST_FILES[$varName])
-                       ){
+                       ) {
                                die('Sorry. An error occurred.');
-                       }               
+                       }
+
                }
        }
 }
 
+
+/** 
+ * Sanitize parameters such as $_GET and $_SERVER['REQUEST_URI'] etc.
+ * to avoid XSS 
+ */
+function sanitizeParams()
+{
+       global $HTTP_SERVER_VARS;
+       
+       $array = array();
+       $str = '';
+       $frontParam = '';
+       
+       // REQUEST_URI of $HTTP_SERVER_VARS
+       $str =& $HTTP_SERVER_VARS["REQUEST_URI"];
+       serverStringToArray($str, $array, $frontParam);
+       sanitizeArray($array);
+       arrayToServerString($array, $frontParam, $str);
+       
+       // QUERY_STRING of $HTTP_SERVER_VARS
+       $str =& $HTTP_SERVER_VARS["QUERY_STRING"];
+       serverStringToArray($str, $array, $frontParam);
+       sanitizeArray($array);
+       arrayToServerString($array, $frontParam, $str);
+       
+       if (phpversion() >= '4.1.0') {
+               // REQUEST_URI of $_SERVER
+               $str =& $_SERVER["REQUEST_URI"];
+               serverStringToArray($str, $array, $frontParam);
+               sanitizeArray($array);
+               arrayToServerString($array, $frontParam, $str);
+       
+               // QUERY_STRING of $_SERVER
+               $str =& $_SERVER["QUERY_STRING"];
+               serverStringToArray($str, $array, $frontParam);
+               sanitizeArray($array);
+               arrayToServerString($array, $frontParam, $str);
+       }
+       
+       // $_GET
+       convArrayForSanitizing($_GET, $array);
+       sanitizeArray($array);
+       revertArrayForSanitizing($array, $_GET);
+       
+       // $_REQUEST (only GET param)
+       convArrayForSanitizing($_REQUEST, $array);
+       sanitizeArray($array);
+       revertArrayForSanitizing($array, $_REQUEST);
+}
+
 /** 
+ * Check ticket when not checked in plugin's admin page
+ * to avoid CSRF.
+ * Also avoid the access to plugin/index.php by guest user.
+ */
+function ticketForPlugin(){
+       global $CONF,$DIR_PLUGINS,$member,$ticketforplugin;
+       
+       /* initialize */
+       $ticketforplugin=array();
+       $ticketforplugin['ticket']=false;
+       
+       /* Check if using plugin's php file. */
+       if ($p_translated=serverVar('PATH_TRANSLATED')) {
+               if (!file_exists($p_translated)) $p_translated='';
+       }
+       if (!$p_translated) {
+               $p_translated=serverVar('SCRIPT_FILENAME');
+               if (!file_exists($p_translated)) {
+                       header("HTTP/1.0 404 Not Found");
+                       exit('');
+               }
+       }
+       $p_translated=str_replace('\\','/',$p_translated);
+       $d_plugins=str_replace('\\','/',$DIR_PLUGINS);
+       if (strpos($p_translated,$d_plugins)!==0) return;// This isn't plugin php file.
+       
+       /* Solve the plugin php file or admin directory */
+       $phppath=substr($p_translated,strlen($d_plugins));
+       $phppath=preg_replace('!^/!','',$phppath);// Remove the first "/" if exists.
+       $path=preg_replace('/^NP_(.*)\.php$/','$1',$phppath); // Remove the first "NP_" and the last ".php" if exists.
+       $path=preg_replace('!^([^/]*)/(.*)$!','$1',$path); // Remove the "/" and beyond.
+       
+       /* Solve the plugin name. */
+       $plugins=array();
+       $query='SELECT pfile FROM '.sql_table('plugin');
+       $res=sql_query($query);
+       while($row=mysql_fetch_row($res)) {
+               $name=substr($row[0],3);
+               $plugins[strtolower($name)]=$name;
+       }
+       mysql_free_result($res);
+       if ($plugins[$path]) $plugin_name=$plugins[$path];
+       else if (in_array($path,$plugins)) $plugin_name=$path;
+       else {
+               header("HTTP/1.0 404 Not Found");
+               exit('');
+       }
+       
+       /* Return if not index.php */
+       if ( $phppath!=strtolower($plugin_name).'/'
+               && $phppath!=strtolower($plugin_name).'/index.php' ) return;
+       
+       /* Exit if not logged in. */
+       if ( !$member->isLoggedIn() ) exit("You aren't logged in.");
+       
+       global $manager,$DIR_LIBS,$DIR_LANG,$HTTP_GET_VARS,$HTTP_POST_VARS;
+       
+       /* Check if this feature is needed (ie, if "$manager->checkTicket()" is not included in the script). */
+       if (!($p_translated=serverVar('PATH_TRANSLATED'))) $p_translated=serverVar('SCRIPT_FILENAME');
+       if ($file=@file($p_translated)) {
+               $prevline='';
+               foreach($file as $line) {
+                       if (preg_match('/[\$]manager([\s]*)[\-]>([\s]*)checkTicket([\s]*)[\(]/i',$prevline.$line)) return;
+                       $prevline=$line;
+               }
+       }
+       
+       /* Show a form if not valid ticket */
+       if ( ( strstr(serverVar('REQUEST_URI'),'?') || serverVar('QUERY_STRING')
+                       || strtoupper(serverVar('REQUEST_METHOD'))=='POST' )
+                               && (!$manager->checkTicket()) ){
+
+               if (!class_exists('PluginAdmin')) {
+                       $language = getLanguageName();
+                       include($DIR_LANG . ereg_replace( '[\\|/]', '', $language) . '.php');
+                       include($DIR_LIBS . 'PLUGINADMIN.php');
+               }
+               if (!(function_exists('mb_strimwidth') || extension_loaded('mbstring'))) {
+                       if (file_exists($DIR_LIBS.'mb_emulator/mb-emulator.php')) {
+                               global $mbemu_internals;
+                               include_once($DIR_LIBS.'mb_emulator/mb-emulator.php');
+                       }
+               }
+               $oPluginAdmin = new PluginAdmin($plugin_name);
+               $oPluginAdmin->start();
+               echo '<p>' . _ERROR_BADTICKET . "</p>\n";
+               
+               /* Show the form to confirm action */
+               // PHP 4.0.x support
+               $get=  (isset($_GET))  ? $_GET  : $HTTP_GET_VARS;
+               $post= (isset($_POST)) ? $_POST : $HTTP_POST_VARS;
+               // Resolve URI and QUERY_STRING
+               if ($uri=serverVar('REQUEST_URI')) {
+                       list($uri,$qstring)=explode('?',$uri);
+               } else {
+                       if ( !($uri=serverVar('PHP_SELF')) ) $uri=serverVar('SCRIPT_NAME');
+                       $qstring=serverVar('QUERY_STRING');
+               }
+               if ($qstring) $qstring='?'.$qstring;
+               echo '<p>'._SETTINGS_UPDATE.' : '._QMENU_PLUGINS.' <span style="color:red;">'.
+                       htmlspecialchars($plugin_name)."</span> ?</p>\n";
+               switch(strtoupper(serverVar('REQUEST_METHOD'))){
+               case 'POST':
+                       echo '<form method="POST" action="'.htmlspecialchars($uri.$qstring).'">';
+                       $manager->addTicketHidden();
+                       _addInputTags($post);
+                       break;
+               case 'GET':
+                       echo '<form method="GET" action="'.htmlspecialchars($uri).'">';
+                       $manager->addTicketHidden();
+                       _addInputTags($get);
+               default:
+                       break;
+               }
+               echo '<input type="submit" value="'._YES.'" />&nbsp;&nbsp;&nbsp;&nbsp;';
+               echo '<input type="button" value="'._NO.'" onclick="history.back(); return false;" />';
+               echo "</form>\n";
+               
+               $oPluginAdmin->end();
+               exit;
+       }
+       
+       /* Create new ticket */
+       $ticket=$manager->addTicketToUrl('');
+       $ticketforplugin['ticket']=substr($ticket,strpos($ticket,'ticket=')+7);
+}
+function _addInputTags(&$keys,$prefix=''){
+       foreach($keys as $key=>$value){
+               if ($prefix) $key=$prefix.'['.$key.']';
+               if (is_array($value)) _addInputTags($value,$key);
+               else {
+                       if (get_magic_quotes_gpc()) $value=stripslashes($value);
+                       if ($key=='ticket') continue;
+                       echo '<input type="hidden" name="'.htmlspecialchars($key).
+                               '" value="'.htmlspecialchars($value).'" />'."\n";
+               }
+       }
+}
+
+/** 
+ * Convert the server string such as $_SERVER['REQUEST_URI']
+ * to arry like arry['blogid']=1 and array['page']=2 etc.
+ */
+function serverStringToArray($str, &$array, &$frontParam)
+{
+       // init param
+       $array = array();
+       $fronParam = "";
+
+       // split front param, e.g. /index.php, and others, e.g. blogid=1&page=2
+       if (strstr($str, "?")){
+               list($frontParam, $args) = preg_split("/\?/", $str, 2);
+       }
+       else {
+               $args = $str;
+               $frontParam = "";
+       }
+       
+       // If there is no args like blogid=1&page=2, return
+       if (!strstr($str, "=") && !strlen($frontParam)) {
+               $frontParam = $str;
+               return;
+       }
+
+       $array = explode("&", $args);
+}
+
+/** 
+ * Convert array like array['blogid'] to server string
+ * such as $_SERVER['REQUEST_URI']
+ */
+function arrayToServerString($array, $frontParam, &$str)
+{
+       if (strstr($str, "?")) {
+               $str = $frontParam . "?";
+       } else {
+               $str = $frontParam;
+       }
+       if (count($array)) {
+               $str .= implode("&", $array);
+       }
+}
+
+/** 
+ * Sanitize array parameters.
+ * This function checks both key and value.
+ * - check key if it inclues " (double quote),  remove from array
+ * - check value if it includes \ (escape sequece), remove remaining string
+ */
+function sanitizeArray(&$array)
+{      
+       $excludeListForSanitization = array('query');
+//     $excludeListForSanitization = array();
+
+       foreach ($array as $k => $v) {
+
+               // split to key and value
+               list($key, $val) = preg_split("/=/", $v, 2);
+               if (!isset($val)) {
+                       continue;
+               }
+
+               // when magic quotes is on, need to use stripslashes,
+               // and then addslashes
+               if (get_magic_quotes_gpc()) {
+                       $val = stripslashes($val);
+               }
+               $val = addslashes($val);
+               
+               // if $key is included in exclude list, skip this param
+               if (!in_array($key, $excludeListForSanitization)) {
+                               
+                       // check value
+                       list($val, $tmp) = explode('\\', $val);
+                       
+                       // remove control code etc.
+                       $val = strtr($val, "\0\r\n<>'\"", "       ");
+                               
+                       // check key
+                       if (preg_match('/\"/i', $key)) {
+                               unset($array[$k]);
+                               continue;
+                       }
+                               
+                       // set sanitized info
+                       $array[$k] = sprintf("%s=%s", $key, $val);
+               }
+       }
+}
+
+/**
+ * Convert array for sanitizeArray function
+ */
+function convArrayForSanitizing($src, &$array)
+{
+       $array = array();
+       foreach ($src as $key => $val) {
+               if (key_exists($key, $_GET)) {
+                       array_push($array, sprintf("%s=%s", $key, $val));
+               }
+       }
+}
+
+/**
+ * Revert array after sanitizeArray function
+ */
+function revertArrayForSanitizing($array, &$dst)
+{
+       foreach ($array as $v) {
+               list($key, $val) = preg_split("/=/", $v, 2);
+               $dst[$key] = $val;
+       }
+}
+
+/**
  * Stops processing the request and redirects to the given URL.
  * - no actual contents should have been sent to the output yet
  * - the URL will be stripped of illegal or dangerous characters
  */
-function redirect($url)
-{
+function redirect($url) {
        $url = preg_replace('|[^a-z0-9-~+_.?#=&;,/:@%]|i', '', $url);
        header('Location: ' . $url);
        exit;
 }
 
-?>
+/**
+ * Strip HTML tags from a string
+ * This function is a bit more intelligent than a regular call to strip_tags(),
+ * because it also deletes the contents of certain tags and cleans up any
+ * unneeded whitespace.
+ */
+function stringStripTags ($string) {
+       $string = preg_replace("/<del[^>]*>.+<\/del[^>]*>/isU", '', $string);
+       $string = preg_replace("/<script[^>]*>.+<\/script[^>]*>/isU", '', $string);
+       $string = preg_replace("/<style[^>]*>.+<\/style[^>]*>/isU", '', $string);
+       $string = str_replace('>', '> ', $string);
+       $string = str_replace('<', ' <', $string);
+       $string = strip_tags($string);
+       $string = preg_replace("/\s+/", " ", $string);
+       $string = trim($string);
+       return $string;
+}
+
+/**
+ * Make a string containing HTML safe for use in a HTML attribute
+ * Tags are stripped and entities are normalized
+ */
+function stringToAttribute ($string) {
+       $string = stringStripTags($string);
+       $string = entity::named_to_numeric($string);
+       $string = entity::normalize_numeric($string);
+
+       if (_CHARSET == 'UTF-8') {
+               $string = entity::numeric_to_utf8($string);
+       }
+
+       $string = entity::specialchars($string, 'html');
+       $string = entity::numeric_to_named($string);
+       return $string;
+}
+
+/**
+ * Make a string containing HTML safe for use in a XML document
+ * Tags are stripped, entities are normalized and named entities are
+ * converted to numeric entities.
+ */
+function stringToXML ($string) {
+       $string = stringStripTags($string);
+       $string = entity::named_to_numeric($string);
+       $string = entity::normalize_numeric($string);
+
+       if (_CHARSET == 'UTF-8') {
+               $string = entity::numeric_to_utf8($string);
+       }
+
+       $string = entity::specialchars($string, 'xml');
+       return $string;
+}
+
+// START: functions from the end of file BLOG.php
+// used for mail notification (html -> text)
+function toAscii($html) {
+       // strip off most tags
+       $html = strip_tags($html,'<a>');
+       $to_replace = "/<a[^>]*href=[\"\']([^\"^']*)[\"\'][^>]*>([^<]*)<\/a>/i";
+       _links_init();
+       $ascii = preg_replace_callback ($to_replace, '_links_add', $html);
+       $ascii .= "\n\n" . _links_list();
+       return strip_tags($ascii);
+}
+
+function _links_init() {
+   global $tmp_links;
+   $tmp_links = array();
+}
+
+function _links_add($match) {
+   global $tmp_links;
+   array_push($tmp_links, $match[1]);
+   return $match[2] . ' [' . sizeof($tmp_links) .']';
+}
+
+function _links_list() {
+   global $tmp_links;
+   $output = '';
+   $i = 1;
+   foreach ($tmp_links as $current) {
+         $output .= "[$i] $current\n";
+         $i++;
+   }
+   return $output;
+}
+// END: functions from the end of file BLOG.php
+
+// START: functions from the end of file ADMIN.php
+/**
+ * @todo document this
+ */
+function encode_desc(&$data)
+    {   //_$to_entities = get_html_translation_table(HTML_ENTITIES);
+        $to_entities = get_html_translation_table(HTML_SPECIALCHARS);
+        $from_entities = array_flip($to_entities);
+        $data = str_replace('<br />','\n',$data); //hack
+        $data = strtr($data,$from_entities);
+        $data = strtr($data,$to_entities);
+        $data = str_replace('\n','<br />',$data); //hack
+        return $data;
+    }
+/**
+ * Returns the Javascript code for a bookmarklet that works on most modern browsers
+ *
+ * @param blogid
+ */
+function getBookmarklet($blogid) {
+       global $CONF;
+
+       // normal
+       $document = 'document';
+       $bookmarkletline = "javascript:Q='';x=".$document.";y=window;if(x.selection){Q=x.selection.createRange().text;}else if(y.getSelection){Q=y.getSelection();}else if(x.getSelection){Q=x.getSelection();}wingm=window.open('";
+       $bookmarkletline .= $CONF['AdminURL'] . "bookmarklet.php?blogid=$blogid";
+       $bookmarkletline .="&logtext='+escape(Q)+'&loglink='+escape(x.location.href)+'&loglinktitle='+escape(x.title),'nucleusbm','scrollbars=yes,width=600,height=500,left=10,top=10,status=yes,resizable=yes');wingm.focus();";
+
+       return $bookmarkletline;
+}
+// END: functions from the end of file ADMIN.php
+
+/**
+ * Returns a variable or null if not set
+ *
+ * @param mixed Variable
+ * @return mixed Variable
+ */
+function ifset(&$var) {
+       if (isset($var)) {
+               return $var;
+       }
+
+       return null;
+}
+
+?>
\ No newline at end of file
index 8aaf6b2..9962177 100755 (executable)
-<?php\r
-/**\r
-  * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/) \r
-  * Copyright (C) 2002-2005 The Nucleus Group\r
-  *\r
-  * This program is free software; you can redistribute it and/or\r
-  * modify it under the terms of the GNU General Public License\r
-  * as published by the Free Software Foundation; either version 2\r
-  * of the License, or (at your option) any later version.\r
-  * (see nucleus/documentation/index.html#license for more info)\r
-  *\r
-  * Media popup window for Nucleus\r
-  *\r
-  * Purpose:\r
-  *   - can be openen from an add-item form or bookmarklet popup\r
-  *   - shows a list of recent files, allowing browsing, search and \r
-  *     upload of new files\r
-  *   - close the popup by selecting a file in the list. The file gets\r
-  *     passed through to the add-item form (linkto, popupimg or inline img)\r
-  *\r
-  * $Id: media.php,v 1.3 2005-03-16 08:04:14 kimitake Exp $\r
-  * $NucleusJP$\r
-  */\r
-  \r
-$CONF = array();\r
-\r
-// defines how much media items will be shown per page. You can override this\r
-// in config.php if you like. (changing it in config.php instead of here will\r
-// allow your settings to be kept even after a Nucleus upgrade)\r
-$CONF['MediaPerPage'] = 10;\r
-\r
-// include all classes and config data\r
-include('../config.php');\r
-include($DIR_LIBS . 'MEDIA.php');      // media classes\r
-\r
-sendContentType('application/xhtml+xml', 'media');\r
-\r
-// user needs to be logged in to use this\r
-if (!$member->isLoggedIn()) {\r
-       media_loginAndPassThrough();\r
-       exit;\r
-}\r
-\r
-// check if member is on at least one teamlist\r
-$query = 'SELECT * FROM ' . sql_table('team'). ' WHERE tmember=' . $member->getID();\r
-$teams = mysql_query($query);\r
-if (mysql_num_rows($teams) == 0)\r
-       media_doError(_ERROR_DISALLOWEDUPLOAD);\r
-       \r
-// get action\r
-$action = requestVar('action');\r
-if ($action == '')\r
-       $action = 'selectmedia';\r
-       \r
-// check ticket\r
-$aActionsNotToCheck = array('selectmedia', _MEDIA_FILTER_APPLY, _MEDIA_COLLECTION_SELECT);\r
-if (!in_array($action, $aActionsNotToCheck))\r
-{\r
-       if (!$manager->checkTicket())\r
-               media_doError(_ERROR_BADTICKET);\r
-} \r
-\r
-\r
-switch($action) {\r
-       case 'chooseupload':\r
-       case _MEDIA_UPLOAD_TO:\r
-       case _MEDIA_UPLOAD_NEW:\r
-               media_choose();\r
-               break;\r
-       case 'uploadfile':\r
-               media_upload();\r
-               break;\r
-       case _MEDIA_FILTER_APPLY:\r
-       case 'selectmedia':\r
-       case _MEDIA_COLLECTION_SELECT:\r
-       default:\r
-               media_select();\r
-               break;\r
-}\r
-\r
-// select a file\r
-function media_select() {\r
-       global $member, $CONF, $DIR_MEDIA, $manager;\r
-       \r
-       media_head();\r
-       \r
-       // show 10 files + navigation buttons \r
-       // show msg when no files\r
-       // show upload form\r
-       // files sorted according to last modification date\r
-\r
-       // currently selected collection\r
-       $currentCollection = requestVar('collection');\r
-       if (!$currentCollection || !@is_dir($DIR_MEDIA . $currentCollection))\r
-               $currentCollection = $member->getID();\r
-               \r
-       \r
-       // get collection list\r
-       $collections = MEDIA::getCollectionList();\r
-\r
-       if (sizeof($collections) > 1) {\r
-       ?>\r
-               <form method="post" action="media.php"><div>\r
-                       <label for="media_collection"><?php echo htmlspecialchars(_MEDIA_COLLECTION_LABEL)?></label>\r
-                       <select name="collection" id="media_collection">\r
-                               <?php                                   foreach ($collections as $dirname => $description) {\r
-                                               echo '<option value="',htmlspecialchars($dirname),'"';\r
-                                               if ($dirname == $currentCollection) {\r
-                                                       echo ' selected="selected"';\r
-                                               }\r
-                                               echo '>',htmlspecialchars($description),'</option>';\r
-                                       }\r
-                               ?>\r
-                       </select>\r
-                       <input type="submit" name="action" value="<?php echo htmlspecialchars(_MEDIA_COLLECTION_SELECT) ?>" title="<?php echo htmlspecialchars(_MEDIA_COLLECTION_TT)?>" />\r
-                       <input type="submit" name="action" value="<?php echo htmlspecialchars(_MEDIA_UPLOAD_TO) ?>" title="<?php echo htmlspecialchars(_MEDIA_UPLOADLINK) ?>" />\r
-                       <?php $manager->addTicketHidden() ?>\r
-               </div></form>\r
-       <?php   } else {\r
-       ?>\r
-               <form method="post" action="media.php" style="float:right"><div>\r
-                       <input type="hidden" name="collection" value="<?php echo htmlspecialchars($currentCollection)?>" />\r
-                       <input type="submit" name="action" value="<?php echo htmlspecialchars(_MEDIA_UPLOAD_NEW) ?>" title="<?php echo htmlspecialchars(_MEDIA_UPLOADLINK) ?>" />\r
-                       <?php $manager->addTicketHidden() ?>\r
-               </div></form>   \r
-       <?php   } // if sizeof\r
-       \r
-       $filter = requestVar('filter'); \r
-       $offset = intRequestVar('offset');      \r
-       $arr = MEDIA::getMediaListByCollection($currentCollection, $filter);\r
-\r
-       ?>\r
-               <form method="post" action="media.php"><div>\r
-                       <label for="media_filter"><?php echo htmlspecialchars(_MEDIA_FILTER_LABEL)?></label>\r
-                       <input id="media_filter" type="text" name="filter" value="<?php echo htmlspecialchars($filter)?>" />\r
-                       <input type="submit" name="action" value="<?php echo htmlspecialchars(_MEDIA_FILTER_APPLY) ?>" />\r
-                       <input type="hidden" name="collection" value="<?php echo htmlspecialchars($currentCollection)?>" />                     \r
-                       <input type="hidden" name="offset" value="<?php echo intval($offset)?>" />                                              \r
-               </div></form>   \r
-       \r
-       <?php\r
-       \r
-       ?>      \r
-               <table width="100%">\r
-               <caption><?php echo _MEDIA_COLLECTION_LABEL . htmlspecialchars($collections[$currentCollection])?></caption>\r
-               <tr>\r
-                <th><?php echo _MEDIA_MODIFIED?></th><th><?php echo _MEDIA_FILENAME?></th><th><?php echo _MEDIA_DIMENSIONS?></th>\r
-               </tr>\r
-       \r
-       <?php   \r
-       \r
-       if (sizeof($arr)>0) {\r
-       \r
-               if (($offset + $CONF['MediaPerPage']) >= sizeof($arr))\r
-                       $offset = sizeof($arr) - $CONF['MediaPerPage'];\r
-\r
-               if ($offset < 0) $offset = 0;\r
-               \r
-               $idxStart = $offset;\r
-               $idxEnd = $offset + $CONF['MediaPerPage'];\r
-               $idxNext = $idxEnd;\r
-               $idxPrev = $idxStart - $CONF['MediaPerPage'];\r
-\r
-               if ($idxPrev < 0) $idxPrev = 0;\r
-\r
-               if ($idxEnd > sizeof($arr))\r
-                       $idxEnd = sizeof($arr);\r
-\r
-               for($i=$idxStart;$i<$idxEnd;$i++) {\r
-                       $obj = $arr[$i];\r
-                       $filename = $DIR_MEDIA . $currentCollection . '/' . $obj->filename;\r
-\r
-                       $old_level = error_reporting(0);\r
-                       $size = @GetImageSize($filename); \r
-                       error_reporting($old_level);\r
-                       $width = $size[0];\r
-                       $height = $size[1];\r
-                       $filetype = $size[2];\r
-                       \r
-                       echo "<tr>";\r
-                       echo "<td>". date("Y-m-d",$obj->timestamp) ."</td>";\r
-                       \r
-                       // strings for javascript\r
-                       $jsCurrentCollection = str_replace("'","\\'",$currentCollection);\r
-                       $jsFileName = str_replace("'","\\'",$obj->filename);\r
-\r
-                       if ($filetype != 0) {\r
-                               // image (gif/jpg/png/swf)\r
-                               echo "<td><a href=\"media.php\" onclick=\"chooseImage('", htmlspecialchars($jsCurrentCollection), "','", htmlspecialchars($jsFileName), "',"\r
-                                                          . "'", htmlspecialchars($width), "','" , htmlspecialchars($height), "'"\r
-                                                          . ")\" title=\"" . htmlspecialchars($obj->filename). "\">"\r
-                                                          . htmlspecialchars(shorten($obj->filename,25,'...'))\r
-                                                          ."</a>";\r
-                               echo ' (<a href="', htmlspecialchars($CONF['MediaURL'] . $currentCollection . '/' . $obj->filename), '" onclick="window.open(this.href); return false;" title="',htmlspecialchars(_MEDIA_VIEW_TT),'">',_MEDIA_VIEW,'</a>)';\r
-                               echo "</td>";\r
-                       } else {\r
-                               // no image (e.g. mpg)\r
-                               echo "<td><a href='media.php' onclick=\"chooseOther('" , htmlspecialchars($jsCurrentCollection), "','", htmlspecialchars($jsFileName), "'"\r
-                                                          . ")\" title=\"" . htmlspecialchars($obj->filename). "\">"\r
-                                                          . htmlspecialchars(shorten($obj->filename,30,'...'))\r
-                                                          ."</a></td>";\r
-\r
-                       }\r
-                       echo '<td>' , htmlspecialchars($width) , 'x' , htmlspecialchars($height) , '</td>';\r
-                       echo '</tr>';\r
-               }\r
-       } // if (sizeof($arr)>0)\r
-       ?>\r
-       \r
-               </table>\r
-       <?php   \r
-       if ($idxStart > 0)\r
-               echo "<a href='media.php?offset=$idxPrev&amp;collection=".urlencode($currentCollection)."'>". _LISTS_PREV."</a> ";\r
-       if ($idxEnd < sizeof($arr))\r
-               echo "<a href='media.php?offset=$idxNext&amp;collection=".urlencode($currentCollection)."'>". _LISTS_NEXT."</a> ";\r
-       \r
-       ?>\r
-               <input id="typeradio0" type="radio" name="typeradio" onclick="setType(0);" checked="checked" /><label for="typeradio0"><?php echo _MEDIA_INLINE?></label>\r
-               <input id="typeradio1" type="radio" name="typeradio" onclick="setType(1);" /><label for="typeradio1"><?php echo _MEDIA_POPUP?></label>\r
-       <?php   \r
-       media_foot();\r
-     \r
-               \r
-}\r
-\r
-/**\r
-  * Shows a screen where you can select the file to upload\r
-  */\r
-function media_choose() {\r
-       global $CONF, $member, $manager;\r
-\r
-       $currentCollection = requestVar('collection');\r
-       \r
-       $collections = MEDIA::getCollectionList();\r
-\r
-       media_head();\r
-       ?>\r
-       <h1><?php echo _UPLOAD_TITLE?></h1>\r
-       \r
-       <p><?php echo _UPLOAD_MSG?></p>\r
-       \r
-       <form method="post" enctype="multipart/form-data" action="media.php">\r
-       <div>\r
-         <input type="hidden" name="action" value="uploadfile" />\r
-         <?php $manager->addTicketHidden() ?>\r
-         <input type="hidden" name="MAX_FILE_SIZE" value="<?php echo $CONF['MaxUploadSize']?>" />\r
-         File:\r
-         <br />\r
-         <input name="uploadfile" type="file" size="40" />\r
-       <?php           if (sizeof($collections) > 1) {\r
-       ?>\r
-               <br /><br /><label for="upload_collection">Collection:</label>\r
-               <br /><select name="collection" id="upload_collection">\r
-                       <?php                           foreach ($collections as $dirname => $description) {\r
-                                       echo '<option value="',htmlspecialchars($dirname),'"';\r
-                                       if ($dirname == $currentCollection) {\r
-                                               echo ' selected="selected"';\r
-                                       }\r
-                                       echo '>',htmlspecialchars($description),'</option>';\r
-                               }\r
-                       ?>\r
-               </select>\r
-       <?php           } else {\r
-       ?>\r
-               <input name="collection" type="hidden" value="<?php echo htmlspecialchars(requestVar('collection'))?>" />                       \r
-       <?php           } // if sizeof\r
-       ?>  \r
-         <br /><br />\r
-         <input type="submit" value="<?php echo _UPLOAD_BUTTON?>" />\r
-       </div>\r
-       </form>\r
-       \r
-       <?php   \r
-       media_foot();\r
-}\r
-\r
-\r
-/**\r
-  * accepts a file for upload\r
-  */\r
-function media_upload() {\r
-       global $DIR_MEDIA, $member, $CONF;\r
-\r
-       $uploadInfo = postFileInfo('uploadfile');\r
-       \r
-       $filename = $uploadInfo['name'];\r
-       $filetype = $uploadInfo['type'];\r
-       $filesize = $uploadInfo['size'];\r
-       $filetempname = $uploadInfo['tmp_name'];\r
-       \r
-       if ($filesize > $CONF['MaxUploadSize'])\r
-               media_doError(_ERROR_FILE_TOO_BIG);\r
-       \r
-       // check file type against allowed types\r
-       $ok = 0;\r
-       $allowedtypes = explode (',', $CONF['AllowedTypes']);\r
-       foreach ( $allowedtypes as $type ) \r
-               if (eregi("\." .$type. "$",$filename)) $ok = 1;    \r
-       if (!$ok) media_doError(_ERROR_BADFILETYPE);\r
-               \r
-       if (!is_uploaded_file($filetempname)) \r
-               media_doError(_ERROR_BADREQUEST);\r
-\r
-       // prefix filename with current date (YYYY-MM-DD-)\r
-       // this to avoid nameclashes\r
-       if ($CONF['MediaPrefix'])\r
-               $filename = strftime("%Y%m%d-", time()) . $filename;\r
-\r
-       $collection = requestVar('collection');\r
-       $res = MEDIA::addMediaObject($collection, $filetempname, $filename);\r
-\r
-       if ($res != '') \r
-               media_doError($res);\r
-       \r
-       // shows updated list afterwards\r
-       media_select();\r
-}\r
-\r
-function media_loginAndPassThrough() {\r
-       media_head();\r
-       ?>\r
-               <h1><?php echo _LOGIN_PLEASE?></h1>\r
-       \r
-               <form method="post" action="media.php">\r
-               <div>\r
-                       <input name="action" value="login" type="hidden" />\r
-                       <input name="collection" value="<?php echo htmlspecialchars(requestVar('collection'))?>" type="hidden" />                       \r
-                       <?php echo _LOGINFORM_NAME?>: <input name="login" />\r
-                       <br /><?php echo _LOGINFORM_PWD?>: <input name="password" type="password" />\r
-                       <br /><input type="submit" value="<?php echo _LOGIN?>" />\r
-               </div>\r
-               </form>\r
-               <p><a href="media.php" onclick="window.close();"><?php echo _POPUP_CLOSE?></a></p>\r
-       <?php   media_foot();\r
-       exit;\r
-}\r
-\r
-function media_doError($msg) {\r
-       media_head();\r
-       ?>\r
-       <h1><?php echo _ERROR?></h1>\r
-       <p><?php echo $msg?></p>\r
-       <p><a href="media.php" onclick="history.back()"><?php echo _BACK?></a></p>\r
-       <?php   media_foot();\r
-       exit;\r
-}\r
-\r
-\r
-function media_head() {\r
-?>\r
-       <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">\r
-       <html xmlns="http://www.w3.org/1999/xhtml">\r
-       <head>\r
-               <meta http-equiv="Content-Type" content="text/html; charset=<?php echo _CHARSET ?>" />\r
-               <title>Nucleus Media</title>\r
-               <link rel="stylesheet" type="text/css" href="styles/popups.css" />\r
-               <script type="text/javascript">\r
-                       var type = 0;\r
-                       function setType(val) { type = val; }\r
-                       \r
-                       function chooseImage(collection, filename, width, height) {\r
-                               window.opener.focus(); \r
-                               window.opener.includeImage(collection,\r
-                                                                                  filename, \r
-                                                          type == 0 ? 'inline' : 'popup',\r
-                                                          width,\r
-                                                          height\r
-                                                          );\r
-                               window.close();\r
-                       }\r
-                       \r
-                       function chooseOther(collection, filename) {\r
-                               window.opener.focus(); \r
-                               window.opener.includeOtherMedia(collection, filename);\r
-                               window.close();\r
-                       \r
-                       }\r
-               </script>\r
-       </head>\r
-       <body>          \r
-<?php }\r
-\r
-function media_foot() {\r
-?>\r
-       </body>\r
-       </html> \r
-<?php }        \r
-\r
-?>\r
+<?php
+/*
+ * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/)
+ * Copyright (C) 2002-2007 The Nucleus Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * (see nucleus/documentation/index.html#license for more info)
+ */
+/**
+ * Media popup window for Nucleus
+ *
+ * Purpose:
+ *   - can be openen from an add-item form or bookmarklet popup
+ *   - shows a list of recent files, allowing browsing, search and
+ *     upload of new files
+ *   - close the popup by selecting a file in the list. The file gets
+ *     passed through to the add-item form (linkto, popupimg or inline img)
+ *
+ * @license http://nucleuscms.org/license.txt GNU General Public License
+ * @copyright Copyright (C) 2002-2007 The Nucleus Group
+ * @version $Id: media.php,v 1.4 2007-03-27 12:13:47 kimitake Exp $
+ * $NucleusJP: media.php,v 1.8 2007/03/20 19:32:19 kmorimatsu Exp $
+ *
+ */
+
+$CONF = array();
+
+// defines how much media items will be shown per page. You can override this
+// in config.php if you like. (changing it in config.php instead of here will
+// allow your settings to be kept even after a Nucleus upgrade)
+$CONF['MediaPerPage'] = 10;
+
+// include all classes and config data
+require('../config.php');
+include($DIR_LIBS . 'MEDIA.php');      // media classes
+
+sendContentType('application/xhtml+xml', 'media');
+
+// user needs to be logged in to use this
+if (!$member->isLoggedIn()) {
+       media_loginAndPassThrough();
+       exit;
+}
+
+// check if member is on at least one teamlist
+$query = 'SELECT * FROM ' . sql_table('team'). ' WHERE tmember=' . $member->getID();
+$teams = mysql_query($query);
+if (mysql_num_rows($teams) == 0)
+       media_doError(_ERROR_DISALLOWEDUPLOAD);
+
+// get action
+$action = requestVar('action');
+if ($action == '')
+       $action = 'selectmedia';
+
+// check ticket
+$aActionsNotToCheck = array('selectmedia', _MEDIA_FILTER_APPLY, _MEDIA_COLLECTION_SELECT);
+if (!in_array($action, $aActionsNotToCheck))
+{
+       if (!$manager->checkTicket())
+               media_doError(_ERROR_BADTICKET);
+}
+
+
+switch($action) {
+       case 'chooseupload':
+       case _MEDIA_UPLOAD_TO:
+       case _MEDIA_UPLOAD_NEW:
+               media_choose();
+               break;
+       case 'uploadfile':
+               media_upload();
+               break;
+       case _MEDIA_FILTER_APPLY:
+       case 'selectmedia':
+       case _MEDIA_COLLECTION_SELECT:
+       default:
+               media_select();
+               break;
+}
+
+// select a file
+function media_select() {
+       global $member, $CONF, $DIR_MEDIA, $manager;
+
+       media_head();
+
+       // show 10 files + navigation buttons
+       // show msg when no files
+       // show upload form
+       // files sorted according to last modification date
+
+       // currently selected collection
+       $currentCollection = requestVar('collection');
+       if (!$currentCollection || !@is_dir($DIR_MEDIA . $currentCollection))
+               $currentCollection = $member->getID();
+
+
+       // get collection list
+       $collections = MEDIA::getCollectionList();
+
+       if (sizeof($collections) > 1) {
+       ?>
+               <form method="post" action="media.php"><div>
+                       <label for="media_collection"><?php echo htmlspecialchars(_MEDIA_COLLECTION_LABEL)?></label>
+                       <select name="collection" id="media_collection">
+                               <?php                                   foreach ($collections as $dirname => $description) {
+                                               echo '<option value="',htmlspecialchars($dirname),'"';
+                                               if ($dirname == $currentCollection) {
+                                                       echo ' selected="selected"';
+                                               }
+                                               echo '>',htmlspecialchars($description),'</option>';
+                                       }
+                               ?>
+                       </select>
+                       <input type="submit" name="action" value="<?php echo htmlspecialchars(_MEDIA_COLLECTION_SELECT) ?>" title="<?php echo htmlspecialchars(_MEDIA_COLLECTION_TT)?>" />
+                       <input type="submit" name="action" value="<?php echo htmlspecialchars(_MEDIA_UPLOAD_TO) ?>" title="<?php echo htmlspecialchars(_MEDIA_UPLOADLINK) ?>" />
+                       <?php $manager->addTicketHidden() ?>
+               </div></form>
+       <?php   } else {
+       ?>
+               <form method="post" action="media.php" style="float:right"><div>
+                       <input type="hidden" name="collection" value="<?php echo htmlspecialchars($currentCollection)?>" />
+                       <input type="submit" name="action" value="<?php echo htmlspecialchars(_MEDIA_UPLOAD_NEW) ?>" title="<?php echo htmlspecialchars(_MEDIA_UPLOADLINK) ?>" />
+                       <?php $manager->addTicketHidden() ?>
+               </div></form>
+       <?php   } // if sizeof
+
+       $filter = requestVar('filter');
+       $offset = intRequestVar('offset');
+       $arr = MEDIA::getMediaListByCollection($currentCollection, $filter);
+
+       ?>
+               <form method="post" action="media.php"><div>
+                       <label for="media_filter"><?php echo htmlspecialchars(_MEDIA_FILTER_LABEL)?></label>
+                       <input id="media_filter" type="text" name="filter" value="<?php echo htmlspecialchars($filter)?>" />
+                       <input type="submit" name="action" value="<?php echo htmlspecialchars(_MEDIA_FILTER_APPLY) ?>" />
+                       <input type="hidden" name="collection" value="<?php echo htmlspecialchars($currentCollection)?>" />
+                       <input type="hidden" name="offset" value="<?php echo intval($offset)?>" />
+               </div></form>
+
+       <?php
+
+       ?>
+               <table width="100%">
+               <caption><?php echo _MEDIA_COLLECTION_LABEL . htmlspecialchars($collections[$currentCollection])?></caption>
+               <tr>
+                <th><?php echo _MEDIA_MODIFIED?></th><th><?php echo _MEDIA_FILENAME?></th><th><?php echo _MEDIA_DIMENSIONS?></th>
+               </tr>
+
+       <?php
+
+       if (sizeof($arr)>0) {
+
+               if (($offset + $CONF['MediaPerPage']) >= sizeof($arr))
+                       $offset = sizeof($arr) - $CONF['MediaPerPage'];
+
+               if ($offset < 0) $offset = 0;
+
+               $idxStart = $offset;
+               $idxEnd = $offset + $CONF['MediaPerPage'];
+               $idxNext = $idxEnd;
+               $idxPrev = $idxStart - $CONF['MediaPerPage'];
+
+               if ($idxPrev < 0) $idxPrev = 0;
+
+               if ($idxEnd > sizeof($arr))
+                       $idxEnd = sizeof($arr);
+
+               for($i=$idxStart;$i<$idxEnd;$i++) {
+                       $obj = $arr[$i];
+                       $filename = $DIR_MEDIA . $currentCollection . '/' . $obj->filename;
+
+                       $old_level = error_reporting(0);
+                       $size = @GetImageSize($filename);
+                       error_reporting($old_level);
+                       $width = $size[0];
+                       $height = $size[1];
+                       $filetype = $size[2];
+
+                       echo "<tr>";
+                       echo "<td>". date("Y-m-d",$obj->timestamp) ."</td>";
+
+                       // strings for javascript
+                       $jsCurrentCollection = str_replace("'","\\'",$currentCollection);
+                       $jsFileName = str_replace("'","\\'",$obj->filename);
+
+                       if ($filetype != 0) {
+                               // image (gif/jpg/png/swf)
+                               echo "<td><a href=\"media.php\" onclick=\"chooseImage('", htmlspecialchars($jsCurrentCollection), "','", htmlspecialchars($jsFileName), "',"
+                                                          . "'", htmlspecialchars($width), "','" , htmlspecialchars($height), "'"
+                                                          . ")\" title=\"" . htmlspecialchars($obj->filename). "\">"
+                                                          . htmlspecialchars(shorten($obj->filename,25,'...'))
+                                                          ."</a>";
+                               echo ' (<a href="', htmlspecialchars($CONF['MediaURL'] . $currentCollection . '/' . $obj->filename), '" onclick="window.open(this.href); return false;" title="',htmlspecialchars(_MEDIA_VIEW_TT),'">',_MEDIA_VIEW,'</a>)';
+                               echo "</td>";
+                       } else {
+                               // no image (e.g. mpg)
+                               echo "<td><a href='media.php' onclick=\"chooseOther('" , htmlspecialchars($jsCurrentCollection), "','", htmlspecialchars($jsFileName), "'"
+                                                          . ")\" title=\"" . htmlspecialchars($obj->filename). "\">"
+                                                          . htmlspecialchars(shorten($obj->filename,30,'...'))
+                                                          ."</a></td>";
+
+                       }
+                       echo '<td>' , htmlspecialchars($width) , 'x' , htmlspecialchars($height) , '</td>';
+                       echo '</tr>';
+               }
+       } // if (sizeof($arr)>0)
+       ?>
+
+               </table>
+       <?php
+       if ($idxStart > 0)
+               echo "<a href='media.php?offset=$idxPrev&amp;collection=".urlencode($currentCollection)."'>". _LISTS_PREV."</a> ";
+       if ($idxEnd < sizeof($arr))
+               echo "<a href='media.php?offset=$idxNext&amp;collection=".urlencode($currentCollection)."'>". _LISTS_NEXT."</a> ";
+
+       ?>
+               <input id="typeradio0" type="radio" name="typeradio" onclick="setType(0);" checked="checked" /><label for="typeradio0"><?php echo _MEDIA_INLINE?></label>
+               <input id="typeradio1" type="radio" name="typeradio" onclick="setType(1);" /><label for="typeradio1"><?php echo _MEDIA_POPUP?></label>
+       <?php
+       media_foot();
+
+
+}
+
+/**
+  * Shows a screen where you can select the file to upload
+  */
+function media_choose() {
+       global $CONF, $member, $manager;
+
+       $currentCollection = requestVar('collection');
+
+       $collections = MEDIA::getCollectionList();
+
+       media_head();
+       ?>
+       <h1><?php echo _UPLOAD_TITLE?></h1>
+
+       <p><?php echo _UPLOAD_MSG?></p>
+
+       <form method="post" enctype="multipart/form-data" action="media.php">
+       <div>
+         <input type="hidden" name="action" value="uploadfile" />
+         <?php $manager->addTicketHidden() ?>
+         <input type="hidden" name="MAX_FILE_SIZE" value="<?php echo $CONF['MaxUploadSize']?>" />
+         File:
+         <br />
+         <input name="uploadfile" type="file" size="40" />
+       <?php           if (sizeof($collections) > 1) {
+       ?>
+               <br /><br /><label for="upload_collection">Collection:</label>
+               <br /><select name="collection" id="upload_collection">
+                       <?php                           foreach ($collections as $dirname => $description) {
+                                       echo '<option value="',htmlspecialchars($dirname),'"';
+                                       if ($dirname == $currentCollection) {
+                                               echo ' selected="selected"';
+                                       }
+                                       echo '>',htmlspecialchars($description),'</option>';
+                               }
+                       ?>
+               </select>
+       <?php           } else {
+       ?>
+               <input name="collection" type="hidden" value="<?php echo htmlspecialchars(requestVar('collection'))?>" />
+       <?php           } // if sizeof
+       ?>
+         <br /><br />
+         <input type="submit" value="<?php echo _UPLOAD_BUTTON?>" />
+       </div>
+       </form>
+
+       <?php
+       media_foot();
+}
+
+
+/**
+  * accepts a file for upload
+  */
+function media_upload() {
+       global $DIR_MEDIA, $member, $CONF;
+
+       $uploadInfo = postFileInfo('uploadfile');
+
+       $filename = $uploadInfo['name'];
+       $filetype = $uploadInfo['type'];
+       $filesize = $uploadInfo['size'];
+       $filetempname = $uploadInfo['tmp_name'];
+       $fileerror = intval($uploadInfo['error']);
+       
+       switch ($fileerror)
+       {
+               case 0: // = UPLOAD_ERR_OK
+                       break;
+               case 1: // = UPLOAD_ERR_INI_SIZE
+               case 2: // = UPLOAD_ERR_FORM_SIZE
+                       media_doError(_ERROR_FILE_TOO_BIG);
+               case 3: // = UPLOAD_ERR_PARTIAL
+               case 4: // = UPLOAD_ERR_NO_FILE
+               case 6: // = UPLOAD_ERR_NO_TMP_DIR
+               case 7: // = UPLOAD_ERR_CANT_WRITE
+               default:
+                       // include error code for debugging
+                       // (see http://www.php.net/manual/en/features.file-upload.errors.php)
+                       media_doError(_ERROR_BADREQUEST . ' (' . $fileerror . ')');
+       }
+
+       if ($filesize > $CONF['MaxUploadSize'])
+               media_doError(_ERROR_FILE_TOO_BIG);
+
+       // check file type against allowed types
+       $ok = 0;
+       $allowedtypes = explode (',', $CONF['AllowedTypes']);
+       foreach ( $allowedtypes as $type )
+               if (eregi("\." .$type. "$",$filename)) $ok = 1;
+       if (!$ok) media_doError(_ERROR_BADFILETYPE);
+
+       if (!is_uploaded_file($filetempname))
+               media_doError(_ERROR_BADREQUEST);
+
+       // prefix filename with current date (YYYY-MM-DD-)
+       // this to avoid nameclashes
+       if ($CONF['MediaPrefix'])
+               $filename = strftime("%Y%m%d-", time()) . $filename;
+
+       $collection = requestVar('collection');
+       $res = MEDIA::addMediaObject($collection, $filetempname, $filename);
+
+       if ($res != '')
+               media_doError($res);
+
+       // shows updated list afterwards
+       media_select();
+}
+
+function media_loginAndPassThrough() {
+       media_head();
+       ?>
+               <h1><?php echo _LOGIN_PLEASE?></h1>
+
+               <form method="post" action="media.php">
+               <div>
+                       <input name="action" value="login" type="hidden" />
+                       <input name="collection" value="<?php echo htmlspecialchars(requestVar('collection'))?>" type="hidden" />
+                       <?php echo _LOGINFORM_NAME?>: <input name="login" />
+                       <br /><?php echo _LOGINFORM_PWD?>: <input name="password" type="password" />
+                       <br /><input type="submit" value="<?php echo _LOGIN?>" />
+               </div>
+               </form>
+               <p><a href="media.php" onclick="window.close();"><?php echo _POPUP_CLOSE?></a></p>
+       <?php   media_foot();
+       exit;
+}
+
+function media_doError($msg) {
+       media_head();
+       ?>
+       <h1><?php echo _ERROR?></h1>
+       <p><?php echo $msg?></p>
+       <p><a href="media.php" onclick="history.back()"><?php echo _BACK?></a></p>
+       <?php   media_foot();
+       exit;
+}
+
+
+function media_head() {
+?>
+       <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+       <html xmlns="http://www.w3.org/1999/xhtml">
+       <head>
+               <meta http-equiv="Content-Type" content="text/html; charset=<?php echo _CHARSET ?>" />
+               <title>Nucleus Media</title>
+               <link rel="stylesheet" type="text/css" href="styles/popups.css" />
+               <script type="text/javascript">
+                       var type = 0;
+                       function setType(val) { type = val; }
+
+                       function chooseImage(collection, filename, width, height) {
+                               window.opener.focus();
+                               window.opener.includeImage(collection,
+                                                                                  filename,
+                                                                                  type == 0 ? 'inline' : 'popup',
+                                                                                  width,
+                                                                                  height
+                                                                                  );
+                               window.close();
+                       }
+
+                       function chooseOther(collection, filename) {
+                               window.opener.focus();
+                               window.opener.includeOtherMedia(collection, filename);
+                               window.close();
+
+                       }
+               </script>
+       </head>
+       <body>
+<?php }
+
+function media_foot() {
+?>
+       </body>
+       </html>
+<?php }
+
+?>
index a2a0c3f..d087a4e 100755 (executable)
-<?php\r
-/** \r
-  * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/) \r
-  * Copyright (C) 2002-2005 The Nucleus Group\r
-  *\r
-  * This program is free software; you can redistribute it and/or\r
-  * modify it under the terms of the GNU General Public License\r
-  * as published by the Free Software Foundation; either version 2\r
-  * of the License, or (at your option) any later version.\r
-  * (see nucleus/documentation/index.html#license for more info)\r
-  *\r
-  * $Id: api_blogger.inc.php,v 1.3 2005-03-16 08:12:06 kimitake Exp $\r
-  * $NucleusJP: api_blogger.inc.php,v 1.3 2005/03/12 06:19:06 kimitake Exp $\r
-  */\r
-  \r
-/*\r
- * This file contains definitions for the methods in the Blogger API\r
- */\r
-\r
-\r
-       // blogger.newPost\r
-       $f_blogger_newPost_sig = array(array(\r
-                       // return type\r
-                       $xmlrpcString,  // itemid of the new item\r
-\r
-                       // params:\r
-                       $xmlrpcString,  // appkey (ignored)\r
-                       $xmlrpcString,  // blogid\r
-                       $xmlrpcString,  // username\r
-                       $xmlrpcString,  // password\r
-                       $xmlrpcString,  // content\r
-                       $xmlrpcBoolean, // publish boolean (set to false to create draft)\r
-\r
-               ));\r
-       $f_blogger_newPost_doc = "Adds a new item to the given blog. Adds it as a draft when publish is false";\r
-       function f_blogger_newPost($m) {\r
-               $blogid = _getScalar($m,1);\r
-               $username = _getScalar($m,2);\r
-               $password = _getScalar($m,3);\r
-               $content = _getScalar($m,4);\r
-               $publish = _getScalar($m,5);\r
-               \r
-               $title = blogger_extractTitle($content);\r
-               $category = blogger_extractCategory($content);\r
-               $content = blogger_removeSpecialTags($content); \r
-\r
-               return _addItem($blogid, $username, $password, $title, $content, '', $publish, 0, $category);\r
-       }\r
-\r
-       // blogger.editPost\r
-       $f_blogger_editPost_sig = array(array(\r
-                       // return type\r
-                       $xmlrpcBoolean, // true or false\r
-\r
-                       // params:\r
-                       $xmlrpcString,  // appkey (ignored)\r
-                       $xmlrpcString,  // postid\r
-                       $xmlrpcString,  // username\r
-                       $xmlrpcString,  // password\r
-                       $xmlrpcString,  // content\r
-                       $xmlrpcBoolean, // publish boolean (only considered when dealing with a draft)\r
-\r
-               ));\r
-       $f_blogger_editPost_doc = "Edits an item of a blog";\r
-       function f_blogger_editPost($m) {\r
-               global $manager;\r
-               \r
-               $itemid = intval(_getScalar($m,1));\r
-               $username = _getScalar($m,2);\r
-               $password = _getScalar($m,3);\r
-               $content = _getScalar($m,4);\r
-               $publish = _getScalar($m,5);\r
-\r
-               $title = blogger_extractTitle($content);\r
-               $category = blogger_extractCategory($content);\r
-               $content = blogger_removeSpecialTags($content); \r
-\r
-               // get old title and extended part \r
-               if (!$manager->existsItem($itemid,1,1))\r
-                       return _error(6,"No such item ($itemid)");\r
-               $old =& $manager->getItem($itemid,1,1);\r
-\r
-               $blogid = getBlogIDFromItemID($itemid);\r
-\r
-               $blog = new BLOG($blogid);\r
-               $catid = $blog->getCategoryIdFromName($category);\r
-               \r
-               if ($old['draft'] && $publish) {\r
-                       $wasdraft = 1;\r
-                       $publish = 1;\r
-               } else {\r
-                       $wasdraft = 0;\r
-               }\r
-\r
-               return _edititem($itemid, $username, $password, $catid, $title, $content, $old['more'], $wasdraft, $publish, $old['closed']);\r
-       }\r
-\r
-\r
-       // blogger.getUsersBlogs\r
-       $f_blogger_getUsersBlogs_sig = array(array(\r
-                       // return type\r
-                       $xmlrpcArray,   // array containing structs containing blog info\r
-\r
-                       // params:\r
-                       $xmlrpcString,  // appkey (ignored)\r
-                       $xmlrpcString,  // username\r
-                       $xmlrpcString,  // password\r
-               ));\r
-       $f_blogger_getUsersBlogs_doc = "Returns a list of all the blogs where the given member is on the team";\r
-       function f_blogger_getUsersBlogs($m) {\r
-               $username = _getScalar($m,1);\r
-               $password = _getScalar($m,2);\r
-\r
-               return _getUsersBlogs($username, $password);\r
-       }\r
-\r
-       // blogger.getRecentPosts\r
-       $f_blogger_getRecentPosts_sig = array(array(\r
-                       // return type\r
-                       $xmlrpcArray,   // array of strucs (representing items)\r
-\r
-                       // params\r
-                       $xmlrpcString,  // appkey (ignored)\r
-                       $xmlrpcString,  // blogid\r
-                       $xmlrpcString,  // username\r
-                       $xmlrpcString,  // password\r
-                       $xmlrpcInt,     // amount of items to return (max = 20)\r
-               ));\r
-       $f_blogger_getRecentPosts_doc = "Returns a maximum of 20 recent items";\r
-       function f_blogger_getRecentPosts($m) {\r
-               $blogid = _getScalar($m, 1);\r
-               $username = _getScalar($m, 2);\r
-               $password = _getScalar($m, 3);\r
-               $amount = _getScalar($m, 4);\r
-\r
-               return _getRecentItemsBlogger($blogid, $username, $password, $amount);\r
-       }\r
-\r
-\r
-       // blogger.getPost\r
-       $f_blogger_getPost_sig = array(array(\r
-                       // return type\r
-                       $xmlrpcStruct,  // A struct representing the item\r
-\r
-                       // params\r
-                       $xmlrpcString,  // appkey (ignored)\r
-                       $xmlrpcString,  // postid\r
-                       $xmlrpcString,  // username\r
-                       $xmlrpcString,  // password\r
-               ));\r
-       $f_blogger_getPost_doc = "Returns an item (only the item body!)";\r
-       function f_blogger_getPost($m) {\r
-               $postid = _getScalar($m, 1);\r
-               $username = _getScalar($m, 2);\r
-               $password = _getScalar($m, 3);\r
-\r
-               return _getItemBlogger($postid, $username, $password);\r
-       }\r
-\r
-\r
-       // blogger.deletePost\r
-       $f_blogger_deletePost_sig = array(array(\r
-                       // return type\r
-                       $xmlrpcBoolean, // boolean (ok or not ok)\r
-\r
-                       // params\r
-                       $xmlrpcString,  // appkey (ignored)\r
-                       $xmlrpcString,  // postid\r
-                       $xmlrpcString,  // username\r
-                       $xmlrpcString,  // password\r
-                       $xmlrpcBoolean, // publish (ignored)\r
-               ));\r
-       $f_blogger_deletePost_doc = "Deletes an item";\r
-       function f_blogger_deletePost($m) {\r
-               $postid = _getScalar($m,1);\r
-               $username = _getScalar($m, 2);\r
-               $password = _getScalar($m, 3);\r
-\r
-               return _deleteItem($postid, $username, $password);\r
-       }\r
-\r
-       // blogger.getTemplate\r
-       $f_blogger_getTemplate_sig = array(array(\r
-                       // return type\r
-                       $xmlrpcString,  // the template\r
-\r
-                       // params\r
-                       $xmlrpcString,  // appkey (ignored)\r
-                       $xmlrpcString,  // blogid\r
-                       $xmlrpcString,  // username\r
-                       $xmlrpcString,  // password\r
-                       $xmlrpcString,  // type of template (main/archiveIndex)\r
-                               ));\r
-       $f_blogger_getTemplate_doc = "Returns the required part of the default skin for the given blog";\r
-       function f_blogger_getTemplate($m) {\r
-               $blogid = _getScalar($m,1);\r
-               $username = _getScalar($m,2);\r
-               $password = _getScalar($m,3);\r
-               $type = _getScalar($m,4);\r
-\r
-               switch($type) {\r
-                       case "main":\r
-                               $type = "index";\r
-                               break;\r
-                       case "archiveIndex":\r
-                               $type = "archivelist";\r
-                               break;\r
-               }\r
-\r
-               return _getSkinPart($blogid, $username, $password, $type);\r
-       }\r
-\r
-       // blogger.setTemplate\r
-       $f_blogger_setTemplate_sig = array(array(\r
-                       // return type\r
-                       $xmlrpcBoolean, // OK or not OK\r
-\r
-                       // params\r
-                       $xmlrpcString,  // appkey (ignored)\r
-                       $xmlrpcString,  // blogid\r
-                       $xmlrpcString,  // username\r
-                       $xmlrpcString,  // password\r
-                       $xmlrpcString,  // template contents\r
-                       $xmlrpcString,  // type of template (main/archiveIndex)\r
-                       ));\r
-       $f_blogger_setTemplate_doc = "Changes a part of the default skin for the selected blog";\r
-       function f_blogger_setTemplate($m) {\r
-               $blogid = _getScalar($m,1);\r
-               $username = _getScalar($m,2);\r
-               $password = _getScalar($m,3);\r
-               $content = _getScalar($m,4);\r
-               $type = _getScalar($m,5);\r
-\r
-               switch($type) {\r
-                       case "main":\r
-                               $type = "index";\r
-                               break;\r
-                       case "archiveIndex":\r
-                               $type = "archivelist";\r
-                               break;\r
-               }\r
-\r
-               return _setSkinPart($blogid, $username, $password, $content, $type);\r
-       }\r
-\r
-       // blogger.getUserInfo\r
-       $f_blogger_getUserInfo_sig = array(array(\r
-                       // return type\r
-                       $xmlrpcStruct,  // Struct\r
-\r
-                       // params\r
-                       $xmlrpcString,  // appkey (ignored)\r
-                       $xmlrpcString,  // username\r
-                       $xmlrpcString,  // password\r
-                       ));\r
-       $f_blogger_getUserInfo_doc = "Returns info on the user";\r
-       function f_blogger_getUserInfo($m) {\r
-               $username = _getScalar($m,1);\r
-               $password = _getScalar($m,2);\r
-\r
-               return _getUserInfo($username, $password);\r
-       }\r
-\r
-\r
-       /**\r
-         * Returns a list of recent items \r
-         */\r
-       function _getRecentItemsBlogger($blogid, $username, $password, $amount) {\r
-               \r
-               $blogid = intval($blogid);\r
-               $amount = intval($amount);\r
-                       \r
-               // 1. login\r
-               $mem = new MEMBER();\r
-               if (!$mem->login($username, $password))\r
-                       return _error(1,"Could not log in");\r
-\r
-               // 2. check if allowed \r
-               if (!BLOG::existsID($blogid))\r
-                       return _error(2,"No such blog ($blogid)");\r
-               if (!$mem->teamRights($blogid))\r
-                       return _error(3,"Not a team member");\r
-               $amount = intval($amount);\r
-               if (($amount < 1) or ($amount > 20))\r
-                       return _error(5,"Amount parameter must be in range 1..20");\r
-\r
-               // 3. create and return list of recent items\r
-               // Struct returned has dateCreated, userid, blogid and content\r
-               \r
-               $blog = new BLOG($blogid);\r
-\r
-               $structarray = array();         // the array in which the structs will be stored\r
-\r
-               $query = "SELECT mname, ibody, iauthor, ibody, inumber, ititle as title, itime, cname as category"\r
-                          .' FROM '.sql_table('item').', '.sql_table('category').', '.sql_table('member')\r
-                          ." WHERE iblog=$blogid and icat=catid and iauthor=mnumber"\r
-                          ." ORDER BY itime DESC"\r
-                          ." LIMIT $amount";\r
-               $r = sql_query($query);\r
-               \r
-               while ($row = mysql_fetch_assoc($r)) {\r
-               \r
-                       // remove linebreaks if needed\r
-                       if ($blog->convertBreaks())\r
-                               $row['ibody'] = removeBreaks($row['ibody']);\r
-\r
-                       $content = blogger_specialTags($row) . $row['ibody'];\r
-               \r
-                       $newstruct = new xmlrpcval(array(\r
-                               "userid" => new xmlrpcval($row['iauthor'],"string"),\r
-                               "dateCreated" => new xmlrpcval(iso8601_encode(strtotime($row['itime'])),"dateTime.iso8601"),\r
-                               "blogid" => new xmlrpcval($blogid,"string"),\r
-                               "content" => new xmlrpcval($content,"string"),\r
-                               "postid" => new xmlrpcval($row['inumber'],"string"),\r
-                               "authorName" => new xmlrpcval($row['mname'],'string'),\r
-                               "title" => new xmlrpcval($row['title'],'string'),\r
-                       ),'struct');\r
-                       array_push($structarray, $newstruct);           \r
-               }\r
-\r
-               return new xmlrpcresp(new xmlrpcval( $structarray , "array"));\r
-\r
-       }\r
-       \r
-       /**\r
-         * Returns one item (Blogger version)\r
-         */\r
-       function _getItemBlogger($itemid, $username, $password) {\r
-               global $manager;\r
-       \r
-               // 1. login\r
-               $mem = new MEMBER();\r
-               if (!$mem->login($username, $password))\r
-                       return _error(1,"Could not log in");\r
-\r
-               // 2. check if allowed \r
-               if (!$manager->existsItem($itemid,1,1))\r
-                       return _error(6,"No such item ($itemid)");\r
-               $blogid = getBlogIDFromItemID($itemid);\r
-               if (!$mem->teamRights($blogid))\r
-                       return _error(3,"Not a team member");\r
-\r
-               // 3. return the item\r
-               // Structure returned has dateCreated, userid, blogid and content\r
-\r
-               $item =& $manager->getItem($itemid,1,1); // (also allow drafts and future items)\r
-               $blog = new BLOG($blogid);\r
-               \r
-               // get category\r
-               $item['category'] = $blog->getCategoryName($item['catid']);\r
-               \r
-               // remove linebreaks if needed\r
-               if ($blog->convertBreaks())\r
-                       $item['body'] = removeBreaks($item['body']);\r
-\r
-               $content = blogger_specialTags($item) . $item['body'];\r
-\r
-               $newstruct = new xmlrpcval(array(\r
-                       "dateCreated" => new xmlrpcval(iso8601_encode($item['timestamp']),"dateTime.iso8601"),\r
-                       "userid" => new xmlrpcval($item['authorid'],"string"),\r
-                       "blogid" => new xmlrpcval($blogid,"string"),\r
-                       "content" => new xmlrpcval($content,"string")\r
-               ),'struct');\r
-\r
-               return new xmlrpcresp($newstruct);\r
-\r
-\r
-       }\r
-\r
-\r
-       function blogger_extractTitle($body) {\r
-               return blogger_matchTag('title',$body);\r
-       }\r
-\r
-       function blogger_extractCategory($body) {\r
-               return blogger_matchTag('category',$body);\r
-       }       \r
-       \r
-       function blogger_matchTag($tag, $body) {\r
-               if (preg_match("/<" . $tag .">(.+?)<\/".$tag.">/is",$body,$match)) \r
-                       return $match[1];\r
-               else\r
-                       return "";\r
-       }\r
-\r
-       function blogger_removeSpecialTags($body) {\r
-               $body = preg_replace("/<title>(.+?)<\/title>/","",$body);\r
-               $body = preg_replace("/<category>(.+?)<\/category>/","",$body);\r
-               return trim($body);\r
-       }\r
-       \r
-       function blogger_specialTags($item) {\r
-               $result = "<title>". $item['title']."</title>";\r
-               $result .= "<category>".$item['category']."</category>";\r
-               return $result;\r
-       }\r
-       \r
-\r
-\r
-       $functionDefs = array_merge($functionDefs,\r
-               array(\r
-                        "blogger.getUsersBlogs" =>\r
-                        array( "function" => "f_blogger_getUsersBlogs",\r
-                               "signature" => $f_blogger_getUsersBlogs_sig,\r
-                               "docstring" => $f_blogger_getUsersBlogs_doc),\r
-\r
-                        "blogger.newPost" =>\r
-                        array( "function" => "f_blogger_newPost",\r
-                               "signature" => $f_blogger_newPost_sig,\r
-                               "docstring" => $f_blogger_newPost_doc),\r
-\r
-                        "blogger.editPost" =>\r
-                        array( "function" => "f_blogger_editPost",\r
-                               "signature" => $f_blogger_editPost_sig,\r
-                               "docstring" => $f_blogger_editPost_doc),\r
-\r
-                        "blogger.deletePost" =>\r
-                        array( "function" => "f_blogger_deletePost",\r
-                               "signature" => $f_blogger_deletePost_sig,\r
-                               "docstring" => $f_blogger_deletePost_doc),\r
-\r
-                        "blogger.getPost" =>\r
-                        array( "function" => "f_blogger_getPost",\r
-                               "signature" => $f_blogger_getPost_sig,\r
-                               "docstring" => $f_blogger_getPost_doc),\r
-\r
-                        "blogger.getRecentPosts" =>\r
-                        array( "function" => "f_blogger_getRecentPosts",\r
-                               "signature" => $f_blogger_getRecentPosts_sig,\r
-                               "docstring" => $f_blogger_getRecentPosts_doc),\r
-\r
-                        "blogger.getUserInfo" =>\r
-                        array( "function" => "f_blogger_getUserInfo",\r
-                               "signature" => $f_blogger_getUserInfo_sig,\r
-                               "docstring" => $f_blogger_getUserInfo_doc),\r
-\r
-                        "blogger.getTemplate" =>\r
-                        array( "function" => "f_blogger_getTemplate",\r
-                               "signature" => $f_blogger_getTemplate_sig,\r
-                               "docstring" => $f_blogger_getTemplate_doc),\r
-\r
-                        "blogger.setTemplate" =>\r
-                        array( "function" => "f_blogger_setTemplate",\r
-                               "signature" => $f_blogger_setTemplate_sig,\r
-                               "docstring" => $f_blogger_setTemplate_doc)\r
-               \r
-               )\r
-       );\r
-\r
-\r
-?>\r
+<?php
+/*
+ * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/)
+ * Copyright (C) 2002-2007 The Nucleus Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * (see nucleus/documentation/index.html#license for more info)
+ */
+
+/**
+ * This file contains definitions for the methods in the Blogger API
+ *
+ * @license http://nucleuscms.org/license.txt GNU General Public License
+ * @copyright Copyright (C) 2002-2007 The Nucleus Group
+ * @version $Id: api_blogger.inc.php,v 1.4 2007-03-27 12:14:05 kimitake Exp $
+ * $NucleusJP: api_blogger.inc.php,v 1.6 2007/02/04 06:28:46 kimitake Exp $
+ */
+
+
+       // blogger.newPost
+       $f_blogger_newPost_sig = array(array(
+                       // return type
+                       $xmlrpcString,  // itemid of the new item
+
+                       // params:
+                       $xmlrpcString,  // appkey (ignored)
+                       $xmlrpcString,  // blogid
+                       $xmlrpcString,  // username
+                       $xmlrpcString,  // password
+                       $xmlrpcString,  // content
+                       $xmlrpcBoolean, // publish boolean (set to false to create draft)
+
+               ));
+       $f_blogger_newPost_doc = "Adds a new item to the given blog. Adds it as a draft when publish is false";
+       function f_blogger_newPost($m) {
+               $blogid = _getScalar($m,1);
+               $username = _getScalar($m,2);
+               $password = _getScalar($m,3);
+               $content = _getScalar($m,4);
+               $publish = _getScalar($m,5);
+
+               $title = blogger_extractTitle($content);
+               $category = blogger_extractCategory($content);
+               $content = blogger_removeSpecialTags($content);
+
+               return _addItem($blogid, $username, $password, $title, $content, '', $publish, 0, $category);
+       }
+
+       // blogger.editPost
+       $f_blogger_editPost_sig = array(array(
+                       // return type
+                       $xmlrpcBoolean, // true or false
+
+                       // params:
+                       $xmlrpcString,  // appkey (ignored)
+                       $xmlrpcString,  // postid
+                       $xmlrpcString,  // username
+                       $xmlrpcString,  // password
+                       $xmlrpcString,  // content
+                       $xmlrpcBoolean, // publish boolean (only considered when dealing with a draft)
+
+               ));
+       $f_blogger_editPost_doc = "Edits an item of a blog";
+       function f_blogger_editPost($m) {
+               global $manager;
+
+               $itemid = intval(_getScalar($m,1));
+               $username = _getScalar($m,2);
+               $password = _getScalar($m,3);
+               $content = _getScalar($m,4);
+               $publish = _getScalar($m,5);
+
+               $title = blogger_extractTitle($content);
+               $category = blogger_extractCategory($content);
+               $content = blogger_removeSpecialTags($content);
+
+               // get old title and extended part
+               if (!$manager->existsItem($itemid,1,1))
+                       return _error(6,"No such item ($itemid)");
+               $old =& $manager->getItem($itemid,1,1);
+
+               $blogid = getBlogIDFromItemID($itemid);
+
+               $blog = new BLOG($blogid);
+               $catid = $blog->getCategoryIdFromName($category);
+
+               if ($old['draft'] && $publish) {
+                       $wasdraft = 1;
+                       $publish = 1;
+               } else {
+                       $wasdraft = 0;
+               }
+
+               return _edititem($itemid, $username, $password, $catid, $title, $content, $old['more'], $wasdraft, $publish, $old['closed']);
+       }
+
+
+       // blogger.getUsersBlogs
+       $f_blogger_getUsersBlogs_sig = array(array(
+                       // return type
+                       $xmlrpcArray,   // array containing structs containing blog info
+
+                       // params:
+                       $xmlrpcString,  // appkey (ignored)
+                       $xmlrpcString,  // username
+                       $xmlrpcString,  // password
+               ));
+       $f_blogger_getUsersBlogs_doc = "Returns a list of all the blogs where the given member is on the team";
+       function f_blogger_getUsersBlogs($m) {
+               $username = _getScalar($m,1);
+               $password = _getScalar($m,2);
+
+               return _getUsersBlogs($username, $password);
+       }
+
+       // blogger.getRecentPosts
+       $f_blogger_getRecentPosts_sig = array(array(
+                       // return type
+                       $xmlrpcArray,   // array of strucs (representing items)
+
+                       // params
+                       $xmlrpcString,  // appkey (ignored)
+                       $xmlrpcString,  // blogid
+                       $xmlrpcString,  // username
+                       $xmlrpcString,  // password
+                       $xmlrpcInt,     // amount of items to return (max = 20)
+               ));
+       $f_blogger_getRecentPosts_doc = "Returns a maximum of 20 recent items";
+       function f_blogger_getRecentPosts($m) {
+               $blogid = _getScalar($m, 1);
+               $username = _getScalar($m, 2);
+               $password = _getScalar($m, 3);
+               $amount = _getScalar($m, 4);
+
+               return _getRecentItemsBlogger($blogid, $username, $password, $amount);
+       }
+
+
+       // blogger.getPost
+       $f_blogger_getPost_sig = array(array(
+                       // return type
+                       $xmlrpcStruct,  // A struct representing the item
+
+                       // params
+                       $xmlrpcString,  // appkey (ignored)
+                       $xmlrpcString,  // postid
+                       $xmlrpcString,  // username
+                       $xmlrpcString,  // password
+               ));
+       $f_blogger_getPost_doc = "Returns an item (only the item body!)";
+       function f_blogger_getPost($m) {
+               $postid = _getScalar($m, 1);
+               $username = _getScalar($m, 2);
+               $password = _getScalar($m, 3);
+
+               return _getItemBlogger($postid, $username, $password);
+       }
+
+
+       // blogger.deletePost
+       $f_blogger_deletePost_sig = array(array(
+                       // return type
+                       $xmlrpcBoolean, // boolean (ok or not ok)
+
+                       // params
+                       $xmlrpcString,  // appkey (ignored)
+                       $xmlrpcString,  // postid
+                       $xmlrpcString,  // username
+                       $xmlrpcString,  // password
+                       $xmlrpcBoolean, // publish (ignored)
+               ));
+       $f_blogger_deletePost_doc = "Deletes an item";
+       function f_blogger_deletePost($m) {
+               $postid = _getScalar($m,1);
+               $username = _getScalar($m, 2);
+               $password = _getScalar($m, 3);
+
+               return _deleteItem($postid, $username, $password);
+       }
+
+       // blogger.getTemplate
+       $f_blogger_getTemplate_sig = array(array(
+                       // return type
+                       $xmlrpcString,  // the template
+
+                       // params
+                       $xmlrpcString,  // appkey (ignored)
+                       $xmlrpcString,  // blogid
+                       $xmlrpcString,  // username
+                       $xmlrpcString,  // password
+                       $xmlrpcString,  // type of template (main/archiveIndex)
+                               ));
+       $f_blogger_getTemplate_doc = "Returns the required part of the default skin for the given blog";
+       function f_blogger_getTemplate($m) {
+               $blogid = _getScalar($m,1);
+               $username = _getScalar($m,2);
+               $password = _getScalar($m,3);
+               $type = _getScalar($m,4);
+
+               switch($type) {
+                       case "main":
+                               $type = "index";
+                               break;
+                       case "archiveIndex":
+                               $type = "archivelist";
+                               break;
+               }
+
+               return _getSkinPart($blogid, $username, $password, $type);
+       }
+
+       // blogger.setTemplate
+       $f_blogger_setTemplate_sig = array(array(
+                       // return type
+                       $xmlrpcBoolean, // OK or not OK
+
+                       // params
+                       $xmlrpcString,  // appkey (ignored)
+                       $xmlrpcString,  // blogid
+                       $xmlrpcString,  // username
+                       $xmlrpcString,  // password
+                       $xmlrpcString,  // template contents
+                       $xmlrpcString,  // type of template (main/archiveIndex)
+                       ));
+       $f_blogger_setTemplate_doc = "Changes a part of the default skin for the selected blog";
+       function f_blogger_setTemplate($m) {
+               $blogid = _getScalar($m,1);
+               $username = _getScalar($m,2);
+               $password = _getScalar($m,3);
+               $content = _getScalar($m,4);
+               $type = _getScalar($m,5);
+
+               switch($type) {
+                       case "main":
+                               $type = "index";
+                               break;
+                       case "archiveIndex":
+                               $type = "archivelist";
+                               break;
+               }
+
+               return _setSkinPart($blogid, $username, $password, $content, $type);
+       }
+
+       // blogger.getUserInfo
+       $f_blogger_getUserInfo_sig = array(array(
+                       // return type
+                       $xmlrpcStruct,  // Struct
+
+                       // params
+                       $xmlrpcString,  // appkey (ignored)
+                       $xmlrpcString,  // username
+                       $xmlrpcString,  // password
+                       ));
+       $f_blogger_getUserInfo_doc = "Returns info on the user";
+       function f_blogger_getUserInfo($m) {
+               $username = _getScalar($m,1);
+               $password = _getScalar($m,2);
+
+               return _getUserInfo($username, $password);
+       }
+
+
+       /**
+         * Returns a list of recent items
+         */
+       function _getRecentItemsBlogger($blogid, $username, $password, $amount) {
+
+               $blogid = intval($blogid);
+               $amount = intval($amount);
+
+               // 1. login
+               $mem = new MEMBER();
+               if (!$mem->login($username, $password))
+                       return _error(1,"Could not log in");
+
+               // 2. check if allowed
+               if (!BLOG::existsID($blogid))
+                       return _error(2,"No such blog ($blogid)");
+               if (!$mem->teamRights($blogid))
+                       return _error(3,"Not a team member");
+               $amount = intval($amount);
+               if (($amount < 1) or ($amount > 20))
+                       return _error(5,"Amount parameter must be in range 1..20");
+
+               // 3. create and return list of recent items
+               // Struct returned has dateCreated, userid, blogid and content
+
+               $blog = new BLOG($blogid);
+
+               $structarray = array();         // the array in which the structs will be stored
+
+               $query = "SELECT mname, ibody, iauthor, ibody, inumber, ititle as title, itime, cname as category"
+                          .' FROM '.sql_table('item').', '.sql_table('category').', '.sql_table('member')
+                          ." WHERE iblog=$blogid and icat=catid and iauthor=mnumber"
+                          ." ORDER BY itime DESC"
+                          ." LIMIT $amount";
+               $r = sql_query($query);
+
+               while ($row = mysql_fetch_assoc($r)) {
+
+                       // remove linebreaks if needed
+                       if ($blog->convertBreaks())
+                               $row['ibody'] = removeBreaks($row['ibody']);
+
+                       $content = blogger_specialTags($row) . $row['ibody'];
+
+                       $newstruct = new xmlrpcval(array(
+                               "userid" => new xmlrpcval($row['iauthor'],"string"),
+                               "dateCreated" => new xmlrpcval(iso8601_encode(strtotime($row['itime'])),"dateTime.iso8601"),
+                               "blogid" => new xmlrpcval($blogid,"string"),
+                               "content" => new xmlrpcval($content,"string"),
+                               "postid" => new xmlrpcval($row['inumber'],"string"),
+                               "authorName" => new xmlrpcval($row['mname'],'string'),
+                               "title" => new xmlrpcval($row['title'],'string'),
+                       ),'struct');
+                       array_push($structarray, $newstruct);
+               }
+
+               return new xmlrpcresp(new xmlrpcval( $structarray , "array"));
+
+       }
+
+       /**
+         * Returns one item (Blogger version)
+         */
+       function _getItemBlogger($itemid, $username, $password) {
+               global $manager;
+
+               // 1. login
+               $mem = new MEMBER();
+               if (!$mem->login($username, $password))
+                       return _error(1,"Could not log in");
+
+               // 2. check if allowed
+               if (!$manager->existsItem($itemid,1,1))
+                       return _error(6,"No such item ($itemid)");
+               $blogid = getBlogIDFromItemID($itemid);
+               if (!$mem->teamRights($blogid))
+                       return _error(3,"Not a team member");
+
+               // 3. return the item
+               // Structure returned has dateCreated, userid, blogid and content
+
+               $item =& $manager->getItem($itemid,1,1); // (also allow drafts and future items)
+               $blog = new BLOG($blogid);
+
+               // get category
+               $item['category'] = $blog->getCategoryName($item['catid']);
+
+               // remove linebreaks if needed
+               if ($blog->convertBreaks())
+                       $item['body'] = removeBreaks($item['body']);
+
+               $content = blogger_specialTags($item) . $item['body'];
+
+               $newstruct = new xmlrpcval(array(
+                       "dateCreated" => new xmlrpcval(iso8601_encode($item['timestamp']),"dateTime.iso8601"),
+                       "userid" => new xmlrpcval($item['authorid'],"string"),
+                       "blogid" => new xmlrpcval($blogid,"string"),
+                       "content" => new xmlrpcval($content,"string")
+               ),'struct');
+
+               return new xmlrpcresp($newstruct);
+
+
+       }
+
+
+       function blogger_extractTitle($body) {
+               return blogger_matchTag('title',$body);
+       }
+
+       function blogger_extractCategory($body) {
+               return blogger_matchTag('category',$body);
+       }
+
+       function blogger_matchTag($tag, $body) {
+               if (preg_match("/<" . $tag .">(.+?)<\/".$tag.">/is",$body,$match))
+                       return $match[1];
+               else
+                       return "";
+       }
+
+       function blogger_removeSpecialTags($body) {
+               $body = preg_replace("/<title>(.+?)<\/title>/","",$body);
+               $body = preg_replace("/<category>(.+?)<\/category>/","",$body);
+               return trim($body);
+       }
+
+       function blogger_specialTags($item) {
+               $result = "<title>". $item['title']."</title>";
+               $result .= "<category>".$item['category']."</category>";
+               return $result;
+       }
+
+
+
+       $functionDefs = array_merge($functionDefs,
+               array(
+                        "blogger.getUsersBlogs" =>
+                        array( "function" => "f_blogger_getUsersBlogs",
+                               "signature" => $f_blogger_getUsersBlogs_sig,
+                               "docstring" => $f_blogger_getUsersBlogs_doc),
+
+                        "blogger.newPost" =>
+                        array( "function" => "f_blogger_newPost",
+                               "signature" => $f_blogger_newPost_sig,
+                               "docstring" => $f_blogger_newPost_doc),
+
+                        "blogger.editPost" =>
+                        array( "function" => "f_blogger_editPost",
+                               "signature" => $f_blogger_editPost_sig,
+                               "docstring" => $f_blogger_editPost_doc),
+
+                        "blogger.deletePost" =>
+                        array( "function" => "f_blogger_deletePost",
+                               "signature" => $f_blogger_deletePost_sig,
+                               "docstring" => $f_blogger_deletePost_doc),
+
+                        "blogger.getPost" =>
+                        array( "function" => "f_blogger_getPost",
+                               "signature" => $f_blogger_getPost_sig,
+                               "docstring" => $f_blogger_getPost_doc),
+
+                        "blogger.getRecentPosts" =>
+                        array( "function" => "f_blogger_getRecentPosts",
+                               "signature" => $f_blogger_getRecentPosts_sig,
+                               "docstring" => $f_blogger_getRecentPosts_doc),
+
+                        "blogger.getUserInfo" =>
+                        array( "function" => "f_blogger_getUserInfo",
+                               "signature" => $f_blogger_getUserInfo_sig,
+                               "docstring" => $f_blogger_getUserInfo_doc),
+
+                        "blogger.getTemplate" =>
+                        array( "function" => "f_blogger_getTemplate",
+                               "signature" => $f_blogger_getTemplate_sig,
+                               "docstring" => $f_blogger_getTemplate_doc),
+
+                        "blogger.setTemplate" =>
+                        array( "function" => "f_blogger_setTemplate",
+                               "signature" => $f_blogger_setTemplate_sig,
+                               "docstring" => $f_blogger_setTemplate_doc)
+
+               )
+       );
+
+
+?>
index 51c0e95..df6accf 100755 (executable)
-<?php\r
-\r
-/** \r
-  * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/) \r
-  * Copyright (C) 2002-2005 The Nucleus Group\r
-  *\r
-  * This program is free software; you can redistribute it and/or\r
-  * modify it under the terms of the GNU General Public License\r
-  * as published by the Free Software Foundation; either version 2\r
-  * of the License, or (at your option) any later version.\r
-  * (see nucleus/documentation/index.html#license for more info)\r
-  *\r
-  * $Id: api_metaweblog.inc.php,v 1.3 2005-03-16 08:12:06 kimitake Exp $\r
-  * $NucleusJP: api_metaweblog.inc.php,v 1.3 2005/03/12 06:19:06 kimitake Exp $\r
-  */\r
-\r
-/*\r
- *     This file contains definitions for the methods of the metaWeblog API\r
- */\r
-        \r
-       \r
-       // metaWeblog.newPost\r
-       $f_metaWeblog_newPost_sig = array(array(\r
-                       // return type\r
-                       $xmlrpcString,  // itemid of the new item\r
-\r
-                       // params:\r
-                       $xmlrpcString,  // blogid\r
-                       $xmlrpcString,  // username\r
-                       $xmlrpcString,  // password\r
-                       $xmlrpcStruct,  // content\r
-                       $xmlrpcBoolean, // publish boolean (set to false to create draft)\r
-\r
-               ));\r
-       $f_metaWeblog_newPost_doc = "Adds a new item to the given blog. Adds it as a draft when publish is false";\r
-       function f_metaWeblog_newPost($m) {\r
-               $blogid =                       _getScalar($m,0);\r
-               $username =             _getScalar($m,1);\r
-               $password =             _getScalar($m,2);\r
-               $struct =                       $m->getParam(3);\r
-                       $content =              _getStructVal($struct, 'description');\r
-                       $title =                _getStructVal($struct, 'title');\r
-\r
-                       // category is optional (thus: be careful)!\r
-                       $catlist = $struct->structmem('categories');\r
-                       if ($catlist && ($catlist->kindOf() == "array") && ($catlist->arraysize() > 0)) \r
-                               $category = _getArrayVal($catlist, 0);\r
-\r
-               $publish = _getScalar($m,4);\r
-\r
-               return _addItem($blogid, $username, $password, $title, $content, '', $publish, 0, $category);\r
-       }\r
-       \r
-       \r
-       // metaWeblog.getCategories\r
-       $f_metaWeblog_getCategories_sig = array(array(\r
-               // return\r
-               $xmlrpcStruct,  // categories for blog\r
-               \r
-               // params\r
-               $xmlrpcString,  // blogid\r
-               $xmlrpcString,  // username\r
-               $xmlrpcString,  // password\r
-               \r
-       ));\r
-       $f_metaWeblog_getCategories_doc = "Returns the categories for a given blog";\r
-       function f_metaWeblog_getCategories($m) {\r
-               $blogid =       _getScalar($m,0);\r
-               $username =     _getScalar($m,1);\r
-               $password =     _getScalar($m,2);\r
-       \r
-               return _categoryList($blogid, $username, $password);\r
-       }\r
-       \r
-\r
-       // metaWeblog.getPost\r
-       $f_metaWeblog_getPost_sig = array(array(\r
-               // return\r
-               $xmlrpcStruct,  // the juice \r
-               \r
-               // params\r
-               $xmlrpcString,  // itemid\r
-               $xmlrpcString,  // username\r
-               $xmlrpcString,  // password\r
-               \r
-       ));\r
-       $f_metaWeblog_getPost_doc = "Retrieves a post";\r
-       function f_metaWeblog_getPost($m) {\r
-               $itemid =       _getScalar($m,0);\r
-               $username =     _getScalar($m,1);\r
-               $password =     _getScalar($m,2);\r
-       \r
-               return _mw_getPost($itemid, $username, $password);\r
-       }\r
-       \r
-\r
-       // metaWeblog.editPost\r
-       $f_metaWeblog_editPost_sig = array(array(\r
-                       // return type\r
-                       $xmlrpcBoolean, // true\r
-\r
-                       // params:\r
-                       $xmlrpcString,  // itemid\r
-                       $xmlrpcString,  // username\r
-                       $xmlrpcString,  // password\r
-                       $xmlrpcStruct,  // content\r
-                       $xmlrpcBoolean, // publish boolean (set to false to create draft)\r
-\r
-               ));\r
-       $f_metaWeblog_editPost_doc = "Edits an item";\r
-       function f_metaWeblog_editPost($m) {\r
-               global $manager;\r
-\r
-               $itemid =                       _getScalar($m,0);\r
-               $username =             _getScalar($m,1);\r
-               $password =             _getScalar($m,2);\r
-\r
-               $category = '';\r
-               $struct =                       $m->getParam(3);\r
-                       $content =              _getStructVal($struct, 'description');\r
-                       $title =                _getStructVal($struct, 'title');\r
-\r
-                       // category is optional (thus: be careful)!\r
-                       $catlist = $struct->structmem('categories');\r
-                       if ($catlist && ($catlist->kindOf() == "array") && ($catlist->arraysize() > 0)) {\r
-                               $category = _getArrayVal($catlist, 0);\r
-                       } \r
-                       \r
-               $publish = _getScalar($m,4);\r
-\r
-               // get old title and extended part \r
-               if (!$manager->existsItem($itemid,1,1))\r
-                       return _error(6,"No such item ($itemid)");\r
-               $blogid = getBlogIDFromItemID($itemid);\r
-\r
-               $old =& $manager->getItem($itemid,1,1);\r
-               \r
-               if ($category == '')\r
-               {\r
-                       // leave category unchanged when not present\r
-                       $catid = $old['catid'];\r
-               }\r
-               else\r
-               {\r
-                       $blog = new BLOG($blogid);\r
-                       $catid = $blog->getCategoryIdFromName($category);\r
-               }\r
-               \r
-               if ($old['draft'] && $publish) {\r
-                       $wasdraft = 1;\r
-                       $publish = 1;\r
-               } else {\r
-                       $wasdraft = 0;\r
-               }\r
-\r
-               return _edititem($itemid, $username, $password, $catid, $title, $content, $old['more'], $wasdraft, $publish, $old['closed']);\r
-\r
-       }\r
-       \r
-       // metaWeblog.newMediaObject\r
-       $f_metaWeblog_newMediaObject_sig = array(array(\r
-               //  return type\r
-               $xmlrpcStruct,          // "url" element\r
-               \r
-               // params\r
-               $xmlrpcString,          // blogid\r
-               $xmlrpcString,          // username\r
-               $xmlrpcString,          // password\r
-               $xmlrpcStruct           // 'name', 'type' and 'bits'\r
-       ));\r
-       $f_metaWeblog_newMediaObject_doc = 'Uploads a file to to the media library of the user';\r
-       function f_metaWeblog_newMediaObject($m) {\r
-               $blogid         = _getScalar($m, 0);\r
-               $username       = _getScalar($m, 1);\r
-               $password       = _getScalar($m, 2);\r
-               \r
-               $struct         = $m->getParam(3);\r
-                       $name   = _getStructVal($struct, 'name');\r
-                       $type   = _getStructVal($struct, 'type');\r
-                       $bits   = _getStructVal($struct, 'bits');\r
-                       \r
-               return _newMediaObject($blogid, $username, $password, array('name' => $name, 'type' => $type, 'bits' => $bits));\r
-       }\r
-       \r
-       // metaWeblog.getRecentPosts\r
-       $f_metaWeblog_getRecentPosts_sig = array(array(\r
-               // return type\r
-               $xmlrpcStruct,          // array of structs\r
-\r
-               // params\r
-               $xmlrpcString,          // blogid\r
-               $xmlrpcString,          // username\r
-               $xmlrpcString,          // password\r
-               $xmlrpcInt                      // number of posts\r
-       ));\r
-       $f_metaWeblog_getRecentPosts_doc = 'Returns recent weblog items.';\r
-       function f_metaWeblog_getRecentPosts($m) {\r
-               $blogid         = _getScalar($m, 0);\r
-               $username       = _getScalar($m, 1);\r
-               $password       = _getScalar($m, 2);\r
-               $amount         = intval(_getScalar($m, 3));\r
-               \r
-               return _getRecentItemsMetaWeblog($blogid, $username, $password, $amount); \r
-       }\r
-       \r
-       function _getRecentItemsMetaWeblog($blogid, $username, $password, $amount) {\r
-       \r
-               $blogid = intval($blogid);\r
-               $amount = intval($amount);\r
-       \r
-               // 1. login\r
-               $mem = new MEMBER();\r
-               if (!$mem->login($username, $password))\r
-                       return _error(1,"Could not log in");\r
-\r
-               // 2. check if allowed \r
-               if (!BLOG::existsID($blogid))\r
-                       return _error(2,"No such blog ($blogid)");\r
-               if (!$mem->teamRights($blogid))\r
-                       return _error(3,"Not a team member");\r
-               $amount = intval($amount);\r
-               if (($amount < 1) or ($amount > 20))\r
-                       return _error(5,"Amount parameter must be in range 1..20");\r
-\r
-               // 3. create and return list of recent items\r
-               // Struct returned has dateCreated, userid, blogid and content\r
-               \r
-               $blog = new BLOG($blogid);\r
-\r
-               $structarray = array();         // the array in which the structs will be stored\r
-\r
-               $query = "SELECT mname, ibody, iauthor, ibody, inumber, ititle as title, itime, cname as category"\r
-                          .' FROM '.sql_table('item').', '.sql_table('category').', '.sql_table('member')\r
-                          ." WHERE iblog=$blogid and icat=catid and iauthor=mnumber"\r
-                          ." ORDER BY itime DESC"\r
-                          ." LIMIT $amount";\r
-               $r = sql_query($query);\r
-               \r
-               while ($row = mysql_fetch_assoc($r)) {\r
-               \r
-                       // remove linebreaks if needed\r
-                       if ($blog->convertBreaks())\r
-                               $row['ibody'] = removeBreaks($row['ibody']);\r
-\r
-                       $newstruct = new xmlrpcval(array(\r
-                               "dateCreated" => new xmlrpcval(iso8601_encode(strtotime($row['itime'])),"dateTime.iso8601"),\r
-                               "userid" => new xmlrpcval($row['iauthor'],"string"),\r
-                               "blogid" => new xmlrpcval($blogid,"string"),\r
-                               "postid" => new xmlrpcval($row['inumber'],"string"),\r
-                               "description" => new xmlrpcval($row['ibody'],"string"),\r
-                               "title" => new xmlrpcval($row['title'],"string"),\r
-                               "categories" => new xmlrpcval(\r
-                                               array(\r
-                                                       new xmlrpcval($row['category'], "string")\r
-                                               )\r
-                                               ,"array")\r
-                       ),'struct');\r
-                       \r
-               //TODO: String link?\r
-               //TODO: String permaLink?\r
-               //TODO: String nucleus_more?\r
-               \r
-               \r
-                       array_push($structarray, $newstruct);           \r
-               }\r
-\r
-               return new xmlrpcresp(new xmlrpcval( $structarray , "array"));\r
-       }\r
-       \r
-       function _newMediaObject($blogid, $username, $password, $info) {\r
-               global $CONF, $DIR_MEDIA, $DIR_LIBS;\r
-               \r
-               // - login\r
-               $mem = new MEMBER();\r
-               if (!$mem->login($username, $password))\r
-                       return _error(1,'Could not log in');\r
-               \r
-               // - check if team member \r
-               if (!BLOG::existsID($blogid))\r
-                       return _error(2,"No such blog ($blogid)");\r
-               if (!$mem->teamRights($blogid))\r
-                       return _error(3,'Not a team member');\r
-                       \r
-               $b = new BLOG($blogid);\r
-               \r
-               // - decode data\r
-               $data = $info['bits']; // decoding was done transparantly by xmlrpclib\r
-               \r
-               // - check filesize\r
-               if (strlen($data) > $CONF['MaxUploadSize'])\r
-                       return _error(9, 'filesize is too big');\r
-\r
-               \r
-               // - check if filetype is allowed (check filename)\r
-               $filename = $info['name'];\r
-               $ok = 0;\r
-               $allowedtypes = explode (',', $CONF['AllowedTypes']);\r
-               foreach ( $allowedtypes as $type ) \r
-                       if (eregi("\." .$type. "$",$filename)) $ok = 1;    \r
-               if (!$ok) \r
-                       _error(8, 'Filetype is not allowed');\r
-                               \r
-               // - add file to media library\r
-               include_once($DIR_LIBS . 'MEDIA.php');  // media classes\r
-               \r
-               // always use private media library of member\r
-               $collection = $mem->getID();\r
-\r
-               // prefix filename with current date (YYYY-MM-DD-)\r
-               // this to avoid nameclashes\r
-               if ($CONF['MediaPrefix'])\r
-                       $filename = strftime("%Y%m%d-", time()) . $filename;    \r
-                       \r
-               $res = MEDIA::addMediaObjectRaw($collection, $filename, $data);\r
-               if ($res)\r
-                       return _error(10, $res);\r
-               \r
-               // - return URL\r
-               $urlstruct = new xmlrpcval(array(\r
-                       "url" => new xmlrpcval($CONF['MediaURL'] . $collection. '/' . $filename,'string')\r
-               ),'struct');            \r
-               \r
-               return new xmlrpcresp($urlstruct);\r
-       }\r
-       \r
-       function _categoryList($blogid, $username, $password) {\r
-               // 1. login\r
-               $mem = new MEMBER();\r
-               if (!$mem->login($username, $password))\r
-                       return _error(1,"Could not log in");\r
-\r
-               // check if on team and blog exists\r
-               if (!BLOG::existsID($blogid))\r
-                       return _error(2,"No such blog ($blogid)");\r
-               if (!$mem->teamRights($blogid))\r
-                       return _error(3,"Not a team member");\r
-                       \r
-               $b = new BLOG($blogid);\r
-               \r
-               $categorystruct = array();\r
-\r
-               $query =  "SELECT cname, cdesc, catid"\r
-                               . ' FROM '.sql_table('category')\r
-                               . " WHERE cblog=" . intval($blogid)\r
-                               . " ORDER BY cname";\r
-               $r = sql_query($query);\r
-\r
-               while ($obj = mysql_fetch_object($r)) {\r
-\r
-                       $categorystruct[$obj->cname] = new xmlrpcval(\r
-                               array(\r
-                                       "description" => new xmlrpcval($obj->cdesc,"string"),\r
-                                       "htmlUrl" => new xmlrpcval($b->getURL() . "?catid=" . $obj->catid ,"string"),\r
-                                       "rssUrl" => new xmlrpcval("","string")\r
-                               )\r
-                       ,'struct');\r
-               }\r
-               \r
-               \r
-               return new xmlrpcresp(new xmlrpcval( $categorystruct , "struct"));\r
-       \r
-       }\r
-       \r
-       \r
-       function _mw_getPost($itemid, $username, $password) {\r
-               global $manager;\r
-               \r
-               // 1. login\r
-               $mem = new MEMBER();\r
-               if (!$mem->login($username, $password))\r
-                       return _error(1,"Could not log in");\r
-\r
-               // 2. check if allowed \r
-               if (!$manager->existsItem($itemid,1,1))\r
-                       return _error(6,"No such item ($itemid)");\r
-               $blogid = getBlogIDFromItemID($itemid);\r
-               if (!$mem->teamRights($blogid))\r
-                       return _error(3,"Not a team member");\r
-\r
-               // 3. return the item\r
-               $item =& $manager->getItem($itemid,1,1); // (also allow drafts and future items)\r
-               \r
-               $b = new BLOG($blogid);\r
-               if ($b->convertBreaks())\r
-                       $item['body'] = removeBreaks($item['body']);\r
-                       \r
-               $categoryname = $b->getCategoryName($item['catid']);\r
-\r
-               $newstruct = new xmlrpcval(array(\r
-                       "dateCreated" => new xmlrpcval(iso8601_encode($item['timestamp']),"dateTime.iso8601"),\r
-                       "userid" => new xmlrpcval($item['authorid'],"string"),\r
-                       "blogid" => new xmlrpcval($blogid,"string"),\r
-                       "postid" => new xmlrpcval($itemid, "string"),\r
-                       "description" => new xmlrpcval($item['body'],"string"),\r
-                       "title" => new xmlrpcval($item['title'],"string"),\r
-                       "categories" => new xmlrpcval(\r
-                                       array(\r
-                                               new xmlrpcval($categoryname, "string")\r
-                                       )\r
-                                       ,"array")\r
-               ),'struct');\r
-               \r
-               //TODO: add "String link" to struct?\r
-               //TODO: add "String permaLink" to struct? \r
-               //TODO: add "String nucleus_more" to struct?\r
-\r
-               return new xmlrpcresp($newstruct);\r
-       \r
-       }\r
-       \r
-       $functionDefs = array_merge($functionDefs,\r
-               array(\r
-                        "metaWeblog.newPost" =>\r
-                        array(\r
-                               "function" => "f_metaWeblog_newPost",\r
-                               "signature" => $f_metaWeblog_newPost_sig,\r
-                               "docstring" => $f_metaWeblog_newPost_doc\r
-                        ),\r
-\r
-                        "metaWeblog.getCategories" =>\r
-                        array(\r
-                               "function" => "f_metaWeblog_getCategories",\r
-                               "signature" => $f_metaWeblog_getCategories_sig,\r
-                               "docstring" => $f_metaWeblog_getCategories_doc\r
-                        ),     \r
-\r
-                        "metaWeblog.getPost" =>\r
-                        array(\r
-                               "function" => "f_metaWeblog_getPost",\r
-                               "signature" => $f_metaWeblog_getPost_sig,\r
-                               "docstring" => $f_metaWeblog_getPost_doc\r
-                        ),     \r
-\r
-                        "metaWeblog.editPost" =>\r
-                        array(\r
-                               "function" => "f_metaWeblog_editPost",\r
-                               "signature" => $f_metaWeblog_editPost_sig,\r
-                               "docstring" => $f_metaWeblog_editPost_doc\r
-                        ),\r
-                        \r
-                        'metaWeblog.newMediaObject' =>\r
-                        array(\r
-                               'function' => 'f_metaWeblog_newMediaObject',\r
-                               'signature' => $f_metaWeblog_newMediaObject_sig,\r
-                               'docstring' => $f_metaWeblog_newMediaObject_doc\r
-                        ),\r
-                        \r
-                        'metaWeblog.getRecentPosts' =>\r
-                        array(\r
-                               'function' => 'f_metaWeblog_getRecentPosts',\r
-                               'signature' => $f_metaWeblog_getRecentPosts_sig,\r
-                               'docstring' => $f_metaWeblog_getRecentPosts_doc\r
-                        )                       \r
-               \r
-               )\r
-       );\r
-?>\r
+<?php
+
+/*
+ * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/)
+ * Copyright (C) 2002-2007 The Nucleus Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * (see nucleus/documentation/index.html#license for more info)
+ */
+
+/**
+ *     This file contains definitions for the methods of the metaWeblog API
+ *
+ * @license http://nucleuscms.org/license.txt GNU General Public License
+ * @copyright Copyright (C) 2002-2007 The Nucleus Group
+ * @version $Id: api_metaweblog.inc.php,v 1.4 2007-03-27 12:14:05 kimitake Exp $
+ * $NucleusJP: api_metaweblog.inc.php,v 1.6 2007/02/04 06:28:46 kimitake Exp $
+ */
+
+
+       // metaWeblog.newPost
+       $f_metaWeblog_newPost_sig = array(array(
+                       // return type
+                       $xmlrpcString,  // itemid of the new item
+
+                       // params:
+                       $xmlrpcString,  // blogid
+                       $xmlrpcString,  // username
+                       $xmlrpcString,  // password
+                       $xmlrpcStruct,  // content
+                       $xmlrpcBoolean, // publish boolean (set to false to create draft)
+
+               ));
+       $f_metaWeblog_newPost_doc = "Adds a new item to the given blog. Adds it as a draft when publish is false";
+       function f_metaWeblog_newPost($m) {
+               global $manager;
+               
+               $blogid =                       _getScalar($m,0);
+               $username =             _getScalar($m,1);
+               $password =             _getScalar($m,2);
+               $struct =                       $m->getParam(3);
+               
+               $content =              _getStructVal($struct, 'description');
+               $more =                 _getStructVal($struct, 'mt_text_more');
+               $title =                _getStructVal($struct, 'title');
+
+               // category is optional (thus: be careful)!
+               $catlist = $struct->structmem('categories');
+               if ($catlist && ($catlist->kindOf() == "array") && ($catlist->arraysize() > 0))
+                       $category = _getArrayVal($catlist, 0);
+               
+               
+               $comments = (int) _getStructVal($struct, 'mt_allow_comments') ? 0 : 1;
+               $publish = _getScalar($m,4);
+
+
+               // Add item
+               $res = _addItem($blogid, $username, $password, $title, $content, $more, $publish, $comments, $category);
+               
+               // Handle trackbacks
+               $trackbacks = array();
+               $tblist = $struct->structmem('mt_tb_ping_urls');
+               if ($tblist && ($tblist->kindOf() == "array") && ($tblist->arraysize() > 0)) {
+                       
+                       for ($i = 0; $i < $tblist->arraysize(); $i++) {
+                               $trackbacks[] = _getArrayVal($tblist, $i);
+                       }
+                       
+                       $manager->notify('SendTrackback', array ('tb_id' => $itemid, 'urls' => & $trackbacks));
+               }
+
+               return $res;
+       }
+
+
+       // metaWeblog.getCategories
+       $f_metaWeblog_getCategories_sig = array(array(
+               // return
+               $xmlrpcStruct,  // categories for blog
+
+               // params
+               $xmlrpcString,  // blogid
+               $xmlrpcString,  // username
+               $xmlrpcString,  // password
+
+       ));
+       $f_metaWeblog_getCategories_doc = "Returns the categories for a given blog";
+       function f_metaWeblog_getCategories($m) {
+               $blogid =       _getScalar($m,0);
+               $username =     _getScalar($m,1);
+               $password =     _getScalar($m,2);
+
+               return _categoryList($blogid, $username, $password);
+       }
+
+
+       // metaWeblog.getPost
+       $f_metaWeblog_getPost_sig = array(array(
+               // return
+               $xmlrpcStruct,  // the juice
+
+               // params
+               $xmlrpcString,  // itemid
+               $xmlrpcString,  // username
+               $xmlrpcString,  // password
+
+       ));
+       $f_metaWeblog_getPost_doc = "Retrieves a post";
+       function f_metaWeblog_getPost($m) {
+               $itemid =       _getScalar($m,0);
+               $username =     _getScalar($m,1);
+               $password =     _getScalar($m,2);
+
+               return _mw_getPost($itemid, $username, $password);
+       }
+
+
+       // metaWeblog.editPost
+       $f_metaWeblog_editPost_sig = array(array(
+                       // return type
+                       $xmlrpcBoolean, // true
+
+                       // params:
+                       $xmlrpcString,  // itemid
+                       $xmlrpcString,  // username
+                       $xmlrpcString,  // password
+                       $xmlrpcStruct,  // content
+                       $xmlrpcBoolean, // publish boolean (set to false to create draft)
+
+               ));
+       $f_metaWeblog_editPost_doc = "Edits an item";
+       function f_metaWeblog_editPost($m) {
+               global $manager;
+
+               $itemid =                       _getScalar($m,0);
+               $username =             _getScalar($m,1);
+               $password =             _getScalar($m,2);
+
+               $category = '';
+               $struct =                       $m->getParam(3);
+                       $content =              _getStructVal($struct, 'description');
+                       $title =                _getStructVal($struct, 'title');
+
+                       // category is optional (thus: be careful)!
+                       $catlist = $struct->structmem('categories');
+                       if ($catlist && ($catlist->kindOf() == "array") && ($catlist->arraysize() > 0)) {
+                               $category = _getArrayVal($catlist, 0);
+                       }
+
+               $publish = _getScalar($m,4);
+
+               
+               // get old title and extended part
+               if (!$manager->existsItem($itemid,1,1))
+                       return _error(6,"No such item ($itemid)");
+               $blogid = getBlogIDFromItemID($itemid);
+
+               $old =& $manager->getItem($itemid,1,1);
+
+               if ($category == '')
+               {
+                       // leave category unchanged when not present
+                       $catid = $old['catid'];
+               }
+               else
+               {
+                       $blog = new BLOG($blogid);
+                       $catid = $blog->getCategoryIdFromName($category);
+               }
+
+               if ($old['draft'] && $publish) {
+                       $wasdraft = 1;
+                       $publish = 1;
+               } else {
+                       $wasdraft = 0;
+               }
+
+               $more = $struct->structmem('mt_text_more');
+               if ($more) {
+                       $more = _getStructVal($struct, 'mt_text_more');
+               } else {
+                       $more = $old['more'];
+               }
+               
+               $comments = $struct->structmem('mt_allow_comments');
+               if ($comments) {
+                       $comments = (int) _getStructVal($struct, 'mt_allow_comments') ? 0 : 1;
+               } else {
+                       $comments = $old['closed'];
+               }
+
+               $res = _edititem($itemid, $username, $password, $catid, $title, $content, $more, $wasdraft, $publish, $comments);
+
+               // Handle trackbacks
+               $trackbacks = array();
+               $tblist = $struct->structmem('mt_tb_ping_urls');
+               if ($tblist && ($tblist->kindOf() == "array") && ($tblist->arraysize() > 0)) {
+                       
+                       for ($i = 0; $i < $tblist->arraysize(); $i++) {
+                               $trackbacks[] = _getArrayVal($tblist, $i);
+                       }
+                       
+                       $manager->notify('SendTrackback', array ('tb_id' => $itemid, 'urls' => & $trackbacks));
+               }
+
+               return $res;
+       }
+
+       // metaWeblog.newMediaObject
+       $f_metaWeblog_newMediaObject_sig = array(array(
+               //  return type
+               $xmlrpcStruct,          // "url" element
+
+               // params
+               $xmlrpcString,          // blogid
+               $xmlrpcString,          // username
+               $xmlrpcString,          // password
+               $xmlrpcStruct           // 'name', 'type' and 'bits'
+       ));
+       $f_metaWeblog_newMediaObject_doc = 'Uploads a file to to the media library of the user';
+       function f_metaWeblog_newMediaObject($m) {
+               $blogid         = _getScalar($m, 0);
+               $username       = _getScalar($m, 1);
+               $password       = _getScalar($m, 2);
+
+               $struct         = $m->getParam(3);
+                       $name   = _getStructVal($struct, 'name');
+                       $type   = _getStructVal($struct, 'type');
+                       $bits   = _getStructVal($struct, 'bits');
+
+               return _newMediaObject($blogid, $username, $password, array('name' => $name, 'type' => $type, 'bits' => $bits));
+       }
+
+       // metaWeblog.getRecentPosts
+       $f_metaWeblog_getRecentPosts_sig = array(array(
+               // return type
+               $xmlrpcStruct,          // array of structs
+
+               // params
+               $xmlrpcString,          // blogid
+               $xmlrpcString,          // username
+               $xmlrpcString,          // password
+               $xmlrpcInt                      // number of posts
+       ));
+       $f_metaWeblog_getRecentPosts_doc = 'Returns recent weblog items.';
+       function f_metaWeblog_getRecentPosts($m) {
+               $blogid         = _getScalar($m, 0);
+               $username       = _getScalar($m, 1);
+               $password       = _getScalar($m, 2);
+               $amount         = intval(_getScalar($m, 3));
+
+               return _getRecentItemsMetaWeblog($blogid, $username, $password, $amount);
+       }
+
+       function _getRecentItemsMetaWeblog($blogid, $username, $password, $amount) {
+
+               $blogid = intval($blogid);
+               $amount = intval($amount);
+
+               // 1. login
+               $mem = new MEMBER();
+               if (!$mem->login($username, $password))
+                       return _error(1,"Could not log in");
+
+               // 2. check if allowed
+               if (!BLOG::existsID($blogid))
+                       return _error(2,"No such blog ($blogid)");
+               if (!$mem->teamRights($blogid))
+                       return _error(3,"Not a team member");
+               $amount = intval($amount);
+               if (($amount < 1) or ($amount > 20))
+                       return _error(5,"Amount parameter must be in range 1..20");
+
+               // 3. create and return list of recent items
+               // Struct returned has dateCreated, userid, blogid and content
+
+               $blog = new BLOG($blogid);
+
+               $structarray = array();         // the array in which the structs will be stored
+
+               $query = "SELECT mname, ibody, imore, iauthor, ibody, inumber, ititle as title, itime, cname as category, iclosed"
+                          .' FROM '.sql_table('item').', '.sql_table('category').', '.sql_table('member')
+                          ." WHERE iblog=$blogid and icat=catid and iauthor=mnumber"
+                          ." ORDER BY itime DESC"
+                          ." LIMIT $amount";
+               $r = sql_query($query);
+
+               while ($row = mysql_fetch_assoc($r)) {
+
+                       // remove linebreaks if needed
+                       if ($blog->convertBreaks()) {
+                               $row['ibody'] = removeBreaks($row['ibody']);
+                               $row['imore'] = removeBreaks($row['imore']);
+                       }
+
+                       $newstruct = new xmlrpcval(array(
+                               "dateCreated" => new xmlrpcval(iso8601_encode(strtotime($row['itime'])),"dateTime.iso8601"),
+                               "userid" => new xmlrpcval($row['iauthor'],"string"),
+                               "blogid" => new xmlrpcval($blogid,"string"),
+                               "postid" => new xmlrpcval($row['inumber'],"string"),
+                               "description" => new xmlrpcval($row['ibody'],"string"),
+                               "title" => new xmlrpcval($row['title'],"string"),
+                               "categories" => new xmlrpcval(
+                                               array(
+                                                       new xmlrpcval($row['category'], "string")
+                                               )
+                                               ,"array"),
+                               
+                                               
+                               "mt_text_more"          => new xmlrpcval($row['imore'], "string"),
+                               "mt_allow_comments" => new xmlrpcval($row['iclosed'] ? 0 : 1, "int"),
+                               "mt_allow_pings"        => new xmlrpcval(1, "int")
+                       ),'struct');
+
+               //TODO: String link?
+               //TODO: String permaLink?
+
+
+                       array_push($structarray, $newstruct);
+               }
+
+               return new xmlrpcresp(new xmlrpcval( $structarray , "array"));
+       }
+
+       function _newMediaObject($blogid, $username, $password, $info) {
+               global $CONF, $DIR_MEDIA, $DIR_LIBS;
+
+               // - login
+               $mem = new MEMBER();
+               if (!$mem->login($username, $password))
+                       return _error(1,'Could not log in');
+
+               // - check if team member
+               if (!BLOG::existsID($blogid))
+                       return _error(2,"No such blog ($blogid)");
+               if (!$mem->teamRights($blogid))
+                       return _error(3,'Not a team member');
+
+               $b = new BLOG($blogid);
+
+               // - decode data
+               $data = $info['bits']; // decoding was done transparantly by xmlrpclib
+
+               // - check filesize
+               if (strlen($data) > $CONF['MaxUploadSize'])
+                       return _error(9, 'filesize is too big');
+
+
+               // - check if filetype is allowed (check filename)
+               $filename = $info['name'];
+               $ok = 0;
+               $allowedtypes = explode (',', $CONF['AllowedTypes']);
+               foreach ( $allowedtypes as $type )
+                       if (eregi("\." .$type. "$",$filename)) $ok = 1;
+               if (!$ok)
+                       _error(8, 'Filetype is not allowed');
+
+               // - add file to media library
+               include_once($DIR_LIBS . 'MEDIA.php');  // media classes
+
+               // always use private media library of member
+               $collection = $mem->getID();
+
+               // prefix filename with current date (YYYY-MM-DD-)
+               // this to avoid nameclashes
+               if ($CONF['MediaPrefix'])
+                       $filename = strftime("%Y%m%d-", time()) . $filename;
+
+               $res = MEDIA::addMediaObjectRaw($collection, $filename, $data);
+               if ($res)
+                       return _error(10, $res);
+
+               // - return URL
+               $urlstruct = new xmlrpcval(array(
+                       "url" => new xmlrpcval($CONF['MediaURL'] . $collection. '/' . $filename,'string')
+               ),'struct');
+
+               return new xmlrpcresp($urlstruct);
+       }
+
+       function _categoryList($blogid, $username, $password) {
+               // 1. login
+               $mem = new MEMBER();
+               if (!$mem->login($username, $password))
+                       return _error(1,"Could not log in");
+
+               // check if on team and blog exists
+               if (!BLOG::existsID($blogid))
+                       return _error(2,"No such blog ($blogid)");
+               if (!$mem->teamRights($blogid))
+                       return _error(3,"Not a team member");
+
+               $b = new BLOG($blogid);
+
+               $categorystruct = array();
+
+               $query =  "SELECT cname, cdesc, catid"
+                               . ' FROM '.sql_table('category')
+                               . " WHERE cblog=" . intval($blogid)
+                               . " ORDER BY cname";
+               $r = sql_query($query);
+
+               while ($obj = mysql_fetch_object($r)) {
+
+                       $categorystruct[$obj->cname] = new xmlrpcval(
+                               array(
+                                       "description" => new xmlrpcval($obj->cdesc,"string"),
+                                       "htmlUrl" => new xmlrpcval($b->getURL() . "?catid=" . $obj->catid ,"string"),
+                                       "rssUrl" => new xmlrpcval("","string")
+                               )
+                       ,'struct');
+               }
+
+
+               return new xmlrpcresp(new xmlrpcval( $categorystruct , "struct"));
+
+       }
+
+
+       function _mw_getPost($itemid, $username, $password) {
+               global $manager;
+
+               // 1. login
+               $mem = new MEMBER();
+               if (!$mem->login($username, $password))
+                       return _error(1,"Could not log in");
+
+               // 2. check if allowed
+               if (!$manager->existsItem($itemid,1,1))
+                       return _error(6,"No such item ($itemid)");
+               $blogid = getBlogIDFromItemID($itemid);
+               if (!$mem->teamRights($blogid))
+                       return _error(3,"Not a team member");
+
+               // 3. return the item
+               $item =& $manager->getItem($itemid,1,1); // (also allow drafts and future items)
+
+               $b = new BLOG($blogid);
+               if ($b->convertBreaks()) {
+                       $item['body'] = removeBreaks($item['body']);
+                       $item['more'] = removeBreaks($item['more']);
+               }
+
+               $categoryname = $b->getCategoryName($item['catid']);
+
+               $newstruct = new xmlrpcval(array(
+                       "dateCreated" => new xmlrpcval(iso8601_encode($item['timestamp']),"dateTime.iso8601"),
+                       "userid" => new xmlrpcval($item['authorid'],"string"),
+                       "blogid" => new xmlrpcval($blogid,"string"),
+                       "postid" => new xmlrpcval($itemid, "string"),
+                       "description" => new xmlrpcval($item['body'],"string"),
+                       "title" => new xmlrpcval($item['title'],"string"),
+                       "categories" => new xmlrpcval(
+                                       array(
+                                               new xmlrpcval($categoryname, "string")
+                                       )
+                                       ,"array"),
+                               
+                       "mt_text_more"          => new xmlrpcval($item['more'], "string"),
+                       "mt_allow_comments" => new xmlrpcval($item['closed'] ? 0 : 1, "int"),
+                       "mt_allow_pings"        => new xmlrpcval(1, "int")
+               ),'struct');
+
+               //TODO: add "String link" to struct?
+               //TODO: add "String permaLink" to struct?
+
+               return new xmlrpcresp($newstruct);
+
+       }
+
+       $functionDefs = array_merge($functionDefs,
+               array(
+                        "metaWeblog.newPost" =>
+                        array(
+                               "function" => "f_metaWeblog_newPost",
+                               "signature" => $f_metaWeblog_newPost_sig,
+                               "docstring" => $f_metaWeblog_newPost_doc
+                        ),
+
+                        "metaWeblog.getCategories" =>
+                        array(
+                               "function" => "f_metaWeblog_getCategories",
+                               "signature" => $f_metaWeblog_getCategories_sig,
+                               "docstring" => $f_metaWeblog_getCategories_doc
+                        ),
+
+                        "metaWeblog.getPost" =>
+                        array(
+                               "function" => "f_metaWeblog_getPost",
+                               "signature" => $f_metaWeblog_getPost_sig,
+                               "docstring" => $f_metaWeblog_getPost_doc
+                        ),
+
+                        "metaWeblog.editPost" =>
+                        array(
+                               "function" => "f_metaWeblog_editPost",
+                               "signature" => $f_metaWeblog_editPost_sig,
+                               "docstring" => $f_metaWeblog_editPost_doc
+                        ),
+
+                        'metaWeblog.newMediaObject' =>
+                        array(
+                               'function' => 'f_metaWeblog_newMediaObject',
+                               'signature' => $f_metaWeblog_newMediaObject_sig,
+                               'docstring' => $f_metaWeblog_newMediaObject_doc
+                        ),
+
+                        'metaWeblog.getRecentPosts' =>
+                        array(
+                               'function' => 'f_metaWeblog_getRecentPosts',
+                               'signature' => $f_metaWeblog_getRecentPosts_sig,
+                               'docstring' => $f_metaWeblog_getRecentPosts_doc
+                        )
+
+               )
+       );
+?>
\ No newline at end of file
index f2b0cdb..7016451 100755 (executable)
-<?php\r
-\r
-/** \r
-  * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/) \r
-  * Copyright (C) 2002-2005 The Nucleus Group\r
-  *\r
-  * This program is free software; you can redistribute it and/or\r
-  * modify it under the terms of the GNU General Public License\r
-  * as published by the Free Software Foundation; either version 2\r
-  * of the License, or (at your option) any later version.\r
-  * (see nucleus/documentation/index.html#license for more info)\r
-  *\r
-  * $Id: api_mt.inc.php,v 1.3 2005-03-16 08:12:06 kimitake Exp $\r
-  * $NucleusJP: api_mt.inc.php,v 1.3 2005/03/12 06:19:06 kimitake Exp $\r
-  */\r
-\r
-/*\r
- * This file contains definitions for the methods in the Movable Type API\r
- *\r
- * Wouter Demuynck 2003-08-31\r
- */\r
-\r
-\r
-       // mt.supportedMethods\r
-       $f_mt_supportedMethods_sig = array(array(\r
-                       // return type\r
-                       $xmlrpcArray // array of strings\r
-               ));\r
-       $f_mt_supportedMethods_doc = 'returns an array of supported methods';\r
-       function f_mt_supportedMethods($m) {\r
-               $res = new xmlrpcresp(new xmlrpcval( \r
-                       array(\r
-                               new xmlrpcval('mt.supportedMethods', 'string'),\r
-                               new xmlrpcval('mt.supportedTextFilters', 'string'),\r
-                               new xmlrpcval('mt.publishPost', 'string'),\r
-                               new xmlrpcval('mt.getCategoryList', 'string'),\r
-                               new xmlrpcval('mt.getPostCategories', 'string'),\r
-                               new xmlrpcval('mt.setPostCategories', 'string'),\r
-                               new xmlrpcval('mt.getRecentPostTitles', 'string'),\r
-                               new xmlrpcval('mt.getTrackbackPings','string'),\r
-                       ), 'array')\r
-               );\r
-               return $res;\r
-       }\r
-       \r
-       // mt.supportedTextFilters\r
-       $f_mt_supportedTextFilters_sig = array(array(\r
-                       // return type\r
-                       $xmlrpcArray    // array of structs\r
-               ));\r
-       $f_mt_supportedTextFilters_doc = 'returns the supported text filters';\r
-       function f_mt_supportedTextFilters($m) {\r
-               $res = new xmlrpcresp(new xmlrpcval( \r
-                       array(\r
-                               // no text filters in nucleus\r
-                       ), 'array')\r
-               );\r
-               return $res;\r
-       }\r
-       \r
-       // mt.getCategoryList\r
-       $f_mt_getCategoryList_sig = array(array(\r
-                       // return type\r
-                       $xmlrpcArray,           // array of structs\r
-                       \r
-                       // params\r
-                       $xmlrpcString,          // blogid\r
-                       $xmlrpcString,          // username\r
-                       $xmlrpcString           // password\r
-                       \r
-               ));\r
-       $f_mt_getCategoryList_doc = 'Returns a list of all categories defined in the weblog';\r
-       function f_mt_getCategoryList($m) {\r
-               $blogid =       _getScalar($m,0);\r
-               $username =     _getScalar($m,1);\r
-               $password =     _getScalar($m,2);\r
-\r
-               return _mt_categoryList($blogid, $username, $password);\r
-       }\r
-       \r
-       // mt.publishPost\r
-       $f_mt_publishPost_sig = array(array(\r
-                       // return type\r
-                       $xmlrpcBoolean,         // true\r
-                       \r
-                       // params\r
-                       $xmlrpcString,          // itemid\r
-                       $xmlrpcString,          // username\r
-                       $xmlrpcString           // password\r
-               ));\r
-       $f_mt_publishPost_doc = 'Transfers an item from the "draft" state to the "published" state. For items that were published earlier, does nothing.';\r
-       function f_mt_publishPost($m) {\r
-               $itemid         = intval(_getScalar($m, 0));\r
-               $username       = _getScalar($m, 1);\r
-               $password       = _getScalar($m, 2);            \r
-               \r
-               return _mt_publishPost($itemid, $username, $password);\r
-       }\r
-       \r
-       // mt.getPostCategories\r
-       $f_mt_getPostCategories_sig = array(array(\r
-               // return\r
-               $xmlrpcArray,           // array of structs\r
-               // parameters\r
-               $xmlrpcString,          // itemid\r
-               $xmlrpcString,          // username\r
-               $xmlrpcString           // password\r
-       ));\r
-       $f_mt_getPostCategories_doc = 'Returns a list of all categories to which the post is assigned.';\r
-       function f_mt_getPostCategories($m) {\r
-               $itemid         = intval(_getScalar($m, 0));\r
-               $username       = _getScalar($m, 1);\r
-               $password       = _getScalar($m, 2);\r
-               \r
-               return _mt_getPostCategories($itemid, $username, $password);\r
-       }\r
-\r
-       // mt.setPostCategories\r
-       $f_mt_setPostCategories_sig = array(array(\r
-               // return\r
-               $xmlrpcBoolean,         // true\r
-               // parameters\r
-               $xmlrpcString,          // itemid\r
-               $xmlrpcString,          // username\r
-               $xmlrpcString,          // password\r
-               $xmlrpcArray            // categories\r
-       ));\r
-       $f_mt_setPostCategories_doc = 'Sets the categories for a post. Only the primary category will be stored';\r
-       function f_mt_setPostCategories($m) {\r
-               $itemid         = intval(_getScalar($m, 0));\r
-               $username       = _getScalar($m, 1);\r
-               $password       = _getScalar($m, 2);\r
-\r
-               $categories = $m->getParam(3);\r
-               $iSize = $categories->arraysize();              \r
-\r
-               $category = '';\r
-               for ($i=0;$i<$iSize;$i++) {\r
-                       $struct = $categories->arraymem($i);\r
-                       $bPrimary = $struct->structmem('isPrimary');\r
-                       if ($bPrimary)\r
-                               $bPrimary = $bPrimary->scalarval();\r
-                       else if (!$category)\r
-                               $bPrimary = 1;  // "Using isPrimary to set the primary category is optional--\r
-                                                               // in the absence of this flag, the first struct in the array \r
-                                                               // will be assigned the primary category for the post." (MT doc)\r
-                       if ($bPrimary) {\r
-                               $category = $struct->structmem('categoryId');\r
-                               $category = $category->scalarval();\r
-                       }\r
-                       \r
-               }\r
-               \r
-               return _mt_setPostCategories($itemid, $username, $password, $category);\r
-       }\r
-       \r
-       // mt.getRecentPostTitles\r
-       $f_mt_getRecentPostTitles_sig = array(array(\r
-               // return\r
-               $xmlrpcArray,           // array of structs\r
-               // params\r
-               $xmlrpcString,          // blogid\r
-               $xmlrpcString,          // userid\r
-               $xmlrpcString,          // password,\r
-               $xmlrpcInt                      // number of posts\r
-       ));\r
-       $f_mt_getRecentPostTitles_doc = 'Returns a bandwidth-friendly list of the most recent posts in the system.';\r
-       function f_mt_getRecentPostTitles($m) {\r
-               $blogid         = intval(_getScalar($m, 0));\r
-               $username       = _getScalar($m, 1);            \r
-               $password       = _getScalar($m, 2);\r
-               $iAmount        = intval(_getScalar($m, 3));\r
-               \r
-               return _mt_getRecentPostTitles($blogid, $username, $password, $iAmount);\r
-       }\r
-\r
-       // mt.getTrackbackPings\r
-       $f_mt_getTrackbackPings_sig = array(array(\r
-               // return\r
-               $xmlrpcArray,           // array of structs\r
-               // params\r
-               $xmlrpcString           // postid\r
-       ));\r
-       $f_mt_getTrackbackPings_doc = '(this is currently just a placeholder. It returns an empty array.)';\r
-       function f_mt_getTrackbackPings($m) {\r
-               $itemid = intval(_getScalar($m, 0));\r
-                               \r
-               return new xmlrpcresp(new xmlrpcval(array(), 'array'));\r
-       }\r
-       \r
-       $functionDefs = array_merge($functionDefs,\r
-               array(\r
-                        "mt.supportedMethods" =>\r
-                        array( "function" => "f_mt_supportedMethods",\r
-                               "signature" => $f_mt_supportedMethods_sig,\r
-                               "docstring" => $f_mt_supportedMethods_doc),\r
-               \r
-                        "mt.supportedTextFilters" =>\r
-                        array( "function" => "f_mt_supportedTextFilters",\r
-                               "signature" => $f_mt_supportedTextFilters_sig,\r
-                               "docstring" => $f_mt_supportedTextFilters_doc),\r
-                               \r
-                        "mt.getCategoryList" =>\r
-                        array( "function" => "f_mt_getCategoryList",\r
-                               "signature" => $f_mt_getCategoryList_sig,\r
-                               "docstring" => $f_mt_getCategoryList_doc),\r
-                               \r
-                        "mt.publishPost" =>\r
-                        array( "function" => "f_mt_publishPost",\r
-                               "signature" => $f_mt_publishPost_sig,\r
-                               "docstring" => $f_mt_publishPost_doc),\r
-                               \r
-                        "mt.getPostCategories" =>\r
-                        array( "function" => "f_mt_getPostCategories",\r
-                               "signature" => $f_mt_getPostCategories_sig,\r
-                               "docstring" => $f_mt_getPostCategories_doc),\r
-                               \r
-                        "mt.setPostCategories" =>\r
-                        array( "function" => "f_mt_setPostCategories",\r
-                               "signature" => $f_mt_setPostCategories_sig,\r
-                               "docstring" => $f_mt_setPostCategories_doc),\r
-                               \r
-                        "mt.getRecentPostTitles" =>\r
-                        array( "function" => "f_mt_getRecentPostTitles",\r
-                               "signature" => $f_mt_getRecentPostTitles_sig,\r
-                               "docstring" => $f_mt_getRecentPostTitles_doc),\r
-\r
-                        "mt.getTrackbackPings" =>\r
-                        array( "function" => "f_mt_getTrackbackPings",\r
-                               "signature" => $f_mt_getTrackbackPings_sig,\r
-                               "docstring" => $f_mt_getTrackbackPings_doc)\r
-\r
-               )\r
-       );\r
-\r
-       function _mt_setPostCategories($itemid, $username, $password, $category) {\r
-               global $manager;\r
-\r
-               // login\r
-               $mem = new MEMBER();\r
-               if (!$mem->login($username, $password))\r
-                       return _error(1,"Could not log in");\r
-\r
-               // check if item exists                 \r
-               if (!$manager->existsItem($itemid,1,1))\r
-                       return _error(6,"No such item ($itemid)");\r
-                       \r
-               $blogid = getBlogIDFromItemID($itemid);\r
-               $blog = new BLOG($blogid);\r
-\r
-               if (!$mem->canAlterItem($itemid))\r
-                       return _error(7,"Not allowed to alter item");\r
-               \r
-               $old =& $manager->getItem($itemid,1,1);         \r
-\r
-               $catid = $blog->getCategoryIdFromName($category);               \r
-\r
-               $publish = 0;\r
-               if ($old['draft'] && $publish) {\r
-                       $wasdraft = 1;\r
-                       $publish = 1;\r
-               } else {\r
-                       $wasdraft = 0;\r
-               }\r
-               \r
-               return _edititem($itemid, $username, $password, $catid, $old['title'], $old['body'], $old['more'], $wasdraft, $publish, $old['closed']);\r
-       }\r
-       \r
-       \r
-       function _mt_getPostCategories($itemid, $username, $password) {\r
-               global $manager;\r
-\r
-               // login\r
-               $mem = new MEMBER();\r
-               if (!$mem->login($username, $password))\r
-                       return _error(1,"Could not log in");\r
-\r
-               // check if item exists                 \r
-               if (!$manager->existsItem($itemid,1,1))\r
-                       return _error(6,"No such item ($itemid)");\r
-\r
-               $blogid = getBlogIDFromItemID($itemid);\r
-               $blog = new BLOG($blogid);\r
-\r
-               if (!$mem->canAlterItem($itemid))\r
-                       return _error(7, 'You are not allowed to request this information');\r
-               \r
-               $info =& $manager->getItem($itemid,1,1);                \r
-               $catName = $blog->getCategoryName($info['catid']);\r
-               \r
-               $struct = new xmlrpcval(\r
-                       array(\r
-                               'categoryId' => new xmlrpcval($catName, 'string'),\r
-                               'categoryName' => new xmlrpcval($catName, 'string'),\r
-                               'isPrimary'     => new xmlrpcval(1, 'boolean')\r
-                       ), 'struct'\r
-               );              \r
-               \r
-               return new xmlrpcresp(new xmlrpcval(array($struct), 'array'));\r
-\r
-       }\r
-       \r
-       function _mt_publishPost($itemid, $username, $password) {\r
-               global $manager;\r
-               \r
-               if (!$manager->existsItem($itemid,1,1))\r
-                       return _error(6,"No such item ($itemid)");\r
-\r
-               // get item data\r
-               $blogid = getBlogIDFromItemID($itemid);\r
-               $blog = new BLOG($blogid);\r
-               $old =& $manager->getItem($itemid,1,1);\r
-\r
-               return _edititem($itemid, $username, $password, $old['catid'], $old['title'], $old['body'], $old['more'], $old['draft'], 1, $old['closed']);\r
-       }\r
-       \r
-       \r
-       function _mt_categoryList($blogid, $username, $password) {\r
-               // 1. login\r
-               $mem = new MEMBER();\r
-               if (!$mem->login($username, $password))\r
-                       return _error(1,"Could not log in");\r
-\r
-               // check if on team and blog exists\r
-               if (!BLOG::existsID($blogid))\r
-                       return _error(2,"No such blog ($blogid)");\r
-               if (!$mem->teamRights($blogid))\r
-                       return _error(3,"Not a team member");\r
-                       \r
-               $b = new BLOG($blogid);\r
-               \r
-               $categorystruct = array();\r
-\r
-               $query =  "SELECT cname, cdesc, catid"\r
-                               . ' FROM '.sql_table('category')\r
-                               . " WHERE cblog=" . intval($blogid)\r
-                               . " ORDER BY cname";\r
-               $r = sql_query($query);\r
-\r
-               while ($obj = mysql_fetch_object($r)) {\r
-\r
-                       $categorystruct[] = new xmlrpcval(\r
-                               array(\r
-                                       "categoryName" => new xmlrpcval($obj->cname,"string"),\r
-                                       "categoryId" => new xmlrpcval($obj->cname,"string")\r
-                               )\r
-                       ,'struct');\r
-                       \r
-               }\r
-               \r
-               \r
-               return new xmlrpcresp(new xmlrpcval( $categorystruct , "array"));\r
-       \r
-       }\r
-       \r
-       function _mt_getRecentPostTitles($blogid, $username, $password, $iAmount) \r
-       {\r
-               $blogid = intval($blogid);\r
-               $iAmount = intval($iAmount);\r
-       \r
-               // 1. login\r
-               $mem = new MEMBER();\r
-               if (!$mem->login($username, $password))\r
-                       return _error(1,"Could not log in");\r
-\r
-               // 2. check if allowed \r
-               if (!BLOG::existsID($blogid))\r
-                       return _error(2,"No such blog ($blogid)");\r
-               if (!$mem->teamRights($blogid))\r
-                       return _error(3,"Not a team member");\r
-               $iAmount = intval($iAmount);\r
-               if ($iAmount < 1)\r
-                       return _error(5,"Amount parameter must be positive");\r
-\r
-               // 3. create and return list of recent items\r
-               // Struct returned has dateCreated, userid, postid and title\r
-               \r
-               $blog = new BLOG($blogid);\r
-\r
-               $structarray = array();         // the array in which the structs will be stored\r
-\r
-               $query = "SELECT inumber, ititle as title, itime, iauthor"\r
-                          .' FROM '.sql_table('item')\r
-                          ." WHERE iblog=$blogid"\r
-                          ." ORDER BY itime DESC"\r
-                          ." LIMIT $iAmount";\r
-               $r = sql_query($query);\r
-               \r
-               while ($row = mysql_fetch_assoc($r)) {\r
-               \r
-                       $newstruct = new xmlrpcval(array(\r
-                               "dateCreated" => new xmlrpcval(iso8601_encode(strtotime($row['itime'])),"dateTime.iso8601"),\r
-                               "postid" => new xmlrpcval($row['inumber'],"string"),\r
-                               "title" => new xmlrpcval($row['title'],"string"),\r
-                               "userid" => new xmlrpcval($row['iauthor'],"string")\r
-                       ),'struct');\r
-               \r
-                       array_push($structarray, $newstruct);           \r
-               }\r
-\r
-               return new xmlrpcresp(new xmlrpcval( $structarray , "array"));\r
-       \r
-       }\r
-       \r
-\r
-\r
-?>\r
+<?php
+
+/*
+ * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/)
+ * Copyright (C) 2002-2007 The Nucleus Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * (see nucleus/documentation/index.html#license for more info)
+ */
+/**
+ * This file contains definitions for the methods in the Movable Type API
+ *
+ * Wouter Demuynck 2003-08-31
+ *
+ * @license http://nucleuscms.org/license.txt GNU General Public License
+ * @copyright Copyright (C) 2002-2007 The Nucleus Group
+ * $NucleusJP: api_mt.inc.php,v 1.6 2007/02/04 06:28:46 kimitake Exp $
+ */
+
+       // mt.supportedMethods
+       $f_mt_supportedMethods_sig = array(array(
+                       // return type
+                       $xmlrpcArray // array of strings
+               ));
+       $f_mt_supportedMethods_doc = 'returns an array of supported methods';
+       function f_mt_supportedMethods($m) {
+               $res = new xmlrpcresp(new xmlrpcval(
+                       array(
+                               new xmlrpcval('mt.supportedMethods', 'string'),
+                               new xmlrpcval('mt.supportedTextFilters', 'string'),
+                               new xmlrpcval('mt.publishPost', 'string'),
+                               new xmlrpcval('mt.getCategoryList', 'string'),
+                               new xmlrpcval('mt.getPostCategories', 'string'),
+                               new xmlrpcval('mt.setPostCategories', 'string'),
+                               new xmlrpcval('mt.getRecentPostTitles', 'string'),
+                               new xmlrpcval('mt.getTrackbackPings','string'),
+                       ), 'array')
+               );
+               return $res;
+       }
+
+       // mt.supportedTextFilters
+       $f_mt_supportedTextFilters_sig = array(array(
+                       // return type
+                       $xmlrpcArray    // array of structs
+               ));
+       $f_mt_supportedTextFilters_doc = 'returns the supported text filters';
+       function f_mt_supportedTextFilters($m) {
+               $res = new xmlrpcresp(new xmlrpcval(
+                       array(
+                               // no text filters in nucleus
+                       ), 'array')
+               );
+               return $res;
+       }
+
+       // mt.getCategoryList
+       $f_mt_getCategoryList_sig = array(array(
+                       // return type
+                       $xmlrpcArray,           // array of structs
+
+                       // params
+                       $xmlrpcString,          // blogid
+                       $xmlrpcString,          // username
+                       $xmlrpcString           // password
+
+               ));
+       $f_mt_getCategoryList_doc = 'Returns a list of all categories defined in the weblog';
+       function f_mt_getCategoryList($m) {
+               $blogid =       _getScalar($m,0);
+               $username =     _getScalar($m,1);
+               $password =     _getScalar($m,2);
+
+               return _mt_categoryList($blogid, $username, $password);
+       }
+
+       // mt.publishPost
+       $f_mt_publishPost_sig = array(array(
+                       // return type
+                       $xmlrpcBoolean,         // true
+
+                       // params
+                       $xmlrpcString,          // itemid
+                       $xmlrpcString,          // username
+                       $xmlrpcString           // password
+               ));
+       $f_mt_publishPost_doc = 'Transfers an item from the "draft" state to the "published" state. For items that were published earlier, does nothing.';
+       function f_mt_publishPost($m) {
+               $itemid         = intval(_getScalar($m, 0));
+               $username       = _getScalar($m, 1);
+               $password       = _getScalar($m, 2);
+
+               return _mt_publishPost($itemid, $username, $password);
+       }
+
+       // mt.getPostCategories
+       $f_mt_getPostCategories_sig = array(array(
+               // return
+               $xmlrpcArray,           // array of structs
+               // parameters
+               $xmlrpcString,          // itemid
+               $xmlrpcString,          // username
+               $xmlrpcString           // password
+       ));
+       $f_mt_getPostCategories_doc = 'Returns a list of all categories to which the post is assigned.';
+       function f_mt_getPostCategories($m) {
+               $itemid         = intval(_getScalar($m, 0));
+               $username       = _getScalar($m, 1);
+               $password       = _getScalar($m, 2);
+
+               return _mt_getPostCategories($itemid, $username, $password);
+       }
+
+       // mt.setPostCategories
+       $f_mt_setPostCategories_sig = array(array(
+               // return
+               $xmlrpcBoolean,         // true
+               // parameters
+               $xmlrpcString,          // itemid
+               $xmlrpcString,          // username
+               $xmlrpcString,          // password
+               $xmlrpcArray            // categories
+       ));
+       $f_mt_setPostCategories_doc = 'Sets the categories for a post. Only the primary category will be stored';
+       function f_mt_setPostCategories($m) {
+               $itemid         = intval(_getScalar($m, 0));
+               $username       = _getScalar($m, 1);
+               $password       = _getScalar($m, 2);
+
+               $categories = $m->getParam(3);
+               $iSize = $categories->arraysize();
+
+               $category = '';
+               for ($i=0;$i<$iSize;$i++) {
+                       $struct = $categories->arraymem($i);
+                       $bPrimary = $struct->structmem('isPrimary');
+                       if ($bPrimary)
+                               $bPrimary = $bPrimary->scalarval();
+                       else if (!$category)
+                               $bPrimary = 1;  // "Using isPrimary to set the primary category is optional--
+                                                               // in the absence of this flag, the first struct in the array
+                                                               // will be assigned the primary category for the post." (MT doc)
+                       if ($bPrimary) {
+                               $category = $struct->structmem('categoryId');
+                               $category = $category->scalarval();
+                       }
+
+               }
+
+               return _mt_setPostCategories($itemid, $username, $password, $category);
+       }
+
+       // mt.getRecentPostTitles
+       $f_mt_getRecentPostTitles_sig = array(array(
+               // return
+               $xmlrpcArray,           // array of structs
+               // params
+               $xmlrpcString,          // blogid
+               $xmlrpcString,          // userid
+               $xmlrpcString,          // password,
+               $xmlrpcInt                      // number of posts
+       ));
+       $f_mt_getRecentPostTitles_doc = 'Returns a bandwidth-friendly list of the most recent posts in the system.';
+       function f_mt_getRecentPostTitles($m) {
+               $blogid         = intval(_getScalar($m, 0));
+               $username       = _getScalar($m, 1);
+               $password       = _getScalar($m, 2);
+               $iAmount        = intval(_getScalar($m, 3));
+
+               return _mt_getRecentPostTitles($blogid, $username, $password, $iAmount);
+       }
+
+       // mt.getTrackbackPings
+       $f_mt_getTrackbackPings_sig = array(array(
+               // return
+               $xmlrpcArray,           // array of structs
+               // params
+               $xmlrpcString           // postid
+       ));
+       $f_mt_getTrackbackPings_doc = '(this is currently just a placeholder. It returns an empty array.)';
+       function f_mt_getTrackbackPings($m) {
+               global $manager;
+               
+               $itemid = intval(_getScalar($m, 0));
+
+               $trackbacks = array ();
+               $tbstruct   = array ();
+                       
+               $manager->notify('RetrieveTrackback', array ('tb_id' => $itemid, 'trackbacks' => & $trackbacks));
+                               
+               while (list(,$v) = each ($trackbacks)) {
+                       $tbstruct[] = new xmlrpcval(
+                               array(
+                                       "pingTitle" => new xmlrpcval($v['title'], "string"),
+                                       "pingURL"   => new xmlrpcval($v['url'], "string"),
+                                       "pingIP"    => new xmlrpcval($v['ip'], "string")
+                               )
+                       ,'struct');                     
+               }               
+                               
+               return new xmlrpcresp(new xmlrpcval( $tbstruct , "array"));
+       }
+
+       $functionDefs = array_merge($functionDefs,
+               array(
+                        "mt.supportedMethods" =>
+                        array( "function" => "f_mt_supportedMethods",
+                               "signature" => $f_mt_supportedMethods_sig,
+                               "docstring" => $f_mt_supportedMethods_doc),
+
+                        "mt.supportedTextFilters" =>
+                        array( "function" => "f_mt_supportedTextFilters",
+                               "signature" => $f_mt_supportedTextFilters_sig,
+                               "docstring" => $f_mt_supportedTextFilters_doc),
+
+                        "mt.getCategoryList" =>
+                        array( "function" => "f_mt_getCategoryList",
+                               "signature" => $f_mt_getCategoryList_sig,
+                               "docstring" => $f_mt_getCategoryList_doc),
+
+                        "mt.publishPost" =>
+                        array( "function" => "f_mt_publishPost",
+                               "signature" => $f_mt_publishPost_sig,
+                               "docstring" => $f_mt_publishPost_doc),
+
+                        "mt.getPostCategories" =>
+                        array( "function" => "f_mt_getPostCategories",
+                               "signature" => $f_mt_getPostCategories_sig,
+                               "docstring" => $f_mt_getPostCategories_doc),
+
+                        "mt.setPostCategories" =>
+                        array( "function" => "f_mt_setPostCategories",
+                               "signature" => $f_mt_setPostCategories_sig,
+                               "docstring" => $f_mt_setPostCategories_doc),
+
+                        "mt.getRecentPostTitles" =>
+                        array( "function" => "f_mt_getRecentPostTitles",
+                               "signature" => $f_mt_getRecentPostTitles_sig,
+                               "docstring" => $f_mt_getRecentPostTitles_doc),
+
+                        "mt.getTrackbackPings" =>
+                        array( "function" => "f_mt_getTrackbackPings",
+                               "signature" => $f_mt_getTrackbackPings_sig,
+                               "docstring" => $f_mt_getTrackbackPings_doc)
+
+               )
+       );
+
+       function _mt_setPostCategories($itemid, $username, $password, $category) {
+               global $manager;
+
+               // login
+               $mem = new MEMBER();
+               if (!$mem->login($username, $password))
+                       return _error(1,"Could not log in");
+
+               // check if item exists
+               if (!$manager->existsItem($itemid,1,1))
+                       return _error(6,"No such item ($itemid)");
+
+               $blogid = getBlogIDFromItemID($itemid);
+               $blog = new BLOG($blogid);
+
+               if (!$mem->canAlterItem($itemid))
+                       return _error(7,"Not allowed to alter item");
+
+               $old =& $manager->getItem($itemid,1,1);
+
+               $catid = $blog->getCategoryIdFromName($category);
+
+               $publish = 0;
+               if ($old['draft'] && $publish) {
+                       $wasdraft = 1;
+                       $publish = 1;
+               } else {
+                       $wasdraft = 0;
+               }
+
+               return _edititem($itemid, $username, $password, $catid, $old['title'], $old['body'], $old['more'], $wasdraft, $publish, $old['closed']);
+       }
+
+
+       function _mt_getPostCategories($itemid, $username, $password) {
+               global $manager;
+
+               // login
+               $mem = new MEMBER();
+               if (!$mem->login($username, $password))
+                       return _error(1,"Could not log in");
+
+               // check if item exists
+               if (!$manager->existsItem($itemid,1,1))
+                       return _error(6,"No such item ($itemid)");
+
+               $blogid = getBlogIDFromItemID($itemid);
+               $blog = new BLOG($blogid);
+
+               if (!$mem->canAlterItem($itemid))
+                       return _error(7, 'You are not allowed to request this information');
+
+               $info =& $manager->getItem($itemid,1,1);
+               $catName = $blog->getCategoryName($info['catid']);
+
+               $struct = new xmlrpcval(
+                       array(
+                               'categoryId' => new xmlrpcval($catName, 'string'),
+                               'categoryName' => new xmlrpcval($catName, 'string'),
+                               'isPrimary'     => new xmlrpcval(1, 'boolean')
+                       ), 'struct'
+               );
+
+               return new xmlrpcresp(new xmlrpcval(array($struct), 'array'));
+
+       }
+
+       function _mt_publishPost($itemid, $username, $password) {
+               global $manager;
+
+               if (!$manager->existsItem($itemid,1,1))
+                       return _error(6,"No such item ($itemid)");
+
+               // get item data
+               $blogid = getBlogIDFromItemID($itemid);
+               $blog = new BLOG($blogid);
+               $old =& $manager->getItem($itemid,1,1);
+
+               return _edititem($itemid, $username, $password, $old['catid'], $old['title'], $old['body'], $old['more'], $old['draft'], 1, $old['closed']);
+       }
+
+
+       function _mt_categoryList($blogid, $username, $password) {
+               // 1. login
+               $mem = new MEMBER();
+               if (!$mem->login($username, $password))
+                       return _error(1,"Could not log in");
+
+               // check if on team and blog exists
+               if (!BLOG::existsID($blogid))
+                       return _error(2,"No such blog ($blogid)");
+               if (!$mem->teamRights($blogid))
+                       return _error(3,"Not a team member");
+
+               $b = new BLOG($blogid);
+
+               $categorystruct = array();
+
+               $query =  "SELECT cname, cdesc, catid"
+                               . ' FROM '.sql_table('category')
+                               . " WHERE cblog=" . intval($blogid)
+                               . " ORDER BY cname";
+               $r = sql_query($query);
+
+               while ($obj = mysql_fetch_object($r)) {
+
+                       $categorystruct[] = new xmlrpcval(
+                               array(
+                                       "categoryName" => new xmlrpcval($obj->cname,"string"),
+                                       "categoryId" => new xmlrpcval($obj->cname,"string")
+                               )
+                       ,'struct');
+
+               }
+
+
+               return new xmlrpcresp(new xmlrpcval( $categorystruct , "array"));
+
+       }
+
+       function _mt_getRecentPostTitles($blogid, $username, $password, $iAmount)
+       {
+               $blogid = intval($blogid);
+               $iAmount = intval($iAmount);
+
+               // 1. login
+               $mem = new MEMBER();
+               if (!$mem->login($username, $password))
+                       return _error(1,"Could not log in");
+
+               // 2. check if allowed
+               if (!BLOG::existsID($blogid))
+                       return _error(2,"No such blog ($blogid)");
+               if (!$mem->teamRights($blogid))
+                       return _error(3,"Not a team member");
+               $iAmount = intval($iAmount);
+               if ($iAmount < 1)
+                       return _error(5,"Amount parameter must be positive");
+
+               // 3. create and return list of recent items
+               // Struct returned has dateCreated, userid, postid and title
+
+               $blog = new BLOG($blogid);
+
+               $structarray = array();         // the array in which the structs will be stored
+
+               $query = "SELECT inumber, ititle as title, itime, iauthor"
+                          .' FROM '.sql_table('item')
+                          ." WHERE iblog=$blogid"
+                          ." ORDER BY itime DESC"
+                          ." LIMIT $iAmount";
+               $r = sql_query($query);
+
+               while ($row = mysql_fetch_assoc($r)) {
+
+                       $newstruct = new xmlrpcval(array(
+                               "dateCreated" => new xmlrpcval(iso8601_encode(strtotime($row['itime'])),"dateTime.iso8601"),
+                               "postid" => new xmlrpcval($row['inumber'],"string"),
+                               "title" => new xmlrpcval($row['title'],"string"),
+                               "userid" => new xmlrpcval($row['iauthor'],"string")
+                       ),'struct');
+
+                       array_push($structarray, $newstruct);
+               }
+
+               return new xmlrpcresp(new xmlrpcval( $structarray , "array"));
+
+       }
+
+
+
+?>
\ No newline at end of file
index e750dc8..5ac6def 100755 (executable)
-<?php\r
-/** \r
-  * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/) \r
-  * Copyright (C) 2002-2005 The Nucleus Group\r
-  *\r
-  * This program is free software; you can redistribute it and/or\r
-  * modify it under the terms of the GNU General Public License\r
-  * as published by the Free Software Foundation; either version 2\r
-  * of the License, or (at your option) any later version.\r
-  * (see nucleus/documentation/index.html#license for more info)\r
-  *\r
-  * $Id: api_nucleus.inc.php,v 1.3 2005-03-16 08:12:06 kimitake Exp $\r
-  * $NucleusJP: api_nucleus.inc.php,v 1.3 2005/03/12 06:19:06 kimitake Exp $\r
-  */\r
-\r
-/*\r
- * This file contains definitions for the functions in the Nucleus API\r
- *\r
- * NOTE: These functions are deprecated and will most likely be removed!\r
- */\r
-\r
-       // nucleus.addItem\r
-       $f_nucleus_addItem_sig = array(array(\r
-                       // return type\r
-                       $xmlrpcString,  // itemid of the new item\r
-\r
-                       // params:\r
-                       $xmlrpcString,  // blogid\r
-                       $xmlrpcString,  // username\r
-                       $xmlrpcString,  // password\r
-                       $xmlrpcString,  // title\r
-                       $xmlrpcString,  // body\r
-                       $xmlrpcString,  // extended part\r
-                       $xmlrpcBoolean, // publish boolean (set to false to create draft)\r
-                       $xmlrpcBoolean, // closed boolean (set to true to disable comments)\r
-\r
-               ));\r
-       $f_nucleus_addItem_doc = "Adds a new item to the given blog. Adds it as a draft when publish is false";\r
-       function f_nucleus_addItem($m) {\r
-               $blogid = _getScalar($m,0);\r
-               $username = _getScalar($m,1);\r
-               $password = _getScalar($m,2);\r
-               $title = _getScalar($m,3);\r
-               $body = _getScalar($m,4);\r
-               $more = _getScalar($m,5);\r
-               $publish = _getScalar($m,6);\r
-               $closed = _getScalar($m,7);\r
-\r
-               return _addItem($blogid, $username, $password, $title, $body, $more, $publish, $closed);\r
-       }\r
-\r
-       // nucleus.addDatedItem (the time of the item can be given here, for offline blogging)\r
-       $f_nucleus_addDatedItem_sig = array(array(\r
-                       // return type\r
-                       $xmlrpcString,  // itemid of the new item\r
-\r
-                       // params:\r
-                       $xmlrpcString,  // blogid\r
-                       $xmlrpcString,  // username\r
-                       $xmlrpcString,  // password\r
-                       $xmlrpcString,  // title\r
-                       $xmlrpcString,  // body\r
-                       $xmlrpcString,  // extended part\r
-                       $xmlrpcBoolean, // publish boolean (set to false to create draft)\r
-                       $xmlrpcBoolean, // closed boolean (set to true to disable comments)\r
-                       $xmlrpcInt      // item time (unix timestamp)\r
-\r
-               ));\r
-       $f_nucleus_addDatedItem_doc = "Adds a new item to the given blog. Adds it as a draft when publish is false. The timestamp of the item needs to be given as a Unix timestamp";\r
-       function f_nucleus_addDatedItem($m) {\r
-               $blogid = _getScalar($m,0);\r
-               $username = _getScalar($m,1);\r
-               $password = _getScalar($m,2);\r
-               $title = _getScalar($m,3);\r
-               $body = _getScalar($m,4);\r
-               $more = _getScalar($m,5);\r
-               $publish = _getScalar($m,6);\r
-               $closed = _getScalar($m,7);\r
-               $timestamp = _getScalar($m,8);\r
-\r
-               // use '1' as $future param to make sure the date does not get erased\r
-               return _addDatedItem($blogid, $username, $password, $title, $body, $more, $publish, $closed, $timestamp, 1);\r
-       }\r
-\r
-       // nucleus.editItem\r
-       $f_nucleus_editItem_sig = array(array(\r
-                       // return type\r
-                       $xmlrpcBoolean, // true or false\r
-\r
-                       // params:\r
-                       $xmlrpcString,  // itemid\r
-                       $xmlrpcString,  // username\r
-                       $xmlrpcString,  // password\r
-                       $xmlrpcString,  // title\r
-                       $xmlrpcString,  // body\r
-                       $xmlrpcString,  // extended part\r
-                       $xmlrpcBoolean, // publish boolean (set to false if you want a draft to stay draft)\r
-                       $xmlrpcBoolean, // closed boolean (set to true to disable comments)\r
-               ));\r
-       $f_nucleus_editItem_doc = "Edits an item of a blog";\r
-       function f_nucleus_editItem($m) {\r
-               global $manager;\r
-       \r
-               $itemid = intval(_getScalar($m,0));\r
-               $username = _getScalar($m,1);\r
-               $password = _getScalar($m,2);\r
-               $title = _getScalar($m,3);\r
-               $content = _getScalar($m,4);\r
-               $more = _getScalar($m,5);\r
-               $publish = _getScalar($m,6);\r
-               $closed = _getScalar($m,7);\r
-\r
-               // get old title and extended part \r
-               if (!$manager->existsItem($itemid,1,1))\r
-                       return _error(6,"No such item ($itemid)");\r
-\r
-               $old =& $manager->getItem($itemid,1,1);\r
-               $wasdraft = ($old['draft']) ? 1 : 0;\r
-\r
-               return _edititem($itemid, $username, $password, $old['catid'], $title, $content, $more, $wasdraft, $publish, $closed);\r
-       }\r
-\r
-\r
-       // nucleus.getUsersBlogs\r
-       $f_nucleus_getUsersBlogs_sig = array(array(\r
-                       // return type\r
-                       $xmlrpcArray,   // array containing structs containing blog info\r
-\r
-                       // params:\r
-                       $xmlrpcString,  // username\r
-                       $xmlrpcString,  // password\r
-               ));\r
-       $f_nucleus_getUsersBlogs_doc = "Returns a list of all the blogs where the given member is on the team";\r
-       function f_nucleus_getUsersBlogs($m) {\r
-               $username = _getScalar($m,0);\r
-               $password = _getScalar($m,1);\r
-\r
-               return _getUsersBlogs($username, $password);\r
-       }\r
-\r
-       // nucleus.getRecentItems\r
-       $f_nucleus_getRecentItems_sig = array(array(\r
-                       // return type\r
-                       $xmlrpcArray,   // array of strucs (representing items)\r
-\r
-                       // params\r
-                       $xmlrpcString,  // blogid\r
-                       $xmlrpcString,  // username\r
-                       $xmlrpcString,  // password\r
-                       $xmlrpcInt,     // amount of items to return (max = 20)\r
-               ));\r
-       $f_nucleus_getRecentItems_doc = "Returns a maximum of 20 recent items for a given webblog";\r
-       function f_nucleus_getRecentItems($m) {\r
-               $blogid = _getScalar($m, 0);\r
-               $username = _getScalar($m, 1);\r
-               $password = _getScalar($m, 2);\r
-               $amount = _getScalar($m, 3);\r
-\r
-               return _getRecentItems($blogid, $username, $password, $amount);\r
-       }\r
-\r
-       // nucleus.getItem\r
-       $f_nucleus_getItem_sig = array(array(\r
-                       // return type\r
-                       $xmlrpcStruct,  // A struct representing the item\r
-\r
-                       // params\r
-                       $xmlrpcString,  // itemid\r
-                       $xmlrpcString,  // username\r
-                       $xmlrpcString,  // password\r
-               ));\r
-       $f_nucleus_getItem_doc = "Returns an item";\r
-       function f_nucleus_getItem($m) {\r
-               $postid = _getScalar($m, 0);\r
-               $username = _getScalar($m, 1);\r
-               $password = _getScalar($m, 2);\r
-\r
-               return _getItem($postid, $username, $password);\r
-       }\r
-\r
-       // nucleus.deleteItem\r
-       $f_nucleus_deleteItem_sig = array(array(\r
-                       // return type\r
-                       $xmlrpcBoolean, // boolean (ok or not ok)\r
-\r
-                       // params\r
-                       $xmlrpcString,  // itemid\r
-                       $xmlrpcString,  // username\r
-                       $xmlrpcString,  // password\r
-               ));\r
-       $f_nucleus_deleteItem_doc = "Deletes an item";\r
-       function f_nucleus_deleteItem($m) {\r
-               $itemid = _getScalar($m,0);\r
-               $username = _getScalar($m, 1);\r
-               $password = _getScalar($m, 2);\r
-\r
-               return _deleteItem($itemid, $username, $password);\r
-       }\r
-\r
-\r
-       /**\r
-         * Returns a list of recent items (Nucleus Version)\r
-         * ($amount = max 20);\r
-         */\r
-       function _getRecentItems($blogid, $username, $password, $amount) {\r
-               $blogid = intval($blogid);\r
-               $amount = intval($amount);\r
-       \r
-               // 1. login\r
-               $mem = new MEMBER();\r
-               if (!$mem->login($username, $password))\r
-                       return _error(1,"Could not log in");\r
-\r
-               // 2. check if allowed \r
-               if (!BLOG::existsID($blogid))\r
-                       return _error(2,"No such blog ($blogid)");\r
-               if (!$mem->teamRights($blogid))\r
-                       return _error(3,"Not a team member");\r
-               $amount = intval($amount);\r
-               if (($amount < 1) or ($amount > 20))\r
-                       return _error(5,"Amount parameter must be in range 1..20");\r
-\r
-               // 3. create and return list of recent items\r
-               // Struct returned has dateCreated, userid, blogid and content\r
-\r
-               $structarray = array();         // the array in which the structs will be stored\r
-\r
-               $query = "SELECT ibody, iauthor, ibody, imore, ititle, iclosed, idraft, itime"\r
-                          .' FROM '.sql_table('item')\r
-                          ." WHERE iblog=$blogid"\r
-                          ." ORDER BY itime DESC"\r
-                          ." LIMIT $amount";\r
-               $r = sql_query($query);\r
-               while ($obj = mysql_fetch_object($r)) {\r
-                       $newstruct = new xmlrpcval(array(\r
-                               "publishDate" => new xmlrpcval(iso8601_encode(strtotime($obj->itime)),"dateTime.iso8601"),\r
-                               "userid" => new xmlrpcval($obj->iauthor,"string"),\r
-                               "blogid" => new xmlrpcval($blogid,"string"),\r
-                               "title" => new xmlrpcval($obj->ititle,"string"),\r
-                               "body" => new xmlrpcval($obj->ibody,"string"),\r
-                               "more" => new xmlrpcval($obj->imore,"string"),\r
-                               "draft" => new xmlrpcval($obj->idraft,"boolean"),\r
-                               "closed" => new xmlrpcval($obj->iclosed,"boolean"),\r
-                       ),'struct');\r
-                       array_push($structarray, $newstruct);           \r
-               }\r
-\r
-               return new xmlrpcresp(new xmlrpcval( $structarray , "array"));\r
-\r
-       }\r
-       \r
-       \r
-\r
-       /**\r
-         * Returns one item (Nucleus version)\r
-         */\r
-       function _getItem($itemid, $username, $password) {\r
-               global $manager;\r
-       \r
-               // 1. login\r
-               $mem = new MEMBER();\r
-               if (!$mem->login($username, $password))\r
-                       return _error(1,"Could not log in");\r
-\r
-               // 2. check if allowed \r
-               if (!$manager->existsItem($itemid,1,1))\r
-                       return _error(6,"No such item ($itemid)");\r
-               $blogid = getBlogIDFromItemID($itemid);\r
-               \r
-               if (!$mem->teamRights($blogid))\r
-                       return _error(3,"Not a team member");\r
-\r
-               // 3. return the item\r
-               // Structure returned has dateCreated, userid, blogid and content\r
-\r
-               $item =& $manager->getItem($itemid,1,1); // (also allow drafts and future items)\r
-               \r
-               $blog = new BLOG($blogid);\r
-               if ($blog->convertBreaks())\r
-                       $item['body'] = removeBreaks($item['body']);\r
-\r
-               $newstruct = new xmlrpcval(array(\r
-                       "publishDate" => new xmlrpcval(iso8601_encode($item['timestamp']),"dateTime.iso8601"),\r
-                       "userid" => new xmlrpcval($item['authorid'],"string"),\r
-                       "blogid" => new xmlrpcval($blogid,"string"),\r
-                       "title" => new xmlrpcval($item['title'],"string"),\r
-                       "body" => new xmlrpcval($item['body'],"string"),\r
-                       "more" => new xmlrpcval($item['more'],"string"),\r
-                       "draft" => new xmlrpcval($item['draft'],"boolean"),\r
-                       "closed" => new xmlrpcval($ite['closed'],"boolean"),\r
-               ),'struct');\r
-\r
-               return new xmlrpcresp($newstruct);\r
-\r
-\r
-       }       \r
-\r
-\r
-       $functionDefs = array_merge($functionDefs,\r
-               array(\r
-                       "nucleus.addItem" =>\r
-                       array( "function" => "f_nucleus_addItem",\r
-                               "signature" => $f_nucleus_addItem_sig,\r
-                               "docstring" => $f_nucleus_addItem_doc),\r
-\r
-                       "nucleus.editItem" =>\r
-                       array( "function" => "f_nucleus_editItem",\r
-                               "signature" => $f_nucleus_editItem_sig,\r
-                               "docstring" => $f_nucleus_editItem_doc),\r
-\r
-                       "nucleus.addDatedItem" =>\r
-                       array( "function" => "f_nucleus_addDatedItem",\r
-                               "signature" => $f_nucleus_addDatedItem_sig,\r
-                               "docstring" => $f_nucleus_addDatedItem_doc),\r
-\r
-                       "nucleus.deleteItem" =>\r
-                       array( "function" => "f_nucleus_deleteItem",\r
-                               "signature" => $f_nucleus_deleteItem_sig,\r
-                               "docstring" => $f_nucleus_deleteItem_doc),\r
-\r
-                       "nucleus.getUsersBlogs" =>\r
-                       array( "function" => "f_nucleus_getUsersBlogs",\r
-                               "signature" => $f_nucleus_getUsersBlogs_sig,\r
-                               "docstring" => $f_nucleus_getUsersBlogs_doc),           \r
-\r
-                       "nucleus.getRecentItems" =>\r
-                       array( "function" => "f_nucleus_getRecentItems",\r
-                               "signature" => $f_nucleus_getRecentItems_sig,\r
-                               "docstring" => $f_nucleus_getRecentItems_doc),          \r
-\r
-                       "nucleus.getItem" =>\r
-                       array( "function" => "f_nucleus_getItem",\r
-                               "signature" => $f_nucleus_getItem_sig,\r
-                               "docstring" => $f_nucleus_getItem_doc)\r
-               )               \r
-               \r
-       );\r
-\r
-?>\r
+<?php
+/*
+ * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/)
+ * Copyright (C) 2002-2007 The Nucleus Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * (see nucleus/documentation/index.html#license for more info)
+ */
+
+/**
+ * This file contains definitions for the functions in the Nucleus API
+ *
+ * NOTE: These functions are deprecated and will most likely be removed!
+ *
+ * @license http://nucleuscms.org/license.txt GNU General Public License
+ * @copyright Copyright (C) 2002-2007 The Nucleus Group
+ * @version $Id: api_nucleus.inc.php,v 1.4 2007-03-27 12:14:05 kimitake Exp $
+ * $NucleusJP: api_nucleus.inc.php,v 1.6 2007/02/04 06:28:46 kimitake Exp $
+ */
+
+       // nucleus.addItem
+       $f_nucleus_addItem_sig = array(array(
+                       // return type
+                       $xmlrpcString,  // itemid of the new item
+
+                       // params:
+                       $xmlrpcString,  // blogid
+                       $xmlrpcString,  // username
+                       $xmlrpcString,  // password
+                       $xmlrpcString,  // title
+                       $xmlrpcString,  // body
+                       $xmlrpcString,  // extended part
+                       $xmlrpcBoolean, // publish boolean (set to false to create draft)
+                       $xmlrpcBoolean, // closed boolean (set to true to disable comments)
+
+               ));
+       $f_nucleus_addItem_doc = "Adds a new item to the given blog. Adds it as a draft when publish is false";
+       function f_nucleus_addItem($m) {
+               $blogid = _getScalar($m,0);
+               $username = _getScalar($m,1);
+               $password = _getScalar($m,2);
+               $title = _getScalar($m,3);
+               $body = _getScalar($m,4);
+               $more = _getScalar($m,5);
+               $publish = _getScalar($m,6);
+               $closed = _getScalar($m,7);
+
+               return _addItem($blogid, $username, $password, $title, $body, $more, $publish, $closed);
+       }
+
+       // nucleus.addDatedItem (the time of the item can be given here, for offline blogging)
+       $f_nucleus_addDatedItem_sig = array(array(
+                       // return type
+                       $xmlrpcString,  // itemid of the new item
+
+                       // params:
+                       $xmlrpcString,  // blogid
+                       $xmlrpcString,  // username
+                       $xmlrpcString,  // password
+                       $xmlrpcString,  // title
+                       $xmlrpcString,  // body
+                       $xmlrpcString,  // extended part
+                       $xmlrpcBoolean, // publish boolean (set to false to create draft)
+                       $xmlrpcBoolean, // closed boolean (set to true to disable comments)
+                       $xmlrpcInt      // item time (unix timestamp)
+
+               ));
+       $f_nucleus_addDatedItem_doc = "Adds a new item to the given blog. Adds it as a draft when publish is false. The timestamp of the item needs to be given as a Unix timestamp";
+       function f_nucleus_addDatedItem($m) {
+               $blogid = _getScalar($m,0);
+               $username = _getScalar($m,1);
+               $password = _getScalar($m,2);
+               $title = _getScalar($m,3);
+               $body = _getScalar($m,4);
+               $more = _getScalar($m,5);
+               $publish = _getScalar($m,6);
+               $closed = _getScalar($m,7);
+               $timestamp = _getScalar($m,8);
+
+               // use '1' as $future param to make sure the date does not get erased
+               return _addDatedItem($blogid, $username, $password, $title, $body, $more, $publish, $closed, $timestamp, 1);
+       }
+
+       // nucleus.editItem
+       $f_nucleus_editItem_sig = array(array(
+                       // return type
+                       $xmlrpcBoolean, // true or false
+
+                       // params:
+                       $xmlrpcString,  // itemid
+                       $xmlrpcString,  // username
+                       $xmlrpcString,  // password
+                       $xmlrpcString,  // title
+                       $xmlrpcString,  // body
+                       $xmlrpcString,  // extended part
+                       $xmlrpcBoolean, // publish boolean (set to false if you want a draft to stay draft)
+                       $xmlrpcBoolean, // closed boolean (set to true to disable comments)
+               ));
+       $f_nucleus_editItem_doc = "Edits an item of a blog";
+       function f_nucleus_editItem($m) {
+               global $manager;
+
+               $itemid = intval(_getScalar($m,0));
+               $username = _getScalar($m,1);
+               $password = _getScalar($m,2);
+               $title = _getScalar($m,3);
+               $content = _getScalar($m,4);
+               $more = _getScalar($m,5);
+               $publish = _getScalar($m,6);
+               $closed = _getScalar($m,7);
+
+               // get old title and extended part
+               if (!$manager->existsItem($itemid,1,1))
+                       return _error(6,"No such item ($itemid)");
+
+               $old =& $manager->getItem($itemid,1,1);
+               $wasdraft = ($old['draft']) ? 1 : 0;
+
+               return _edititem($itemid, $username, $password, $old['catid'], $title, $content, $more, $wasdraft, $publish, $closed);
+       }
+
+
+       // nucleus.getUsersBlogs
+       $f_nucleus_getUsersBlogs_sig = array(array(
+                       // return type
+                       $xmlrpcArray,   // array containing structs containing blog info
+
+                       // params:
+                       $xmlrpcString,  // username
+                       $xmlrpcString,  // password
+               ));
+       $f_nucleus_getUsersBlogs_doc = "Returns a list of all the blogs where the given member is on the team";
+       function f_nucleus_getUsersBlogs($m) {
+               $username = _getScalar($m,0);
+               $password = _getScalar($m,1);
+
+               return _getUsersBlogs($username, $password);
+       }
+
+       // nucleus.getRecentItems
+       $f_nucleus_getRecentItems_sig = array(array(
+                       // return type
+                       $xmlrpcArray,   // array of strucs (representing items)
+
+                       // params
+                       $xmlrpcString,  // blogid
+                       $xmlrpcString,  // username
+                       $xmlrpcString,  // password
+                       $xmlrpcInt,     // amount of items to return (max = 20)
+               ));
+       $f_nucleus_getRecentItems_doc = "Returns a maximum of 20 recent items for a given webblog";
+       function f_nucleus_getRecentItems($m) {
+               $blogid = _getScalar($m, 0);
+               $username = _getScalar($m, 1);
+               $password = _getScalar($m, 2);
+               $amount = _getScalar($m, 3);
+
+               return _getRecentItems($blogid, $username, $password, $amount);
+       }
+
+       // nucleus.getItem
+       $f_nucleus_getItem_sig = array(array(
+                       // return type
+                       $xmlrpcStruct,  // A struct representing the item
+
+                       // params
+                       $xmlrpcString,  // itemid
+                       $xmlrpcString,  // username
+                       $xmlrpcString,  // password
+               ));
+       $f_nucleus_getItem_doc = "Returns an item";
+       function f_nucleus_getItem($m) {
+               $postid = _getScalar($m, 0);
+               $username = _getScalar($m, 1);
+               $password = _getScalar($m, 2);
+
+               return _getItem($postid, $username, $password);
+       }
+
+       // nucleus.deleteItem
+       $f_nucleus_deleteItem_sig = array(array(
+                       // return type
+                       $xmlrpcBoolean, // boolean (ok or not ok)
+
+                       // params
+                       $xmlrpcString,  // itemid
+                       $xmlrpcString,  // username
+                       $xmlrpcString,  // password
+               ));
+       $f_nucleus_deleteItem_doc = "Deletes an item";
+       function f_nucleus_deleteItem($m) {
+               $itemid = _getScalar($m,0);
+               $username = _getScalar($m, 1);
+               $password = _getScalar($m, 2);
+
+               return _deleteItem($itemid, $username, $password);
+       }
+
+
+       /**
+         * Returns a list of recent items (Nucleus Version)
+         * ($amount = max 20);
+         */
+       function _getRecentItems($blogid, $username, $password, $amount) {
+               $blogid = intval($blogid);
+               $amount = intval($amount);
+
+               // 1. login
+               $mem = new MEMBER();
+               if (!$mem->login($username, $password))
+                       return _error(1,"Could not log in");
+
+               // 2. check if allowed
+               if (!BLOG::existsID($blogid))
+                       return _error(2,"No such blog ($blogid)");
+               if (!$mem->teamRights($blogid))
+                       return _error(3,"Not a team member");
+               $amount = intval($amount);
+               if (($amount < 1) or ($amount > 20))
+                       return _error(5,"Amount parameter must be in range 1..20");
+
+               // 3. create and return list of recent items
+               // Struct returned has dateCreated, userid, blogid and content
+
+               $structarray = array();         // the array in which the structs will be stored
+
+               $query = "SELECT ibody, iauthor, ibody, imore, ititle, iclosed, idraft, itime"
+                          .' FROM '.sql_table('item')
+                          ." WHERE iblog=$blogid"
+                          ." ORDER BY itime DESC"
+                          ." LIMIT $amount";
+               $r = sql_query($query);
+               while ($obj = mysql_fetch_object($r)) {
+                       $newstruct = new xmlrpcval(array(
+                               "publishDate" => new xmlrpcval(iso8601_encode(strtotime($obj->itime)),"dateTime.iso8601"),
+                               "userid" => new xmlrpcval($obj->iauthor,"string"),
+                               "blogid" => new xmlrpcval($blogid,"string"),
+                               "title" => new xmlrpcval($obj->ititle,"string"),
+                               "body" => new xmlrpcval($obj->ibody,"string"),
+                               "more" => new xmlrpcval($obj->imore,"string"),
+                               "draft" => new xmlrpcval($obj->idraft,"boolean"),
+                               "closed" => new xmlrpcval($obj->iclosed,"boolean"),
+                       ),'struct');
+                       array_push($structarray, $newstruct);
+               }
+
+               return new xmlrpcresp(new xmlrpcval( $structarray , "array"));
+
+       }
+
+
+
+       /**
+         * Returns one item (Nucleus version)
+         */
+       function _getItem($itemid, $username, $password) {
+               global $manager;
+
+               // 1. login
+               $mem = new MEMBER();
+               if (!$mem->login($username, $password))
+                       return _error(1,"Could not log in");
+
+               // 2. check if allowed
+               if (!$manager->existsItem($itemid,1,1))
+                       return _error(6,"No such item ($itemid)");
+               $blogid = getBlogIDFromItemID($itemid);
+
+               if (!$mem->teamRights($blogid))
+                       return _error(3,"Not a team member");
+
+               // 3. return the item
+               // Structure returned has dateCreated, userid, blogid and content
+
+               $item =& $manager->getItem($itemid,1,1); // (also allow drafts and future items)
+
+               $blog = new BLOG($blogid);
+               if ($blog->convertBreaks())
+                       $item['body'] = removeBreaks($item['body']);
+
+               $newstruct = new xmlrpcval(array(
+                       "publishDate" => new xmlrpcval(iso8601_encode($item['timestamp']),"dateTime.iso8601"),
+                       "userid" => new xmlrpcval($item['authorid'],"string"),
+                       "blogid" => new xmlrpcval($blogid,"string"),
+                       "title" => new xmlrpcval($item['title'],"string"),
+                       "body" => new xmlrpcval($item['body'],"string"),
+                       "more" => new xmlrpcval($item['more'],"string"),
+                       "draft" => new xmlrpcval($item['draft'],"boolean"),
+                       "closed" => new xmlrpcval($ite['closed'],"boolean"),
+               ),'struct');
+
+               return new xmlrpcresp($newstruct);
+
+
+       }
+
+
+       $functionDefs = array_merge($functionDefs,
+               array(
+                       "nucleus.addItem" =>
+                       array( "function" => "f_nucleus_addItem",
+                               "signature" => $f_nucleus_addItem_sig,
+                               "docstring" => $f_nucleus_addItem_doc),
+
+                       "nucleus.editItem" =>
+                       array( "function" => "f_nucleus_editItem",
+                               "signature" => $f_nucleus_editItem_sig,
+                               "docstring" => $f_nucleus_editItem_doc),
+
+                       "nucleus.addDatedItem" =>
+                       array( "function" => "f_nucleus_addDatedItem",
+                               "signature" => $f_nucleus_addDatedItem_sig,
+                               "docstring" => $f_nucleus_addDatedItem_doc),
+
+                       "nucleus.deleteItem" =>
+                       array( "function" => "f_nucleus_deleteItem",
+                               "signature" => $f_nucleus_deleteItem_sig,
+                               "docstring" => $f_nucleus_deleteItem_doc),
+
+                       "nucleus.getUsersBlogs" =>
+                       array( "function" => "f_nucleus_getUsersBlogs",
+                               "signature" => $f_nucleus_getUsersBlogs_sig,
+                               "docstring" => $f_nucleus_getUsersBlogs_doc),
+
+                       "nucleus.getRecentItems" =>
+                       array( "function" => "f_nucleus_getRecentItems",
+                               "signature" => $f_nucleus_getRecentItems_sig,
+                               "docstring" => $f_nucleus_getRecentItems_doc),
+
+                       "nucleus.getItem" =>
+                       array( "function" => "f_nucleus_getItem",
+                               "signature" => $f_nucleus_getItem_sig,
+                               "docstring" => $f_nucleus_getItem_doc)
+               )
+
+       );
+
+?>
\ No newline at end of file
index 7807cb8..eeef714 100755 (executable)
@@ -1,7 +1,7 @@
 <?php
 /*
  * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/)
- * Copyright (C) 2002-2005 The Nucleus Group
+ * Copyright (C) 2002-2007 The Nucleus Group
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
  * mt.supportedMethods
  *
  * @license http://nucleuscms.org/license.txt GNU General Public License
- * @copyright Copyright (C) 2002-2005 The Nucleus Group
- * @version $Id: server.php,v 1.7 2007-03-22 08:32:43 kimitake Exp $
- * @version $NucleusJP: server.php,v 1.6 2005/08/13 07:22:41 kimitake Exp $
+ * @copyright Copyright (C) 2002-2007 The Nucleus Group
+ * @version $Id: server.php,v 1.8 2007-03-27 12:14:05 kimitake Exp $
+ * @version $NucleusJP: server.php,v 1.8 2007/03/20 19:33:25 kmorimatsu Exp $
  */
 $CONF = array();
-include("../../config.php");   // include Nucleus libs and code
+require("../../config.php");   // include Nucleus libs and code
 include($DIR_LIBS . "xmlrpc.inc.php");
 include($DIR_LIBS . "xmlrpcs.inc.php");
 
@@ -306,7 +306,10 @@ function _getScalar($m, $idx) {
 
 function _getStructVal($struct, $key) {
        $t = $struct->structmem($key);
-       return $t->scalarval();
+       if (!$t) 
+               return '';      // no such struct value
+       else
+               return $t->scalarval();
 }
 
 function _getArrayVal($a, $idx) {
@@ -322,4 +325,4 @@ function _error($err, $msg) {
        global $xmlrpcerruser;
        return new xmlrpcresp(0, $xmlrpcerruser + $err, $msg);
 }
-?>
+?>
\ No newline at end of file
index 4906125..7d4b19e 100755 (executable)
@@ -3,45 +3,51 @@
                <skin name="feeds/atom" />
                <template name="feeds/atom/modified" />
                <template name="feeds/atom/entries" />
+               <info>
+                       <![CDATA[Atom 1.0 weblog syndication]]>
+               </info>
        </meta>
 
-
        <skin name="feeds/atom" type="application/atom+xml" includeMode="normal" includePrefix="">
-               <description>Atom 0.3 weblog syndication</description>
+               <description>Atom 1.0 weblog syndication</description>
                <part name="index"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
-<feed version="0.3" xmlns="http://purl.org/atom/ns#">
+<feed xml:lang="ja" xmlns="http://www.w3.org/2005/Atom">
     <title><%blogsetting(name)%></title>
+       <subtitle><%blogsetting(desc)%></subtitle>
+       <id><%blogsetting(url)%>:<%blogsetting(id)%></id>
+
     <link rel="alternate" type="text/html" href="<%blogsetting(url)%>" />
-    <generator url="http://nucleuscms.org/"><%version%></generator>
-    <modified><%blog(feeds/atom/modified,1)%></modified>
+    <link rel="self" type="application/atom+xml" href="<%blogsetting(url)%><%self%>" />
+    <generator uri="http://nucleuscms.org/"><%version%></generator>
+    <updated><%blog(feeds/atom/modified,1)%></updated>
+
     <%blog(feeds/atom/entries,10)%>
 </feed>]]></part>
-
        </skin>
 
 
        <template name="feeds/atom/modified">
                <description>Atom feeds: Inserts last modification date</description>
                <part name="ITEM"><![CDATA[<%date(utc)%>]]></part>
-
        </template>
 
 
        <template name="feeds/atom/entries">
                <description>Atom feeds: Feed items</description>
                <part name="ITEM"><![CDATA[<entry>
- <title type="text/html" mode="escaped"><![CDATA[<%title%>]]]]><![CDATA[></title>
+ <title type="html"><![CDATA[<%title%>]]]]><![CDATA[></title>
  <link rel="alternate" type="text/html" href="<%blogurl%>?itemid=<%itemid%>" />
  <author>
   <name><%author%></name>
  </author>
- <modified><%date(utc)%></modified>
- <issued><%date(iso8601)%></issued>
- <content type="text/html" mode="escaped"><![CDATA[<%body%><%more%>]]]]><![CDATA[></content>
+ <updated><%date(utc)%></updated>
+ <published><%date(iso8601)%></published>
+ <content type="html"><![CDATA[<%body%><%more%>]]]]><![CDATA[></content>
  <id><%blogurl%>:<%blogid%>:<%itemid%></id>
 </entry>]]></part>
-
+               <part name="IMAGE_CODE"><![CDATA[<%image%>]]></part>
+               <part name="MEDIA_CODE"><![CDATA[<%media%>]]></part>
+               <part name="POPUP_CODE"><![CDATA[<%media%>]]></part>
        </template>
 
-
 </nucleusskin>
index 1c8c52d..d7a71b1 100644 (file)
-<!-- page menu -->\r
-<div class="sidebar">\r
-<dl class="sidebardl">\r
-<dt>Navigation</dt>\r
-\r
-<!-- archive: navigation -->\r
-<%if(skintype,archive)%>\r
-<dd><a href="<%prevlink%>" title="Previous month">Previous <%archivetype%></a></dd>\r
-<dd><a href="<%nextlink%>" title="Next month">Next <%archivetype%></a></dd>\r
-<dd><a href="<%todaylink%>" title="Today's entry">Today</a></dd>\r
-<dd><a href="<%archivelink%>" title="Archives">Archives</a></dd>\r
-<%endif%>\r
-\r
-<!-- archivelist: navigation -->\r
-<%if(skintype,archivelist)%>\r
-<dd><a href="<%todaylink%>" title="Today's entry">Today</a></dd>\r
-<dd><a href="<%archivelink%>" title="Archives">Archives</a></dd>\r
-<%endif%>\r
-\r
-<!-- error: navigation -->\r
-<%if(skintype,error)%>\r
-<dd><a href="<%todaylink%>" title="Today's entry">Today</a></dd>\r
-<%endif%>\r
-\r
-<!-- index: navigation -->\r
-<%if(skintype,index)%>\r
-<dd><a href="<%todaylink%>" title="Today's entry">Today</a></dd>\r
-<dd><a href="<%archivelink%>" title="Archives">Archives</a></dd>\r
-<%endif%>\r
-\r
-<!-- item: navigation -->\r
-<%if(skintype,item)%>\r
-<dd><a href="<%nextlink%>" title="Previous item">Previous Item</a></dd>\r
-<dd><a href="<%prevlink%>" title="Next item">Next Item</a></dd>\r
-<dd><a href="<%todaylink%>" title="Today's entry">Today</a></dd>\r
-<dd><a href="<%archivelink%>" title="Archives">Archives</a></dd>\r
-<%endif%>\r
-\r
-<!-- member: navigation -->\r
-<%if(skintype,member)%>\r
-<dd><a href="<%todaylink%>" title="Today's entry">Today</a></dd>\r
-<%endif%>\r
-\r
-<!-- search: navigation -->\r
-<%if(skintype,search)%>\r
-<dd><a href="<%todaylink%>" title="Today's entry">Today</a></dd>\r
-<dd><a href="<%archivelink%>" title="Archives">Archives</a></dd>\r
-<%endif%>\r
-\r
-<!-- admin link, only visible if logged in -->\r
-<%if(loggedin)%>\r
-<dd><a href="<%adminurl%>" title="Admin Area">Admin</a></dd>\r
-<%endif%>\r
-</dl>\r
-</div>\r
-\r
-<!-- category list, not on error or member page -->\r
-<%if(skintype,error)%><%else%>\r
-<%if(skintype,member)%><%else%>\r
-<div class="sidebar">\r
-<dl class="sidebardl">\r
-<dt>Categories</dt>\r
-<%categorylist(default/index)%>\r
-</dl>\r
-</div>\r
-<%endif%><%endif%>\r
-\r
-<!-- search form -->\r
-<div class="sidebar">\r
-<dl class="sidebardl">\r
-<dt>Search</dt>\r
-<dd><%searchform%></dd>\r
-</dl>\r
-</div>\r
-\r
-<!-- login form -->\r
-<div class="sidebar">\r
-<dl class="sidebardl">\r
-<dt>Login</dt>\r
-<dd><%loginform%></dd>\r
-</dl>\r
-</div>\r
-\r
-<!-- links -->\r
-<div class="sidebar">\r
-<dl class="sidebardl">\r
-<dt>Links</dt>\r
-<dd><a href="http://nucleuscms.org" title="Nucleus CMS Home">nucleuscms.org</a></dd>\r
-<dd><a href="http://docs.nucleuscms.org/" title="Nucleus CMS Documentation">docs.nucleuscms.org</a></dd>\r
-<dd><a href="http://forum.nucleuscms.org" title="Nucleus CMS Support Forum">forum.nucleuscms.org</a></dd>\r
-<dd><a href="http://wiki.nucleuscms.org/" title="Nucleus CMS Wiki">wiki.nucleuscms.org</a></dd>\r
-<dd><a href="http://skins.nucleuscms.org/" title="Nucleus CMS Skins">skins.nucleuscms.org</a></dd>\r
-<dd><a href="http://wiki.nucleuscms.org/plugin" title="Nucleus CMS Plugins">plugins.nucleuscms.org</a></dd>\r
-<dd><a href="http://dev.nucleuscms.org/" title="Nucleus Developer Network">dev.nucleuscms.org</a></dd>\r
-</dl>\r
-</div>\r
-\r
-<!-- Powered by -->\r
-<div class="sidebar">\r
-<div class="sidebardl centerize">\r
-<%nucleusbutton(images/nucleus.gif,85,31)%>\r
-</div>\r
+<!-- page menu -->
+<div class="sidebar">
+<dl class="sidebardl">
+<dt>Navigation</dt>
+
+<!-- archive: navigation -->
+<%if(skintype,archive)%>
+<%if(archiveprevexists)%>
+<dd><a href="<%prevlink%>" title="Previous month">Previous <%archivetype%></a></dd>
+<%else%>
+<dd>&nbsp;</dd>
+<%endif%>
+<%if(archivenextexists)%>
+<dd><a href="<%nextlink%>" title="Next month">Next <%archivetype%></a></dd>
+<%else%>
+<dd>&nbsp;</dd>
+<%endif%>
+<dd><a href="<%todaylink%>" title="Today&#39;s entry">Today</a></dd>
+<dd><a href="<%archivelink%>" title="Archives">Archives</a></dd>
+<%endif%>
+
+<!-- archivelist: navigation -->
+<%if(skintype,archivelist)%>
+<dd><a href="<%todaylink%>" title="Today&#39;s entry">Today</a></dd>
+<dd><a href="<%archivelink%>" title="Archives">Archives</a></dd>
+<%endif%>
+
+<!-- error: navigation -->
+<%if(skintype,error)%>
+<dd><a href="<%todaylink%>" title="Today&#39;s entry">Today</a></dd>
+<%endif%>
+
+<!-- index: navigation -->
+<%if(skintype,index)%>
+<dd><a href="<%todaylink%>" title="Today&#39;s entry">Today</a></dd>
+<dd><a href="<%archivelink%>" title="Archives">Archives</a></dd>
+<%endif%>
+
+<!-- item: navigation -->
+<%if(skintype,item)%>
+<dd><a href="<%nextlink%>" title="Previous item">Previous Item</a></dd>
+<dd><a href="<%prevlink%>" title="Next item">Next Item</a></dd>
+<dd><a href="<%todaylink%>" title="Today&#39;s entry">Today</a></dd>
+<dd><a href="<%archivelink%>" title="Archives">Archives</a></dd>
+<%endif%>
+
+<!-- member: navigation -->
+<%if(skintype,member)%>
+<dd><a href="<%todaylink%>" title="Today&#39;s entry">Today</a></dd>
+<%endif%>
+
+<!-- search: navigation -->
+<%if(skintype,search)%>
+<dd><a href="<%todaylink%>" title="Today&#39;s entry">Today</a></dd>
+<dd><a href="<%archivelink%>" title="Archives">Archives</a></dd>
+<%endif%>
+
+<!-- admin link, only visible if logged in -->
+<%if(loggedin)%>
+<dd><a href="<%adminurl%>" title="Admin Area">Admin</a></dd>
+<%endif%>
+</dl>
+</div>
+
+<!-- category list, not on error or member page -->
+<%if(skintype,error)%><%else%>
+<%if(skintype,member)%><%else%>
+<div class="sidebar">
+<dl class="sidebardl">
+<dt>Categories</dt>
+<%categorylist(default/index)%>
+</dl>
+</div>
+<%endif%><%endif%>
+
+<!-- bloglist-->
+<div class="sidebar">
+<dl class="sidebardl">
+<dt>Blogs</dt>
+<%bloglist(default/index)%>
+</dl>
+</div>
+
+<!-- search form -->
+<div class="sidebar">
+<dl class="sidebardl">
+<dt>Search</dt>
+<dd><%searchform%></dd>
+</dl>
+</div>
+
+<!-- login form -->
+<div class="sidebar">
+<dl class="sidebardl">
+<dt>Login</dt>
+<dd><%loginform%></dd>
+</dl>
+</div>
+
+<!-- links -->
+<div class="sidebar">
+<dl class="sidebardl">
+<dt>Links</dt>
+<dd><a href="http://nucleuscms.org" title="Nucleus CMS Home">nucleuscms.org</a></dd>
+<dd><a href="http://docs.nucleuscms.org/" title="Nucleus CMS Documentation">docs.nucleuscms.org</a></dd>
+<dd><a href="http://forum.nucleuscms.org" title="Nucleus CMS Support Forum">forum.nucleuscms.org</a></dd>
+<dd><a href="http://wiki.nucleuscms.org/" title="Nucleus CMS Wiki">wiki.nucleuscms.org</a></dd>
+<dd><a href="http://skins.nucleuscms.org/" title="Nucleus CMS Skins">skins.nucleuscms.org</a></dd>
+<dd><a href="http://wiki.nucleuscms.org/plugin" title="Nucleus CMS Plugins">plugins.nucleuscms.org</a></dd>
+<dd><a href="http://dev.nucleuscms.org/" title="Nucleus Developer Network">dev.nucleuscms.org</a></dd>
+</dl>
+</div>
+
+<!-- Powered by -->
+<div class="sidebar">
+<div class="sidebardl centerize">
+<%nucleusbutton(images/nucleus.gif,85,31)%>
+</div>
 </div>
\ No newline at end of file
index 3150b93..d964d85 100644 (file)
@@ -3,9 +3,9 @@
                <skin name="default" />
                <template name="default/index" />
                <template name="default/item" />
+               <info><![CDATA[Nucleus CMS Default Skin]]></info>
        </meta>
 
-
        <skin name="default" type="text/html" includeMode="skindir" includePrefix="default/">
                <description>Nucleus CMS default skin</description>
                <part name="archive"><![CDATA[<%parsedinclude(head.inc)%>
@@ -228,6 +228,10 @@ Website: <a href="<%member(url)%>"><%member(url)%></a>
 <a href="<%archivelink%>" title="Archive for %B, %Y">%B, %Y</a>
 </dd>]]></part>
 
+       <part name="BLOGLIST_LISTITEM"><![CDATA[<dd>
+<a href="<%bloglink%>" title="<%blogdesc%>"><%blogname%></a>
+</dd>]]></part>
+
                <part name="CATLIST_HEADER"><![CDATA[<dd>
 <a href="<%blogurl%>" title="All categories">All</a>
 </dd>]]></part>
@@ -240,7 +244,7 @@ Website: <a href="<%member(url)%>"><%member(url)%></a>
 
                <part name="COMMENTS_NONE"><![CDATA[<div class="contentitem3">
 <small class="contentitemcomments">
-<a href="<%itemlink%>#c" rel="bookmark" title="Add comment on '<%itemtitle%>'">Add comment</a>
+<a href="<%itemlink%>#c" rel="bookmark" title="Add comment on &#39;<%itemtitle(attribute)%>&#39;">Add comment</a>
 </small>
 </div>]]></part>
 
@@ -248,7 +252,7 @@ Website: <a href="<%member(url)%>"><%member(url)%></a>
 
                <part name="COMMENTS_TOOMUCH"><![CDATA[<div class="contentitem3">
 <small class="contentitemcomments">
-<a href="<%itemlink%>#c" rel="bookmark" title="Add comment on '<%itemtitle%>'"><%commentcount%> <%commentword%></a>
+<a href="<%itemlink%>#c" rel="bookmark" title="Add comment on &#39;<%itemtitle(attribute)%>&#39;"><%commentcount%> <%commentword%></a>
 </small>
 </div>]]></part>
 
@@ -265,7 +269,7 @@ Website: <a href="<%member(url)%>"><%member(url)%></a>
                <part name="IMAGE_CODE"><![CDATA[<%image%>]]></part>
 
                <part name="ITEM"><![CDATA[<div class="contenttitle">
-<h2><%date%>: <a href="<%itemlink%>" title="Read entry: <%title%>"><%title%></a></h2>
+<h2><%date%>: <a href="<%itemlink%>" title="Read entry: <%title(attribute)%>"><%title(raw)%></a></h2>
 </div>
 <div class="contentitem">
 <div class="contentitem1">
@@ -291,7 +295,7 @@ Posted by: <a href="<%authorlink%>" title="Author: <%author%>"><%author%></a>
                <part name="MEDIA_CODE"><![CDATA[<%media%>]]></part>
 
                <part name="MORELINK"><![CDATA[<p>&raquo;
-<a href="<%itemlink%>#more" title="Read more on '<%title%>'">Read More</a>
+<a href="<%itemlink%>#more" title="Read more on &#39;<%title(attribute)%>&#39;">Read More</a>
 </p>]]></part>
 
                <part name="POPUP_CODE"><![CDATA[<%popuplink%>]]></part>
@@ -336,7 +340,7 @@ title="<%ip%> | Click to visit <%user%>'s website or send an email">
                <part name="IMAGE_CODE"><![CDATA[<%image%>]]></part>
 
                <part name="ITEM"><![CDATA[<div class="contenttitle">
-<h2><%date%>: <%title%></h2>
+<h2><%date%>: <%title(raw)%></h2>
 </div>
 <div class="contentitem">
 <div class="contentitem1">
@@ -367,4 +371,4 @@ Posted by: <a href="<%authorlink%>" title="Author: <%author%>"><%author%></a>
        </template>
 
 
-</nucleusskin>
\ No newline at end of file
+</nucleusskin>
index 8713930..5799d6f 100755 (executable)
@@ -1,9 +1,9 @@
 <nucleusskin>
        <meta>
                <skin name="xml/rsd" />
+               <info><![CDATA[RSD (Really Simple Discovery) information for weblog clients]]></info>
        </meta>
 
-
        <skin name="xml/rsd" type="text/xml" includeMode="normal" includePrefix="">
                <description>RSD (Really Simple Discovery) information for weblog clients</description>
                <part name="index"><![CDATA[<?xml version="1.0"?>
@@ -22,8 +22,6 @@
   </apis>
  </service>
 </rsd>]]></part>
-
        </skin>
 
-
-</nucleusskin>
\ No newline at end of file
+</nucleusskin>
index 67c9914..77bc0e0 100755 (executable)
@@ -2,9 +2,9 @@
        <meta>
                <skin name="feeds/rss20" />
                <template name="feeds/rss20" />
+               <info><![CDATA[RSS 2.0 syndication of weblogs]]></info>
        </meta>
 
-
        <skin name="feeds/rss20" type="text/xml" includeMode="normal" includePrefix="">
                <description>RSS 2.0 syndication of weblogs</description>
                <part name="index"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
     <title><%blogsetting(name)%></title>
     <link><%blogsetting(url)%></link>
     <description><%blogsetting(desc)%></description>
-    <!-- optional tags -->
-    <language>ja</language>           <!-- valid langugae goes here -->
+    <language>ja</language>
     <generator><%version%></generator>
-    <copyright>&#169;</copyright>             <!-- Copyright notice -->
+    <copyright>&#169;</copyright>
     <category>Weblog</category>
     <docs>http://backend.userland.com/rss</docs>
     <image>
     <%blog(feeds/rss20,10)%>
   </channel>
 </rss>]]></part>
-
        </skin>
 
-
        <template name="feeds/rss20">
                <description>Used for RSS 2.0 syndication of your blog</description>
                <part name="EDITLINK"><![CDATA[<a href="<%editlink%>" onclick="<%editpopupcode%>">edit</a>]]></part>
-
                <part name="FORMAT_DATE"><![CDATA[%Y-%m-%d]]></part>
-
                <part name="FORMAT_TIME"><![CDATA[%H:%M:%S]]></part>
-
                <part name="ITEM"><![CDATA[<item>
- <title><![CDATA[<%title%>]]]]><![CDATA[></title>
- <link><%blogurl%>?itemid=<%itemid%></link>
+<title><![CDATA[<%title(xml)%>]]]]><![CDATA[></title>
+<link><%blogurl%>?itemid=<%itemid%></link>
 <description><![CDATA[<%body%><%more%>]]]]><![CDATA[></description>
- <category><%category%></category>
+<category><%category%></category>
 <comments><%blogurl%>?itemid=<%itemid%></comments>
- <pubDate><%date(rfc822)%></pubDate>
+<pubDate><%date(rfc822)%></pubDate>
 </item>]]></part>
 
-       </template>
-
+               <part name="IMAGE_CODE"><![CDATA[<%image%>]]></part>
+               <part name="MEDIA_CODE"><![CDATA[<%media%>]]></part>
+               <part name="POPUP_CODE"><![CDATA[<%media%>]]></part>
 
+       </template>
 </nucleusskin>