OSDN Git Service

定数名修正(nucleus/language/english.php)
authorshizuki <shizuki@1ca29b6e-896d-4ea0-84a5-967f57386b96>
Sat, 7 Feb 2009 14:19:40 +0000 (14:19 +0000)
committershizuki <shizuki@1ca29b6e-896d-4ea0-84a5-967f57386b96>
Sat, 7 Feb 2009 14:19:40 +0000 (14:19 +0000)
本家3.4RCにSync(nucleus/libs/*.php)
libsディレクトリに.htaccess追加

git-svn-id: https://svn.sourceforge.jp/svnroot/nucleus-jp/nucleus-jp/trunk/utf8@919 1ca29b6e-896d-4ea0-84a5-967f57386b96

37 files changed:
nucleus/language/english.php
nucleus/libs/.htaccess [new file with mode: 0644]
nucleus/libs/ACTION.php
nucleus/libs/ACTIONLOG.php
nucleus/libs/ACTIONS.php
nucleus/libs/ADMIN.php
nucleus/libs/BAN.php
nucleus/libs/BLOG.php
nucleus/libs/BODYACTIONS.php
nucleus/libs/BaseActions.php
nucleus/libs/COMMENT.php
nucleus/libs/COMMENTACTIONS.php
nucleus/libs/COMMENTS.php
nucleus/libs/ENCAPSULATE.php
nucleus/libs/ITEM.php
nucleus/libs/ITEMACTIONS.php
nucleus/libs/KARMA.php
nucleus/libs/MANAGER.php
nucleus/libs/MEDIA.php
nucleus/libs/MEMBER.php
nucleus/libs/NOTIFICATION.php
nucleus/libs/PAGEFACTORY.php
nucleus/libs/PARSER.php
nucleus/libs/PLUGIN.php
nucleus/libs/PLUGINADMIN.php
nucleus/libs/SEARCH.php
nucleus/libs/SKIN.php
nucleus/libs/TEMPLATE.php
nucleus/libs/backup.php
nucleus/libs/globalfunctions.php
nucleus/libs/mysql.php
nucleus/libs/showlist.php
nucleus/libs/skinie.php
nucleus/libs/vars4.0.6.php
nucleus/libs/vars4.1.0.php
nucleus/libs/xmlrpc.inc.php
nucleus/libs/xmlrpcs.inc.php

index 6c32a2c..5492687 100755 (executable)
@@ -1034,8 +1034,8 @@ define('_MOVE_BTN',                                                                       'Move Item');
 define('_OVERVIEW_SHOWALL',                                                    'Show all blogs');      // <add by shizuki />\r
 \r
 // Edit skins\r
-define('_SKIN_ALLOWEDBLOGS',                                           'Short blog names:');                   // <add by shizuki>\r
-define('_SKIN_ALLOWEDTEMPLATESS',                                      'Template names:');             // <add by shizuki>\r
+define('_SKINEDIT_ALLOWEDBLOGS',                                               'Short blog names:');                   // <add by shizuki>\r
+define('_SKINEDIT_ALLOWEDTEMPLATESS',                                  'Template names:');             // <add by shizuki>\r
 \r
 // delete member\r
 define('_WARNINGTXT_NOTDELMEDIAFILES',                         'Please note that media files will <b>NOT</b> be deleted. (At least not in this Nucleus version)');     // <add by shizuki />\r
diff --git a/nucleus/libs/.htaccess b/nucleus/libs/.htaccess
new file mode 100644 (file)
index 0000000..6b2c90b
--- /dev/null
@@ -0,0 +1,2 @@
+Order allow,deny\r
+Deny from all\r
index fb56aed..67b9c01 100755 (executable)
@@ -2,7 +2,7 @@
 
 /*
  * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/)
- * Copyright (C) 2002-2007 The Nucleus Group
+ * Copyright (C) 2002-2009 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
  * Actions that can be called via action.php
  *
  * @license http://nucleuscms.org/license.txt GNU General Public License
- * @copyright Copyright (C) 2002-2007 The Nucleus Group
- * @version $Id: ACTION.php,v 1.11 2008-02-08 09:31:22 kimitake Exp $
+ * @copyright Copyright (C) 2002-2009 The Nucleus Group
+ * @version $Id$
  * $NucleusJP: ACTION.php,v 1.10 2007/05/31 07:23:39 kimitake Exp $
  */
-class ACTION
-{
-       /**
-        *  Constructor for an new ACTION object
-        */
-       function ACTION()
-       {
-               // do nothing
-       }
-
-       /**
-        *  Calls functions that handle an action called from action.php
-        */
-       function doAction($action)
-       {
-               switch($action) {
-                       case 'autodraft':
-                               return $this->autoDraft();
-                               break;
-                       case 'updateticket':
-                               return $this->updateTicket();
-                               break;
-                       case 'addcomment':
-                               return $this->addComment();
-                               break;
-                       case 'sendmessage':
-                               return $this->sendMessage();
-                               break;
-                       case 'createaccount':
-                               return $this->createAccount();
-                               break;
-                       case 'forgotpassword':
-                               return $this->forgotPassword();
-                               break;
-                       case 'votepositive':
-                               return $this->doKarma('pos');
-                               break;
-                       case 'votenegative':
-                               return $this->doKarma('neg');
-                               break;
-                       case 'plugin':
-                               return $this->callPlugin();
-                               break;
-                       default:
-                               doError(_ERROR_BADACTION);
-               }
-       }
-
-       /**
-        *  Adds a new comment to an item (if IP isn't banned)
-        */
-       function addComment() {
-               global $CONF, $errormessage, $manager;
-
-               $post['itemid'] =       intPostVar('itemid');
-               $post['user'] =         postVar('user');
-               $post['userid'] =       postVar('userid');
-               $post['email'] =   postVar('email');
-               $post['body'] =         postVar('body');
-
-               // set cookies when required
-               $remember = intPostVar('remember');
-               if ($remember == 1) {
-                       $lifetime = time()+2592000;
-                       setcookie($CONF['CookiePrefix'] . 'comment_user',$post['user'],$lifetime,'/','',0);
-                       setcookie($CONF['CookiePrefix'] . 'comment_userid', $post['userid'],$lifetime,'/','',0);
-                       setcookie($CONF['CookiePrefix'] . 'comment_email',  $post['email'], $lifetime,'/','',0);
-               }
-
-               $comments = new COMMENTS($post['itemid']);
-
-               $blogid = getBlogIDFromItemID($post['itemid']);
-               $this->checkban($blogid);
-               $blog =& $manager->getBlog($blogid);
-
-               // note: PreAddComment and PostAddComment gets called somewhere inside addComment
-               $errormessage = $comments->addComment($blog->getCorrectTime(),$post);
-
-               if ($errormessage == '1') {
-                       // redirect when adding comments succeeded
-                       if (postVar('url')) {
-                               redirect(postVar('url'));
-                       } else {
-                               $url = createItemLink($post['itemid']);
-                               redirect($url);
-                       }
-               } else {
-                       // else, show error message using default skin for blog
-                       return array(
-                               'message' => $errormessage,
-                               'skinid' => $blog->getDefaultSkin()
-                       );
-               }
-
-               exit;
-       }
-
-       /**
-        *  Sends a message from the current member to the member given as argument
-        */
-       function sendMessage() {
-               global $CONF, $member;
-
-               $error = $this->validateMessage();
-               if ($error != '')
-                       return array('message' => $error);
-
-               if (!$member->isLoggedIn()) {
-                       $fromMail = postVar('frommail');
-                       $fromName = _MMAIL_FROMANON;
-               } else {
-                       $fromMail = $member->getEmail();
-                       $fromName = $member->getDisplayName();
-               }
-
-               $tomem = new MEMBER();
-               $tomem->readFromId(postVar('memberid'));
-
-               $message  = _MMAIL_MSG . ' ' . $fromName . "\n"
-                         . '(' . _MMAIL_FROMNUC. ' ' . $CONF['IndexURL'] .") \n\n"
-                         . _MMAIL_MAIL . " \n\n"
-                         . postVar('message');
-               $message .= getMailFooter();
-
-               $title = _MMAIL_TITLE . ' ' . $fromName;
-               mb_language('ja');
-               mb_internal_encoding(_CHARSET);
-               @mb_send_mail($tomem->getEmail(), $title, $message, "From: ". $fromMail);
-
-               if (postVar('url')) {
-                       redirect(postVar('url'));
-               } else {
-                       $CONF['MemberURL'] = $CONF['IndexURL'];
-                       if ($CONF['URLMode'] == 'pathinfo')
-                       {
-                               $url = createLink('member', array('memberid' => $tomem->getID(), 'name' => $tomem->getDisplayName()));
-                       }
-                       else
-                       {
-                               $url = $CONF['IndexURL'] . createMemberLink($tomem->getID());
-                       }
-                       redirect($url);
-               }
-               exit;
-       }
-
-       /**
-        *  Checks if a mail to a member is allowed
-        *  Returns a string with the error message if the mail is disallowed
-        */
-       function validateMessage() {
-               global $CONF, $member, $manager;
-
-               if (!$CONF['AllowMemberMail'])
-                       return _ERROR_MEMBERMAILDISABLED;
-
-               if (!$member->isLoggedIn() && !$CONF['NonmemberMail'])
-                       return _ERROR_DISALLOWED;
-
-               if (!$member->isLoggedIn() && (!isValidMailAddress(postVar('frommail'))))
-                       return _ERROR_BADMAILADDRESS;
-
-               // let plugins do verification (any plugin which thinks the comment is invalid
-               // can change 'error' to something other than '')
-               $result = '';
-               $manager->notify('ValidateForm', array('type' => 'membermail', 'error' => &$result));
-
-               return $result;
-
-       }
-
-       /**
-        *  Creates a new user account
-        */
-       function createAccount() {
-               global $CONF, $manager;
-
-               if (!$CONF['AllowMemberCreate'])
-                       doError(_ERROR_MEMBERCREATEDISABLED);
-
-               // evaluate content from FormExtra
-               $result = 1;
-               $manager->notify('ValidateForm', array('type' => 'membermail', 'error' => &$result));
-
-               if ($result!=1) {
-                       return $result;
-               }
-               else {
-
-                       // even though the member can not log in, set some random initial password. One never knows.
-                       srand((double)microtime()*1000000);
-                       $initialPwd = md5(uniqid(rand(), true));
-
-                       // create member (non admin/can not login/no notes/random string as password)
-                       $r = MEMBER::create(postVar('name'), postVar('realname'), $initialPwd, postVar('email'), postVar('url'), 0, 0, '');
-
-                       if ($r != 1) {
-                               return $r;
-                       }
-
-                       // send message containing password.
-                       $newmem = new MEMBER();
-                       $newmem->readFromName(postVar('name'));
-                       $newmem->sendActivationLink('register');
-
-                       $manager->notify('PostRegister',array('member' => &$newmem));
-
-                       if (postVar('desturl')) {
-                               redirect(postVar('desturl'));
-                       } else {
-                               // header has been already sent, so deleted the line below
-                               //header ("Content-Type: text/html; charset="._CHARSET);
-                               echo _MSG_ACTIVATION_SENT;
-                       }
-                       exit;
-               }
-       }
-
-       /**
-        *  Sends a new password
-        */
-       function forgotPassword() {
-               $membername = trim(postVar('name'));
-
-               if (!MEMBER::exists($membername))
-                       doError(_ERROR_NOSUCHMEMBER);
-               $mem = MEMBER::createFromName($membername);
-
-               if (!$mem->canLogin())
-                       doError(_ERROR_NOLOGON_NOACTIVATE);
-
-               // check if e-mail address is correct
-               if (!($mem->getEmail() == postVar('email')))
-                       doError(_ERROR_INCORRECTEMAIL);
-
-               // send activation link
-               $mem->sendActivationLink('forgot');
-
-               if (postVar('url')) {
-                       redirect(postVar('url'));
-               } else {
-                       header ("Content-Type: text/html; charset="._CHARSET);
-                       echo _MSG_ACTIVATION_SENT;
-               }
-               exit;
-       }
-
-       /**
-        *  Handle karma votes
-        */
-       function doKarma($type) {
-               global $itemid, $member, $CONF, $manager;
-
-               // check if itemid exists
-               if (!$manager->existsItem($itemid,0,0))
-                       doError(_ERROR_NOSUCHITEM);
-
-               $blogid = getBlogIDFromItemID($itemid);
-               $this->checkban($blogid);
-
-               $karma =& $manager->getKarma($itemid);
-
-               // check if not already voted
-               if (!$karma->isVoteAllowed(serverVar('REMOTE_ADDR')))
-                       doError(_ERROR_VOTEDBEFORE);
-
-               // check if item does allow voting
-               $item =& $manager->getItem($itemid,0,0);
-               if ($item['closed'])
-                       doError(_ERROR_ITEMCLOSED);
-
-               switch($type) {
-                       case 'pos':
-                               $karma->votePositive();
-                               break;
-                       case 'neg':
-                               $karma->voteNegative();
-                               break;
-               }
-
-               $blogid = getBlogIDFromItemID($itemid);
-               $blog =& $manager->getBlog($blogid);
-
-               // send email to notification address, if any
-               if ($blog->getNotifyAddress() && $blog->notifyOnVote()) {
-
-                       $mailto_msg = _NOTIFY_KV_MSG . ' ' . $itemid . "\n";
-                       $mailto_msg .= $CONF['IndexURL'] . 'index.php?itemid=' . $itemid . "\n\n";
-                       if ($member->isLoggedIn()) {
-                               $mailto_msg .= _NOTIFY_MEMBER . ' ' . $member->getDisplayName() . ' (ID=' . $member->getID() . ")\n";
-                       }
-                       $mailto_msg .= _NOTIFY_IP . ' ' . serverVar('REMOTE_ADDR') . "\n";
-                       $mailto_msg .= _NOTIFY_HOST . ' ' .  gethostbyaddr(serverVar('REMOTE_ADDR'))  . "\n";
-                       $mailto_msg .= _NOTIFY_VOTE . "\n " . $type . "\n";
-                       $mailto_msg .= getMailFooter();
-
-                       $mailto_title = _NOTIFY_KV_TITLE . ' ' . strip_tags($item['title']) . ' (' . $itemid . ')';
-
-                       $frommail = $member->getNotifyFromMailAddress();
-
-                       $notify = new NOTIFICATION($blog->getNotifyAddress());
-                       $notify->notify($mailto_title, $mailto_msg , $frommail);
-               }
-
-
-               $refererUrl = serverVar('HTTP_REFERER');
-               if ($refererUrl)
-                       $url = $refererUrl;
-               else
-                       $url = $CONF['IndexURL'] . 'index.php?itemid=' . $itemid;
-
-               redirect($url);
-               exit;
-       }
-
-       /**
-         * Calls a plugin action
-         */
-       function callPlugin() {
-               global $manager;
-
-               $pluginName = 'NP_' . requestVar('name');
-               $actionType = requestVar('type');
-
-               // 1: check if plugin is installed
-               if (!$manager->pluginInstalled($pluginName))
-                       doError(_ERROR_NOSUCHPLUGIN);
-
-               // 2: call plugin
-               $pluginObject =& $manager->getPlugin($pluginName);
-               if ($pluginObject)
-                       $error = $pluginObject->doAction($actionType);
-               else
-                       $error = 'Could not load plugin (see actionlog)';
-
-               // doAction returns error when:
-               // - an error occurred (duh)
-               // - no actions are allowed (doAction is not implemented)
-               if ($error)
-                       doError($error);
-
-               exit;
-
-       }
-
-       /**
-        *  Checks if an IP or IP range is banned
-        */
-       function checkban($blogid) {
-               // check if banned
-               $ban = BAN::isBanned($blogid, serverVar('REMOTE_ADDR'));
-               if ($ban != 0) {
-                       doError(_ERROR_BANNED1 . $ban->iprange . _ERROR_BANNED2 . $ban->message . _ERROR_BANNED3);
-               }
-
-       }
-
-       /**
-        * Gets a new ticket
-        */
-       function updateTicket() {
-               global $manager;
-               if ($manager->checkTicket()) {
-                       echo $manager->getNewTicket();
-               }
-               else {
-                       echo 'err:' . _ERROR_BADTICKET;
-               }
-               return false;
-       }
-
-       /**
-        * Handles AutoSaveDraft
-        */
-       function autoDraft() {
-               global $manager;
-               if ($manager->checkTicket()) {
-                       $manager->loadClass('ITEM');
-                       $info = ITEM::createDraftFromRequest();
-                       if ($info['status'] == 'error') {
-                               echo $info['message'];
-                       }
-                       else {
-                               echo $info['draftid'];
-                       }
-               }
-               else {
-                       echo 'err:' . _ERROR_BADTICKET;
-               }
-               return false;
-       }
-
-
-}
-
-?>
+class ACTION\r
+{\r
+       /**\r
+        *  Constructor for an new ACTION object\r
+        */\r
+       function ACTION()\r
+       {\r
+               // do nothing\r
+       }\r
+\r
+       /**\r
+        *  Calls functions that handle an action called from action.php\r
+        */\r
+       function doAction($action)\r
+       {\r
+               switch($action) {\r
+                       case 'autodraft':\r
+                               return $this->autoDraft();\r
+                               break;\r
+                       case 'updateticket':\r
+                               return $this->updateTicket();\r
+                               break;\r
+                       case 'addcomment':\r
+                               return $this->addComment();\r
+                               break;\r
+                       case 'sendmessage':\r
+                               return $this->sendMessage();\r
+                               break;\r
+                       case 'createaccount':\r
+                               return $this->createAccount();\r
+                               break;\r
+                       case 'forgotpassword':\r
+                               return $this->forgotPassword();\r
+                               break;\r
+                       case 'votepositive':\r
+                               return $this->doKarma('pos');\r
+                               break;\r
+                       case 'votenegative':\r
+                               return $this->doKarma('neg');\r
+                               break;\r
+                       case 'plugin':\r
+                               return $this->callPlugin();\r
+                               break;\r
+                       default:\r
+                               doError(_ERROR_BADACTION);\r
+               }\r
+       }\r
+\r
+       /**\r
+        *  Adds a new comment to an item (if IP isn't banned)\r
+        */\r
+       function addComment() {\r
+               global $CONF, $errormessage, $manager;\r
+\r
+               $post['itemid'] =       intPostVar('itemid');\r
+               $post['user'] =         postVar('user');\r
+               $post['userid'] =       postVar('userid');\r
+               $post['email'] =   postVar('email');\r
+               $post['body'] =         postVar('body');\r
+\r
+               // set cookies when required\r
+               $remember = intPostVar('remember');\r
+               if ($remember == 1) {\r
+                       $lifetime = time()+2592000;\r
+                       setcookie($CONF['CookiePrefix'] . 'comment_user',$post['user'],$lifetime,'/','',0);\r
+                       setcookie($CONF['CookiePrefix'] . 'comment_userid', $post['userid'],$lifetime,'/','',0);\r
+                       setcookie($CONF['CookiePrefix'] . 'comment_email',  $post['email'], $lifetime,'/','',0);\r
+               }\r
+\r
+               $comments = new COMMENTS($post['itemid']);\r
+\r
+               $blogid = getBlogIDFromItemID($post['itemid']);\r
+               $this->checkban($blogid);\r
+               $blog =& $manager->getBlog($blogid);\r
+\r
+               // note: PreAddComment and PostAddComment gets called somewhere inside addComment\r
+               $errormessage = $comments->addComment($blog->getCorrectTime(),$post);\r
+\r
+               if ($errormessage == '1') {\r
+                       // redirect when adding comments succeeded\r
+                       if (postVar('url')) {\r
+                               redirect(postVar('url'));\r
+                       } else {\r
+                               $url = createItemLink($post['itemid']);\r
+                               redirect($url);\r
+                       }\r
+               } else {\r
+                       // else, show error message using default skin for blog\r
+                       return array(\r
+                               'message' => $errormessage,\r
+                               'skinid' => $blog->getDefaultSkin()\r
+                       );\r
+               }\r
+\r
+               exit;\r
+       }\r
+\r
+       /**\r
+        *  Sends a message from the current member to the member given as argument\r
+        */\r
+       function sendMessage() {\r
+               global $CONF, $member;\r
+\r
+               $error = $this->validateMessage();\r
+               if ($error != '')\r
+                       return array('message' => $error);\r
+\r
+               if (!$member->isLoggedIn()) {\r
+                       $fromMail = postVar('frommail');\r
+                       $fromName = _MMAIL_FROMANON;\r
+               } else {\r
+                       $fromMail = $member->getEmail();\r
+                       $fromName = $member->getDisplayName();\r
+               }\r
+\r
+               $tomem = new MEMBER();\r
+               $tomem->readFromId(postVar('memberid'));\r
+\r
+               $message  = _MMAIL_MSG . ' ' . $fromName . "\n"\r
+                         . '(' . _MMAIL_FROMNUC. ' ' . $CONF['IndexURL'] .") \n\n"\r
+                         . _MMAIL_MAIL . " \n\n"\r
+                         . postVar('message');\r
+               $message .= getMailFooter();\r
+\r
+               $title = _MMAIL_TITLE . ' ' . $fromName;\r
+               mb_language('ja');\r
+               mb_internal_encoding(_CHARSET);\r
+               @mb_send_mail($tomem->getEmail(), $title, $message, "From: ". $fromMail);\r
+\r
+               if (postVar('url')) {\r
+                       redirect(postVar('url'));\r
+               } else {\r
+                       $CONF['MemberURL'] = $CONF['IndexURL'];\r
+                       if ($CONF['URLMode'] == 'pathinfo')\r
+                       {\r
+                               $url = createLink('member', array('memberid' => $tomem->getID(), 'name' => $tomem->getDisplayName()));\r
+                       }\r
+                       else\r
+                       {\r
+                               $url = $CONF['IndexURL'] . createMemberLink($tomem->getID());\r
+                       }\r
+                       redirect($url);\r
+               }\r
+               exit;\r
+       }\r
+\r
+       /**\r
+        *  Checks if a mail to a member is allowed\r
+        *  Returns a string with the error message if the mail is disallowed\r
+        */\r
+       function validateMessage() {\r
+               global $CONF, $member, $manager;\r
+\r
+               if (!$CONF['AllowMemberMail'])\r
+                       return _ERROR_MEMBERMAILDISABLED;\r
+\r
+               if (!$member->isLoggedIn() && !$CONF['NonmemberMail'])\r
+                       return _ERROR_DISALLOWED;\r
+\r
+               if (!$member->isLoggedIn() && (!isValidMailAddress(postVar('frommail'))))\r
+                       return _ERROR_BADMAILADDRESS;\r
+\r
+               // let plugins do verification (any plugin which thinks the comment is invalid\r
+               // can change 'error' to something other than '')\r
+               $result = '';\r
+               $manager->notify('ValidateForm', array('type' => 'membermail', 'error' => &$result));\r
+\r
+               return $result;\r
+\r
+       }\r
+\r
+       /**\r
+        *  Creates a new user account\r
+        */\r
+       function createAccount() {\r
+               global $CONF, $manager;\r
+\r
+               if (!$CONF['AllowMemberCreate'])\r
+                       doError(_ERROR_MEMBERCREATEDISABLED);\r
+\r
+               // evaluate content from FormExtra\r
+               $result = 1;\r
+               $data = array('type' => 'membermail', 'error' => &$result);\r
+               $manager->notify('ValidateForm', &$data);\r
+\r
+               if ($result!=1) {\r
+                       return $result;\r
+               }\r
+               else {\r
+\r
+                       // even though the member can not log in, set some random initial password. One never knows.\r
+                       srand((double)microtime()*1000000);\r
+                       $initialPwd = md5(uniqid(rand(), true));\r
+\r
+                       // create member (non admin/can not login/no notes/random string as password)\r
+                       $name = shorten(postVar('name'),16,'');\r
+                       $r = MEMBER::create($name, postVar('realname'), $initialPwd, postVar('email'), postVar('url'), 0, 0, '');\r
+\r
+                       if ($r != 1) {\r
+                               return $r;\r
+                       }\r
+\r
+                       // send message containing password.\r
+                       $newmem = new MEMBER();\r
+                       $newmem->readFromName($name);\r
+                       $newmem->sendActivationLink('register');\r
+\r
+                       $manager->notify('PostRegister',array('member' => &$newmem));\r
+\r
+                       if (postVar('desturl')) {\r
+                               redirect(postVar('desturl'));\r
+                       } else {\r
+                               // header has been already sent, so deleted the line below\r
+                               //header ("Content-Type: text/html; charset="._CHARSET);\r
+                               echo _MSG_ACTIVATION_SENT;\r
+                       }\r
+                       exit;\r
+               }\r
+       }\r
+\r
+       /**\r
+        *  Sends a new password\r
+        */\r
+       function forgotPassword() {\r
+               $membername = trim(postVar('name'));\r
+\r
+               if (!MEMBER::exists($membername))\r
+                       doError(_ERROR_NOSUCHMEMBER);\r
+               $mem = MEMBER::createFromName($membername);\r
+\r
+               if (!$mem->canLogin())\r
+                       doError(_ERROR_NOLOGON_NOACTIVATE);\r
+\r
+               // check if e-mail address is correct\r
+               if (!($mem->getEmail() == postVar('email')))\r
+                       doError(_ERROR_INCORRECTEMAIL);\r
+\r
+               // send activation link\r
+               $mem->sendActivationLink('forgot');\r
+\r
+               if (postVar('url')) {\r
+                       redirect(postVar('url'));\r
+               } else {\r
+                       header ("Content-Type: text/html; charset="._CHARSET);\r
+                       echo _MSG_ACTIVATION_SENT;\r
+               }\r
+               exit;\r
+       }\r
+\r
+       /**\r
+        *  Handle karma votes\r
+        */\r
+       function doKarma($type) {\r
+               global $itemid, $member, $CONF, $manager;\r
+\r
+               // check if itemid exists\r
+               if (!$manager->existsItem($itemid,0,0))\r
+                       doError(_ERROR_NOSUCHITEM);\r
+\r
+               $blogid = getBlogIDFromItemID($itemid);\r
+               $this->checkban($blogid);\r
+\r
+               $karma =& $manager->getKarma($itemid);\r
+\r
+               // check if not already voted\r
+               if (!$karma->isVoteAllowed(serverVar('REMOTE_ADDR')))\r
+                       doError(_ERROR_VOTEDBEFORE);\r
+\r
+               // check if item does allow voting\r
+               $item =& $manager->getItem($itemid,0,0);\r
+               if ($item['closed'])\r
+                       doError(_ERROR_ITEMCLOSED);\r
+\r
+               switch($type) {\r
+                       case 'pos':\r
+                               $karma->votePositive();\r
+                               break;\r
+                       case 'neg':\r
+                               $karma->voteNegative();\r
+                               break;\r
+               }\r
+\r
+               $blogid = getBlogIDFromItemID($itemid);\r
+               $blog =& $manager->getBlog($blogid);\r
+\r
+               // send email to notification address, if any\r
+               if ($blog->getNotifyAddress() && $blog->notifyOnVote()) {\r
+\r
+                       $mailto_msg = _NOTIFY_KV_MSG . ' ' . $itemid . "\n";\r
+                       $mailto_msg .= $CONF['IndexURL'] . 'index.php?itemid=' . $itemid . "\n\n";\r
+                       if ($member->isLoggedIn()) {\r
+                               $mailto_msg .= _NOTIFY_MEMBER . ' ' . $member->getDisplayName() . ' (ID=' . $member->getID() . ")\n";\r
+                       }\r
+                       $mailto_msg .= _NOTIFY_IP . ' ' . serverVar('REMOTE_ADDR') . "\n";\r
+                       $mailto_msg .= _NOTIFY_HOST . ' ' .  gethostbyaddr(serverVar('REMOTE_ADDR'))  . "\n";\r
+                       $mailto_msg .= _NOTIFY_VOTE . "\n " . $type . "\n";\r
+                       $mailto_msg .= getMailFooter();\r
+\r
+                       $mailto_title = _NOTIFY_KV_TITLE . ' ' . strip_tags($item['title']) . ' (' . $itemid . ')';\r
+\r
+                       $frommail = $member->getNotifyFromMailAddress();\r
+\r
+                       $notify = new NOTIFICATION($blog->getNotifyAddress());\r
+                       $notify->notify($mailto_title, $mailto_msg , $frommail);\r
+               }\r
+\r
+\r
+               $refererUrl = serverVar('HTTP_REFERER');\r
+               if ($refererUrl)\r
+                       $url = $refererUrl;\r
+               else\r
+                       $url = $CONF['IndexURL'] . 'index.php?itemid=' . $itemid;\r
+\r
+               redirect($url);\r
+               exit;\r
+       }\r
+\r
+       /**\r
+         * Calls a plugin action\r
+         */\r
+       function callPlugin() {\r
+               global $manager;\r
+\r
+               $pluginName = 'NP_' . requestVar('name');\r
+               $actionType = requestVar('type');\r
+\r
+               // 1: check if plugin is installed\r
+               if (!$manager->pluginInstalled($pluginName))\r
+                       doError(_ERROR_NOSUCHPLUGIN);\r
+\r
+               // 2: call plugin\r
+               $pluginObject =& $manager->getPlugin($pluginName);\r
+               if ($pluginObject)\r
+                       $error = $pluginObject->doAction($actionType);\r
+               else\r
+                       $error = 'Could not load plugin (see actionlog)';\r
+\r
+               // doAction returns error when:\r
+               // - an error occurred (duh)\r
+               // - no actions are allowed (doAction is not implemented)\r
+               if ($error)\r
+                       doError($error);\r
+\r
+               exit;\r
+\r
+       }\r
+\r
+       /**\r
+        *  Checks if an IP or IP range is banned\r
+        */\r
+       function checkban($blogid) {\r
+               // check if banned\r
+               $ban = BAN::isBanned($blogid, serverVar('REMOTE_ADDR'));\r
+               if ($ban != 0) {\r
+                       doError(_ERROR_BANNED1 . $ban->iprange . _ERROR_BANNED2 . $ban->message . _ERROR_BANNED3);\r
+               }\r
+\r
+       }\r
+\r
+       /**\r
+        * Gets a new ticket\r
+        */\r
+       function updateTicket() {\r
+               global $manager;\r
+               if ($manager->checkTicket()) {\r
+                       echo $manager->getNewTicket();\r
+               }\r
+               else {\r
+                       echo 'err:' . _ERROR_BADTICKET;\r
+               }\r
+               return false;\r
+       }\r
+\r
+       /**\r
+        * Handles AutoSaveDraft\r
+        */\r
+       function autoDraft() {\r
+               global $manager;\r
+               if ($manager->checkTicket()) {\r
+                       $manager->loadClass('ITEM');\r
+                       $info = ITEM::createDraftFromRequest();\r
+                       if ($info['status'] == 'error') {\r
+                               echo $info['message'];\r
+                       }\r
+                       else {\r
+                               echo $info['draftid'];\r
+                       }\r
+               }\r
+               else {\r
+                       echo 'err:' . _ERROR_BADTICKET;\r
+               }\r
+               return false;\r
+       }\r
+\r
+\r
+}\r
+\r
+?>
\ No newline at end of file
index 53145e0..381da8e 100755 (executable)
@@ -1,7 +1,7 @@
 <?php
 /*
  * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/)
- * Copyright (C) 2002-2007 The Nucleus Group
+ * Copyright (C) 2002-2009 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
@@ -13,8 +13,8 @@
  * Actionlog class for Nucleus
  *
  * @license http://nucleuscms.org/license.txt GNU General Public License
- * @copyright Copyright (C) 2002-2007 The Nucleus Group
- * @version $Id: ACTIONLOG.php,v 1.8 2007-04-19 05:49:29 kimitake Exp $
+ * @copyright Copyright (C) 2002-2009 The Nucleus Group
+ * @version $Id$
  * $NucleusJP: ACTIONLOG.php,v 1.7 2007/03/13 05:18:32 shizuki Exp $
  */
 define('ERROR',1);             // only errors
index 2928500..1b6b5cf 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 /*
  * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/)
- * Copyright (C) 2002-2007 The Nucleus Group
+ * Copyright (C) 2002-2009 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
@@ -17,8 +17,8 @@
  * SKIN::getAllowedActionsForType($type) method
  *
  * @license http://nucleuscms.org/license.txt GNU General Public License
- * @copyright Copyright (C) 2002-2007 The Nucleus Group
- * @version $Id: ACTIONS.php,v 1.9 2007-05-10 08:12:51 kimitake Exp $
+ * @copyright Copyright (C) 2002-2009 The Nucleus Group
+ * @version $Id$
  * @version $NucleusJP: ACTIONS.php,v 1.8 2007/04/19 06:05:55 kimitake Exp $
  */
 
@@ -395,6 +395,25 @@ class ACTIONS extends BaseActions {
                $blog->InsertJavaScriptInfo();
                $this->doForm('additemform');
        }
+       \r
+       /**\r
+        * Parse skinvar addlink\r
+        * A Link that allows to open a bookmarklet to add an item\r
+        */\r
+       function parse_addlink() {\r
+               global $CONF, $member, $blog;\r
+               if ($member->isLoggedIn() && $member->isTeamMember($blog->blogid) ) {\r
+                       echo $CONF['AdminURL'].'bookmarklet.php?blogid='.$blog->blogid;\r
+               }\r
+       }\r
+       \r
+       /**\r
+        * Parse skinvar addpopupcode\r
+        * Code that opens a bookmarklet in an popup window\r
+        */\r
+       function parse_addpopupcode() {\r
+               echo "if (event &amp;&amp; event.preventDefault) event.preventDefault();winbm=window.open(this.href,'nucleusbm','scrollbars=yes,width=600,height=500,left=10,top=10,status=yes,resizable=yes');winbm.focus();return false;";\r
+       }\r
        
        /**
         * Parse skinvar adminurl
@@ -506,9 +525,11 @@ class ACTIONS extends BaseActions {
        *       Parse skinvar bloglist
        *       Shows a list of all blogs
        *       bnametype: whether 'name' or 'shortname' is used for the link text        
+       *       orderby: order criteria\r
+       *       direction: order ascending or descending                  \r
        */
-       function parse_bloglist($template, $bnametype = '') {
-               BLOG::showBlogList($template, $bnametype);
+       function parse_bloglist($template, $bnametype = '', $orderby='number', $direction='asc') {\r
+               BLOG::showBlogList($template, $bnametype, $orderby, $direction);\r
        }
        
        /**
@@ -600,7 +621,7 @@ class ACTIONS extends BaseActions {
                if (stristr($destinationurl, 'action.php')) {
                        $args = func_get_args();
                        $destinationurl = $args[1];
-                       ACTIONLOG::add(WARNING,'actionurl is not longer a parameter on commentform skinvars. Moved to be a global setting instead.');
+                       ACTIONLOG::add(WARNING,_ACTIONURL_NOTLONGER_PARAMATER);\r
                }
 
                $actionurl = $CONF['ActionURL'];
@@ -1076,9 +1097,10 @@ class ACTIONS extends BaseActions {
        function parse_plugin($pluginName) {
                global $manager;
 
-               // only continue when the plugin is really installed
-               if (!$manager->pluginInstalled('NP_' . $pluginName))
-                       return;
+               // should be already tested from the parser (PARSER.php)\r
+               // only continue when the plugin is really installed\r
+               /*if (!$manager->pluginInstalled('NP_' . $pluginName))\r
+                       return;*/
 
                $plugin =& $manager->getPlugin('NP_' . $pluginName);
                if (!$plugin) return;
index a58cf1c..43be878 100755 (executable)
@@ -1,7 +1,7 @@
 <?php\r
 /*\r
  * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/)\r
- * Copyright (C) 2002-2007 The Nucleus Group\r
+ * Copyright (C) 2002-2009 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
@@ -13,8 +13,8 @@
  * The code for the Nucleus admin area\r
  *\r
  * @license http://nucleuscms.org/license.txt GNU General Public License\r
- * @copyright Copyright (C) 2002-2007 The Nucleus Group\r
- * @version $Id: ADMIN.php,v 1.24 2008-02-08 09:31:22 kimitake Exp $\r
+ * @copyright Copyright (C) 2002-2009 The Nucleus Group\r
+ * @version $Id$\r
  * @version $NucleusJP: ADMIN.php,v 1.21.2.4 2007/10/30 19:04:24 kmorimatsu Exp $\r
  */\r
 \r
@@ -62,7 +62,57 @@ class ADMIN {
                // check ticket. All actions need a ticket, unless they are considered to be safe (a safe action\r
                // is an action that requires user interaction before something is actually done)\r
                // all safe actions are in this array:\r
-               $aActionsNotToCheck = array('showlogin', 'login', 'overview', 'itemlist', 'blogcommentlist', 'bookmarklet', 'blogsettings', 'banlist', 'deleteblog', 'editmembersettings', 'browseownitems', 'browseowncomments', 'createitem', 'itemedit', 'itemmove', 'categoryedit', 'categorydelete', 'manage', 'actionlog', 'settingsedit', 'backupoverview', 'pluginlist', 'createnewlog', 'usermanagement', 'skinoverview', 'templateoverview', 'skinieoverview', 'itemcommentlist', 'commentedit', 'commentdelete', 'banlistnewfromitem', 'banlistdelete', 'itemdelete', 'manageteam', 'teamdelete', 'banlistnew', 'memberedit', 'memberdelete', 'pluginhelp', 'pluginoptions', 'plugindelete', 'skinedittype', 'skinremovetype', 'skindelete', 'skinedit', 'templateedit', 'templatedelete', 'activate');\r
+               $aActionsNotToCheck = array(\r
+                       'showlogin',\r
+                       'login',\r
+                       'overview',\r
+                       'itemlist',\r
+                       'blogcommentlist',\r
+                       'bookmarklet',\r
+                       'blogsettings',\r
+                       'banlist',\r
+                       'deleteblog',\r
+                       'editmembersettings',\r
+                       'browseownitems',\r
+                       'browseowncomments',\r
+                       'createitem',\r
+                       'itemedit',\r
+                       'itemmove',\r
+                       'categoryedit',\r
+                       'categorydelete',\r
+                       'manage',\r
+                       'actionlog',\r
+                       'settingsedit',\r
+                       'backupoverview',\r
+                       'pluginlist',\r
+                       'createnewlog',\r
+                       'usermanagement',\r
+                       'skinoverview',\r
+                       'templateoverview',\r
+                       'skinieoverview',\r
+                       'itemcommentlist',\r
+                       'commentedit',\r
+                       'commentdelete',\r
+                       'banlistnewfromitem',\r
+                       'banlistdelete',\r
+                       'itemdelete',\r
+                       'manageteam',\r
+                       'teamdelete',\r
+                       'banlistnew',\r
+                       'memberedit',\r
+                       'memberdelete',\r
+                       'pluginhelp',\r
+                       'pluginoptions',\r
+                       'plugindelete',\r
+                       'skinedittype',\r
+                       'skinremovetype',\r
+                       'skindelete',\r
+                       'skinedit',\r
+                       'templateedit',\r
+                       'templatedelete',\r
+                       'activate',\r
+                       'systemoverview'\r
+               );\r
 /*\r
                // the rest of the actions needs to be checked\r
                $aActionsToCheck = array('additem', 'itemupdate', 'itemmoveto', 'categoryupdate', 'categorydeleteconfirm', 'itemdeleteconfirm', 'commentdeleteconfirm', 'teamdeleteconfirm', 'memberdeleteconfirm', 'templatedeleteconfirm', 'skindeleteconfirm', 'banlistdeleteconfirm', 'plugindeleteconfirm', 'batchitem', 'batchcomment', 'batchmember', 'batchcategory', 'batchteam', 'regfile', 'commentupdate', 'banlistadd', 'changemembersettings', 'clearactionlog', 'settingsupdate', 'blogsettingsupdate', 'categorynew', 'teamchangeadmin', 'teamaddmember', 'memberadd', 'addnewlog', 'addnewlog2', 'backupcreate', 'backuprestore', 'pluginup', 'plugindown', 'pluginupdate', 'pluginadd', 'pluginoptionsupdate', 'skinupdate', 'skinclone', 'skineditgeneral', 'templateclone', 'templatenew', 'templateupdate', 'skinieimport', 'skinieexport', 'skiniedoimport', 'skinnew', 'deleteblogconfirm', 'sendping', 'rawping', 'activatesetpwd');\r
@@ -168,7 +218,7 @@ class ADMIN {
                if (($showAll != 'yes') && ($member->isAdmin())) {\r
                        $total = quickQuery('SELECT COUNT(*) as result FROM ' . sql_table('blog'));\r
                        if ($total > $amount)\r
-                               echo '<p><a href="index.php?action=overview&amp;showall=yes">Show all blogs</a></p>';\r
+                               echo '<p><a href="index.php?action=overview&amp;showall=yes">' . _OVERVIEW_SHOWALL . '</a></p>';\r
                }\r
 \r
                if ($amount == 0)\r
@@ -258,7 +308,7 @@ class ADMIN {
         * @todo document this\r
         */\r
        function action_itemlist($blogid = '') {\r
-               global $member, $manager;\r
+               global $member, $manager, $CONF;\r
 \r
                if ($blogid == '')\r
                        $blogid = intRequestVar('blogid');\r
@@ -283,8 +333,11 @@ class ADMIN {
                // amount of items to show\r
                if (postVar('amount'))\r
                        $amount = intPostVar('amount');\r
-               else\r
-                       $amount = 10;\r
+               else {\r
+                       $amount = intval($CONF['DefaultListSize']);\r
+                       if ($amount < 1) \r
+                               $amount = 10;\r
+               }\r
 \r
                $search = postVar('search');    // search through items\r
 \r
@@ -831,7 +884,7 @@ class ADMIN {
         * @todo document this\r
         */\r
        function action_browseownitems() {\r
-               global $member, $manager;\r
+               global $member, $manager, $CONF;\r
 \r
                $this->pagehead();\r
 \r
@@ -847,8 +900,11 @@ class ADMIN {
                // amount of items to show\r
                if (postVar('amount'))\r
                        $amount = intPostVar('amount');\r
-               else\r
-                       $amount = 10;\r
+               else {\r
+                       $amount = intval($CONF['DefaultListSize']);\r
+                       if ($amount < 1) \r
+                               $amount = 10;\r
+               }\r
 \r
                $search = postVar('search');    // search through items\r
 \r
@@ -878,7 +934,7 @@ class ADMIN {
         * @param int $itemid\r
         */\r
        function action_itemcommentlist($itemid = '') {\r
-               global $member, $manager;\r
+               global $member, $manager, $CONF;\r
 \r
                if ($itemid == '')\r
                        $itemid = intRequestVar('itemid');\r
@@ -899,15 +955,18 @@ class ADMIN {
                // amount of items to show\r
                if (postVar('amount'))\r
                        $amount = intPostVar('amount');\r
-               else\r
-                       $amount = 10;\r
+               else {\r
+                       $amount = intval($CONF['DefaultListSize']);\r
+                       if ($amount < 1) \r
+                               $amount = 10;\r
+               }\r
 \r
                $search = postVar('search');\r
 \r
                echo '<p>(<a href="index.php?action=itemlist&amp;blogid=',$blogid,'">',_BACKTOOVERVIEW,'</a>)</p>';\r
                echo '<h2>',_COMMENTS,'</h2>';\r
 \r
-               $query =  'SELECT cbody, cuser, cmail, mname, ctime, chost, cnumber, cip, citem FROM '.sql_table('comment').' LEFT OUTER JOIN '.sql_table('member').' ON mnumber=cmember WHERE citem=' . $itemid;\r
+               $query = 'SELECT cbody, cuser, cmail, cemail, mname, ctime, chost, cnumber, cip, citem FROM ' . sql_table('comment') . ' LEFT OUTER JOIN ' . sql_table('member') . ' ON mnumber = cmember WHERE citem = ' . $itemid;\r
 \r
                if ($search)\r
                        $query .= ' and cbody LIKE "%' . addslashes($search) . '%"';\r
@@ -929,7 +988,7 @@ class ADMIN {
         * Browse own comments\r
         */\r
        function action_browseowncomments() {\r
-               global $member, $manager;\r
+               global $member, $manager, $CONF;\r
 \r
                // start index\r
                if (postVar('start'))\r
@@ -940,8 +999,11 @@ class ADMIN {
                // amount of items to show\r
                if (postVar('amount'))\r
                        $amount = intPostVar('amount');\r
-               else\r
-                       $amount = 10;\r
+               else {\r
+                       $amount = intval($CONF['DefaultListSize']);\r
+                       if ($amount < 1) \r
+                               $amount = 10;\r
+               }\r
 \r
                $search = postVar('search');\r
 \r
@@ -975,7 +1037,7 @@ class ADMIN {
         */\r
        function action_blogcommentlist($blogid = '')\r
        {\r
-               global $member, $manager;\r
+               global $member, $manager, $CONF;\r
 \r
                if ($blogid == '')\r
                        $blogid = intRequestVar('blogid');\r
@@ -993,8 +1055,11 @@ class ADMIN {
                // amount of items to show\r
                if (postVar('amount'))\r
                        $amount = intPostVar('amount');\r
-               else\r
-                       $amount = 10;\r
+               else {\r
+                       $amount = intval($CONF['DefaultListSize']);\r
+                       if ($amount < 1) \r
+                               $amount = 10;\r
+               }\r
 \r
                $search = postVar('search');            // search through comments\r
 \r
@@ -1134,6 +1199,7 @@ class ADMIN {
                                $wasdraft: set to 1 when the item used to be a draft item\r
                                $publish: set to 1 when the edited item is not a draft\r
                */\r
+/*<del by shizuki>\r
                switch ($actiontype) {\r
                        case 'adddraft':\r
                                $publish = 0;\r
@@ -1143,7 +1209,7 @@ class ADMIN {
                        case 'addfuture':\r
                                $wasdraft = 1;\r
                                $publish = 1;\r
-                               $timestamp = mktime(postVar('hour'), postVar('minutes'), 0, postVar('month'), postVar('day'), postVar('year'));\r
+                               $timestamp = mktime(intPostVar('hour'), intPostVar('minutes'), 0, intPostVar('month'), intPostVar('day'), intPostVar('year'));\r
                                break;\r
                        case 'addnow':\r
                                $wasdraft = 1;\r
@@ -1151,20 +1217,41 @@ class ADMIN {
                                $timestamp = 0;\r
                                break;\r
                        case 'changedate':\r
-                               $timestamp = mktime(postVar('hour'), postVar('minutes'), 0, postVar('month'), postVar('day'), postVar('year'));\r
+                               $timestamp = mktime(intPostVar('hour'), intPostVar('minutes'), 0, intPostVar('month'), intPostVar('day'), intPostVar('year'));\r
                                $publish = 1;\r
                                $wasdraft = 0;\r
                                break;\r
+                       case 'backtodrafts':\r
+                               $wasdraft = 0;\r
+                               $publish = 0;\r
+                               $timestamp = 0;\r
+                               break;                  \r
                        case 'edit':\r
                        default:\r
                                $publish = 1;\r
                                $wasdraft = 0;\r
                                $timestamp = 0;\r
                }\r
+</del by shizuki>*/\r
+// <add by shizuki>\r
+               $blogid =  getBlogIDFromItemID($itemid);\r
+               $blog   =& $manager->getBlog($blogid);\r
+\r
+               $wasdrafts = array('adddraft', 'addfuture', 'addnow');\r
+               $wasdraft  = in_array($actiontype, $wasdrafts) ? 1 : 0;\r
+               $publish   = ($actiontype != 'adddraft' && $actiontype != 'backtodrafts') ? 1 : 0;\r
+               if ($actiontype == 'addfuture' || $actiontype == 'changedate') {\r
+                       $timestamp = mktime(intPostVar('hour'), intPostVar('minutes'), 0, intPostVar('month'), intPostVar('day'), intPostVar('year'));\r
+               } else {\r
+                       $timestamp =0;\r
+               }\r
+               $doping = ($publish && $timestamp < $blog->getCorrectTime() && postVar('dosendping')) ? 1 : 0;\r
+// </add by shizuki>\r
 \r
                // edit the item for real\r
                ITEM::update($itemid, $catid, $title, $body, $more, $closed, $wasdraft, $publish, $timestamp);\r
 \r
+/* <del by shizuki>\r
                $blogid = getBlogIDFromItemID($itemid);\r
                $blog =& $manager->getBlog($blogid);\r
 \r
@@ -1173,6 +1260,7 @@ class ADMIN {
                        $isFuture = 1;\r
                }\r
 \r
+</del by shizuki>*/\r
                $this->updateFuturePosted($blogid);\r
 \r
                if ($draftid > 0) {\r
@@ -1180,7 +1268,8 @@ class ADMIN {
                        ITEM::delete($draftid);\r
                }\r
 \r
-               if (!$closed && $publish && $wasdraft && $blog->sendPing() && numberOfEventSubscriber('SendPing') > 0 && !$isFuture) {\r
+//             if (!$closed && $publish && $wasdraft && $blog->sendPing() && numberOfEventSubscriber('SendPing') > 0 && !$isFuture) {\r
+               if (!$closed && $doping && $blog->sendPing() && numberOfEventSubscriber('SendPing') > 0) {              //<mod by shizuki />\r
                        $this->action_sendping($blogid);\r
                        return;\r
                }\r
@@ -1405,7 +1494,7 @@ class ADMIN {
 \r
                $blogid = getBlogIDFromItemID($result['itemid']);\r
                $blog =& $manager->getBlog($blogid);\r
-\r
+/* <del by shizuki>\r
                $pingUrl = $manager->addTicketToUrl($CONF['AdminURL'] . 'index.php?action=sendping&blogid=' . intval($blogid));\r
 \r
                if ($result['status'] == 'newcategory')\r
@@ -1418,6 +1507,27 @@ class ADMIN {
                        $this->action_sendping($blogid);\r
                else\r
                        $this->action_itemlist($blogid);\r
+</del by shizuki>*/\r
+// <add by shizuki>\r
+               $btimestamp = $blog->getCorrectTime();\r
+               $bPingInfo  = ($blog->sendPing() && numberOfEventSubscriber('SendPing') > 0);\r
+               $item       = $manager->getItem(intval($result['itemid']), 1, 1);\r
+               $iPingInfo  = (!$item['draft'] && postVar('dosendping') && $item['timestamp'] < $btimestamp);\r
+               if ($iPingInfo && $bPingInfo) {\r
+                       $nextAction = 'sendping';\r
+               } else {\r
+                       $nextAction = 'itemlist';\r
+               }\r
+               if ($result['status'] == 'newcategory') {\r
+                       $distURI = ($nextAction = 'sendping') ? $manager->addTicketToUrl($CONF['AdminURL'] . 'index.php?action='\r
+                                        . $nextAction . '&blogid=' . intval($blogid)) : \r
+                                          '';\r
+                       $this->action_categoryedit($result['catid'], $blogid, $distURI);\r
+               } else {\r
+                       $methodName = 'action_' . $nextAction;\r
+                       call_user_func(array(&$this, $methodName), $blogid);\r
+               }\r
+//</add by shizuki>\r
        }\r
 \r
        /**\r
@@ -1438,17 +1548,12 @@ class ADMIN {
                $rawPingUrl = $manager->addTicketToUrl('index.php?action=rawping&blogid=' . intval($blogid));\r
 \r
                $this->pagehead('<meta http-equiv="refresh" content="1; url='.htmlspecialchars($rawPingUrl).'" />');\r
+               echo _UPDATEDPING_MESSAGE;\r
                ?>\r
-               <h2>Site Updated, Now pinging various weblog listing services...</h2>\r
-\r
-               <p>\r
-                       This can take a while...\r
-               </p>\r
-\r
-               <p>\r
-                       If you aren't automatically passed through, <a href="index.php?action=rawping&amp;blogid=<?php echo $blogid?>">try again</a>\r
+               <a href="index.php?action=rawping&amp;blogid=<?php echo $blogid?>"><?php echo _UPDATEDPING_GOPINGPAGE ?></a>\r
                </p>\r
-               <?php           $this->pagefoot();\r
+               <?php\r
+               $this->pagefoot();\r
        }\r
 \r
        /**\r
@@ -1465,7 +1570,7 @@ class ADMIN {
 \r
                ?>\r
 \r
-               <h2>Pinging services, please wait...</h2>\r
+               <h2><?php echo _UPDATEDPING_PINGING ?></h2>\r
                <div class='note'>\r
                 <?php\r
 \r
@@ -1476,8 +1581,8 @@ class ADMIN {
                 </div>\r
 \r
                <ul>\r
-                       <li><a href="index.php?action=itemlist&amp;blogid=<?php echo $blog->getID()?>">View list of recent items for <?php echo htmlspecialchars($blog->getName())?></a></li>\r
-                       <li><a href="<?php echo $blog->getURL()?>">Visit your own site</a></li>\r
+                       <li><a href="index.php?action=itemlist&amp;blogid=<?php echo $blog->getID()?>"><?php echo _UPDATEDPING_VIEWITEM . htmlspecialchars($blog->getName())?></a></li>\r
+                       <li><a href="<?php echo $blog->getURL()?>"><?php echo _UPDATEDPING_VISITOWNSITE ?></a></li>\r
                </ul>\r
 \r
                <?php           $this->pagefoot();\r
@@ -1529,7 +1634,16 @@ class ADMIN {
                </tr><tr>\r
                        <td><?php echo _EDITC_HOST?></td>\r
                        <td><?php echo  $comment['host']; ?></td>\r
-               </tr><tr>\r
+               </tr>\r
+               <tr>\r
+                       <td><?php echo _EDITC_URL; ?></td>\r
+                       <td><input type="text" name="url" size="30" tabindex="6" value="<?php echo $comment['userid']; ?>" /></td>\r
+               </tr>\r
+               <tr>\r
+                       <td><?php echo _EDITC_EMAIL; ?></td>\r
+                       <td><input type="text" name="email" size="30" tabindex="8" value="<?php echo $comment['email']; ?>" /></td>\r
+               </tr>\r
+               <tr>\r
                        <td><?php echo _EDITC_TEXT?></td>\r
                        <td>\r
                                <textarea name="body" tabindex="10" rows="10" cols="50"><?php                                   // htmlspecialchars not needed (things should be escaped already)\r
@@ -1556,6 +1670,8 @@ class ADMIN {
 \r
                $member->canAlterComment($commentid) or $this->disallow();\r
 \r
+               $url = postVar('url');\r
+               $email = postVar('email');\r
                $body = postVar('body');\r
 \r
                // intercept words that are too long\r
@@ -1576,7 +1692,7 @@ class ADMIN {
                $manager->notify('PreUpdateComment',array('body' => &$body));\r
 \r
                $query =  'UPDATE '.sql_table('comment')\r
-                          . " SET cbody='" .addslashes($body). "'"\r
+                          . " SET cmail = '" . addslashes($url) . "', cemail = '" . addslashes($email) . "', cbody = '" . addslashes($body) . "'"\r
                           . " WHERE cnumber=" . $commentid;\r
                sql_query($query);\r
 \r
@@ -1868,6 +1984,10 @@ class ADMIN {
 \r
                        </td>\r
                </tr>\r
+               <tr>\r
+                       <td><?php echo _MEMBERS_USEAUTOSAVE?> <?php help('autosave'); ?></td>\r
+                       <td><?php $this->input_yesno('autosave', $mem->getAutosave(), 87); ?></td>\r
+               </tr>\r
                <?php\r
                        // plugin options\r
                        $this->_insertPluginOptions('member',$memberid);\r
@@ -1980,6 +2100,8 @@ class ADMIN {
                        $mem->setCanLogin($canlogin);\r
                }\r
 \r
+               $autosave = postVar ('autosave'); \r
+               $mem->setAutosave($autosave);\r
 \r
                $mem->write();\r
 \r
@@ -2350,11 +2472,11 @@ class ADMIN {
 \r
                // check if: - there remains at least one blog admin\r
                //           - (there remains at least one team member)\r
-               $mem = MEMBER::createFromID($memberid);\r
+               $tmem = MEMBER::createFromID($memberid);\r
 \r
-               $manager->notify('PreDeleteTeamMember', array('member' => &$mem, 'blogid' => $blogid));\r
+               $manager->notify('PreDeleteTeamMember', array('member' => &$tmem, 'blogid' => $blogid));\r
 \r
-               if ($mem->isBlogAdmin($blogid)) {\r
+               if ($tmem->isBlogAdmin($blogid)) {\r
                        // check if there are more blog members left and at least one admin\r
                        // (check for at least two admins before deletion)\r
                        $query = 'SELECT * FROM '.sql_table('team') . ' WHERE tblog='.$blogid.' and tadmin=1';\r
@@ -3112,7 +3234,7 @@ class ADMIN {
                        </p>\r
 \r
                        <p>\r
-                       Please note that media files will <b>NOT</b> be deleted. (At least not in this Nucleus version)\r
+                       <?php echo _WARNINGTXT_NOTDELMEDIAFILES ?>\r
                        </p>\r
 \r
                        <form method="post" action="index.php"><div>\r
@@ -3161,9 +3283,11 @@ class ADMIN {
                $manager->notify('PreDeleteMember', array('member' => &$mem));\r
 \r
                /* unlink comments from memberid */\r
-               $query = 'UPDATE ' . sql_table('comment') . ' SET cmember="0", cuser="'. addslashes($mem->getDisplayName())\r
-                                       .'" WHERE cmember='.$memberid;\r
-               sql_query($query);\r
+               if ($memberid) {\r
+                       $query = 'UPDATE ' . sql_table('comment') . ' SET cmember="0", cuser="'. addslashes($mem->getDisplayName())\r
+                                  .'" WHERE cmember='.$memberid;\r
+                       sql_query($query);\r
+               }\r
 \r
                $query = 'DELETE FROM '.sql_table('member').' WHERE mnumber='.$memberid;\r
                sql_query($query);\r
@@ -3197,18 +3321,18 @@ class ADMIN {
                ?>\r
                <h2><?php echo _EBLOG_CREATE_TITLE?></h2>\r
 \r
-               <h3>注意事項</h3>\r
+               <h3><?php echo _ADMIN_NOTABILIA ?></h3>\r
 \r
-               <p>作成にあたって、下記の<strong>注意事項</strong> をまずお読み下さい</p>\r
+               <p><?php echo _ADMIN_PLEASE_READ ?></p>\r
 \r
-               <p>新しいweblogを作成した後に、このblogにアクセスするための方法を紹介しておきます。方法は2つあります:</p>\r
+               <p><?php echo _ADMIN_HOW_TO_ACCESS ?></p>\r
 \r
                <ol>\r
-                       <li><strong>簡単な方法:</strong> <code>index.php</code>の複製を作り、新しいblogを表示するように変更を加えます。 この変更の詳細は、作成後に表示されます。</li>\r
-                       <li><strong>高度な方法:</strong> 現在のblogで使用しているスキンに<code>otherblog</code>というコードを使った記述を加えます。この方法では、同じページ内で複数のblogを展開することが可能となります。</li>\r
+                       <li><?php echo _ADMIN_SIMPLE_WAY ?></li>\r
+                       <li><?php echo _ADMIN_ADVANCED_WAY ?></li>\r
                </ol>\r
 \r
-               <h3>Weblogの作成</h3>\r
+               <h3><?php echo _ADMIN_HOW_TO_CREATE ?></h3>\r
 \r
                <p>\r
                <?php echo _EBLOG_CREATE_TEXT?>\r
@@ -3290,9 +3414,9 @@ class ADMIN {
                $manager->notify(\r
                        'PreAddBlog',\r
                        array(\r
-                               'name' => &$bname,\r
-                               'shortname' => &$bshortname,\r
-                               'timeoffset' => &$btimeoffset,\r
+                               'name'        => &$bname,\r
+                               'shortname'   => &$bshortname,\r
+                               'timeoffset'  => &$btimeoffset,\r
                                'description' => &$bdesc,\r
                                'defaultskin' => &$bdefskin\r
                        )\r
@@ -3300,11 +3424,11 @@ class ADMIN {
 \r
 \r
                // add slashes for sql queries\r
-               $bname =                addslashes($bname);\r
-               $bshortname =   addslashes($bshortname);\r
-               $btimeoffset =  addslashes($btimeoffset);\r
-               $bdesc =                addslashes($bdesc);\r
-               $bdefskin =     addslashes($bdefskin);\r
+               $bname       = addslashes($bname);\r
+               $bshortname  = addslashes($bshortname);\r
+               $btimeoffset = addslashes($btimeoffset);\r
+               $bdesc       = addslashes($bdesc);\r
+               $bdefskin    = addslashes($bdefskin);\r
 \r
                // create blog\r
                $query = 'INSERT INTO '.sql_table('blog')." (bname, bshortname, bdesc, btimeoffset, bdefskin) VALUES ('$bname', '$bshortname', '$bdesc', '$btimeoffset', '$bdefskin')";\r
@@ -3313,7 +3437,7 @@ class ADMIN {
                $blog   =& $manager->getBlog($blogid);\r
 \r
                // create new category\r
-               sql_query('INSERT INTO '.sql_table('category')." (cblog, cname, cdesc) VALUES ($blogid, 'General','Items that do not fit in other categories')");\r
+               sql_query('INSERT INTO '.sql_table('category')." (cblog, cname, cdesc) VALUES ($blogid, _EBLOGDEFAULTCATEGORY_NAME, _EBLOGDEFAULTCATEGORY_DESC)");\r
                $catid = mysql_insert_id();\r
 \r
                // set as default category\r
@@ -3326,7 +3450,7 @@ class ADMIN {
                sql_query($query);\r
 \r
 \r
-               $blog->additem($blog->getDefaultCategory(),'First Item','これはあなたのweblogにおける最初のアイテムです。自由に削除していただいてかまいません。','',$blogid, $memberid,$blog->getCorrectTime(),0,0,0);\r
+               $blog->additem($blog->getDefaultCategory(),_EBLOG_FIRSTITEM_TITLE,_EBLOG_FIRSTITEM_BODY,'',$blogid, $memberid,$blog->getCorrectTime(),0,0,0);\r
 \r
                $manager->notify(\r
                        'PostAddBlog',\r
@@ -3338,27 +3462,27 @@ class ADMIN {
                $manager->notify(\r
                        'PostAddCategory',\r
                        array(\r
-                               'blog' => &$blog,\r
-                               'name' => 'General',\r
-                               'description' => 'Items that do not fit in other categories',\r
-                               'catid' => $catid\r
+                               'blog'        => &$blog,\r
+                               'name'        => _EBLOGDEFAULTCATEGORY_NAME,\r
+                               'description' => _EBLOGDEFAULTCATEGORY_DESC,\r
+                               'catid'       => $catid\r
                        )\r
                );\r
 \r
                $this->pagehead();\r
                ?>\r
-               <h2>新しいweblogが作成されました</h2>\r
+               <h2><?php echo _BLOGCREATED_TITLE ?></h2>\r
 \r
-               <p>新しいweblog 「<?php echo htmlspecialchars($bname)?>」が作成されました。続けて、これにアクセスするために以下のどちらかの手順に進んでください。</p>\r
+               <p><?php echo sprintf(_BLOGCREATED_ADDEDTXT, htmlspecialchars($bname)) ?></p>\r
 \r
                <ol>\r
-                       <li><a href="#index_php">簡単な方法: 下のコードを貼付けた <code><?php echo htmlspecialchars($bshortname)?>.php</code> というファイルを作成する</a></li>\r
-                       <li><a href="#skins">高度な方法: 現在使用しているスキンに新しいweblogを展開させるための記述を加える</a></li>\r
+                       <li><a href="#index_php"><?php sprintf(_BLOGCREATED_SIMPLEWAY, htmlspecialchars($bshortname)) ?></code></a></li>\r
+                       <li><a href="#skins"><?php _BLOGCREATED_ADVANCEDWAY ?></a></li>\r
                </ol>\r
 \r
-               <h3><a id="index_php">方法 1: <code><?php echo htmlspecialchars($bshortname)?>.php</code> というファイルを作成</a></h3>\r
+               <h3><a id="index_php"><?php sprintf(_BLOGCREATED_SIMPLEDESC1, htmlspecialchars($bshortname)) ?></a></h3>\r
 \r
-               <p><code><?php echo htmlspecialchars($bshortname)?>.php</code> というファイルを作成して、中身に以下のコードを貼り付ける:</p>\r
+               <p><?php sprintf(_BLOGCREATED_SIMPLEDESC2, htmlspecialchars($bshortname)) ?></p>\r
 <pre><code>&lt;?php\r
 \r
 $CONF['Self'] = '<b><?php echo htmlspecialchars($bshortname)?>.php</b>';\r
@@ -3370,9 +3494,9 @@ selector();
 \r
 ?&gt;</code></pre>\r
 \r
-               <p>すでにある<code>index.php</code>と同じディレクトリにアップロードします。</p>\r
+               <p><?php echo _BLOGCREATED_SIMPLEDESC3 ?></p>\r
 \r
-               <p>新しいweblogの作成を完了するためには、下にこのファイルのURLを入力してください。 (すでに用意した値で合っているとは思いますが保証はしません):</p>\r
+               <p><?php echo _BLOGCREATED_SIMPLEDESC4 ?></p>\r
 \r
                <form action="index.php" method="post"><div>\r
                        <input type="hidden" name="action" value="addnewlog2" />\r
@@ -3387,9 +3511,9 @@ selector();
                        </tr></table>\r
                </div></form>\r
 \r
-               <h3><a id="skins">方法 2: 現在使用しているスキンに新しいweblogを展開する記述を加える</a></h3>\r
+               <h3><a id="skins"><?php echo _BLOGCREATED_ADVANCEDWAY2 ?></a></h3>\r
 \r
-               <p>新しいweblogの作成を完了するためには、下にURLを入力してください。 (大抵は既存blogと同じURL)</p>\r
+               <p><?php echo _BLOGCREATED_ADVANCEDWAY3 ?></p>\r
 \r
                <form action="index.php" method="post"><div>\r
                        <input type="hidden" name="action" value="addnewlog2" />\r
@@ -3842,36 +3966,51 @@ selector();
 ?>\r
                </tr><tr>\r
                        <th colspan="2"><?php echo _TEMPLATE_CATEGORYLIST?> <?php help('templatecategorylists'); ?></th>\r
-<?php  $this->_templateEditRow($template, _TEMPLATE_CATHEADER, 'CATLIST_HEADER', '', 160);\r
-       $this->_templateEditRow($template, _TEMPLATE_CATITEM, 'CATLIST_LISTITEM', '', 170);\r
-       $this->_templateEditRow($template, _TEMPLATE_CATFOOTER, 'CATLIST_FOOTER', '', 180);\r
+<?php  $this->_templateEditRow($template, _TEMPLATE_CATHEADER, 'CATLIST_HEADER', '', 190);\r
+       $this->_templateEditRow($template, _TEMPLATE_CATITEM, 'CATLIST_LISTITEM', '', 200);\r
+       $this->_templateEditRow($template, _TEMPLATE_CATFOOTER, 'CATLIST_FOOTER', '', 210);\r
 ?>\r
                </tr><tr>\r
                        <th colspan="2"><?php echo _TEMPLATE_DATETIME?></th>\r
-<?php  $this->_templateEditRow($template, _TEMPLATE_DHEADER, 'DATE_HEADER', 'dateheads', 190);\r
-       $this->_templateEditRow($template, _TEMPLATE_DFOOTER, 'DATE_FOOTER', 'dateheads', 200);\r
-       $this->_templateEditRow($template, _TEMPLATE_DFORMAT, 'FORMAT_DATE', 'datetime', 210);\r
-       $this->_templateEditRow($template, _TEMPLATE_TFORMAT, 'FORMAT_TIME', 'datetime', 220);\r
-       $this->_templateEditRow($template, _TEMPLATE_LOCALE, 'LOCALE', 'locale', 230);\r
+<?php  $this->_templateEditRow($template, _TEMPLATE_DHEADER, 'DATE_HEADER', 'dateheads', 220);\r
+       $this->_templateEditRow($template, _TEMPLATE_DFOOTER, 'DATE_FOOTER', 'dateheads', 230);\r
+       $this->_templateEditRow($template, _TEMPLATE_DFORMAT, 'FORMAT_DATE', 'datetime', 240);\r
+       $this->_templateEditRow($template, _TEMPLATE_TFORMAT, 'FORMAT_TIME', 'datetime', 250);\r
+       $this->_templateEditRow($template, _TEMPLATE_LOCALE, 'LOCALE', 'locale', 260);\r
 ?>\r
                </tr><tr>\r
                        <th colspan="2"><?php echo _TEMPLATE_IMAGE?> <?php help('templatepopups'); ?></th>\r
-<?php  $this->_templateEditRow($template, _TEMPLATE_PCODE, 'POPUP_CODE', '', 240);\r
-       $this->_templateEditRow($template, _TEMPLATE_ICODE, 'IMAGE_CODE', '', 250);\r
-       $this->_templateEditRow($template, _TEMPLATE_MCODE, 'MEDIA_CODE', '', 260);\r
+<?php  $this->_templateEditRow($template, _TEMPLATE_PCODE, 'POPUP_CODE', '', 270);\r
+       $this->_templateEditRow($template, _TEMPLATE_ICODE, 'IMAGE_CODE', '', 280);\r
+       $this->_templateEditRow($template, _TEMPLATE_MCODE, 'MEDIA_CODE', '', 290);\r
 ?>\r
                </tr><tr>\r
                        <th colspan="2"><?php echo _TEMPLATE_SEARCH?></th>\r
-<?php  $this->_templateEditRow($template, _TEMPLATE_SHIGHLIGHT, 'SEARCH_HIGHLIGHT', 'highlight',270);\r
-       $this->_templateEditRow($template, _TEMPLATE_SNOTFOUND, 'SEARCH_NOTHINGFOUND', 'nothingfound',280);\r
+<?php  $this->_templateEditRow($template, _TEMPLATE_SHIGHLIGHT, 'SEARCH_HIGHLIGHT', 'highlight',300);\r
+       $this->_templateEditRow($template, _TEMPLATE_SNOTFOUND, 'SEARCH_NOTHINGFOUND', 'nothingfound',310);\r
 ?>\r
                </tr><tr>\r
+                       <th colspan="2"><?php echo _TEMPLATE_PLUGIN_FIELDS?></th>\r
+<?php\r
+               $tab = 600;\r
+               $pluginfields = array();\r
+               $manager->notify('TemplateExtraFields',array('fields'=>&$pluginfields));\r
+\r
+               foreach ($pluginfields as $pfkey=>$pfvalue) {\r
+                       echo "</tr><tr>\n";\r
+                       echo '<th colspan="2">'.htmlentities($pfkey)."</th>\n";\r
+                       foreach ($pfvalue as $pffield=>$pfdesc) {\r
+                               $this->_templateEditRow($template, $pfdesc, $pffield, '',++$tab,0);\r
+                       }\r
+               }\r
+?>                     \r
+               </tr><tr>\r
                        <th colspan="2"><?php echo _TEMPLATE_UPDATE?></th>\r
                </tr><tr>\r
                        <td><?php echo _TEMPLATE_UPDATE?></td>\r
                        <td>\r
-                               <input type="submit" tabindex="290" value="<?php echo _TEMPLATE_UPDATE_BTN?>" onclick="return checkSubmit();" />\r
-                               <input type="reset" tabindex="300" value="<?php echo _TEMPLATE_RESET_BTN?>" />\r
+                               <input type="submit" tabindex="800" value="<?php echo _TEMPLATE_UPDATE_BTN?>" onclick="return checkSubmit();" />\r
+                               <input type="reset" tabindex="810" value="<?php echo _TEMPLATE_RESET_BTN?>" />\r
                        </td>\r
                </tr></table>\r
 \r
@@ -3897,7 +4036,7 @@ selector();
         * @todo document this\r
         */\r
        function action_templateupdate() {\r
-               global $member;\r
+               global $member, $manager;\r
 \r
                $templateid = intRequestVar('templateid');\r
 \r
@@ -3963,6 +4102,13 @@ selector();
                $this->addToTemplate($templateid, 'MEDIA_CODE', postVar('MEDIA_CODE'));\r
                $this->addToTemplate($templateid, 'IMAGE_CODE', postVar('IMAGE_CODE'));\r
 \r
+               $pluginfields = array();\r
+               $manager->notify('TemplateExtraFields',array('fields'=>&$pluginfields));\r
+               foreach ($pluginfields as $pfkey=>$pfvalue) {\r
+                       foreach ($pfvalue as $pffield=>$pfdesc) {\r
+                               $this->addToTemplate($templateid, $pffield, postVar($pffield));\r
+                       }\r
+               }\r
 \r
                // jump back to template edit\r
                $this->action_templateedit(_TEMPLATE_UPDATED);\r
@@ -3983,7 +4129,7 @@ selector();
 \r
                $query = 'INSERT INTO '.sql_table('template')." (tdesc, tpartname, tcontent) "\r
                           . "VALUES ($id, '$partname', '$content')";\r
-               sql_query($query) or die("Query error: " . mysql_error());\r
+               sql_query($query) or exit(_ADMIN_SQLDIE_QUERYERROR . mysql_error());\r
                return mysql_insert_id();\r
        }\r
 \r
@@ -4370,25 +4516,14 @@ selector();
                                echo helplink('skinvar-' . $current) . "$current</a>";\r
                                if (count($actions) != 0) echo ", ";\r
                        }\r
-               ?>\r
-               <br /><br />\r
-               Short blog names:\r
-               <?php                   $query = 'SELECT bshortname, bname FROM '.sql_table('blog');\r
+               echo '<br /><br />' . _SKINEDIT_ALLOWEDBLOGS;\r
+               $query = 'SELECT bshortname, bname FROM '.sql_table('blog');\r
                        showlist($query,'table',array('content'=>'shortblognames'));\r
-               ?>\r
-\r
-               <br />\r
-               Template names:\r
-               <?php                   $query = 'SELECT tdname as name, tddesc as description FROM '.sql_table('template_desc');\r
+               echo '<br />' . _SKINEDIT_ALLOWEDTEMPLATESS;\r
+               $query = 'SELECT tdname as name, tddesc as description FROM '.sql_table('template_desc');\r
                        showlist($query,'table',array('content'=>'shortnames'));\r
-               ?>\r
-\r
-\r
-               </div>\r
-               </form>\r
-\r
-\r
-               <?php           $this->pagefoot();\r
+               echo '</div></form>';\r
+               $this->pagefoot();\r
        }\r
 \r
        /**\r
@@ -4723,7 +4858,7 @@ selector();
                        </td>\r
                        <td><?php $this->input_yesno('DisableSite',$CONF['DisableSite'],10060); ?>\r
                                        <br />\r
-                               URL: <input name="DisableSiteURL" tabindex="10070" size="40" value="<?php echo  htmlspecialchars($CONF['DisableSiteURL'])?>" />\r
+                               <?php echo _SETTINGS_DISABLESITEURL ?> <input name="DisableSiteURL" tabindex="10070" size="40" value="<?php echo  htmlspecialchars($CONF['DisableSiteURL'])?>" />\r
                        </td>\r
                </tr><tr>\r
                        <td><?php echo _SETTINGS_DIRS?></td>\r
@@ -4772,6 +4907,26 @@ selector();
 \r
                                           </td>\r
                </tr><tr>\r
+                       <td><?php echo _SETTINGS_DEBUGVARS?> <?php help('debugvars');?></td>\r
+                                          <td><?php\r
+\r
+                                               $this->input_yesno('DebugVars',$CONF['DebugVars'],10078);\r
+                                               \r
+                                                        ?>\r
+\r
+                                          </td>\r
+               </tr><tr>\r
+                       <td><?php echo _SETTINGS_DEFAULTLISTSIZE?> <?php help('defaultlistsize');?></td>\r
+                       <td>\r
+                       <?php \r
+                               if (!array_key_exists('DefaultListSize',$CONF)) {\r
+                                       sql_query("INSERT INTO ".sql_table('config')." VALUES ('DefaultListSize', '10')");\r
+                                       $CONF['DefaultListSize'] = 10;\r
+                               }\r
+                       ?>\r
+                               <input name="DefaultListSize" tabindex="10079" size="40" value="<?php echo  htmlspecialchars((intval($CONF['DefaultListSize']) < 1 ? '10' : $CONF['DefaultListSize'])) ?>" />\r
+                       </td>\r
+               </tr><tr>\r
                        <th colspan="2"><?php echo _SETTINGS_MEDIA?> <?php help('media'); ?></th>\r
                </tr><tr>\r
                        <td><?php echo _SETTINGS_MEDIADIR?></td>\r
@@ -4936,6 +5091,8 @@ selector();
                $this->updateConfig('CookieSecure',             postVar('CookieSecure'));\r
                $this->updateConfig('URLMode',                  postVar('URLMode'));\r
                $this->updateConfig('CookiePrefix',             postVar('CookiePrefix'));\r
+               $this->updateConfig('DebugVars',                postVar('DebugVars'));\r
+               $this->updateConfig('DefaultListSize',  postVar('DefaultListSize'));\r
 \r
                // load new config and redirect (this way, the new language will be used is necessary)\r
                // note that when changing cookie settings, this redirect might cause the user\r
@@ -4947,6 +5104,143 @@ selector();
        }\r
 \r
        /**\r
+        *  Give an overview over the used system\r
+        */     \r
+       function action_systemoverview() {\r
+               global $member, $nucleus, $CONF;\r
+\r
+               $this->pagehead();\r
+\r
+               echo '<h2>' . _ADMIN_SYSTEMOVERVIEW_HEADING . "</h2>\n";\r
+\r
+               if ($member->isLoggedIn() && $member->isAdmin()) {\r
+\r
+                       // Information about the used PHP and MySQL installation\r
+                       echo '<h3>' . _ADMIN_SYSTEMOVERVIEW_PHPANDMYSQL . "</h3>\n";\r
+\r
+                       // Version of PHP MySQL\r
+                       echo "<table>\n";\r
+                       echo "\t<tr>\n";\r
+                       echo "\t\t" . '<th colspan="2">' . _ADMIN_SYSTEMOVERVIEW_VERSIONS . "</th>\n";\r
+                       echo "\t</tr><tr>\n";\r
+                       echo "\t\t" . '<td width="50%">' . _ADMIN_SYSTEMOVERVIEW_PHPVERSION . "</td>\n";\r
+                       echo "\t\t" . '<td>' . phpversion() . "</td>\n";\r
+                       echo "\t</tr><tr>\n";\r
+                       echo "\t\t" . '<td>' . _ADMIN_SYSTEMOVERVIEW_MYSQLVERSION . "</td>\n";\r
+                       echo "\t\t" . '<td>' . mysql_get_server_info() . ' (' . mysql_get_client_info() . ')' . "</td>\n";\r
+                       echo "\t</tr>";\r
+                       echo "</table>\n";\r
+\r
+                       // Important PHP settings\r
+                       echo "<table>\n";\r
+                       echo "\t<tr>\n";\r
+                       echo "\t\t" . '<th colspan="2">' . _ADMIN_SYSTEMOVERVIEW_SETTINGS . "</th>\n";\r
+                       echo "\t</tr><tr>\n";\r
+                       echo "\t\t" . '<td width="50%">magic_quotes_gpc' . "</td>\n";\r
+                       $mqg = get_magic_quotes_gpc() ? 'On' : 'Off';\r
+                       echo "\t\t" . '<td>' . $mqg . "</td>\n";\r
+                       echo "\t</tr><tr>\n";\r
+                       echo "\t\t" . '<td>magic_quotes_runtime' . "</td>\n";\r
+                       $mqr = get_magic_quotes_runtime() ? 'On' : 'Off';\r
+                       echo "\t\t" . '<td>' . $mqr . "</td>\n";\r
+                       echo "\t</tr><tr>\n";\r
+                       echo "\t\t" . '<td>magic_quotes_runtime' . "</td>\n";\r
+                       $rg = ini_get('register_globals') ? 'On' : 'Off';\r
+                       echo "\t\t" . '<td>' . $rg . "</td>\n";\r
+                       echo "\t</tr>";\r
+                       echo "</table>\n";\r
+\r
+                       // Information about GD library\r
+                       $gdinfo = gd_info();\r
+                       echo "<table>\n";\r
+                       echo "\t<tr>";\r
+                       echo "\t\t" . '<th colspan="2">' . _ADMIN_SYSTEMOVERVIEW_GDLIBRALY . "</th>\n";\r
+                       echo "\t</tr>\n";\r
+                       foreach ($gdinfo as $key=>$value) {\r
+                               if (is_bool($value)) {\r
+                                       $value = $value ? _ADMIN_SYSTEMOVERVIEW_ENABLE : _ADMIN_SYSTEMOVERVIEW_DISABLE;\r
+                               } else {\r
+                                       $value = htmlspecialchars($value, ENT_QUOTES);\r
+                               }\r
+                               echo "\t<tr>";\r
+                               echo "\t\t" . '<td width="50%">' . $key . "</td>\n";\r
+                               echo "\t\t" . '<td>' . $value . "</td>\n";\r
+                               echo "\t</tr>\n";\r
+                       }\r
+                       echo "</table>\n";\r
+\r
+                       // Check if special modules are loaded\r
+                       ob_start();\r
+                       phpinfo(INFO_MODULES);\r
+                       $im = ob_get_contents();\r
+                       ob_clean();\r
+                       echo "<table>\n";\r
+                       echo "\t<tr>";\r
+                       echo "\t\t" . '<th colspan="2">' . _ADMIN_SYSTEMOVERVIEW_MODULES . "</th>\n";\r
+                       echo "\t</tr><tr>\n";\r
+                       echo "\t\t" . '<td width="50%">mod_rewrite' . "</td>\n";\r
+                       $modrewrite = (strstr($im, 'mod_rewrite') != '') ? \r
+                                               _ADMIN_SYSTEMOVERVIEW_ENABLE :\r
+                                               _ADMIN_SYSTEMOVERVIEW_DISABLE;\r
+                       echo "\t\t" . '<td>' . $modrewrite . "</td>\n";\r
+                       echo "\t</tr>\n";\r
+                       echo "</table>\n";\r
+\r
+                       // Information about the used Nucleus CMS \r
+                       echo '<h3>' . _ADMIN_SYSTEMOVERVIEW_NUCLEUSSYSTEM . "</h3>\n";\r
+                       global $nucleus;\r
+                       $nv = getNucleusVersion() / 100 . '(' . $nucleus['version'] . ')';\r
+                       $np = getNucleusPatchLevel();\r
+                       echo "<table>\n";\r
+                       echo "\t<tr>";\r
+                       echo "\t\t" . '<th colspan="2">Nucleus CMS' . "</th>\n";\r
+                       echo "\t</tr><tr>\n";\r
+                       echo "\t\t" . '<td width="50%">' . _ADMIN_SYSTEMOVERVIEW_NUCLEUSVERSION . "</td>\n";\r
+                       echo "\t\t" . '<td>' . $nv . "</td>\n";\r
+                       echo "\t</tr><tr>\n";\r
+                       echo "\t\t" . '<td width="50%">' . _ADMIN_SYSTEMOVERVIEW_NUCLEUSPATCHLEVEL . "</td>\n";\r
+                       echo "\t\t" . '<td>' . $np . "</td>\n";\r
+                       echo "\t</tr>\n";\r
+                       echo "</table>\n";\r
+\r
+                       // Important settings of the installation\r
+                       echo "<table>\n";\r
+                       echo "\t<tr>";\r
+                       echo "\t\t" . '<th colspan="2">' . _ADMIN_SYSTEMOVERVIEW_NUCLEUSSETTINGS . "</th>\n";\r
+                       echo "\t</tr><tr>\n";\r
+                       echo "\t\t" . '<td width="50%">' . '$CONF[' . "'Self']</td>\n";\r
+                       echo "\t\t" . '<td>' . $CONF['Self'] . "</td>\n";\r
+                       echo "\t</tr><tr>\n";\r
+                       echo "\t\t" . '<td width="50%">' . '$CONF[' . "'alertOnHeadersSent']</td>\n";\r
+                       $ohs = $CONF['alertOnHeadersSent'] ?\r
+                                               _ADMIN_SYSTEMOVERVIEW_ENABLE :\r
+                                               _ADMIN_SYSTEMOVERVIEW_DISABLE;\r
+                       echo "\t\t" . '<td>' . $ohs . "</td>\n";\r
+                       echo "\t</tr>\n";\r
+                       echo "</table>\n";\r
+\r
+                       // Link to the online version test at the Nucleus CMS website\r
+                       echo '<h3>' . _ADMIN_SYSTEMOVERVIEW_VERSIONCHECK . "</h3>\n";\r
+                       if ($nucleus['codename'] != '') {\r
+                               $codenamestring = ' &quot;' . $nucleus['codename'] . '&quot;';\r
+                       } else {\r
+                               $codenamestring = '';\r
+                       }\r
+                       echo _ADMIN_SYSTEMOVERVIEW_VERSIONCHECK_TXT;\r
+                       $checkURL = sprintf(_ADMIN_SYSTEMOVERVIEW_VERSIONCHECK_URL, getNucleusVersion(), getNucleusPatchLevel());\r
+                       echo '<a href="' . $checkURL . '" title="' . _ADMIN_SYSTEMOVERVIEW_VERSIONCHECK_TITLE . '">';\r
+                       echo 'Nucleus CMS ' . $nv . $codenamestring;\r
+                       echo '</a>';\r
+               //echo '<br />';\r
+               }\r
+               else {\r
+                       echo _ADMIN_SYSTEMOVERVIEW_NOT_ADMIN;\r
+               }\r
+               \r
+               $this->pagefoot();\r
+       }\r
+\r
+       /**\r
         * @todo document this\r
         */\r
        function updateConfig($name, $val) {\r
@@ -5003,7 +5297,7 @@ selector();
 \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
+               <html <?php echo _HTML_XML_NAME_SPACE_AND_LANG_CODE; ?>>\r
                <head>\r
                        <meta http-equiv="Content-Type" content="text/html; charset=<?php echo _CHARSET ?>" />\r
                        <title><?php echo htmlspecialchars($CONF['SiteName'])?> - Admin</title>\r
@@ -5039,17 +5333,12 @@ selector();
 \r
                        echo '<br />(';\r
 \r
-                       // Note(JP): disabled code name description\r
-/*\r
-                       if ($member->isLoggedIn() && $member->isAdmin())\r
-                               echo '<a href="http://nucleuscms.org/version.php?v=',getNucleusVersion(),'&amp;pl=',getNucleusPatchLevel(),'" title="Check for upgrade">Nucleus CMS ', $nucleus['version'], ' &quot;', $nucleus['codename'], '&quot;</a>';\r
-                       else\r
-                               echo 'Nucleus CMS ', $nucleus['version'], ' &quot;', $nucleus['codename'], '&quot;';\r
-*/\r
+                       $codenamestring = ($nucleus['codename']!='')? ' &quot;'.$nucleus['codename'].'&quot;':'';\r
+\r
                        if ($member->isLoggedIn() && $member->isAdmin())\r
-                               echo '<a href="http://nucleuscms.org/version.php?v=',getNucleusVersion(),'&amp;pl=',getNucleusPatchLevel(),'" title="Check for upgrade">Nucleus CMS ', $nucleus['version'], </a>';\r
+                               echo '<a href="http://nucleuscms.org/version.php?v=',getNucleusVersion(),'&amp;pl=',getNucleusPatchLevel(),'" title="Check for upgrade">Nucleus CMS ', $nucleus['version'], $codenamestring, '</a>';\r
                        else\r
-                               echo 'Nucleus CMS ', $nucleus['version'];\r
+                               echo 'Nucleus CMS ', $nucleus['version'], $codenamestring;\r
                        echo ')';\r
                echo '</div>';\r
        }\r
@@ -5077,9 +5366,9 @@ selector();
                        <?php           }\r
                ?>\r
                        <div class="foot">\r
-                               <a href="http://nucleuscms.org/">Nucleus CMS</a> &copy; 2002-<?php echo date('Y'); ?> The Nucleus Group\r
+                               <a href="<?php echo _ADMINPAGEFOOT_OFFICIALURL ?>">Nucleus CMS</a> &copy; 2002-<?php echo date('Y') . ' ' . _ADMINPAGEFOOT_COPYRIGHT; ?>\r
                                -\r
-                               <a href="http://nucleuscms.org/donate.php">Donate!</a>\r
+                               <a href="<?php echo _ADMINPAGEFOOT_DONATEURL ?>"><?php echo _ADMINPAGEFOOT_DONATE ?></a>\r
                        </div>\r
 \r
                        </div><!-- content -->\r
@@ -5121,9 +5410,9 @@ selector();
 \r
                                        echo '<h2>' . $member->getDisplayName(). '</h2>';\r
                                        echo '<ul>';\r
-                                       echo '<li><a href="index.php?action=editmembersettings">',_QMENU_USER_SETTINGS,'</a></li>';\r
-                                       echo '<li><a href="index.php?action=browseownitems">',_QMENU_USER_ITEMS,'</a></li>';\r
-                                       echo '<li><a href="index.php?action=browseowncomments">',_QMENU_USER_COMMENTS,'</a></li>';\r
+                                       echo '<li><a href="index.php?action=editmembersettings">' . _QMENU_USER_SETTINGS . '</a></li>';\r
+                                       echo '<li><a href="index.php?action=browseownitems">' . _QMENU_USER_ITEMS . '</a></li>';\r
+                                       echo '<li><a href="index.php?action=browseowncomments">' . _QMENU_USER_COMMENTS . '</a></li>';\r
                                        echo '</ul>';\r
 \r
 \r
@@ -5135,19 +5424,20 @@ selector();
                                                echo '<h2>',_QMENU_MANAGE,'</h2>';\r
 \r
                                                echo '<ul>';\r
-                                               echo '<li><a href="index.php?action=actionlog">',_QMENU_MANAGE_LOG,'</a></li>';\r
-                                               echo '<li><a href="index.php?action=settingsedit">',_QMENU_MANAGE_SETTINGS,'</a></li>';\r
-                                               echo '<li><a href="index.php?action=usermanagement">',_QMENU_MANAGE_MEMBERS,'</a></li>';\r
-                                               echo '<li><a href="index.php?action=createnewlog">',_QMENU_MANAGE_NEWBLOG,'</a></li>';\r
-                                               echo '<li><a href="index.php?action=backupoverview">',_QMENU_MANAGE_BACKUPS,'</a></li>';\r
-                                               echo '<li><a href="index.php?action=pluginlist">',_QMENU_MANAGE_PLUGINS,'</a></li>';\r
+                                               echo '<li><a href="index.php?action=actionlog">' . _QMENU_MANAGE_LOG . '</a></li>';\r
+                                               echo '<li><a href="index.php?action=settingsedit">' . _QMENU_MANAGE_SETTINGS . '</a></li>';\r
+                                               echo '<li><a href="index.php?action=usermanagement">' . _QMENU_MANAGE_MEMBERS . '</a></li>';\r
+                                               echo '<li><a href="index.php?action=createnewlog">' . _QMENU_MANAGE_NEWBLOG . '</a></li>';\r
+                                               echo '<li><a href="index.php?action=backupoverview">' . _QMENU_MANAGE_BACKUPS . '</a></li>';\r
+                                               echo '<li><a href="index.php?action=pluginlist">' . _QMENU_MANAGE_PLUGINS . '</a></li>';\r
+                                               echo '<li><a href="index.php?action=systemoverview">' . _QMENU_MANAGE_SYSTEM . '</a></li>';\r
                                                echo '</ul>';\r
 \r
                                                echo '<h2>',_QMENU_LAYOUT,'</h2>';\r
                                                echo '<ul>';\r
-                                               echo '<li><a href="index.php?action=skinoverview">',_QMENU_LAYOUT_SKINS,'</a></li>';\r
-                                               echo '<li><a href="index.php?action=templateoverview">',_QMENU_LAYOUT_TEMPL,'</a></li>';\r
-                                               echo '<li><a href="index.php?action=skinieoverview">',_QMENU_LAYOUT_IEXPORT,'</a></li>';\r
+                                               echo '<li><a href="index.php?action=skinoverview">' . _QMENU_LAYOUT_SKINS . '</a></li>';\r
+                                               echo '<li><a href="index.php?action=templateoverview">' . _QMENU_LAYOUT_TEMPL . '</a></li>';\r
+                                               echo '<li><a href="index.php?action=skinieoverview">' . _QMENU_LAYOUT_IEXPORT . '</a></li>';\r
                                                echo '</ul>';\r
 \r
                                        }\r
@@ -5201,7 +5491,7 @@ selector();
                // header-code stolen from phpMyAdmin\r
                // REGEDIT and bookmarklet code stolen from GreyMatter\r
 \r
-               $sjisBlogName = getBlogNameFromID($blogid);\r
+               $sjisBlogName = sprintf(_WINREGFILE_TEXT, getBlogNameFromID($blogid));\r
                $sjisBlogName = mb_convert_encoding($sjisBlogName, "SJIS", "auto");\r
 \r
                header('Content-Type: application/octetstream');\r
@@ -5210,7 +5500,7 @@ selector();
                header('Expires: 0');\r
 \r
                echo "REGEDIT4\n";\r
-               echo "[HKEY_CURRENT_USER\\Software\\Microsoft\\Internet Explorer\\MenuExt\\Post To &Nucleus (".$sjisBlogName.")]\n";\r
+               echo "[HKEY_CURRENT_USER\\Software\\Microsoft\\Internet Explorer\\MenuExt\\" . $sjisBlogName . "]\n";\r
                echo '@="' . $CONF['AdminURL'] . "bookmarklet.php?action=contextmenucode&blogid=".intval($blogid)."\"\n";\r
                echo '"contexts"=hex:31';\r
        }\r
@@ -5234,48 +5524,48 @@ selector();
 \r
                ?>\r
 \r
-               <h2>Bookmarklet<!-- and Right Click Menu --></h2>\r
+               <h2><?php echo _BOOKMARKLET_TITLE ?></h2>\r
 \r
                <p>\r
-               Bookmarklet とは、クリック1回で記事の投稿ができるシステムです。 この Bookmarklet をインストールすると、ブラウザのツールバーの'add to weblog'ボタンが利用可能となり、Nucleusの新規アイテムの追加ウィンドウがポップアップします。任意のWebページを開いた状態でこのボタンを押せば、そのWebページのタイトルと、そのページへのリンクタグがすでに埋め込まれた状態でアイテム追加ウィンドウが開き、さらに、そのページ内に引用したい文を選択した状態であればその引用文も自動的に引用します。\r
+               <?php echo _BOOKMARKLET_DESC1 . _BOOKMARKLET_DESC2 . _BOOKMARKLET_DESC3 . _BOOKMARKLET_DESC4 . _BOOKMARKLET_DESC5 ?>\r
                </p>\r
 \r
-               <h3>Bookmarklet</h3>\r
+               <h3><?php echo _BOOKMARKLET_BOOKARKLET ?></h3>\r
                <p>\r
-                       下のリンク部分を「お気に入り」もしくはツールバーにドラッグできます。<small>(その前にテストしてみたい場合は単純に下のリンクをクリックしてみてください)</small>\r
+                       <?php echo _BOOKMARKLET_BMARKTEXT ?><small><?php echo _BOOKMARKLET_BMARKTEST ?></small>\r
                        <br />\r
                        <br />\r
-                       <a href="<?php echo htmlspecialchars($bm)?>">Add to <?php echo $blog->getShortName()?></a> (ほとんどのブラウザで動作します)\r
+                       <?php echo '<a href="' . htmlspecialchars($bm, ENT_QUOTES) . '">' . sprintf(_BOOKMARKLET_ANCHOR, htmlspecialchars($blog->getName(), ENT_QUOTES)) . '</a>' . _BOOKMARKLET_BMARKFOLLOW; ?>\r
                </p>\r
 \r
-               <h3>右クリックメニューにインストール (WindowsでIE使用時)</h3>\r
+               <h3><?php echo _BOOKMARKLET_RIGHTCLICK ?></h3>\r
                <p>\r
                        <?php\r
                                $url = 'index.php?action=regfile&blogid=' . intval($blogid);\r
                                $url = $manager->addTicketToUrl($url);\r
                        ?>\r
-                       あるいは<a href="<?php echo htmlspecialchars($url) ?>">右クリックメニュー</a>にインストールすることもできます (「開く」を選択すれば直接レジストリに登録します)\r
+                       <?php echo _BOOKMARKLET_RIGHTTEXT1 . '<a href="' . htmlspecialchars($url, ENT_QUOTES, "SJIS") . '">' . _BOOKMARKLET_RIGHTLABEL . '</a>' . _BOOKMARKLET_RIGHTTEXT2; ?>\r
                </p>\r
 \r
                <p>\r
-                       このインストールした右クリックメニューを表示するためにはIEの再起動が必要です。\r
+                       <?php echo _BOOKMARKLET_RIGHTTEXT3 ?>\r
                </p>\r
 \r
-               <h3>アンインストール</h3>\r
+               <h3><?php echo _BOOKMARKLET_UNINSTALLTT ?></h3>\r
                <p>\r
-                       「お気に入り」もしくはツールバーから消すには、単に削除するだけです。\r
+                       <?php echo _BOOKMARKLET_DELETEBAR ?>\r
                </p>\r
-               \r
+\r
                <p>\r
-                       右クリックメニューから消したい時は、以下の手順を踏んでください:\r
+                       <?php echo _BOOKMARKLET_DELETERIGHTT ?>\r
                </p>\r
 \r
                <ol>\r
-                       <li>スタートメニューから「ファイルを指定して実行...」を選択</li>\r
-                       <li>"regedit" と入力</li>\r
-                       <li>"OK" ボタンを押す</li>\r
-                       <li>"\HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\MenuExt" をツリーの中から検索</li>\r
-                       <li>"add to weblog" エントリを削除</li>                          \r
+                       <li><?php echo _BOOKMARKLET_DELETERIGHT1 ?></li>\r
+                       <li><?php echo _BOOKMARKLET_DELETERIGHT2 ?></li>\r
+                       <li><?php echo _BOOKMARKLET_DELETERIGHT3 ?></li>\r
+                       <li><?php echo _BOOKMARKLET_DELETERIGHT4 ?></li>\r
+                       <li><?php echo _BOOKMARKLET_DELETERIGHT5 ?></li>\r
                </ol>\r
 \r
                <?php\r
@@ -5356,6 +5646,7 @@ selector();
                $member->blogAdminRights($blogid) or $this->disallow();\r
 \r
                $blog =& $manager->getBlog($blogid);\r
+               $banBlogName =  htmlspecialchars($blog->getName(), ENT_QUOTES);\r
 \r
                $this->pagehead();\r
                ?>\r
@@ -5374,7 +5665,8 @@ selector();
 \r
                        <div>\r
                                <input type="hidden" name="blogid" value="<?php echo $blogid?>" />\r
-                               <input name="allblogs" type="radio" value="0" id="allblogs_one" /><label for="allblogs_one">Only blog '<?php echo htmlspecialchars($blog->getName())?>'</label>\r
+                               <input name="allblogs" type="radio" value="0" id="allblogs_one" />\r
+                               <label for="allblogs_one"><?php echo sprintf(_BAN_BANBLOGNAME, $banBlogName) ?></label>\r
                                <br />\r
                                <input name="allblogs" type="radio" value="1" checked="checked" id="allblogs_all" /><label for="allblogs_all"><?php echo _BAN_ALLBLOGS?></label>\r
                        </div>\r
@@ -5472,16 +5764,23 @@ selector();
                <p><?php echo _BAN_IPRANGE_TEXT?></p>\r
 \r
                <div class="note">\r
-               <b>An example</b>: "134.58.253.193" will only block one computer, while "134.58.253" will block 256 IP addresses, including the one from the first example.\r
+                       <strong><?php echo _BAN_EXAMPLE_TITLE ?></strong>\r
+                       <?php echo _BAN_EXAMPLE_TEXT ?>\r
                </div>\r
 \r
                <div>\r
-               <?php                   if ($ip) {\r
+               <?php\r
+               if ($ip) {\r
+                       $iprangeVal = htmlspecialchars($ip, ENT_QUOTES);\r
                ?>\r
-                       <input name="iprange" type="radio" value="<?php echo htmlspecialchars($ip)?>" checked="checked" id="ip_fixed" /><label for="ip_fixed"><?php echo htmlspecialchars($ip)?></label>\r
+                       <input name="iprange" type="radio" value="<?php echo $iprangeVal ?>" checked="checked" id="ip_fixed" />\r
+                       <label for="ip_fixed"><?php echo $iprangeVal ?></label>\r
                        <br />\r
-                       <input name="iprange" type="radio" value="custom" id="ip_custom" /><label for="ip_custom">Custom: </label><input name='customiprange' value='<?php echo htmlspecialchars($ip)?>' maxlength='15' size='15' />\r
-               <?php   } else {\r
+                       <input name="iprange" type="radio" value="custom" id="ip_custom" />\r
+                       <label for="ip_custom"><?php echo _BAN_IP_CUSTOM ?></label>\r
+                       <input name='customiprange' value='<?php echo $iprangeVal ?>' maxlength='15' size='15' />\r
+               <?php\r
+               } else {\r
                                echo "<input name='iprange' value='custom' type='hidden' />";\r
                                echo "<input name='customiprange' value='' maxlength='15' size='15' />";\r
                        }\r
@@ -5636,7 +5935,8 @@ selector();
                // (creating/restoring dumps might take a while)\r
                @set_time_limit(1200);\r
 \r
-               do_backup($useGzip);\r
+               $bu = new Backup();\r
+               $bu->do_backup($useGzip);\r
                exit;\r
        }\r
 \r
@@ -5657,7 +5957,8 @@ selector();
                // (creating/restoring dumps might take a while)\r
                @set_time_limit(1200);\r
 \r
-               $message = do_restore();\r
+               $bu = new Backup();\r
+               $message = $bu->do_restore();\r
                if ($message != '')\r
                        $this->error($message);\r
 \r
@@ -5858,7 +6159,7 @@ selector();
                                // uninstall plugin again...\r
                                $this->deleteOnePlugin($plugin->getID());\r
 \r
-                               $this->error(_ERROR_INSREQPLUGIN . htmlspecialchars($pluginName));\r
+                               $this->error(sprintf(_ERROR_INSREQPLUGIN, htmlspecialchars($pluginName, ENT_QUOTES)));\r
                        }\r
                }\r
 \r
@@ -5901,7 +6202,8 @@ selector();
                        }\r
                }\r
 \r
-               $this->action_pluginlist();\r
+               redirect('?action=pluginlist');\r
+//             $this->action_pluginlist();\r
        }\r
 \r
        /**\r
@@ -5949,7 +6251,8 @@ selector();
                        $this->error($error);\r
                }\r
 \r
-               $this->action_pluginlist();\r
+               redirect('?action=pluginlist');\r
+//             $this->action_pluginlist();\r
        }\r
 \r
        /**\r
@@ -5965,11 +6268,11 @@ selector();
 \r
                $name = quickQuery('SELECT pfile as result FROM '.sql_table('plugin').' WHERE pid='.$pid);\r
 \r
-               // call the unInstall method of the plugin\r
+/*             // call the unInstall method of the plugin\r
                if ($callUninstall) {\r
                        $plugin =& $manager->getPlugin($name);\r
                        if ($plugin) $plugin->unInstall();\r
-               }\r
+               }*/\r
 \r
                // check dependency before delete\r
                $res = sql_query('SELECT pfile FROM '.sql_table('plugin'));\r
@@ -5982,7 +6285,7 @@ selector();
                                {\r
                                        if ($name == $depName)\r
                                        {\r
-                                               return _ERROR_DELREQPLUGIN . $o->pfile;\r
+                                               return sprintf(_ERROR_DELREQPLUGIN, $o->pfile);\r
                                        }\r
                                }\r
                        }\r
@@ -5990,6 +6293,12 @@ selector();
 \r
                $manager->notify('PreDeletePlugin', array('plugid' => $pid));\r
 \r
+               // call the unInstall method of the plugin\r
+               if ($callUninstall) {\r
+                       $plugin =& $manager->getPlugin($name);\r
+                       if ($plugin) $plugin->unInstall();\r
+               }\r
+\r
                // delete all subscriptions\r
                sql_query('DELETE FROM '.sql_table('plugin_event').' WHERE pid=' . $pid);\r
 \r
@@ -6098,12 +6407,13 @@ selector();
                        $this->error(_ERROR_NOSUCHPLUGIN);\r
 \r
                $extrahead = '<script type="text/javascript" src="javascript/numbercheck.js"></script>';\r
+               $pluginName = htmlspecialchars(getPluginNameFromPid($pid), ENT_QUOTES);\r
                $this->pagehead($extrahead);\r
 \r
                ?>\r
                        <p><a href="index.php?action=pluginlist">(<?php echo _PLUGS_BACK?>)</a></p>\r
 \r
-                       <h2>Options for <?php echo htmlspecialchars(getPluginNameFromPid($pid))?></h2>\r
+                       <h2><?php echo sprintf(_PLUGIN_OPTIONS_TITLE, $pluginName) ?></h2>\r
 \r
                        <?php if  ($message) echo $message?>\r
 \r
@@ -6229,9 +6539,12 @@ selector();
                                echo '<tr><th colspan="2">Options for ', htmlspecialchars($aOption['pfile']),'</th></tr>';\r
                        }\r
 \r
-                       echo '<tr>';\r
-                       listplug_plugOptionRow($aOption);\r
-                       echo '</tr>';\r
+                       $meta = NucleusPlugin::getOptionMeta($current['typeinfo']);\r
+                       if (@$meta['access'] != 'hidden') {\r
+                               echo '<tr>';\r
+                               listplug_plugOptionRow($aOption);\r
+                               echo '</tr>';\r
+                       }\r
 \r
                }\r
 \r
@@ -6267,10 +6580,10 @@ selector();
                        if ($checkedval != $value1)\r
                                echo "tabindex='$tabindex' checked='checked'";\r
                        if ($isAdmin && $name=="canlogin")\r
-                               echo " disabled='true'";\r
+                               echo ' disabled="disabled"';\r
                        echo ' id="'.$id2.'" /><label for="'.$id2.'">' . $noval . '</label>';\r
        }\r
 \r
 } // class ADMIN\r
 \r
-?>\r
+?>
\ No newline at end of file
index d1c05c1..2129aff 100755 (executable)
@@ -1,7 +1,7 @@
 <?php
 /*
  * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/)
- * Copyright (C) 2002-2007 The Nucleus Group
+ * Copyright (C) 2002-2009 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
@@ -13,8 +13,8 @@
  * PHP class responsible for ban-management.
  *
  * @license http://nucleuscms.org/license.txt GNU General Public License
- * @copyright Copyright (C) 2002-2007 The Nucleus Group
- * @version $Id: BAN.php,v 1.7 2007-02-04 06:28:46 kimitake Exp $
+ * @copyright Copyright (C) 2002-2009 The Nucleus Group
+ * @version $Id$
  * $NucleusJP: BAN.php,v 1.6 2006/07/20 08:01:52 kimitake Exp $
  */
 
index 3b09f93..b9508d1 100755 (executable)
@@ -2,7 +2,7 @@
 
 /*
  * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/)
- * Copyright (C) 2002-2007 The Nucleus Group
+ * Copyright (C) 2002-2009 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
  * on the screen
  *
  * @license http://nucleuscms.org/license.txt GNU General Public License
- * @copyright Copyright (C) 2002-2007 The Nucleus Group
- * @version $Id: BLOG.php,v 1.15 2008-02-08 09:31:22 kimitake Exp $
+ * @copyright Copyright (C) 2002-2009 The Nucleus Group
+ * @version $Id$
  * $NucleusJP: BLOG.php,v 1.12.2.2 2007/08/08 05:26:22 kimitake Exp $
  */
 
-if ( !function_exists('requestVar') ) exit;
-require_once dirname(__FILE__) . '/ITEMACTIONS.php';
-
-class BLOG {
-
-       // blog id
-       var $blogid;
-
-       // ID of currently selected category
-       var $selectedcatid;
-
-       // After creating an object of the blog class, contains true if the BLOG object is
-       // valid (the blog exists)
-       var $isValid;
-
-       // associative array, containing all blogsettings (use the get/set functions instead)
-       var $settings;
-
-       /**
-        * Creates a new BLOG object for the given blog
-        *
-        * @param $id blogid
-        */
-       function BLOG($id) {
-               $this->blogid = intval($id);
-               $this->readSettings();
-
-               // try to set catid
-               // (the parse functions in SKIN.php will override this, so it's mainly useless)
-               global $catid;
-               $this->setSelectedCategory($catid);
-       }
-
-       /**
-        * Shows the given amount of items for this blog
-        *
-        * @param $template
-        *              String representing the template _NAME_ (!)
-        * @param $amountEntries
-        *              amount of entries to show
-        * @param $startpos
-        *              offset from where items should be shown (e.g. 5 = start at fifth item)
-        * @returns int
-        *              amount of items shown
-        */
-       function readLog($template, $amountEntries, $offset = 0, $startpos = 0) {
-               return $this->readLogAmount($template,$amountEntries,'','',1,1,$offset, $startpos);
-       }
-
-       /**
-        * Shows an archive for a given month
-        *
-        * @param $year
-        *              year
-        * @param $month
-        *              month
-        * @param $template
-        *              String representing the template name to be used
-        */
-       function showArchive($templatename, $year, $month, $day=0) {
-
-               // create extra where clause for select query
-               if ($day == 0) {
-                       $timestamp_start = mktime(0,0,0,$month,1,$year);
-                       $timestamp_end = mktime(0,0,0,$month+1,1,$year);  // also works when $month==12
-               } else {
-                       $timestamp_start = mktime(0,0,0,$month,$day,$year);
-                       $timestamp_end = mktime(0,0,0,$month,$day+1,$year);
-               }
-               $extra_query = ' and i.itime>=' . mysqldate($timestamp_start)
-                                        . ' and i.itime<' . mysqldate($timestamp_end);
-
-
-               $this->readLogAmount($templatename,0,$extra_query,'',1,1);
-
-       }
-
-
-       // sets/gets current category (only when category exists)
-       function setSelectedCategory($catid) {
-               if ($this->isValidCategory($catid) || (intval($catid) == 0))
-                       $this->selectedcatid = intval($catid);
-       }
-
-       function setSelectedCategoryByName($catname) {
-               $this->setSelectedCategory($this->getCategoryIdFromName($catname));
-       }
-
-       function getSelectedCategory() {
-               return $this->selectedcatid;
-       }
-
-       /**
-        * Shows the given amount of items for this blog
-        *
-        * @param $template
-        *              String representing the template _NAME_ (!)
-        * @param $amountEntries
-        *              amount of entries to show (0 = no limit)
-        * @param $extraQuery
-        *              extra conditions to be added to the query
-        * @param $highlight
-        *              contains a query that should be highlighted
-        * @param $comments
-        *              1=show comments 0=don't show comments
-        * @param $dateheads
-        *              1=show dateheads 0=don't show dateheads
-        * @param $offset
-        *              offset
-        * @returns int
-        *              amount of items shown
-        */
-       function readLogAmount($template, $amountEntries, $extraQuery, $highlight, $comments, $dateheads, $offset = 0, $startpos = 0) {
-
-               $query = $this->getSqlBlog($extraQuery);
-
-               if ($amountEntries > 0) {
-                               // $offset zou moeten worden:
-                               // (($startpos / $amountentries) + 1) * $offset ... later testen ...
-                          $query .= ' LIMIT ' . intval($startpos + $offset).',' . intval($amountEntries);
-               }
-               return $this->showUsingQuery($template, $query, $highlight, $comments, $dateheads);
-       }
-
-       function showUsingQuery($templateName, $query, $highlight = '', $comments = 0, $dateheads = 1) {
-               global $CONF, $manager;
-
-               $lastVisit = cookieVar($CONF['CookiePrefix'] .'lastVisit');
-               if ($lastVisit != 0)
-                       $lastVisit = $this->getCorrectTime($lastVisit);
-
-               // set templatename as global variable (so plugins can access it)
-               global $currentTemplateName;
-               $currentTemplateName = $templateName;
-
-               $template =& $manager->getTemplate($templateName);
-
-               // create parser object & action handler
-               $actions =& new ITEMACTIONS($this);
-               $parser =& new PARSER($actions->getDefinedActions(),$actions);
-               $actions->setTemplate($template);
-               $actions->setHighlight($highlight);
-               $actions->setLastVisit($lastVisit);
-               $actions->setParser($parser);
-               $actions->setShowComments($comments);
-
-               // execute query
-               $items = sql_query($query);
-
-               // loop over all items
-               $old_date = 0;
-               while ($item = mysql_fetch_object($items)) {
-
-                       $item->timestamp = strtotime($item->itime);     // string timestamp -> unix timestamp
-
-                       // action handler needs to know the item we're handling
-                       $actions->setCurrentItem($item);
-
-                       // add date header if needed
-                       if ($dateheads) {
-                               $new_date = date('dFY',$item->timestamp);
-                               if ($new_date != $old_date) {
-                                       // unless this is the first time, write date footer
-                                       $timestamp = $item->timestamp;
-                                       if ($old_date != 0) {
-                                               $oldTS = strtotime($old_date);
-                                               $manager->notify('PreDateFoot',array('blog' => &$this, 'timestamp' => $oldTS));
-                                               $tmp_footer = strftime($template['DATE_FOOTER'], $oldTS);
-                                               $parser->parse($tmp_footer);
-                                               $manager->notify('PostDateFoot',array('blog' => &$this, 'timestamp' => $oldTS));
-                                       }
-                                       $manager->notify('PreDateHead',array('blog' => &$this, 'timestamp' => $timestamp));
-                                       // note, to use templatvars in the dateheader, the %-characters need to be doubled in
-                                       // order to be preserved by strftime
-                                       $tmp_header = strftime((isset($template['DATE_HEADER']) ? $template['DATE_HEADER'] : null), $timestamp);
-                                       $parser->parse($tmp_header);
-                                       $manager->notify('PostDateHead',array('blog' => &$this, 'timestamp' => $timestamp));
-                               }
-                               $old_date = $new_date;
-                       }
-
-                       // parse item
-                       $parser->parse($template['ITEM_HEADER']);
-                       $manager->notify('PreItem', array('blog' => &$this, 'item' => &$item));
-                       $parser->parse($template['ITEM']);
-                       $manager->notify('PostItem', array('blog' => &$this, 'item' => &$item));
-                       $parser->parse($template['ITEM_FOOTER']);
-
-               }
-
-               $numrows = mysql_num_rows($items);
-
-               // add another date footer if there was at least one item
-               if (($numrows > 0) && $dateheads) {
-                       $manager->notify('PreDateFoot',array('blog' => &$this, 'timestamp' => strtotime($old_date)));
-                       $parser->parse($template['DATE_FOOTER']);
-                       $manager->notify('PostDateFoot',array('blog' => &$this, 'timestamp' => strtotime($old_date)));
-               }
-
-               mysql_free_result($items);      // free memory
-
-               return $numrows;
-
-       }
-
-       function showOneitem($itemid, $template, $highlight) {
-               $extraQuery = ' and inumber=' . intval($itemid);
-
-               return $this->readLogAmount($template, 1, $extraQuery, $highlight, 0, 0);
-       }
-
-
-       /**
-         * Adds an item to this blog
-         */
-       function additem($catid, $title, $body, $more, $blogid, $authorid, $timestamp, $closed, $draft, $posted='1') {
-               global $manager;
-
-               $blogid         = intval($blogid);
-               $authorid       = intval($authorid);
-               $title          = $title;
-               $body           = $body;
-               $more           = $more;
-               $catid          = intval($catid);
-
-               // convert newlines to <br />
-               if ($this->convertBreaks()) {
-                       $body = addBreaks($body);
-                       $more = addBreaks($more);
-               }
-
-               if ($closed != '1') $closed = '0';
-               if ($draft != '0') $draft = '1';
-
-               if (!$this->isValidCategory($catid))
-                       $catid = $this->getDefaultCategory();
-
-               if ($timestamp > $this->getCorrectTime())
-                       $isFuture = 1;
-
-               $timestamp = date('Y-m-d H:i:s',$timestamp);
-
-               $manager->notify('PreAddItem',array('title' => &$title, 'body' => &$body, 'more' => &$more, 'blog' => &$this, 'authorid' => &$authorid, 'timestamp' => &$timestamp, 'closed' => &$closed, 'draft' => &$draft, 'catid' => &$catid));
-
-               $title = addslashes($title);
-               $body = addslashes($body);
-               $more = addslashes($more);
-
-               $query = 'INSERT INTO '.sql_table('item').' (ITITLE, IBODY, IMORE, IBLOG, IAUTHOR, ITIME, ICLOSED, IDRAFT, ICAT, IPOSTED) '
-                          . "VALUES ('$title', '$body', '$more', $blogid, $authorid, '$timestamp', $closed, $draft, $catid, $posted)";
-               sql_query($query);
-               $itemid = mysql_insert_id();
-
-               $manager->notify('PostAddItem',array('itemid' => $itemid));
-
-               if (!$draft)
-                       $this->updateUpdateFile();
-
-               // send notification mail
-               if (!$draft && !$isFuture && $this->getNotifyAddress() && $this->notifyOnNewItem())
-                       $this->sendNewItemNotification($itemid, stripslashes($title), stripslashes($body));
-
-               return $itemid;
-       }
-
-       function sendNewItemNotification($itemid, $title, $body) {
-               global $CONF, $member;
-
-               // create text version of html post
-               $ascii = toAscii($body);
-
-               $mailto_msg = _NOTIFY_NI_MSG . " \n";
-//             $mailto_msg .= $CONF['IndexURL'] . 'index.php?itemid=' . $itemid . "\n\n";
-               $temp = parse_url($CONF['Self']);
-               if ($temp['scheme']) {
-                       $mailto_msg .= createItemLink($itemid) . "\n\n";
-               } else {
-                       $tempurl = $this->getURL();
-                       if (substr($tempurl, -1) == '/' || substr($tempurl, -4) == '.php') {
-                               $mailto_msg .= $tempurl . '?itemid=' . $itemid . "\n\n";
-                       } else {
-                               $mailto_msg .= $tempurl . '/?itemid=' . $itemid . "\n\n";
-                       }
-               }
-               $mailto_msg .= _NOTIFY_TITLE . ' ' . strip_tags($title) . "\n";
-               $mailto_msg .= _NOTIFY_CONTENTS . "\n " . $ascii . "\n";
-               $mailto_msg .= getMailFooter();
-
-               $mailto_title = $this->getName() . ': ' . _NOTIFY_NI_TITLE;
-
-               $frommail = $member->getNotifyFromMailAddress();
-
-               $notify =& new NOTIFICATION($this->getNotifyAddress());
-               $notify->notify($mailto_title, $mailto_msg , $frommail);
-
-
-
-       }
-
-
-       /**
-         * Creates a new category for this blog
-         *
-         * @param $catName
-         *             name of the new category. When empty, a name is generated automatically
-         *             (starting with newcat)
-         * @param $catDescription
-         *             description of the new category. Defaults to 'New Category'
-         *
-         * @returns
-         *             the new category-id in case of success.
-         *             0 on failure
-         */
-       function createNewCategory($catName = '', $catDescription = 'New category') {
-               global $member, $manager;
-
-               if ($member->blogAdminRights($this->getID())) {
-                       // generate
-                       if ($catName == '')
-                       {
-                               $catName = 'newcat';
-                               $i = 1;
-
-                               $res = sql_query('SELECT * FROM '.sql_table('category')." WHERE cname='".$catName.$i."' and cblog=".$this->getID());
-                               while (mysql_num_rows($res) > 0)
-                               {
-                                       $i++;
-                                       $res = sql_query('SELECT * FROM '.sql_table('category')." WHERE cname='".$catName.$i."' and cblog=".$this->getID());
-                               }
-
-                               $catName = $catName . $i;
-                       }
-
-                       $manager->notify(
-                               'PreAddCategory',
-                               array(
-                                       'blog' => &$this,
-                                       'name' => &$catName,
-                                       'description' => $catDescription
-                               )
-                       );
-
-                       $query = 'INSERT INTO '.sql_table('category').' (cblog, cname, cdesc) VALUES (' . $this->getID() . ", '" . addslashes($catName) . "', '" . addslashes($catDescription) . "')";
-                       sql_query($query);
-                       $catid = mysql_insert_id();
-
-                       $manager->notify(
-                               'PostAddCategory',
-                               array(
-                                       'blog' => &$this,
-                                       'name' => $catName,
-                                       'description' => $catDescription,
-                                       'catid' => $catid
-                               )
-                       );
-
-                       return $catid;
-               } else {
-                       return 0;
-               }
-
-       }
-
-
-       /**
-        * Searches all months of this blog for the given query
-        *
-        * @param $query
-        *              search query
-        * @param $template
-        *              template to be used (__NAME__ of the template)
-        * @param $amountMonths
-        *              max amount of months to be search (0 = all)
-        * @param $maxresults
-        *              max number of results to show
-        * @param $startpos
-        *              offset
-        * @returns
-        *              amount of hits found
-        */
-       function search($query, $template, $amountMonths, $maxresults, $startpos) {
-               global $CONF, $manager;
-
-               $highlight      = '';
-               $sqlquery       = $this->getSqlSearch($query, $amountMonths, $highlight);
-
-               if ($sqlquery == '')
-               {
-                       // no query -> show everything
-                       $extraquery = '';
-                       $amountfound = $this->readLogAmount($template, $maxresults, $extraQuery, $query, 1, 1);
-               } else {
-
-                       // add LIMIT to query (to split search results into pages)
-                       if (intval($maxresults > 0))
-                               $sqlquery .= ' LIMIT ' . intval($startpos).',' . intval($maxresults);
-
-                       // show results
-                       $amountfound = $this->showUsingQuery($template, $sqlquery, $highlight, 1, 1);
-
-                       // when no results were found, show a message
-                       if ($amountfound == 0)
-                       {
-                               $template =& $manager->getTemplate($template);
-                               $vars = array(
-                                       'query'         => htmlspecialchars($query),
-                                       'blogid'        => $this->getID()
-                               );
-                               echo TEMPLATE::fill($template['SEARCH_NOTHINGFOUND'],$vars);
-                       }
-               }
-
-               return $amountfound;
-       }
-
-       /**
-        * Returns an SQL query to use for a search query
-        *
-        * @param $query
-        *              search query
-        * @param $amountMonths
-        *              amount of months to search back. Default = 0 = unlimited
-        * @param $mode
-        *              either empty, or 'count'. In this case, the query will be a SELECT COUNT(*) query
-        * @returns $highlight
-        *              words to highlight (out parameter)
-        * @returns
-        *              either a full SQL query, or an empty string (if querystring empty)
-        * @note
-        *              No LIMIT clause is added. (caller should add this if multiple pages are requested)
-        */
-       function getSqlSearch($query, $amountMonths = 0, &$highlight, $mode = '')
-       {
-               $searchclass =& new SEARCH($query);
-
-               $highlight        = $searchclass->inclusive;
-
-               // if querystring is empty, return empty string
-               if ($searchclass->inclusive == '')
-                       return '';
-
-
-               $where  = $searchclass->boolean_sql_where('ititle,ibody,imore');
-               $select = $searchclass->boolean_sql_select('ititle,ibody,imore');
-
-               // get list of blogs to search
-               $blogs          = $searchclass->blogs;          // array containing blogs that always need to be included
-               $blogs[]        = $this->getID();                       // also search current blog (duh)
-               $blogs          = array_unique($blogs);         // remove duplicates
-               $selectblogs = '';
-               if (count($blogs) > 0)
-                       $selectblogs = ' and i.iblog in (' . implode(',', $blogs) . ')';
-
-               if ($mode == '')
-               {
-                       $query = 'SELECT i.inumber as itemid, i.ititle as title, i.ibody as body, m.mname as author, m.mrealname as authorname, i.itime, i.imore as more, m.mnumber as authorid, m.memail as authormail, m.murl as authorurl, c.cname as category, i.icat as catid, i.iclosed as closed';
-                       if ($select)
-                               $query .= ', '.$select. ' as score ';
-               } else {
-                       $query = 'SELECT COUNT(*) as result ';
-               }
-
-               $query .= ' FROM '.sql_table('item').' as i, '.sql_table('member').' as m, '.sql_table('category').' as c'
-                          . ' WHERE i.iauthor=m.mnumber'
-                          . ' and i.icat=c.catid'
-                          . ' and i.idraft=0'  // exclude drafts
-                          . $selectblogs
-                                       // don't show future items
-                          . ' and i.itime<=' . mysqldate($this->getCorrectTime())
-                          . ' and '.$where;
-
-               // take into account amount of months to search
-               if ($amountMonths > 0)
-               {
-                       $localtime = getdate($this->getCorrectTime());
-                       $timestamp_start = mktime(0,0,0,$localtime['mon'] - $amountMonths,1,$localtime['year']);
-                       $query .= ' and i.itime>' . mysqldate($timestamp_start);
-               }
-
-               if ($mode == '')
-               {
-                       if ($select)
-                               $query .= ' ORDER BY score DESC';
-                       else
-                               $query .= ' ORDER BY i.itime DESC ';
-               }
-
-               return $query;
-       }
-
-       /**
-        * Returns the SQL query that's normally used to display the blog items on the index type skins
-        *
-        * @param $mode
-        *              either empty, or 'count'. In this case, the query will be a SELECT COUNT(*) query
-        * @returns
-        *              either a full SQL query, or an empty string
-        * @note
-        *              No LIMIT clause is added. (caller should add this if multiple pages are requested)
-        */
-       function getSqlBlog($extraQuery, $mode = '')
-       {
-               if ($mode == '')
-                       $query = 'SELECT i.inumber as itemid, i.ititle as title, i.ibody as body, m.mname as author, m.mrealname as authorname, i.itime, i.imore as more, m.mnumber as authorid, m.memail as authormail, m.murl as authorurl, c.cname as category, i.icat as catid, i.iclosed as closed';
-               else
-                       $query = 'SELECT COUNT(*) as result ';
-
-               $query .= ' FROM '.sql_table('item').' as i, '.sql_table('member').' as m, '.sql_table('category').' as c'
-                          . ' WHERE i.iblog='.$this->blogid
-                          . ' and i.iauthor=m.mnumber'
-                          . ' and i.icat=c.catid'
-                          . ' and i.idraft=0'  // exclude drafts
-                                       // don't show future items
-                          . ' and i.itime<=' . mysqldate($this->getCorrectTime());
-
-               if ($this->getSelectedCategory())
-                       $query .= ' and i.icat=' . $this->getSelectedCategory() . ' ';
-
-
-               $query .= $extraQuery;
-
-               if ($mode == '')
-                       $query .= ' ORDER BY i.itime DESC';
-
-               return $query;
-       }
-
-       /**
-         * Shows the archivelist using the given template
-         */
-       function showArchiveList($template, $mode = 'month', $limit = 0) {
-               global $CONF, $catid, $manager;
-
-               if ($catid)
-                       $linkparams = array('catid' => $catid);
-
-               $template =& $manager->getTemplate($template);
-               $data['blogid'] = $this->getID();
-
-               echo TEMPLATE::fill($template['ARCHIVELIST_HEADER'],$data);
-
-               $query = 'SELECT itime, SUBSTRING(itime,1,4) AS Year, SUBSTRING(itime,6,2) AS Month, SUBSTRING(itime,9,2) as Day FROM '.sql_table('item')
-               . ' WHERE iblog=' . $this->getID()
-               . ' and itime <=' . mysqldate($this->getCorrectTime())  // don't show future items!
-               . ' and idraft=0'; // don't show draft items
-
-               if ($catid)
-                       $query .= ' and icat=' . intval($catid);
-
-               $query .= ' GROUP BY Year, Month';
-               if ($mode == 'day')
-                       $query .= ', Day';
-
-
-               $query .= ' ORDER BY itime DESC';
-
-               if ($limit > 0)
-                       $query .= ' LIMIT ' . intval($limit);
-
-               $res = sql_query($query);
-
-               while ($current = mysql_fetch_object($res)) {
-                       $current->itime = strtotime($current->itime);   // string time -> unix timestamp
-
-                       if ($mode == 'day') {
-                               $archivedate = date('Y-m-d',$current->itime);
-                               $archive['day'] = date('d',$current->itime);
-                       } else {
-                               $archivedate = date('Y-m',$current->itime);
-                       }
-                       $data['month'] = date('m',$current->itime);
-                       $data['year'] = date('Y',$current->itime);
-                       $data['archivelink'] = createArchiveLink($this->getID(),$archivedate,$linkparams);
-
-                       $temp = TEMPLATE::fill($template['ARCHIVELIST_LISTITEM'],$data);
-                       echo strftime($temp,$current->itime);
-
-               }
-
-               mysql_free_result($res);
-
-               echo TEMPLATE::fill($template['ARCHIVELIST_FOOTER'],$data);
-       }
-
-
-       /**
-         * Shows the list of categories using a given template
-         */
-       function showCategoryList($template) {
-               global $CONF, $manager;
-
-               // determine arguments next to catids
-               // I guess this can be done in a better way, but it works
-               global $archive, $archivelist;
-
-               $linkparams = array();
-               if ($archive) {
-                       $blogurl = createArchiveLink($this->getID(), $archive, '');
-                       $linkparams['blogid'] = $this->getID();
-                       $linkparams['archive'] = $archive;
-               } else if ($archivelist) {
-                       $blogurl = createArchiveListLink($this->getID(), '');
-                       $linkparams['archivelist'] = $archivelist;
-               } else {
-                       $blogurl = createBlogidLink($this->getID(), '');
-                       $linkparams['blogid'] = $this->getID();
-               }
-
-               //$blogurl = $this->getURL() . $qargs;
-               //$blogurl = createBlogLink($this->getURL(), $linkparams);
-
-               $template =& $manager->getTemplate($template);
-
-               echo TEMPLATE::fill((isset($template['CATLIST_HEADER']) ? $template['CATLIST_HEADER'] : null),
-                                                       array(
-                                                               'blogid' => $this->getID(),
-                                                               'blogurl' => $blogurl,
-                                                               'self' => $CONF['Self']
-                                                       ));
-
-               $query = 'SELECT catid, cdesc as catdesc, cname as catname FROM '.sql_table('category').' WHERE cblog=' . $this->getID() . ' ORDER BY cname ASC';
-               $res = sql_query($query);
-
-
-               while ($data = mysql_fetch_assoc($res)) {
-                       $data['blogid'] = $this->getID();
-                       $data['blogurl'] = $blogurl;
-                       $data['catlink'] = createLink(
-                                                               'category',
-                                                               array(
-                                                                       'catid' => $data['catid'],
-                                                                       'name' => $data['catname'],
-                                                                       'extra' => $linkparams
-                                                               )
-                                                          );
-                       $data['self'] = $CONF['Self'];
-
-                       echo TEMPLATE::fill((isset($template['CATLIST_LISTITEM']) ? $template['CATLIST_LISTITEM'] : null), $data);
-                       //$temp = TEMPLATE::fill((isset($template['CATLIST_LISTITEM']) ? $template['CATLIST_LISTITEM'] : null), $data);
-                       //echo strftime($temp, $current->itime);
-
-               }
-
-               mysql_free_result($res);
-
-               echo TEMPLATE::fill((isset($template['CATLIST_FOOTER']) ? $template['CATLIST_FOOTER'] : null),
-                                                       array(
-                                                               'blogid' => $this->getID(),
-                                                               'blogurl' => $blogurl,
-                                                               'self' => $CONF['Self']
-                                                       ));
-       }
-       
-       /**
-         * Shows a list of all blogs in the system using a given template
-         */
-       function showBlogList($template, $bnametype) {
-               global $CONF, $manager;
-               
-               $template =& $manager->getTemplate($template);
-               
-               echo TEMPLATE::fill((isset($template['BLOGLIST_HEADER']) ? $template['BLOGLIST_HEADER'] : null),
-                                                       array(
-                                                               'sitename' => $CONF['SiteName'],
-                                                               'siteurl' => $CONF['IndexURL']
-                                                       ));
-               
-               $query = 'SELECT bnumber, bname, bshortname, bdesc, burl FROM '.sql_table('blog').' ORDER BY bnumber ASC';
-               $res = sql_query($query);
-               
-               while ($data = mysql_fetch_assoc($res)) {
-               
-                       $list = array();
-               
-//                     $list['bloglink'] = createLink('blog', array('blogid' => $data['bnumber']));
-                       $list['bloglink'] = createBlogidLink($data['bnumber']);
-               
-                       $list['blogdesc'] = $data['bdesc'];
-                       
-                       if ($bnametype=='shortname') {
-                               $list['blogname'] = $data['bshortname'];
-                       }
-                       else { // all other cases
-                               $list['blogname'] = $data['bname'];
-                       }
-                       
-                       echo TEMPLATE::fill((isset($template['BLOGLIST_LISTITEM']) ? $template['BLOGLIST_LISTITEM'] : null), $list);
-                       
-               }
-               
-               mysql_free_result($res);
-               
-               echo TEMPLATE::fill((isset($template['BLOGLIST_FOOTER']) ? $template['BLOGLIST_FOOTER'] : null),
-                                                       array(
-                                                               'sitename' => $CONF['SiteName'],
-                                                               'siteurl' => $CONF['IndexURL']
-                                                       ));
-
-       }
-
-       /**
-         * Blogsettings functions
-         */
-
-       function readSettings() {
-               $query =  'SELECT *'
-                          . ' FROM '.sql_table('blog')
-                          . ' WHERE bnumber=' . $this->blogid;
-               $res = sql_query($query);
-
-               $this->isValid = (mysql_num_rows($res) > 0);
-               if (!$this->isValid)
-                       return;
-
-               $this->settings = mysql_fetch_assoc($res);
-       }
-
-       function writeSettings() {
-
-               // (can't use floatval since not available prior to PHP 4.2)
-               $offset = $this->getTimeOffset();
-               if (!is_float($offset))
-                       $offset = intval($offset);
-
-               $query =  'UPDATE '.sql_table('blog')
-                          . " SET bname='" . addslashes($this->getName()) . "',"
-                          . "     bshortname='". addslashes($this->getShortName()) . "',"
-                          . "     bcomments=". intval($this->commentsEnabled()) . ","
-                          . "     bmaxcomments=" . intval($this->getMaxComments()) . ","
-                          . "     btimeoffset=" . $offset . ","
-                          . "     bpublic=" . intval($this->isPublic()) . ","
-                          . "     breqemail=" . intval($this->emailRequired()) . ","
-                          . "     bsendping=" . intval($this->sendPing()) . ","
-                          . "     bconvertbreaks=" . intval($this->convertBreaks()) . ","
-                          . "     ballowpast=" . intval($this->allowPastPosting()) . ","
-                          . "     bnotify='" . addslashes($this->getNotifyAddress()) . "',"
-                          . "     bnotifytype=" . intval($this->getNotifyType()) . ","
-                          . "     burl='" . addslashes($this->getURL()) . "',"
-                          . "     bupdate='" . addslashes($this->getUpdateFile()) . "',"
-                          . "     bdesc='" . addslashes($this->getDescription()) . "',"
-                          . "     bdefcat=" . intval($this->getDefaultCategory()) . ","
-                          . "     bdefskin=" . intval($this->getDefaultSkin()) . ","
-                          . "     bincludesearch=" . intval($this->getSearchable())
-                          . " WHERE bnumber=" . intval($this->getID());
-               sql_query($query);
-
-       }
-
-
-
-       // update update file if requested
-       function updateUpdatefile() {
-                if ($this->getUpdateFile()) {
-                       $f_update = fopen($this->getUpdateFile(),'w');
-                       fputs($f_update,$this->getCorrectTime());
-                       fclose($f_update);
-                }
-
-       }
-
-       function isValidCategory($catid) {
-               $query = 'SELECT * FROM '.sql_table('category').' WHERE cblog=' . $this->getID() . ' and catid=' . intval($catid);
-               $res = sql_query($query);
-               return (mysql_num_rows($res) != 0);
-       }
-
-       function getCategoryName($catid) {
-               $res = sql_query('SELECT cname FROM '.sql_table('category').' WHERE cblog='.$this->getID().' and catid=' . intval($catid));
-               $o = mysql_fetch_object($res);
-               return $o->cname;
-       }
-
-       function getCategoryDesc($catid) {
-               $res = sql_query('SELECT cdesc FROM '.sql_table('category').' WHERE cblog='.$this->getID().' and catid=' . intval($catid));
-               $o = mysql_fetch_object($res);
-               return $o->cdesc;
-       }
-
-       function getCategoryIdFromName($name) {
-               $res = sql_query('SELECT catid FROM '.sql_table('category').' WHERE cblog='.$this->getID().' and cname="' . addslashes($name) . '"');
-               if (mysql_num_rows($res) > 0) {
-                       $o = mysql_fetch_object($res);
-                       return $o->catid;
-               } else {
-                       return $this->getDefaultCategory();
-               }
-       }
-
-       function sendPing() {
-               return $this->getSetting('bsendping');
-       }
-
-       function setPingUserland($val) {
-               $this->setSetting('bsendping',$val);
-       }
-
-       function convertBreaks() {
-               return $this->getSetting('bconvertbreaks');
-       }
-
-       function insertJavaScriptInfo($authorid = '') {
-               global $member, $CONF;
-
-               if ($authorid == '')
-                       $authorid = $member->getID();
-
-               ?>
-               <script type="text/javascript">
-                       setConvertBreaks(<?php echo  $this->convertBreaks() ? 'true' : 'false' ?>);
-                       setMediaUrl("<?php echo $CONF['MediaURL']?>");
-                       setAuthorId(<?php echo $authorid?>);
-               </script><?php  }
-
-       function setConvertBreaks($val) {
-               $this->setSetting('bconvertbreaks',$val);
-       }
-       function setAllowPastPosting($val) {
-               $this->setSetting('ballowpast',$val);
-       }
-       function allowPastPosting() {
-               return $this->getSetting('ballowpast');
-       }
-
-       function getCorrectTime($t=0) {
-               if ($t == 0) $t = time();
-               return ($t + 3600 * $this->getTimeOffset());
-       }
-
-       function getName() {
-               return $this->getSetting('bname');
-       }
-
-       function getShortName() {
-               return $this->getSetting('bshortname');
-       }
-
-       function getMaxComments() {
-               return $this->getSetting('bmaxcomments');
-       }
-
-       function getNotifyAddress() {
-               return $this->getSetting('bnotify');
-       }
-
-       function getNotifyType() {
-               return $this->getSetting('bnotifytype');
-       }
-
-       function notifyOnComment() {
-               $n = $this->getNotifyType();
-               return (($n != 0) && (($n % 3) == 0));
-       }
-
-       function notifyOnVote() {
-               $n = $this->getNotifyType();
-               return (($n != 0) && (($n % 5) == 0));
-       }
-
-       function notifyOnNewItem() {
-               $n = $this->getNotifyType();
-               return (($n != 0) && (($n % 7) == 0));
-       }
-
-       function setNotifyType($val) {
-               $this->setSetting('bnotifytype',$val);
-       }
-
-
-       function getTimeOffset() {
-               return $this->getSetting('btimeoffset');
-       }
-
-       function commentsEnabled() {
-               return $this->getSetting('bcomments');
-       }
-
-       function getURL() {
-               return $this->getSetting('burl');
-       }
-
-       function getDefaultSkin() {
-               return $this->getSetting('bdefskin');
-       }
-
-       function getUpdateFile() {
-               return $this->getSetting('bupdate');
-       }
-
-       function getDescription() {
-               return $this->getSetting('bdesc');
-       }
-
-       function isPublic() {
-               return $this->getSetting('bpublic');
-       }
-
-       function emailRequired() {
-               return $this->getSetting('breqemail');
-       }
-
-       function getSearchable() {
-               return $this->getSetting('bincludesearch');
-       }
-
-       function getDefaultCategory() {
-               return $this->getSetting('bdefcat');
-       }
-
-       function setPublic($val) {
-               $this->setSetting('bpublic',$val);
-       }
-
-       function setSearchable($val) {
-               $this->setSetting('bincludesearch',$val);
-       }
-
-       function setDescription($val) {
-               $this->setSetting('bdesc',$val);
-       }
-
-       function setUpdateFile($val) {
-               $this->setSetting('bupdate',$val);
-       }
-
-       function setDefaultSkin($val) {
-               $this->setSetting('bdefskin',$val);
-       }
-
-       function setURL($val) {
-               $this->setSetting('burl',$val);
-       }
-
-       function setName($val) {
-               $this->setSetting('bname',$val);
-       }
-
-       function setShortName($val) {
-               $this->setSetting('bshortname',$val);
-       }
-
-       function setCommentsEnabled($val) {
-               $this->setSetting('bcomments',$val);
-       }
-
-       function setMaxComments($val) {
-               $this->setSetting('bmaxcomments',$val);
-       }
-
-       function setNotifyAddress($val) {
-               $this->setSetting('bnotify',$val);
-       }
-
-       function setEmailRequired($val) {
-               $this->setSetting('breqemail',$val);
-       }
-
-       function setTimeOffset($val) {
-               // check validity of value
-               // 1. replace , by . (common mistake)
-               $val = str_replace(',','.',$val);
-               // 2. cast to float or int
-               if (is_numeric($val) && strstr($val,'.5')) {
-                       $val = (float) $val;
-               } else {
-                       $val = intval($val);
-               }
-
-               $this->setSetting('btimeoffset',$val);
-       }
-
-       function setDefaultCategory($val) {
-               $this->setSetting('bdefcat',$val);
-       }
-
-       function getSetting($key) {
-               return $this->settings[$key];
-       }
-
-       function setSetting($key,$value) {
-               $this->settings[$key] = $value;
-       }
-
-
-       // tries to add a member to the team. Returns false if the member was already on
-       // the team
-       function addTeamMember($memberid, $admin) {
-               global $manager;
-
-               $memberid = intval($memberid);
-               $admin = intval($admin);
-
-               // check if member is already a member
-               $tmem = MEMBER::createFromID($memberid);
-
-               if ($tmem->isTeamMember($this->getID()))
-                       return 0;
-
-               $manager->notify(
-                       'PreAddTeamMember',
-                       array(
-                               'blog' => &$this,
-                               'member' => &$tmem,
-                               'admin' => &$admin
-                       )
-               );
-
-               // add to team
-               $query = 'INSERT INTO '.sql_table('team').' (TMEMBER, TBLOG, TADMIN) '
-                          . 'VALUES (' . $memberid .', '.$this->getID().', "'.$admin.'")';
-               sql_query($query);
-
-               $manager->notify(
-                       'PostAddTeamMember',
-                       array(
-                               'blog' => &$this,
-                               'member' => &$tmem,
-                               'admin' => $admin
-                       )
-
-               );
-
-               ACTIONLOG::add(INFO, 'Added ' . $tmem->getDisplayName() . ' (ID=' .
-                                          $memberid .') to the team of blog "' . $this->getName() . '"');
-
-               return 1;
-       }
-
-       function getID() {
-               return intVal($this->blogid);
-       }
-
-       // returns true if there is a blog with the given shortname (static)
-       function exists($name) {
-               $r = sql_query('select * FROM '.sql_table('blog').' WHERE bshortname="'.addslashes($name).'"');
-               return (mysql_num_rows($r) != 0);
-       }
-
-       // returns true if there is a blog with the given ID (static)
-       function existsID($id) {
-               $r = sql_query('select * FROM '.sql_table('blog').' WHERE bnumber='.intval($id));
-               return (mysql_num_rows($r) != 0);
-       }
-
-        // flag there is a future post pending
-        function setFuturePost() {
-               $query =  'UPDATE '.sql_table('blog')
-                          . " SET bfuturepost='1' WHERE bnumber=" . $this->getID();
-               sql_query($query);
-        }
-
-       // clear there is a future post pending
-       function clearFuturePost() {
-               $query =  'UPDATE '.sql_table('blog')
-                          . " SET bfuturepost='0' WHERE bnumber=" . $this->getID();
-               sql_query($query);
-       }
-
-       // check if we should throw justPosted event
-       function checkJustPosted() {
-               global $manager;
-
-               if ($this->settings['bfuturepost'] == 1) {
-                       $blogid = $this->getID();
-                       $result = sql_query("SELECT * FROM " . sql_table('item')
-                                 . " WHERE iposted=0 AND iblog=" . $blogid . " AND itime<NOW()");
-                       if (mysql_num_rows($result) > 0) {
-                               // This $pinged is allow a plugin to tell other hook to the event that a ping is sent already
-                               // Note that the plugins's calling order is subject to thri order in the plugin list
-                               $pinged = false;
-                               $manager->notify(
-                                               'JustPosted',
-                                               array('blogid' => $blogid,
-                                               'pinged' => &$pinged
-                                               )
-                               );
-
-                               // clear all expired future posts
-                               sql_query("UPDATE " . sql_table('item') . " SET iposted='1' WHERE iblog=" . $blogid . " AND itime<NOW()");
-
-                               // check to see any pending future post, clear the flag is none 
-                               $result = sql_query("SELECT * FROM " . sql_table('item') 
-                                         . " WHERE iposted=0 AND iblog=" . $blogid);
-                               if (mysql_num_rows($result) == 0) {
-                                       $this->clearFuturePost();
-                               }
-                       }
-               }
-       }
-
-}
-
-?>
+if ( !function_exists('requestVar') ) exit;\r
+require_once dirname(__FILE__) . '/ITEMACTIONS.php';\r
+\r
+class BLOG {\r
+\r
+       // blog id\r
+       var $blogid;\r
+\r
+       // ID of currently selected category\r
+       var $selectedcatid;\r
+\r
+       // After creating an object of the blog class, contains true if the BLOG object is\r
+       // valid (the blog exists)\r
+       var $isValid;\r
+\r
+       // associative array, containing all blogsettings (use the get/set functions instead)\r
+       var $settings;\r
+\r
+       /**\r
+        * Creates a new BLOG object for the given blog\r
+        *\r
+        * @param $id blogid\r
+        */\r
+       function BLOG($id) {\r
+               $this->blogid = intval($id);\r
+               $this->readSettings();\r
+\r
+               // try to set catid\r
+               // (the parse functions in SKIN.php will override this, so it's mainly useless)\r
+               global $catid;\r
+               $this->setSelectedCategory($catid);\r
+       }\r
+\r
+       /**\r
+        * Shows the given amount of items for this blog\r
+        *\r
+        * @param $template\r
+        *              String representing the template _NAME_ (!)\r
+        * @param $amountEntries\r
+        *              amount of entries to show\r
+        * @param $startpos\r
+        *              offset from where items should be shown (e.g. 5 = start at fifth item)\r
+        * @returns int\r
+        *              amount of items shown\r
+        */\r
+       function readLog($template, $amountEntries, $offset = 0, $startpos = 0) {\r
+               return $this->readLogAmount($template,$amountEntries,'','',1,1,$offset, $startpos);\r
+       }\r
+\r
+       /**\r
+        * Shows an archive for a given month\r
+        *\r
+        * @param $year\r
+        *              year\r
+        * @param $month\r
+        *              month\r
+        * @param $template\r
+        *              String representing the template name to be used\r
+        */\r
+       function showArchive($templatename, $year, $month, $day=0) {\r
+\r
+               // create extra where clause for select query\r
+               if ($day == 0) {\r
+                       $timestamp_start = mktime(0,0,0,$month,1,$year);\r
+                       $timestamp_end = mktime(0,0,0,$month+1,1,$year);  // also works when $month==12\r
+               } else {\r
+                       $timestamp_start = mktime(0,0,0,$month,$day,$year);\r
+                       $timestamp_end = mktime(0,0,0,$month,$day+1,$year);\r
+               }\r
+               $extra_query = ' and i.itime>=' . mysqldate($timestamp_start)\r
+                                        . ' and i.itime<' . mysqldate($timestamp_end);\r
+\r
+\r
+               $this->readLogAmount($templatename,0,$extra_query,'',1,1);\r
+\r
+       }\r
+\r
+\r
+       // sets/gets current category (only when category exists)\r
+       function setSelectedCategory($catid) {\r
+               if ($this->isValidCategory($catid) || (intval($catid) == 0))\r
+                       $this->selectedcatid = intval($catid);\r
+       }\r
+\r
+       function setSelectedCategoryByName($catname) {\r
+               $this->setSelectedCategory($this->getCategoryIdFromName($catname));\r
+       }\r
+\r
+       function getSelectedCategory() {\r
+               return $this->selectedcatid;\r
+       }\r
+\r
+       /**\r
+        * Shows the given amount of items for this blog\r
+        *\r
+        * @param $template\r
+        *              String representing the template _NAME_ (!)\r
+        * @param $amountEntries\r
+        *              amount of entries to show (0 = no limit)\r
+        * @param $extraQuery\r
+        *              extra conditions to be added to the query\r
+        * @param $highlight\r
+        *              contains a query that should be highlighted\r
+        * @param $comments\r
+        *              1=show comments 0=don't show comments\r
+        * @param $dateheads\r
+        *              1=show dateheads 0=don't show dateheads\r
+        * @param $offset\r
+        *              offset\r
+        * @returns int\r
+        *              amount of items shown\r
+        */\r
+       function readLogAmount($template, $amountEntries, $extraQuery, $highlight, $comments, $dateheads, $offset = 0, $startpos = 0) {\r
+\r
+               $query = $this->getSqlBlog($extraQuery);\r
+\r
+               if ($amountEntries > 0) {\r
+                               // $offset zou moeten worden:\r
+                               // (($startpos / $amountentries) + 1) * $offset ... later testen ...\r
+                          $query .= ' LIMIT ' . intval($startpos + $offset).',' . intval($amountEntries);\r
+               }\r
+               return $this->showUsingQuery($template, $query, $highlight, $comments, $dateheads);\r
+       }\r
+\r
+       function showUsingQuery($templateName, $query, $highlight = '', $comments = 0, $dateheads = 1) {\r
+               global $CONF, $manager;\r
+\r
+               $lastVisit = cookieVar($CONF['CookiePrefix'] .'lastVisit');\r
+               if ($lastVisit != 0)\r
+                       $lastVisit = $this->getCorrectTime($lastVisit);\r
+\r
+               // set templatename as global variable (so plugins can access it)\r
+               global $currentTemplateName;\r
+               $currentTemplateName = $templateName;\r
+\r
+               $template =& $manager->getTemplate($templateName);\r
+\r
+               // create parser object & action handler\r
+               $actions =& new ITEMACTIONS($this);\r
+               $parser =& new PARSER($actions->getDefinedActions(),$actions);\r
+               $actions->setTemplate($template);\r
+               $actions->setHighlight($highlight);\r
+               $actions->setLastVisit($lastVisit);\r
+               $actions->setParser($parser);\r
+               $actions->setShowComments($comments);\r
+\r
+               // execute query\r
+               $items = sql_query($query);\r
+\r
+               // loop over all items\r
+               $old_date = 0;\r
+               while ($item = mysql_fetch_object($items)) {\r
+\r
+                       $item->timestamp = strtotime($item->itime);     // string timestamp -> unix timestamp\r
+\r
+                       // action handler needs to know the item we're handling\r
+                       $actions->setCurrentItem($item);\r
+\r
+                       // add date header if needed\r
+                       if ($dateheads) {\r
+                               $new_date = date('dFY',$item->timestamp);\r
+                               if ($new_date != $old_date) {\r
+                                       // unless this is the first time, write date footer\r
+                                       $timestamp = $item->timestamp;\r
+                                       if ($old_date != 0) {\r
+                                               $oldTS = strtotime($old_date);\r
+                                               $manager->notify('PreDateFoot',array('blog' => &$this, 'timestamp' => $oldTS));\r
+                                               $tmp_footer = strftime($template['DATE_FOOTER'], $oldTS);\r
+                                               $parser->parse($tmp_footer);\r
+                                               $manager->notify('PostDateFoot',array('blog' => &$this, 'timestamp' => $oldTS));\r
+                                       }\r
+                                       $manager->notify('PreDateHead',array('blog' => &$this, 'timestamp' => $timestamp));\r
+                                       // note, to use templatvars in the dateheader, the %-characters need to be doubled in\r
+                                       // order to be preserved by strftime\r
+                                       $tmp_header = strftime((isset($template['DATE_HEADER']) ? $template['DATE_HEADER'] : null), $timestamp);\r
+                                       $parser->parse($tmp_header);\r
+                                       $manager->notify('PostDateHead',array('blog' => &$this, 'timestamp' => $timestamp));\r
+                               }\r
+                               $old_date = $new_date;\r
+                       }\r
+\r
+                       // parse item\r
+                       $parser->parse($template['ITEM_HEADER']);\r
+                       $manager->notify('PreItem', array('blog' => &$this, 'item' => &$item));\r
+                       $parser->parse($template['ITEM']);\r
+                       $manager->notify('PostItem', array('blog' => &$this, 'item' => &$item));\r
+                       $parser->parse($template['ITEM_FOOTER']);\r
+\r
+               }\r
+\r
+               $numrows = mysql_num_rows($items);\r
+\r
+               // add another date footer if there was at least one item\r
+               if (($numrows > 0) && $dateheads) {\r
+                       $manager->notify('PreDateFoot',array('blog' => &$this, 'timestamp' => strtotime($old_date)));\r
+                       $parser->parse($template['DATE_FOOTER']);\r
+                       $manager->notify('PostDateFoot',array('blog' => &$this, 'timestamp' => strtotime($old_date)));\r
+               }\r
+\r
+               mysql_free_result($items);      // free memory\r
+\r
+               return $numrows;\r
+\r
+       }\r
+\r
+       function showOneitem($itemid, $template, $highlight) {\r
+               $extraQuery = ' and inumber=' . intval($itemid);\r
+\r
+               return $this->readLogAmount($template, 1, $extraQuery, $highlight, 0, 0);\r
+       }\r
+\r
+\r
+       /**\r
+         * Adds an item to this blog\r
+         */\r
+       function additem($catid, $title, $body, $more, $blogid, $authorid, $timestamp, $closed, $draft, $posted='1') {\r
+               global $manager;\r
+\r
+               $blogid         = intval($blogid);\r
+               $authorid       = intval($authorid);\r
+               $title          = $title;\r
+               $body           = $body;\r
+               $more           = $more;\r
+               $catid          = intval($catid);\r
+\r
+               // convert newlines to <br />\r
+               if ($this->convertBreaks()) {\r
+                       $body = addBreaks($body);\r
+                       $more = addBreaks($more);\r
+               }\r
+\r
+               if ($closed != '1') $closed = '0';\r
+               if ($draft != '0') $draft = '1';\r
+\r
+               if (!$this->isValidCategory($catid))\r
+                       $catid = $this->getDefaultCategory();\r
+\r
+               if ($timestamp > $this->getCorrectTime())\r
+                       $isFuture = 1;\r
+\r
+               $timestamp = date('Y-m-d H:i:s',$timestamp);\r
+\r
+               $manager->notify('PreAddItem',array('title' => &$title, 'body' => &$body, 'more' => &$more, 'blog' => &$this, 'authorid' => &$authorid, 'timestamp' => &$timestamp, 'closed' => &$closed, 'draft' => &$draft, 'catid' => &$catid));\r
+\r
+               $title = addslashes($title);\r
+               $body = addslashes($body);\r
+               $more = addslashes($more);\r
+\r
+               $query = 'INSERT INTO '.sql_table('item').' (ITITLE, IBODY, IMORE, IBLOG, IAUTHOR, ITIME, ICLOSED, IDRAFT, ICAT, IPOSTED) '\r
+                          . "VALUES ('$title', '$body', '$more', $blogid, $authorid, '$timestamp', $closed, $draft, $catid, $posted)";\r
+               sql_query($query);\r
+               $itemid = mysql_insert_id();\r
+\r
+               $manager->notify('PostAddItem',array('itemid' => $itemid));\r
+\r
+               if (!$draft)\r
+                       $this->updateUpdateFile();\r
+\r
+               // send notification mail\r
+               if (!$draft && !$isFuture && $this->getNotifyAddress() && $this->notifyOnNewItem())\r
+                       $this->sendNewItemNotification($itemid, stripslashes($title), stripslashes($body));\r
+\r
+               return $itemid;\r
+       }\r
+\r
+       function sendNewItemNotification($itemid, $title, $body) {\r
+               global $CONF, $member;\r
+\r
+               // create text version of html post\r
+               $ascii = toAscii($body);\r
+\r
+               $mailto_msg = _NOTIFY_NI_MSG . " \n";\r
+//             $mailto_msg .= $CONF['IndexURL'] . 'index.php?itemid=' . $itemid . "\n\n";\r
+               $temp = parse_url($CONF['Self']);\r
+               if ($temp['scheme']) {\r
+                       $mailto_msg .= createItemLink($itemid) . "\n\n";\r
+               } else {\r
+                       $tempurl = $this->getURL();\r
+                       if (substr($tempurl, -1) == '/' || substr($tempurl, -4) == '.php') {\r
+                               $mailto_msg .= $tempurl . '?itemid=' . $itemid . "\n\n";\r
+                       } else {\r
+                               $mailto_msg .= $tempurl . '/?itemid=' . $itemid . "\n\n";\r
+                       }\r
+               }\r
+               $mailto_msg .= _NOTIFY_TITLE . ' ' . strip_tags($title) . "\n";\r
+               $mailto_msg .= _NOTIFY_CONTENTS . "\n " . $ascii . "\n";\r
+               $mailto_msg .= getMailFooter();\r
+\r
+               $mailto_title = $this->getName() . ': ' . _NOTIFY_NI_TITLE;\r
+\r
+               $frommail = $member->getNotifyFromMailAddress();\r
+\r
+               $notify =& new NOTIFICATION($this->getNotifyAddress());\r
+               $notify->notify($mailto_title, $mailto_msg , $frommail);\r
+\r
+\r
+\r
+       }\r
+\r
+\r
+       /**\r
+         * Creates a new category for this blog\r
+         *\r
+         * @param $catName\r
+         *             name of the new category. When empty, a name is generated automatically\r
+         *             (starting with newcat)\r
+         * @param $catDescription\r
+         *             description of the new category. Defaults to 'New Category'\r
+         *\r
+         * @returns\r
+         *             the new category-id in case of success.\r
+         *             0 on failure\r
+         */\r
+       function createNewCategory($catName = '', $catDescription = _CREATED_NEW_CATEGORY_DESC) {\r
+               global $member, $manager;\r
+\r
+               if ($member->blogAdminRights($this->getID())) {\r
+                       // generate\r
+                       if ($catName == '')\r
+                       {\r
+                               $catName = _CREATED_NEW_CATEGORY_NAME;\r
+                               $i = 1;\r
+\r
+                               $res = sql_query('SELECT * FROM '.sql_table('category')." WHERE cname='".$catName.$i."' and cblog=".$this->getID());\r
+                               while (mysql_num_rows($res) > 0)\r
+                               {\r
+                                       $i++;\r
+                                       $res = sql_query('SELECT * FROM '.sql_table('category')." WHERE cname='".$catName.$i."' and cblog=".$this->getID());\r
+                               }\r
+\r
+                               $catName = $catName . $i;\r
+                       }\r
+\r
+                       $manager->notify(\r
+                               'PreAddCategory',\r
+                               array(\r
+                                       'blog' => &$this,\r
+                                       'name' => &$catName,\r
+                                       'description' => $catDescription\r
+                               )\r
+                       );\r
+\r
+                       $query = 'INSERT INTO '.sql_table('category').' (cblog, cname, cdesc) VALUES (' . $this->getID() . ", '" . addslashes($catName) . "', '" . addslashes($catDescription) . "')";\r
+                       sql_query($query);\r
+                       $catid = mysql_insert_id();\r
+\r
+                       $manager->notify(\r
+                               'PostAddCategory',\r
+                               array(\r
+                                       'blog' => &$this,\r
+                                       'name' => $catName,\r
+                                       'description' => $catDescription,\r
+                                       'catid' => $catid\r
+                               )\r
+                       );\r
+\r
+                       return $catid;\r
+               } else {\r
+                       return 0;\r
+               }\r
+\r
+       }\r
+\r
+\r
+       /**\r
+        * Searches all months of this blog for the given query\r
+        *\r
+        * @param $query\r
+        *              search query\r
+        * @param $template\r
+        *              template to be used (__NAME__ of the template)\r
+        * @param $amountMonths\r
+        *              max amount of months to be search (0 = all)\r
+        * @param $maxresults\r
+        *              max number of results to show\r
+        * @param $startpos\r
+        *              offset\r
+        * @returns\r
+        *              amount of hits found\r
+        */\r
+       function search($query, $template, $amountMonths, $maxresults, $startpos) {\r
+               global $CONF, $manager;\r
+\r
+               $highlight      = '';\r
+               $sqlquery       = $this->getSqlSearch($query, $amountMonths, $highlight);\r
+\r
+               if ($sqlquery == '')\r
+               {\r
+                       // no query -> show everything\r
+                       $extraquery = '';\r
+                       $amountfound = $this->readLogAmount($template, $maxresults, $extraQuery, $query, 1, 1);\r
+               } else {\r
+\r
+                       // add LIMIT to query (to split search results into pages)\r
+                       if (intval($maxresults > 0))\r
+                               $sqlquery .= ' LIMIT ' . intval($startpos).',' . intval($maxresults);\r
+\r
+                       // show results\r
+                       $amountfound = $this->showUsingQuery($template, $sqlquery, $highlight, 1, 1);\r
+\r
+                       // when no results were found, show a message\r
+                       if ($amountfound == 0)\r
+                       {\r
+                               $template =& $manager->getTemplate($template);\r
+                               $vars = array(\r
+                                       'query'         => htmlspecialchars($query),\r
+                                       'blogid'        => $this->getID()\r
+                               );\r
+                               echo TEMPLATE::fill($template['SEARCH_NOTHINGFOUND'],$vars);\r
+                       }\r
+               }\r
+\r
+               return $amountfound;\r
+       }\r
+\r
+       /**\r
+        * Returns an SQL query to use for a search query\r
+        *\r
+        * @param $query\r
+        *              search query\r
+        * @param $amountMonths\r
+        *              amount of months to search back. Default = 0 = unlimited\r
+        * @param $mode\r
+        *              either empty, or 'count'. In this case, the query will be a SELECT COUNT(*) query\r
+        * @returns $highlight\r
+        *              words to highlight (out parameter)\r
+        * @returns\r
+        *              either a full SQL query, or an empty string (if querystring empty)\r
+        * @note\r
+        *              No LIMIT clause is added. (caller should add this if multiple pages are requested)\r
+        */\r
+       function getSqlSearch($query, $amountMonths = 0, &$highlight, $mode = '')\r
+       {\r
+               $searchclass =& new SEARCH($query);\r
+\r
+               $highlight        = $searchclass->inclusive;\r
+\r
+               // if querystring is empty, return empty string\r
+               if ($searchclass->inclusive == '')\r
+                       return '';\r
+\r
+\r
+               $where  = $searchclass->boolean_sql_where('ititle,ibody,imore');\r
+               $select = $searchclass->boolean_sql_select('ititle,ibody,imore');\r
+\r
+               // get list of blogs to search\r
+               $blogs          = $searchclass->blogs;          // array containing blogs that always need to be included\r
+               $blogs[]        = $this->getID();                       // also search current blog (duh)\r
+               $blogs          = array_unique($blogs);         // remove duplicates\r
+               $selectblogs = '';\r
+               if (count($blogs) > 0)\r
+                       $selectblogs = ' and i.iblog in (' . implode(',', $blogs) . ')';\r
+\r
+               if ($mode == '')\r
+               {\r
+                       $query = 'SELECT i.inumber as itemid, i.ititle as title, i.ibody as body, m.mname as author, m.mrealname as authorname, i.itime, i.imore as more, m.mnumber as authorid, m.memail as authormail, m.murl as authorurl, c.cname as category, i.icat as catid, i.iclosed as closed';\r
+                       if ($select)\r
+                               $query .= ', '.$select. ' as score ';\r
+               } else {\r
+                       $query = 'SELECT COUNT(*) as result ';\r
+               }\r
+\r
+               $query .= ' FROM '.sql_table('item').' as i, '.sql_table('member').' as m, '.sql_table('category').' as c'\r
+                          . ' WHERE i.iauthor=m.mnumber'\r
+                          . ' and i.icat=c.catid'\r
+                          . ' and i.idraft=0'  // exclude drafts\r
+                          . $selectblogs\r
+                                       // don't show future items\r
+                          . ' and i.itime<=' . mysqldate($this->getCorrectTime())\r
+                          . ' and '.$where;\r
+\r
+               // take into account amount of months to search\r
+               if ($amountMonths > 0)\r
+               {\r
+                       $localtime = getdate($this->getCorrectTime());\r
+                       $timestamp_start = mktime(0,0,0,$localtime['mon'] - $amountMonths,1,$localtime['year']);\r
+                       $query .= ' and i.itime>' . mysqldate($timestamp_start);\r
+               }\r
+\r
+               if ($mode == '')\r
+               {\r
+                       if ($select)\r
+                               $query .= ' ORDER BY score DESC';\r
+                       else\r
+                               $query .= ' ORDER BY i.itime DESC ';\r
+               }\r
+\r
+               return $query;\r
+       }\r
+\r
+       /**\r
+        * Returns the SQL query that's normally used to display the blog items on the index type skins\r
+        *\r
+        * @param $mode\r
+        *              either empty, or 'count'. In this case, the query will be a SELECT COUNT(*) query\r
+        * @returns\r
+        *              either a full SQL query, or an empty string\r
+        * @note\r
+        *              No LIMIT clause is added. (caller should add this if multiple pages are requested)\r
+        */\r
+       function getSqlBlog($extraQuery, $mode = '')\r
+       {\r
+               if ($mode == '')\r
+                       $query = 'SELECT i.inumber as itemid, i.ititle as title, i.ibody as body, m.mname as author, m.mrealname as authorname, i.itime, i.imore as more, m.mnumber as authorid, m.memail as authormail, m.murl as authorurl, c.cname as category, i.icat as catid, i.iclosed as closed';\r
+               else\r
+                       $query = 'SELECT COUNT(*) as result ';\r
+\r
+               $query .= ' FROM '.sql_table('item').' as i, '.sql_table('member').' as m, '.sql_table('category').' as c'\r
+                          . ' WHERE i.iblog='.$this->blogid\r
+                          . ' and i.iauthor=m.mnumber'\r
+                          . ' and i.icat=c.catid'\r
+                          . ' and i.idraft=0'  // exclude drafts\r
+                                       // don't show future items\r
+                          . ' and i.itime<=' . mysqldate($this->getCorrectTime());\r
+\r
+               if ($this->getSelectedCategory())\r
+                       $query .= ' and i.icat=' . $this->getSelectedCategory() . ' ';\r
+\r
+\r
+               $query .= $extraQuery;\r
+\r
+               if ($mode == '')\r
+                       $query .= ' ORDER BY i.itime DESC';\r
+\r
+               return $query;\r
+       }\r
+\r
+       /**\r
+         * Shows the archivelist using the given template\r
+         */\r
+       function showArchiveList($template, $mode = 'month', $limit = 0) {\r
+               global $CONF, $catid, $manager;\r
+\r
+               if ($catid)\r
+                       $linkparams = array('catid' => $catid);\r
+\r
+               $template =& $manager->getTemplate($template);\r
+               $data['blogid'] = $this->getID();\r
+\r
+               echo TEMPLATE::fill($template['ARCHIVELIST_HEADER'],$data);\r
+\r
+               $query = 'SELECT itime, SUBSTRING(itime,1,4) AS Year, SUBSTRING(itime,6,2) AS Month, SUBSTRING(itime,9,2) as Day FROM '.sql_table('item')\r
+               . ' WHERE iblog=' . $this->getID()\r
+               . ' and itime <=' . mysqldate($this->getCorrectTime())  // don't show future items!\r
+               . ' and idraft=0'; // don't show draft items\r
+\r
+               if ($catid)\r
+                       $query .= ' and icat=' . intval($catid);\r
+\r
+               $query .= ' GROUP BY Year, Month';\r
+               if ($mode == 'day')\r
+                       $query .= ', Day';\r
+\r
+\r
+               $query .= ' ORDER BY itime DESC';\r
+\r
+               if ($limit > 0)\r
+                       $query .= ' LIMIT ' . intval($limit);\r
+\r
+               $res = sql_query($query);\r
+\r
+               while ($current = mysql_fetch_object($res)) {\r
+                       $current->itime = strtotime($current->itime);   // string time -> unix timestamp\r
+\r
+                       if ($mode == 'day') {\r
+                               $archivedate    = date('Y-m-d',$current->itime);\r
+                               $archive['day'] = date('d',$current->itime);\r
+                               $data['day']    = date('d',$current->itime);\r
+                       } else {\r
+                               $archivedate = date('Y-m',$current->itime);\r
+                       }\r
+                       $data['month'] = date('m',$current->itime);\r
+                       $data['year'] = date('Y',$current->itime);\r
+                       $data['archivelink'] = createArchiveLink($this->getID(),$archivedate,$linkparams);\r
+\r
+                       $manager->notify(\r
+                               'PreArchiveListItem',\r
+                               array(\r
+                                       'listitem' => &$data\r
+                               )\r
+                       );\r
+\r
+                       $temp = TEMPLATE::fill($template['ARCHIVELIST_LISTITEM'],$data);\r
+                       echo strftime($temp,$current->itime);\r
+\r
+               }\r
+\r
+               mysql_free_result($res);\r
+\r
+               echo TEMPLATE::fill($template['ARCHIVELIST_FOOTER'],$data);\r
+       }\r
+\r
+\r
+       /**\r
+         * Shows the list of categories using a given template\r
+         */\r
+       function showCategoryList($template) {\r
+               global $CONF, $manager;\r
+\r
+               // determine arguments next to catids\r
+               // I guess this can be done in a better way, but it works\r
+               global $archive, $archivelist;\r
+\r
+               $linkparams = array();\r
+               if ($archive) {\r
+                       $blogurl = createArchiveLink($this->getID(), $archive, '');\r
+                       $linkparams['blogid'] = $this->getID();\r
+                       $linkparams['archive'] = $archive;\r
+               } else if ($archivelist) {\r
+                       $blogurl = createArchiveListLink($this->getID(), '');\r
+                       $linkparams['archivelist'] = $archivelist;\r
+               } else {\r
+                       $blogurl = createBlogidLink($this->getID(), '');\r
+                       $linkparams['blogid'] = $this->getID();\r
+               }\r
+\r
+               //$blogurl = $this->getURL() . $qargs;\r
+               //$blogurl = createBlogLink($this->getURL(), $linkparams);\r
+\r
+               $template =& $manager->getTemplate($template);\r
+\r
+               echo TEMPLATE::fill((isset($template['CATLIST_HEADER']) ? $template['CATLIST_HEADER'] : null),\r
+                                                       array(\r
+                                                               'blogid' => $this->getID(),\r
+                                                               'blogurl' => $blogurl,\r
+                                                               'self' => $CONF['Self']\r
+                                                       ));\r
+\r
+               $query = 'SELECT catid, cdesc as catdesc, cname as catname FROM '.sql_table('category').' WHERE cblog=' . $this->getID() . ' ORDER BY cname ASC';\r
+               $res = sql_query($query);\r
+\r
+\r
+               while ($data = mysql_fetch_assoc($res)) {\r
+                       $data['blogid'] = $this->getID();\r
+                       $data['blogurl'] = $blogurl;\r
+                       $data['catlink'] = createLink(\r
+                                                               'category',\r
+                                                               array(\r
+                                                                       'catid' => $data['catid'],\r
+                                                                       'name' => $data['catname'],\r
+                                                                       'extra' => $linkparams\r
+                                                               )\r
+                                                          );\r
+                       $data['self'] = $CONF['Self'];\r
+\r
+                       $manager->notify(\r
+                               'PreCategoryListItem',\r
+                               array(\r
+                                       'listitem' => &$data\r
+                               )\r
+                       );\r
+                       \r
+                       echo TEMPLATE::fill((isset($template['CATLIST_LISTITEM']) ? $template['CATLIST_LISTITEM'] : null), $data);\r
+                       //$temp = TEMPLATE::fill((isset($template['CATLIST_LISTITEM']) ? $template['CATLIST_LISTITEM'] : null), $data);\r
+                       //echo strftime($temp, $current->itime);\r
+\r
+               }\r
+\r
+               mysql_free_result($res);\r
+\r
+               echo TEMPLATE::fill((isset($template['CATLIST_FOOTER']) ? $template['CATLIST_FOOTER'] : null),\r
+                                                       array(\r
+                                                               'blogid' => $this->getID(),\r
+                                                               'blogurl' => $blogurl,\r
+                                                               'self' => $CONF['Self']\r
+                                                       ));\r
+       }\r
+       \r
+       /**\r
+         * Shows a list of all blogs in the system using a given template\r
+         * ordered by  number, name, shortname or description\r
+         * in ascending or descending order        \r
+         */\r
+       function showBlogList($template, $bnametype, $orderby, $direction) {\r
+               global $CONF, $manager;\r
+               \r
+               switch ($orderby) {\r
+                       case 'number':\r
+                               $orderby='bnumber';\r
+                               break;\r
+                       case 'name':\r
+                               $orderby='bname';\r
+                               break;\r
+                       case 'shortname':\r
+                               $orderby='bshortname';\r
+                               break;\r
+                       case 'description':\r
+                               $orderby='bdesc';\r
+                               break;\r
+                       default:\r
+                               $orderby='bnumber';\r
+                               break;\r
+               }\r
+               \r
+               $direction=strtolower($direction);\r
+               switch ($direction) {\r
+                       case 'asc':\r
+                               $direction='ASC';\r
+                               break;\r
+                       case 'desc':\r
+                               $direction='DESC';\r
+                               break;\r
+                       default:\r
+                               $direction='ASC';\r
+                               break;\r
+               }\r
+               \r
+               $template =& $manager->getTemplate($template);\r
+               \r
+               echo TEMPLATE::fill((isset($template['BLOGLIST_HEADER']) ? $template['BLOGLIST_HEADER'] : null),\r
+                                                       array(\r
+                                                               'sitename' => $CONF['SiteName'],\r
+                                                               'siteurl' => $CONF['IndexURL']\r
+                                                       ));\r
+               \r
+               $query = 'SELECT bnumber, bname, bshortname, bdesc, burl FROM '.sql_table('blog').' ORDER BY '.$orderby.' '.$direction;\r
+               $res = sql_query($query);\r
+               \r
+               while ($data = mysql_fetch_assoc($res)) {\r
+               \r
+                       $list = array();\r
+               \r
+//                     $list['bloglink'] = createLink('blog', array('blogid' => $data['bnumber']));\r
+                       $list['bloglink'] = createBlogidLink($data['bnumber']);\r
+               \r
+                       $list['blogdesc'] = $data['bdesc'];\r
+                       \r
+                       $list['blogurl'] = $data['burl'];\r
+                       \r
+                       if ($bnametype=='shortname') {\r
+                               $list['blogname'] = $data['bshortname'];\r
+                       }\r
+                       else { // all other cases\r
+                               $list['blogname'] = $data['bname'];\r
+                       }\r
+                       \r
+                       $manager->notify(\r
+                               'PreBlogListItem',\r
+                               array(\r
+                                       'listitem' => &$list\r
+                               )\r
+                       );\r
+                       \r
+                       echo TEMPLATE::fill((isset($template['BLOGLIST_LISTITEM']) ? $template['BLOGLIST_LISTITEM'] : null), $list);\r
+                       \r
+               }\r
+               \r
+               mysql_free_result($res);\r
+               \r
+               echo TEMPLATE::fill((isset($template['BLOGLIST_FOOTER']) ? $template['BLOGLIST_FOOTER'] : null),\r
+                                                       array(\r
+                                                               'sitename' => $CONF['SiteName'],\r
+                                                               'siteurl' => $CONF['IndexURL']\r
+                                                       ));\r
+\r
+       }\r
+\r
+       /**\r
+         * Blogsettings functions\r
+         */\r
+\r
+       function readSettings() {\r
+               $query =  'SELECT *'\r
+                          . ' FROM '.sql_table('blog')\r
+                          . ' WHERE bnumber=' . $this->blogid;\r
+               $res = sql_query($query);\r
+\r
+               $this->isValid = (mysql_num_rows($res) > 0);\r
+               if (!$this->isValid)\r
+                       return;\r
+\r
+               $this->settings = mysql_fetch_assoc($res);\r
+       }\r
+\r
+       function writeSettings() {\r
+\r
+               // (can't use floatval since not available prior to PHP 4.2)\r
+               $offset = $this->getTimeOffset();\r
+               if (!is_float($offset))\r
+                       $offset = intval($offset);\r
+\r
+               $query =  'UPDATE '.sql_table('blog')\r
+                          . " SET bname='" . addslashes($this->getName()) . "',"\r
+                          . "     bshortname='". addslashes($this->getShortName()) . "',"\r
+                          . "     bcomments=". intval($this->commentsEnabled()) . ","\r
+                          . "     bmaxcomments=" . intval($this->getMaxComments()) . ","\r
+                          . "     btimeoffset=" . $offset . ","\r
+                          . "     bpublic=" . intval($this->isPublic()) . ","\r
+                          . "     breqemail=" . intval($this->emailRequired()) . ","\r
+                          . "     bsendping=" . intval($this->sendPing()) . ","\r
+                          . "     bconvertbreaks=" . intval($this->convertBreaks()) . ","\r
+                          . "     ballowpast=" . intval($this->allowPastPosting()) . ","\r
+                          . "     bnotify='" . addslashes($this->getNotifyAddress()) . "',"\r
+                          . "     bnotifytype=" . intval($this->getNotifyType()) . ","\r
+                          . "     burl='" . addslashes($this->getURL()) . "',"\r
+                          . "     bupdate='" . addslashes($this->getUpdateFile()) . "',"\r
+                          . "     bdesc='" . addslashes($this->getDescription()) . "',"\r
+                          . "     bdefcat=" . intval($this->getDefaultCategory()) . ","\r
+                          . "     bdefskin=" . intval($this->getDefaultSkin()) . ","\r
+                          . "     bincludesearch=" . intval($this->getSearchable())\r
+                          . " WHERE bnumber=" . intval($this->getID());\r
+               sql_query($query);\r
+\r
+       }\r
+\r
+\r
+\r
+       // update update file if requested\r
+       function updateUpdatefile() {\r
+                if ($this->getUpdateFile()) {\r
+                       $f_update = fopen($this->getUpdateFile(),'w');\r
+                       fputs($f_update,$this->getCorrectTime());\r
+                       fclose($f_update);\r
+                }\r
+\r
+       }\r
+\r
+       function isValidCategory($catid) {\r
+               $query = 'SELECT * FROM '.sql_table('category').' WHERE cblog=' . $this->getID() . ' and catid=' . intval($catid);\r
+               $res = sql_query($query);\r
+               return (mysql_num_rows($res) != 0);\r
+       }\r
+\r
+       function getCategoryName($catid) {\r
+               $res = sql_query('SELECT cname FROM '.sql_table('category').' WHERE cblog='.$this->getID().' and catid=' . intval($catid));\r
+               $o = mysql_fetch_object($res);\r
+               return $o->cname;\r
+       }\r
+\r
+       function getCategoryDesc($catid) {\r
+               $res = sql_query('SELECT cdesc FROM '.sql_table('category').' WHERE cblog='.$this->getID().' and catid=' . intval($catid));\r
+               $o = mysql_fetch_object($res);\r
+               return $o->cdesc;\r
+       }\r
+\r
+       function getCategoryIdFromName($name) {\r
+               $res = sql_query('SELECT catid FROM '.sql_table('category').' WHERE cblog='.$this->getID().' and cname="' . addslashes($name) . '"');\r
+               if (mysql_num_rows($res) > 0) {\r
+                       $o = mysql_fetch_object($res);\r
+                       return $o->catid;\r
+               } else {\r
+                       return $this->getDefaultCategory();\r
+               }\r
+       }\r
+\r
+       function sendPing() {\r
+               return $this->getSetting('bsendping');\r
+       }\r
+\r
+       function setPingUserland($val) {\r
+               $this->setSetting('bsendping',$val);\r
+       }\r
+\r
+       function convertBreaks() {\r
+               return $this->getSetting('bconvertbreaks');\r
+       }\r
+\r
+       function insertJavaScriptInfo($authorid = '') {\r
+               global $member, $CONF;\r
+\r
+               if ($authorid == '')\r
+                       $authorid = $member->getID();\r
+\r
+               ?>\r
+               <script type="text/javascript">\r
+                       setConvertBreaks(<?php echo  $this->convertBreaks() ? 'true' : 'false' ?>);\r
+                       setMediaUrl("<?php echo $CONF['MediaURL']?>");\r
+                       setAuthorId(<?php echo $authorid?>);\r
+               </script><?php  }\r
+\r
+       function setConvertBreaks($val) {\r
+               $this->setSetting('bconvertbreaks',$val);\r
+       }\r
+       function setAllowPastPosting($val) {\r
+               $this->setSetting('ballowpast',$val);\r
+       }\r
+       function allowPastPosting() {\r
+               return $this->getSetting('ballowpast');\r
+       }\r
+\r
+       function getCorrectTime($t=0) {\r
+               if ($t == 0) $t = time();\r
+               return ($t + 3600 * $this->getTimeOffset());\r
+       }\r
+\r
+       function getName() {\r
+               return $this->getSetting('bname');\r
+       }\r
+\r
+       function getShortName() {\r
+               return $this->getSetting('bshortname');\r
+       }\r
+\r
+       function getMaxComments() {\r
+               return $this->getSetting('bmaxcomments');\r
+       }\r
+\r
+       function getNotifyAddress() {\r
+               return $this->getSetting('bnotify');\r
+       }\r
+\r
+       function getNotifyType() {\r
+               return $this->getSetting('bnotifytype');\r
+       }\r
+\r
+       function notifyOnComment() {\r
+               $n = $this->getNotifyType();\r
+               return (($n != 0) && (($n % 3) == 0));\r
+       }\r
+\r
+       function notifyOnVote() {\r
+               $n = $this->getNotifyType();\r
+               return (($n != 0) && (($n % 5) == 0));\r
+       }\r
+\r
+       function notifyOnNewItem() {\r
+               $n = $this->getNotifyType();\r
+               return (($n != 0) && (($n % 7) == 0));\r
+       }\r
+\r
+       function setNotifyType($val) {\r
+               $this->setSetting('bnotifytype',$val);\r
+       }\r
+\r
+\r
+       function getTimeOffset() {\r
+               return $this->getSetting('btimeoffset');\r
+       }\r
+\r
+       function commentsEnabled() {\r
+               return $this->getSetting('bcomments');\r
+       }\r
+\r
+       function getURL() {\r
+               return $this->getSetting('burl');\r
+       }\r
+\r
+       function getDefaultSkin() {\r
+               return $this->getSetting('bdefskin');\r
+       }\r
+\r
+       function getUpdateFile() {\r
+               return $this->getSetting('bupdate');\r
+       }\r
+\r
+       function getDescription() {\r
+               return $this->getSetting('bdesc');\r
+       }\r
+\r
+       function isPublic() {\r
+               return $this->getSetting('bpublic');\r
+       }\r
+\r
+       function emailRequired() {\r
+               return $this->getSetting('breqemail');\r
+       }\r
+\r
+       function getSearchable() {\r
+               return $this->getSetting('bincludesearch');\r
+       }\r
+\r
+       function getDefaultCategory() {\r
+               return $this->getSetting('bdefcat');\r
+       }\r
+\r
+       function setPublic($val) {\r
+               $this->setSetting('bpublic',$val);\r
+       }\r
+\r
+       function setSearchable($val) {\r
+               $this->setSetting('bincludesearch',$val);\r
+       }\r
+\r
+       function setDescription($val) {\r
+               $this->setSetting('bdesc',$val);\r
+       }\r
+\r
+       function setUpdateFile($val) {\r
+               $this->setSetting('bupdate',$val);\r
+       }\r
+\r
+       function setDefaultSkin($val) {\r
+               $this->setSetting('bdefskin',$val);\r
+       }\r
+\r
+       function setURL($val) {\r
+               $this->setSetting('burl',$val);\r
+       }\r
+\r
+       function setName($val) {\r
+               $this->setSetting('bname',$val);\r
+       }\r
+\r
+       function setShortName($val) {\r
+               $this->setSetting('bshortname',$val);\r
+       }\r
+\r
+       function setCommentsEnabled($val) {\r
+               $this->setSetting('bcomments',$val);\r
+       }\r
+\r
+       function setMaxComments($val) {\r
+               $this->setSetting('bmaxcomments',$val);\r
+       }\r
+\r
+       function setNotifyAddress($val) {\r
+               $this->setSetting('bnotify',$val);\r
+       }\r
+\r
+       function setEmailRequired($val) {\r
+               $this->setSetting('breqemail',$val);\r
+       }\r
+\r
+       function setTimeOffset($val) {\r
+               // check validity of value\r
+               // 1. replace , by . (common mistake)\r
+               $val = str_replace(',','.',$val);\r
+               // 2. cast to float or int\r
+               if (is_numeric($val) && strstr($val,'.5')) {\r
+                       $val = (float) $val;\r
+               } else {\r
+                       $val = intval($val);\r
+               }\r
+\r
+               $this->setSetting('btimeoffset',$val);\r
+       }\r
+\r
+       function setDefaultCategory($val) {\r
+               $this->setSetting('bdefcat',$val);\r
+       }\r
+\r
+       function getSetting($key) {\r
+               return $this->settings[$key];\r
+       }\r
+\r
+       function setSetting($key,$value) {\r
+               $this->settings[$key] = $value;\r
+       }\r
+\r
+\r
+       // tries to add a member to the team. Returns false if the member was already on\r
+       // the team\r
+       function addTeamMember($memberid, $admin) {\r
+               global $manager;\r
+\r
+               $memberid = intval($memberid);\r
+               $admin = intval($admin);\r
+\r
+               // check if member is already a member\r
+               $tmem = MEMBER::createFromID($memberid);\r
+\r
+               if ($tmem->isTeamMember($this->getID()))\r
+                       return 0;\r
+\r
+               $manager->notify(\r
+                       'PreAddTeamMember',\r
+                       array(\r
+                               'blog' => &$this,\r
+                               'member' => &$tmem,\r
+                               'admin' => &$admin\r
+                       )\r
+               );\r
+\r
+               // add to team\r
+               $query = 'INSERT INTO '.sql_table('team').' (TMEMBER, TBLOG, TADMIN) '\r
+                          . 'VALUES (' . $memberid .', '.$this->getID().', "'.$admin.'")';\r
+               sql_query($query);\r
+\r
+               $manager->notify(\r
+                       'PostAddTeamMember',\r
+                       array(\r
+                               'blog' => &$this,\r
+                               'member' => &$tmem,\r
+                               'admin' => $admin\r
+                       )\r
+\r
+               );\r
+\r
+               $logMsg = sprintf(_TEAM_ADD_NEWTEAMMEMBER, $tmem->getDisplayName(), $memberid, $this->getName());\r
+               ACTIONLOG::add(INFO, $logMsg);\r
+\r
+               return 1;\r
+       }\r
+\r
+       function getID() {\r
+               return intVal($this->blogid);\r
+       }\r
+\r
+       // returns true if there is a blog with the given shortname (static)\r
+       function exists($name) {\r
+               $r = sql_query('select * FROM '.sql_table('blog').' WHERE bshortname="'.addslashes($name).'"');\r
+               return (mysql_num_rows($r) != 0);\r
+       }\r
+\r
+       // returns true if there is a blog with the given ID (static)\r
+       function existsID($id) {\r
+               $r = sql_query('select * FROM '.sql_table('blog').' WHERE bnumber='.intval($id));\r
+               return (mysql_num_rows($r) != 0);\r
+       }\r
+\r
+        // flag there is a future post pending\r
+        function setFuturePost() {\r
+               $query =  'UPDATE '.sql_table('blog')\r
+                          . " SET bfuturepost='1' WHERE bnumber=" . $this->getID();\r
+               sql_query($query);\r
+        }\r
+\r
+       // clear there is a future post pending\r
+       function clearFuturePost() {\r
+               $query =  'UPDATE '.sql_table('blog')\r
+                          . " SET bfuturepost='0' WHERE bnumber=" . $this->getID();\r
+               sql_query($query);\r
+       }\r
+\r
+       // check if we should throw justPosted event\r
+       function checkJustPosted() {\r
+               global $manager;\r
+\r
+               if ($this->settings['bfuturepost'] == 1) {\r
+                       $blogid = $this->getID();\r
+                       $result = sql_query("SELECT * FROM " . sql_table('item')\r
+                                 . " WHERE iposted=0 AND iblog=" . $blogid . " AND itime<NOW()");\r
+                       if (mysql_num_rows($result) > 0) {\r
+                               // This $pinged is allow a plugin to tell other hook to the event that a ping is sent already\r
+                               // Note that the plugins's calling order is subject to thri order in the plugin list\r
+                               $pinged = false;\r
+                               $manager->notify(\r
+                                               'JustPosted',\r
+                                               array('blogid' => $blogid,\r
+                                               'pinged' => &$pinged\r
+                                               )\r
+                               );\r
+\r
+                               // clear all expired future posts\r
+                               sql_query("UPDATE " . sql_table('item') . " SET iposted='1' WHERE iblog=" . $blogid . " AND itime<NOW()");\r
+\r
+                               // check to see any pending future post, clear the flag is none \r
+                               $result = sql_query("SELECT * FROM " . sql_table('item') \r
+                                         . " WHERE iposted=0 AND iblog=" . $blogid);\r
+                               if (mysql_num_rows($result) == 0) {\r
+                                       $this->clearFuturePost();\r
+                               }\r
+                       }\r
+               }\r
+       }\r
+       \r
+       /**\r
+        * Shows the given list of items for this blog\r
+        *\r
+        * @param $itemarray\r
+        *              array of item numbers to be displayed\r
+        * @param $template\r
+        *              String representing the template _NAME_ (!)      \r
+        * @param $highlight\r
+        *              contains a query that should be highlighted\r
+        * @param $comments\r
+        *              1=show comments 0=don't show comments\r
+        * @param $dateheads\r
+        *              1=show dateheads 0=don't show dateheads\r
+        * @returns int\r
+        *              amount of items shown\r
+        */\r
+       function readLogFromList($itemarray, $template, $highlight = '', $comments = 1, $dateheads = 1) {\r
+\r
+               $query = $this->getSqlItemList($itemarray);\r
+\r
+               return $this->showUsingQuery($template, $query, $highlight, $comments, $dateheads);\r
+       }\r
+       \r
+       /**\r
+        * Returns the SQL query used to fill out templates for a list of items\r
+        *\r
+        * @param $itemarray\r
+        *              an array holding the item numbers of the items to be displayed\r
+        * @returns\r
+        *              either a full SQL query, or an empty string\r
+        * @note\r
+        *              No LIMIT clause is added. (caller should add this if multiple pages are requested)\r
+        */\r
+       function getSqlItemList($itemarray)\r
+       {\r
+               if (!is_array($itemarray)) return '';\r
+               $items = array();\r
+               foreach ($itemarray as $value) {\r
+                       if (intval($value)) $items[] = intval($value);\r
+               }\r
+               if (!count($items)) return '';\r
+               //$itemlist = implode(',',$items);\r
+               $i = count($items);\r
+               $query = '';\r
+               foreach ($items as $value) {\r
+                       $query .= '('\r
+                                       .   'SELECT'\r
+                                       .   ' i.inumber as itemid,'\r
+                                       .   ' i.ititle as title,'\r
+                                       .   ' i.ibody as body,'\r
+                                       .   ' m.mname as author,'\r
+                                       .   ' m.mrealname as authorname,'\r
+                                       .   ' i.itime,'\r
+                                       .   ' i.imore as more,'\r
+                                       .   ' m.mnumber as authorid,'\r
+                                       .   ' m.memail as authormail,'\r
+                                       .   ' m.murl as authorurl,'\r
+                                       .   ' c.cname as category,'\r
+                                       .   ' i.icat as catid,'\r
+                                       .   ' i.iclosed as closed';\r
+                       \r
+                       $query .= ' FROM '\r
+                                       . sql_table('item') . ' as i, '\r
+                                       . sql_table('member') . ' as m, '\r
+                                       . sql_table('category').' as c'\r
+                                   . ' WHERE'\r
+                                       .     ' i.iblog   = ' . $this->blogid\r
+                                   . ' and i.iauthor = m.mnumber'\r
+                                   . ' and i.icat    = c.catid'\r
+                                   . ' and i.idraft  = 0'      // exclude drafts\r
+                                               // don't show future items\r
+                                   . ' and i.itime  <= ' . mysqldate($this->getCorrectTime());\r
+\r
+                       //$query .= ' and i.inumber IN ('.$itemlist.')';\r
+                       $query .= ' and i.inumber = '.intval($value);\r
+                       $query .= ')';\r
+                       $i--;\r
+                       if ($i) $query .= ' UNION ';\r
+               }\r
+               \r
+               return $query;\r
+       }\r
+\r
+}\r
+\r
+?>
\ No newline at end of file
index 897fc80..1b24f14 100644 (file)
@@ -2,7 +2,7 @@
 
 /*
  * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/)
- * Copyright (C) 2002-2007 The Nucleus Group
+ * Copyright (C) 2002-2009 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
@@ -14,8 +14,8 @@
  * A class to parses plugin calls inside items
  *
  * @license http://nucleuscms.org/license.txt GNU General Public License
- * @copyright Copyright (C) 2002-2007 The Nucleus Group
- * @version $Id: BODYACTIONS.php,v 1.7 2008-02-08 09:31:22 kimitake Exp $
+ * @copyright Copyright (C) 2002-2009 The Nucleus Group
+ * @version $Id$
  * @version $NucleusJP: BODYACTIONS.php,v 1.6.2.1 2007/08/08 05:27:14 kimitake Exp $
  */
 
@@ -44,10 +44,11 @@ class BODYACTIONS extends BaseActions {
        function parse_plugin($pluginName) {
                global $manager;
 
-               // only continue when the plugin is really installed
-               if (!$manager->pluginInstalled('NP_' . $pluginName)) {
-                       return;
-               }
+               // should be already tested from the parser (PARSER.php)\r
+               // only continue when the plugin is really installed\r
+               /*if (!$manager->pluginInstalled('NP_' . $pluginName)) {\r
+                       return;\r
+               }*/\r
 
                $plugin =& $manager->getPlugin('NP_' . $pluginName);
                if (!$plugin) return;
index fa56c52..7035a8a 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 /*
  * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/)
- * Copyright (C) 2002-2007 The Nucleus Group
+ * Copyright (C) 2002-2009 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
  * It should never be used on it's own
  *
  * @license http://nucleuscms.org/license.txt GNU General Public License
- * @copyright Copyright (C) 2002-2007 The Nucleus Group
- * @version $Id: BaseActions.php,v 1.3 2007-02-04 06:28:46 kimitake Exp $
+ * @copyright Copyright (C) 2002-2009 The Nucleus Group
+ * @version $Id$
  * @version $NucleusJP: BaseActions.php,v 1.2 2006/07/20 08:01:52 kimitake Exp $
  */
 
-class BaseActions {
-
-       // depth level for includes (max. level is 3)
-       var $level;
-
-       // array of evaluated conditions (true/false). The element at the end is the one for the most nested
-       // if block.
-       var $if_conditions;
-
-       // in the "elseif" / "elseifnot" sequences, if one of the conditions become "true" remained conditions should not
-       // be tested. this variable (actually a stack) holds this information.
-       var $if_execute;
-
-       // at all times, can be evaluated to either true if the current block needs to be displayed. This
-       // variable is used to decide to skip skinvars in parts that will never be outputted.
-       var $if_currentlevel;
-
-       // contains a search string with keywords that need to be highlighted. These get parsed into $aHighlight
-       var $strHighlight;
-
-       // array of keywords that need to be highlighted in search results (see the highlight()
-       // and parseHighlight() methods)
-       var $aHighlight;
-
-       // reference to the parser object that is using this object as actions-handler
-       var $parser;
-
-       function BaseActions() {
-               $this->level = 0;
-
-               // if nesting level
-               $this->if_conditions = array(); // array on which condition values are pushed/popped
-               $this->if_execute = array();    // array on which condition values are pushed/popped
-               $this->if_currentlevel = 1;             // 1 = current level is displayed; 0 = current level not displayed
-
-               // highlights
-               $this->strHighlight = '';                       // full highlight
-               $this->aHighlight = array();            // parsed highlight
-
-       }
-
-       // include file (no parsing of php)
-       function parse_include($filename) {
-               @readfile($this->getIncludeFileName($filename));
-       }
-
-       // php-include file
-       function parse_phpinclude($filename) {
-               includephp($this->getIncludeFileName($filename));
-       }
-
-       // parsed include
-       function parse_parsedinclude($filename) {
-               // check current level
-               if ($this->level > 3) return;   // max. depth reached (avoid endless loop)
-               $filename = $this->getIncludeFileName($filename);
-               if (!file_exists($filename)) return '';
-
-               $fsize = filesize($filename);
-
-               // nothing to include
-               if ($fsize <= 0)
-                       return;
-
-               $this->level = $this->level + 1;
-
-               // read file
-               $fd = fopen ($filename, 'r');
-               $contents = fread ($fd, $fsize);
-               fclose ($fd);
-
-               // parse file contents
-               $this->parser->parse($contents);
-
-               $this->level = $this->level - 1;
-       }
-
-       /**
-        * Returns the correct location of the file to be included, according to
-        * parser properties
-        *
-        * IF IncludeMode = 'skindir' => use skindir
-        */
-       function getIncludeFileName($filename) {
-               // leave absolute filenames and http urls as they are
-               if (
-                               (substr($filename,0,1) == '/')
-                       ||      (substr($filename,0,7) == 'http://')
-                       ||      (substr($filename,0,6) == 'ftp://')
-                       )
-                       return $filename;
-
-               $filename = PARSER::getProperty('IncludePrefix') . $filename;
-               if (PARSER::getProperty('IncludeMode') == 'skindir') {
-                       global $DIR_SKINS;
-                       return $DIR_SKINS . $filename;
-               } else {
-                       return $filename;
-               }
-       }
-
-       /**
-        * Inserts an url relative to the skindir (useful when doing import/export)
-        *
-        * e.g. <skinfile(default/myfile.sth)>
-        */
-       function parse_skinfile($filename) {
-               global $CONF;
-
-               echo $CONF['SkinsURL'] . PARSER::getProperty('IncludePrefix') . $filename;
-       }
-
-       /**
-        * Sets a property for the parser
-        */
-       function parse_set($property, $value) {
-               PARSER::setProperty($property, $value);
-       }
-
-       /**
-        * Helper function: add if condition
-        */
-       function _addIfCondition($condition) {
-
-               array_push($this->if_conditions,$condition);
-
-               $this->_updateTopIfCondition();
-
-               ob_start();
-       }
-
-       function _updateTopIfCondition() {
-               if (sizeof($this->if_conditions) == 0)
-                       $this->if_currentlevel = 1;
-               else
-                       $this->if_currentlevel = $this->if_conditions[sizeof($this->if_conditions) - 1];
-       }
-
-       /**
-        * Helper function for elseif / elseifnot
-        */
-       function _addIfExecute() {
-               array_push($this->if_execute, 0);
-       }
-
-       /**
-        * Helper function for elseif / elseifnot
-        * @param string condition to be fullfilled
-        */
-       function _updateIfExecute($condition) {
-               $index = sizeof($this->if_execute) - 1;
-               $this->if_execute[$index] = $this->if_execute[$index] || $condition;
-       }
-
-       /**
-        * returns the currently top if condition
-        */
-       function _getTopIfCondition() {
-               return $this->if_currentlevel;
-       }
-
-       /**
-        * Sets the search terms to be highlighted
-        *
-        * @param $highlight
-        *              A series of search terms
-        */
-       function setHighlight($highlight) {
-               $this->strHighlight = $highlight;
-               if ($highlight) {
-                       $this->aHighlight = parseHighlight($highlight);
-               }
-       }
-
-       /**
-        * Applies the highlight to the given piece of text
-        *
-        * @param &$data
-        *              Data that needs to be highlighted
-        * @see setHighlight
-        */
-       function highlight(&$data) {
-               if ($this->aHighlight)
-                       return highlight($data,$this->aHighlight,$this->template['SEARCH_HIGHLIGHT']);
-               else
-                       return $data;
-       }
-
-       /**
-        * Parses <%if%> statements
-        */
-       function parse_if() {
-               $this->_addIfExecute();
-
-               $args = func_get_args();
-               $condition = call_user_func_array(array(&$this,'checkCondition'), $args);
-               $this->_addIfCondition($condition);
-       }
-
-       /**
-        * Parses <%else%> statements
-        */
-       function parse_else() {
-               if (sizeof($this->if_conditions) == 0) return;
-               array_pop($this->if_conditions);
-               if ($this->if_currentlevel) {
-                       ob_end_flush();
-                       $this->_updateIfExecute(1);
-                       $this->_addIfCondition(0);
-               } elseif ($this->if_execute[sizeof($this->if_execute) - 1]) {
-                       ob_end_clean();
-                       $this->_addIfCondition(0);
-               } else {
-                       ob_end_clean();
-                       $this->_addIfCondition(1);
-               }
-       }
-
-       /**
-        * Parses <%elseif%> statements
-        */
-       function parse_elseif() {
-               if (sizeof($this->if_conditions) == 0) return;
-               array_pop($this->if_conditions);
-               if ($this->if_currentlevel) {
-                       ob_end_flush();
-                       $this->_updateIfExecute(1);
-                       $this->_addIfCondition(0);
-               } elseif ($this->if_execute[sizeof($this->if_execute) - 1]) {
-                       ob_end_clean();
-                       $this->_addIfCondition(0);
-               } else {
-                       ob_end_clean();
-                       $args = func_get_args();
-                       $condition = call_user_func_array(array(&$this,'checkCondition'), $args);
-                       $this->_addIfCondition($condition);
-               }
-       }
-
-       /**
-        * Parses <%ifnot%> statements
-        */
-       function parse_ifnot() {
-               $this->_addIfExecute();
-
-               $args = func_get_args();
-               $condition = call_user_func_array(array(&$this,'checkCondition'), $args);
-               $this->_addIfCondition(!$condition);
-       }
-
-       /**
-        * Parses <%elseifnot%> statements
-        */
-       function parse_elseifnot() {
-               if (sizeof($this->if_conditions) == 0) return;
-               array_pop($this->if_conditions);
-               if ($this->if_currentlevel) {
-                       ob_end_flush();
-                       $this->_updateIfExecute(1);
-                       $this->_addIfCondition(0);
-               } elseif ($this->if_execute[sizeof($this->if_execute) - 1]) {
-                       ob_end_clean();
-                       $this->_addIfCondition(0);
-               } else {
-                       ob_end_clean();
-                       $args = func_get_args();
-                       $condition = call_user_func_array(array(&$this,'checkCondition'), $args);
-                       $this->_addIfCondition(!$condition);
-               }
-       }
-
-       /**
-        * Ends a conditional if-block
-        * see e.g. ifcat (BLOG), ifblogsetting (PAGEFACTORY)
-        */
-       function parse_endif() {
-               // we can only close what has been opened
-               if (sizeof($this->if_conditions) == 0) return;
-
-               if ($this->if_currentlevel) {
-                       ob_end_flush();
-               } else {
-                       ob_end_clean();
-               }
-               array_pop($this->if_conditions);
-               array_pop($this->if_execute);
-
-               $this->_updateTopIfCondition();
-       }
-}
-?>
+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
+       // in the "elseif" / "elseifnot" sequences, if one of the conditions become "true" remained conditions should not\r
+       // be tested. this variable (actually a stack) holds this information.\r
+       var $if_execute;\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
+       // reference to the parser object that is using this object as actions-handler\r
+       var $parser;\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_execute = 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
+\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
+               global $skinid;\r
+               $skin = new SKIN($skinid);\r
+               $file = $this->getIncludeFileName($filename);\r
+               if (!$skin->isValid && !file_exists($file)) {\r
+                       return;\r
+               }\r
+               $parts = explode('|', $filename, 2);\r
+               if ($skin->getContent($parts[0])) {\r
+                       $contents = $skin->getContent($parts[0]);\r
+               } else {\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) 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
+\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
+        * Helper function for elseif / elseifnot\r
+        */\r
+       function _addIfExecute() {\r
+               array_push($this->if_execute, 0);\r
+       }\r
+\r
+       /**\r
+        * Helper function for elseif / elseifnot\r
+        * @param string condition to be fullfilled\r
+        */\r
+       function _updateIfExecute($condition) {\r
+               $index = sizeof($this->if_execute) - 1;\r
+               $this->if_execute[$index] = $this->if_execute[$index] || $condition;\r
+       }\r
+\r
+       /**\r
+        * returns the currently top if condition\r
+        */\r
+       function _getTopIfCondition() {\r
+               return $this->if_currentlevel;\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
+        * Parses <%if%> statements\r
+        */\r
+       function parse_if() {\r
+               $this->_addIfExecute();\r
+\r
+               $args = func_get_args();\r
+               $condition = call_user_func_array(array(&$this,'checkCondition'), $args);\r
+               $this->_addIfCondition($condition);\r
+       }\r
+\r
+       /**\r
+        * Parses <%else%> statements\r
+        */\r
+       function parse_else() {\r
+               if (sizeof($this->if_conditions) == 0) return;\r
+               array_pop($this->if_conditions);\r
+               if ($this->if_currentlevel) {\r
+                       ob_end_flush();\r
+                       $this->_updateIfExecute(1);\r
+                       $this->_addIfCondition(0);\r
+               } elseif ($this->if_execute[sizeof($this->if_execute) - 1]) {\r
+                       ob_end_clean();\r
+                       $this->_addIfCondition(0);\r
+               } else {\r
+                       ob_end_clean();\r
+                       $this->_addIfCondition(1);\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Parses <%elseif%> statements\r
+        */\r
+       function parse_elseif() {\r
+               if (sizeof($this->if_conditions) == 0) return;\r
+               array_pop($this->if_conditions);\r
+               if ($this->if_currentlevel) {\r
+                       ob_end_flush();\r
+                       $this->_updateIfExecute(1);\r
+                       $this->_addIfCondition(0);\r
+               } elseif ($this->if_execute[sizeof($this->if_execute) - 1]) {\r
+                       ob_end_clean();\r
+                       $this->_addIfCondition(0);\r
+               } else {\r
+                       ob_end_clean();\r
+                       $args = func_get_args();\r
+                       $condition = call_user_func_array(array(&$this,'checkCondition'), $args);\r
+                       $this->_addIfCondition($condition);\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Parses <%ifnot%> statements\r
+        */\r
+       function parse_ifnot() {\r
+               $this->_addIfExecute();\r
+\r
+               $args = func_get_args();\r
+               $condition = call_user_func_array(array(&$this,'checkCondition'), $args);\r
+               $this->_addIfCondition(!$condition);\r
+       }\r
+\r
+       /**\r
+        * Parses <%elseifnot%> statements\r
+        */\r
+       function parse_elseifnot() {\r
+               if (sizeof($this->if_conditions) == 0) return;\r
+               array_pop($this->if_conditions);\r
+               if ($this->if_currentlevel) {\r
+                       ob_end_flush();\r
+                       $this->_updateIfExecute(1);\r
+                       $this->_addIfCondition(0);\r
+               } elseif ($this->if_execute[sizeof($this->if_execute) - 1]) {\r
+                       ob_end_clean();\r
+                       $this->_addIfCondition(0);\r
+               } else {\r
+                       ob_end_clean();\r
+                       $args = func_get_args();\r
+                       $condition = call_user_func_array(array(&$this,'checkCondition'), $args);\r
+                       $this->_addIfCondition(!$condition);\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 ($this->if_currentlevel) {\r
+                       ob_end_flush();\r
+               } else {\r
+                       ob_end_clean();\r
+               }\r
+               array_pop($this->if_conditions);\r
+               array_pop($this->if_execute);\r
+\r
+               $this->_updateTopIfCondition();\r
+       }\r
+}\r
+?>
\ No newline at end of file
index c74584f..61328e3 100755 (executable)
  *
  * @license http://nucleuscms.org/license.txt GNU General Public License
  * @copyright Copyright (C) 2002-2007 The Nucleus Group
- * @version $Id: COMMENT.php,v 1.5 2007-02-04 06:28:46 kimitake Exp $
+ * @version $Id$
  * $NucleusJP: COMMENT.php,v 1.4 2006/07/17 20:03:44 kimitake Exp $
  */
-class COMMENT {
-
-       /**
-         * Returns the requested comment (static)
-         */
-       function getComment($commentid) {
-               $query =  'SELECT cnumber as commentid, cbody as body, cuser as user, cmail as userid, cemail as email, cmember as memberid, ctime, chost as host, mname as member, cip as ip, cblog as blogid'
-                          . ' FROM '.sql_table('comment').' left outer join '.sql_table('member').' on cmember=mnumber'
-                          . ' WHERE cnumber=' . intval($commentid);
-               $comments = sql_query($query);
-
-               $aCommentInfo = mysql_fetch_assoc($comments);
-               if ($aCommentInfo)
-               {
-                       $aCommentInfo['timestamp'] = strtotime($aCommentInfo['ctime']);
-               }
-               return $aCommentInfo;
-       }
-
-       /**
-         * prepares a comment to be saved
-         * (static)
-         */
-       function prepare($comment) {
-               $comment['user'] = strip_tags($comment['user']);
-               $comment['userid'] = strip_tags($comment['userid']);
-               $comment['email'] = strip_tags($comment['email']);
-
-               // remove quotes and newlines from user and userid
-               $comment['user'] = strtr($comment['user'], "\'\"\n",'-- ');
-               $comment['userid'] = strtr($comment['userid'], "\'\"\n",'-- ');
-               $comment['email'] = strtr($comment['email'], "\'\"\n",'-- ');
-
-               $comment['body'] = COMMENT::prepareBody($comment['body']);
-
-               return $comment;
-       }
-
-       // prepares the body of a comment (static)
-       function prepareBody($body) {
-
-               // remove newlines when too many in a row
-               $body = ereg_replace("\n.\n.\n","\n",$body);
-
-               // encode special characters as entities
-               $body = htmlspecialchars($body);
-
-               // trim away whitespace and newlines at beginning and end
-               $body = trim($body);
-
-               // add <br /> tags
-               $body = addBreaks($body);
-
-               // create hyperlinks for http:// addresses
-               // there's a testcase for this in /build/testcases/urllinking.txt
-               $replaceFrom = array(
-                       '/([^:\/\/\w]|^)((https:\/\/)([\w\.-]+)([\/\w+\.~%&?@=_:;#,-]+))/ie',
-                       '/([^:\/\/\w]|^)((http:\/\/|www\.)([\w\.-]+)([\/\w+\.~%&?@=_:;#,-]+))/ie',
-                       '/([^:\/\/\w]|^)((ftp:\/\/|ftp\.)([\w\.-]+)([\/\w+\.~%&?@=_:;#,-]+))/ie',
-                       '/([^:\/\/\w]|^)(mailto:(([a-zA-Z\@\%\.\-\+_])+))/ie'
-               );
-               $replaceTo = array(
-                       'COMMENT::createLinkCode("\\1", "\\2","https")',
-                       'COMMENT::createLinkCode("\\1", "\\2","http")',
-                       'COMMENT::createLinkCode("\\1", "\\2","ftp")',
-                       'COMMENT::createLinkCode("\\1", "\\3","mailto")'
-               );
-               $body = preg_replace($replaceFrom, $replaceTo, $body);
-
-               return $body;
-       }
-
-       function createLinkCode($pre, $url, $protocol = 'http') {
-               $post = '';
-
-               // it's possible that $url ends contains entities we don't want,
-               // since htmlspecialchars is applied _before_ URL linking
-               // move the part of URL, starting from the disallowed entity to the 'post' link part
-               $aBadEntities = array('&quot;', '&gt;', '&lt;');
-               foreach ($aBadEntities as $entity)
-               {
-                       $pos = strpos($url, $entity);
-                       if ($pos)
-                       {
-                               $post = substr($url, $pos) . $post;
-                               $url = substr($url, 0, $pos);
-
-                       }
-               }
-
-               // remove entities at end (&&&&)
-               if (preg_match('/(&\w+;)+$/i', $url, $matches)) {
-                       $post = $matches[0] . $post;    // found entities (1 or more)
-                       $url = substr($url, 0, strlen($url) - strlen($post));
-               }
-
-               // move ending comma from url to 'post' part
-               if (substr($url, strlen($url) - 1) == ',')
-               {
-                       $url = substr($url, 0, strlen($url) - 1);
-                       $post = ',' . $post;
-               }
-
-               if (!ereg('^'.$protocol.'://',$url))
-                       $linkedUrl = $protocol . (($protocol == 'mailto') ? ':' : '://') . $url;
-               else
-                       $linkedUrl = $url;
-
-
-               if ($protocol != 'mailto')
-                       $displayedUrl = $linkedUrl;
-               else
-                       $displayedUrl = $url;
-               return $pre . '<a href="'.$linkedUrl.'" rel="nofollow">'.shorten($displayedUrl,30,'...').'</a>' . $post;
-       }
-
-}
-
+class COMMENT {\r
+\r
+       /**\r
+         * Returns the requested comment\r
+         * \r
+         * @static\r
+         */\r
+       function getComment($commentid) {\r
+               $query =  'SELECT cnumber as commentid, cbody as body, cuser as user, cmail as userid, cemail as email, cmember as memberid, ctime, chost as host, mname as member, cip as ip, cblog as blogid'\r
+                          . ' FROM '.sql_table('comment').' left outer join '.sql_table('member').' on cmember=mnumber'\r
+                          . ' WHERE cnumber=' . intval($commentid);\r
+               $comments = sql_query($query);\r
+\r
+               $aCommentInfo = mysql_fetch_assoc($comments);\r
+               if ($aCommentInfo)\r
+               {\r
+                       $aCommentInfo['timestamp'] = strtotime($aCommentInfo['ctime']);\r
+               }\r
+               return $aCommentInfo;\r
+       }\r
+\r
+       /**\r
+         * Prepares a comment to be saved\r
+         *       \r
+         * @static\r
+         */\r
+       function prepare($comment) {\r
+               $comment['user'] = strip_tags($comment['user']);\r
+               $comment['userid'] = strip_tags($comment['userid']);\r
+               $comment['email'] = strip_tags($comment['email']);\r
+\r
+               // remove quotes and newlines from user and userid\r
+               $comment['user'] = strtr($comment['user'], "\'\"\n",'-- ');\r
+               $comment['userid'] = strtr($comment['userid'], "\'\"\n",'-- ');\r
+               $comment['email'] = strtr($comment['email'], "\'\"\n",'-- ');\r
+\r
+               $comment['body'] = COMMENT::prepareBody($comment['body']);\r
+\r
+               return $comment;\r
+       }\r
+\r
+       /**\r
+        * Prepares the body of a comment\r
+        *\r
+        * @ static\r
+        */             \r
+       function prepareBody($body) {\r
+\r
+               // remove newlines when too many in a row\r
+               $body = ereg_replace("\n.\n.\n","\n",$body);\r
+\r
+               // encode special characters as entities\r
+               $body = htmlspecialchars($body);\r
+\r
+               // trim away whitespace and newlines at beginning and end\r
+               $body = trim($body);\r
+\r
+               // add <br /> tags\r
+               $body = addBreaks($body);\r
+\r
+               // create hyperlinks for http:// addresses\r
+               // there's a testcase for this in /build/testcases/urllinking.txt\r
+               $replaceFrom = array(\r
+                       '/([^:\/\/\w]|^)((https:\/\/)([\w\.-]+)([\/\w+\.~%&?@=_:;#,-]+))/ie',\r
+                       '/([^:\/\/\w]|^)((http:\/\/|www\.)([\w\.-]+)([\/\w+\.~%&?@=_:;#,-]+))/ie',\r
+                       '/([^:\/\/\w]|^)((ftp:\/\/|ftp\.)([\w\.-]+)([\/\w+\.~%&?@=_:;#,-]+))/ie',\r
+                       '/([^:\/\/\w]|^)(mailto:(([a-zA-Z\@\%\.\-\+_])+))/ie'\r
+               );\r
+               $replaceTo = array(\r
+                       'COMMENT::createLinkCode("\\1", "\\2","https")',\r
+                       'COMMENT::createLinkCode("\\1", "\\2","http")',\r
+                       'COMMENT::createLinkCode("\\1", "\\2","ftp")',\r
+                       'COMMENT::createLinkCode("\\1", "\\3","mailto")'\r
+               );\r
+               $body = preg_replace($replaceFrom, $replaceTo, $body);\r
+\r
+               return $body;\r
+       }\r
+\r
+       /**\r
+        * Creates a link code for unlinked URLs with different protocols\r
+        *\r
+        * @ static\r
+        */     \r
+       function createLinkCode($pre, $url, $protocol = 'http') {\r
+               $post = '';\r
+\r
+               // it's possible that $url ends contains entities we don't want,\r
+               // since htmlspecialchars is applied _before_ URL linking\r
+               // move the part of URL, starting from the disallowed entity to the 'post' link part\r
+               $aBadEntities = array('&quot;', '&gt;', '&lt;');\r
+               foreach ($aBadEntities as $entity)\r
+               {\r
+                       $pos = strpos($url, $entity);\r
+                       if ($pos)\r
+                       {\r
+                               $post = substr($url, $pos) . $post;\r
+                               $url = substr($url, 0, $pos);\r
+\r
+                       }\r
+               }\r
+\r
+               // remove entities at end (&&&&)\r
+               if (preg_match('/(&\w+;)+$/i', $url, $matches)) {\r
+                       $post = $matches[0] . $post;    // found entities (1 or more)\r
+                       $url = substr($url, 0, strlen($url) - strlen($post));\r
+               }\r
+\r
+               // move ending comma from url to 'post' part\r
+               if (substr($url, strlen($url) - 1) == ',')\r
+               {\r
+                       $url = substr($url, 0, strlen($url) - 1);\r
+                       $post = ',' . $post;\r
+               }\r
+\r
+               if (!ereg('^'.$protocol.'://',$url))\r
+                       $linkedUrl = $protocol . (($protocol == 'mailto') ? ':' : '://') . $url;\r
+               else\r
+                       $linkedUrl = $url;\r
+\r
+\r
+               if ($protocol != 'mailto')\r
+                       $displayedUrl = $linkedUrl;\r
+               else\r
+                       $displayedUrl = $url;\r
+               return $pre . '<a href="'.$linkedUrl.'" rel="nofollow">'.shorten($displayedUrl,30,'...').'</a>' . $post;\r
+       }\r
+\r
+}\r
+\r
 ?>
\ No newline at end of file
index 17f6e85..2344a1b 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 /*
  * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/)
- * Copyright (C) 2002-2007 The Nucleus Group
+ * Copyright (C) 2002-2009 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
  * This class is used when parsing comment templates
  *
  * @license http://nucleuscms.org/license.txt GNU General Public License
- * @copyright Copyright (C) 2002-2007 The Nucleus Group
- * @version $Id: COMMENTACTIONS.php,v 1.6 2008-02-08 09:31:22 kimitake Exp $
+ * @copyright Copyright (C) 2002-2009 The Nucleus Group
+ * @version $Id$
  * @version $NucleusJP: COMMENTACTIONS.php,v 1.5.2.1 2007/08/08 05:31:31 kimitake Exp $
  */
-
-class COMMENTACTIONS extends BaseActions {
-
-       // ref to COMMENTS object which is using this object to handle
-       // its templatevars
-       var $commentsObj;
-
-       // template to use to parse the comments
-       var $template;
-
-       // comment currenlty being handled (mysql result assoc array; see COMMENTS::showComments())
-       var $currentComment;
-
-       function COMMENTACTIONS(&$comments) {
-               // call constructor of superclass first
-               $this->BaseActions();
-
-               // reference to the comments object
-               $this->setCommentsObj($comments);
-       }
-
-       function getDefinedActions() {
-               return array(
-                       'blogurl',
-                       'commentcount',
-                       'commentword',
-                       'email',
-                       'itemlink',
-                       'itemid',
-                       'itemtitle',
-                       'date',
-                       'time',
-                       'commentid',
-                       'body',
-                       'memberid',
-                       'timestamp',
-                       'host',
-                       'ip',
-                       'blogid',
-                       'authtext',
-                       'user',
-                       'userid',
-                       'userlinkraw',
-                       'userlink',
-                       'useremail',
-                       'userwebsite',
-                       'excerpt',
-                       'short',
-                       'skinfile',
-                       'set',
-                       'plugin',
-                       'include',
-                       'phpinclude',
-                       'parsedinclude'
-               );
-       }
-
-       function setParser(&$parser) {
-               $this->parser =& $parser;
-       }
-       
-       function setCommentsObj(&$commentsObj) {
-               $this->commentsObj =& $commentsObj;
-       }
-       
-       function setTemplate($template) {
-               $this->template =& $template;
-       }
-       
-       function setCurrentComment(&$comment) {
-               global $manager;
-               if ($comment['memberid'] != 0) {
-                       $comment['authtext'] = $template['COMMENTS_AUTH'];
-
-                       $mem =& $manager->getMember($comment['memberid']);
-                       $comment['user'] = $mem->getDisplayName();
-                       if ($mem->getURL())
-                               $comment['userid'] = $mem->getURL();
-                       else
-                               $comment['userid'] = $mem->getEmail();
-
-                       $comment['userlinkraw'] = createLink(
-                                                                               'member',
-                                                                               array(
-                                                                                       'memberid' => $comment['memberid'],
-                                                                                       'name' => $mem->getDisplayName(),
-                                                                                       'extra' => $this->commentsObj->itemActions->linkparams
-                                                                               )
-                                                                         );
-
-               } else {
-
-                       // create smart links
-/*                     if (isValidMailAddress($comment['userid']))
-                               $comment['userlinkraw'] = 'mailto:'.$comment['userid'];
-                       elseif (strstr($comment['userid'],'http://') != false)
-                               $comment['userlinkraw'] = $comment['userid'];
-                       elseif (strstr($comment['userid'],'www') != false)
-                               $comment['userlinkraw'] = 'http://'.$comment['userid'];*/
-                       if (strstr($comment['userid'],'http://') != false)
-                               $comment['userlinkraw'] = $comment['userid'];
-                       elseif (strstr($comment['userid'],'www') != false)
-                               $comment['userlinkraw'] = 'http://'.$comment['userid'];
-                       elseif (isValidMailAddress($comment['email']))
-                               $comment['userlinkraw'] = 'mailto:'.$comment['email'];
-                       elseif (isValidMailAddress($comment['userid']))
-                               $comment['userlinkraw'] = 'mailto:'.$comment['userid'];
-               }
-
-               $this->currentComment =& $comment;
-       }
-
-       function parse_blogurl() {
-               global $manager;
-               $blogid = getBlogIDFromItemID($this->commentsObj->itemid);
-               $blog =& $manager->getBlog($blogid);
-               echo $blog->getURL();
-       }
-
-       function parse_commentcount() {
-                       echo $this->commentsObj->commentcount;
-       }
-       
-       function parse_commentword() {
-               if ($this->commentsObj->commentcount == 1)
-                       echo $this->template['COMMENTS_ONE'];
-               else
-                       echo $this->template['COMMENTS_MANY'];
-       }
-
-       function parse_itemlink() {
-               echo createLink(
-                       'item',
-                       array(
-                               'itemid' => $this->commentsObj->itemid,
-                               'timestamp' => $this->commentsObj->itemActions->currentItem->timestamp,
-                               'title' => $this->commentsObj->itemActions->currentItem->title,
-                               'extra' => $this->commentsObj->itemActions->linkparams
-                       )
-               );
-       }
-       
-       function parse_itemid() {
-               echo $this->commentsObj->itemid;
-       }
-       
-       function parse_itemtitle($maxLength = 0) {
-               if ($maxLength == 0)
-                       $this->commentsObj->itemActions->parse_title();
-               else
-                       $this->commentsObj->itemActions->parse_syndicate_title($maxLength);
-       }
-
-       function parse_date($format = '') {
-               echo formatDate($format, $this->currentComment['timestamp'], $this->template['FORMAT_DATE'], $this->commentsObj->itemActions->blog);
-       }
-       
-       function parse_time($format = '') {
-               echo strftime(
-                               ($format == '') ? $this->template['FORMAT_TIME'] : $format,
-                               $this->currentComment['timestamp']
-                       );
-       }
-
-       function parse_commentid() {
-               echo $this->currentComment['commentid'];
-       }
-       
-       function parse_body() {
-               echo $this->highlight($this->currentComment['body']);
-       }
-       
-       function parse_memberid() {
-               echo $this->currentComment['memberid'];
-       }
-       
-       function parse_timestamp() {
-               echo $this->currentComment['timestamp'];
-       }
-       
-       function parse_host() {
-               echo $this->currentComment['host'];
-       }
-       
-       function parse_ip() {
-               echo $this->currentComment['ip'];
-       }
-       
-       function parse_blogid() {
-               echo $this->currentComment['blogid'];
-       }
-
-//     function parse_user() {
-       function parse_user($mode='') {
-               global $manager;
-               if ($mode == 'realname' && $this->currentComment['memberid'] > 0) {
-                       $member =& $manager->getMember($this->currentComment['memberid']);
-                       echo $member->getRealName();
-               } else {
-                       echo $this->currentComment['user'];
-               }
-       }
-       
-       function parse_userid() {
-                       echo $this->currentComment['userid'];
-       }
-       
-       function parse_email() {
-               $email = $this->currentComment['email'];
-               $email = str_replace('@', ' (at) ', $email);
-               $email = str_replace('.', ' (dot) ', $email);
-               echo $email;
-       }
-       
-       function parse_userlinkraw() {
-               echo $this->currentComment['userlinkraw'];
-       }
-       
-       function parse_userlink() {
-               if ($this->currentComment['userlinkraw']) {
-                       echo '<a href="'.$this->currentComment['userlinkraw'].'" rel="nofollow">'.$this->currentComment['user'].'</a>';
-               } else {
-                       echo $this->currentComment['user'];
-               }
-       }
-
-       function parse_useremail() {
-               global $manager;
-               if ($this->currentComment['memberid'] > 0)
-               {
-                       $member =& $manager->getMember($this->currentComment['memberid']);
-
-                       if ($member->email != '')
-                               echo $member->email;
-               }
-               else
-               {
-                       if (isValidMailAddress($this->currentComment['email']))
-                               echo $this->currentComment['email'];
-                       elseif (isValidMailAddress($this->currentComment['userid']))
-                               echo $this->currentComment['userid'];
-//                     if (!(strpos($this->currentComment['userlinkraw'], 'mailto:') === false))
-//                             echo str_replace('mailto:', '', $this->currentComment['userlinkraw']);
-               }
-       }
-
-       function parse_userwebsite() {
-               if (!(strpos($this->currentComment['userlinkraw'], 'http://') === false))
-                       echo $this->currentComment['userlinkraw'];
-       }
-
-       function parse_excerpt() {
-               echo stringToXML(shorten($this->currentComment['body'], 60, '...'));
-       }
-       
-       function parse_short() {
-               $tmp = strtok($this->currentComment['body'],"\n");
-               $tmp = str_replace('<br />','',$tmp);
-               echo $tmp;
-               if ($tmp != $this->currentComment['body'])
-                       $this->parser->parse($this->template['COMMENTS_CONTINUED']);
-       }
-       
-       function parse_authtext() {
-               if ($this->currentComment['memberid'] != 0)
-                       $this->parser->parse($this->template['COMMENTS_AUTH']);
-       }
-
-       /**
-         * Executes a plugin templatevar
-         *
-         * @param pluginName name of plugin (without the NP_)
-         *
-         * extra parameters can be added
-         */
-       function parse_plugin($pluginName) {
-               global $manager;
-
-               // only continue when the plugin is really installed
-               if (!$manager->pluginInstalled('NP_' . $pluginName))
-                       return;
-
-               $plugin =& $manager->getPlugin('NP_' . $pluginName);
-               if (!$plugin) return;
-
-               // get arguments
-               $params = func_get_args();
-
-               // remove plugin name
-               array_shift($params);
-
-               // pass info on current item and current comment as well
-               $params = array_merge(array(&$this->currentComment),$params);
-               $params = array_merge(array(&$this->commentsObj->itemActions->currentItem),$params);
-
-               call_user_func_array(array(&$plugin,'doTemplateCommentsVar'), $params);
-       }
-}
-?>
+\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
+                       'blogurl',\r
+                       'commentcount',\r
+                       'commentword',\r
+                       'email',\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
+                       'useremail',\r
+                       'userwebsite',\r
+                       'excerpt',\r
+                       'short',\r
+                       'skinfile',\r
+                       'set',\r
+                       'plugin',\r
+                       'include',\r
+                       'phpinclude',\r
+                       'parsedinclude'\r
+               );\r
+       }\r
+\r
+       function setParser(&$parser) {\r
+               $this->parser =& $parser;\r
+       }\r
+       \r
+       function setCommentsObj(&$commentsObj) {\r
+               $this->commentsObj =& $commentsObj;\r
+       }\r
+       \r
+       function setTemplate($template) {\r
+               $this->template =& $template;\r
+       }\r
+       \r
+       function setCurrentComment(&$comment) {\r
+               global $manager;\r
+               if ($comment['memberid'] != 0) {\r
+                       $comment['authtext'] = $template['COMMENTS_AUTH'];\r
+\r
+                       $mem =& $manager->getMember($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'] = createLink(\r
+                                                                               'member',\r
+                                                                               array(\r
+                                                                                       'memberid' => $comment['memberid'],\r
+                                                                                       'name' => $mem->getDisplayName(),\r
+                                                                                       'extra' => $this->commentsObj->itemActions->linkparams\r
+                                                                               )\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
+                       if (strstr($comment['userid'],'http://') != false)\r
+                               $comment['userlinkraw'] = $comment['userid'];\r
+                       elseif (strstr($comment['userid'],'www') != false)\r
+                               $comment['userlinkraw'] = 'http://'.$comment['userid'];\r
+                       elseif (isValidMailAddress($comment['email']))\r
+                               $comment['userlinkraw'] = 'mailto:'.$comment['email'];\r
+                       elseif (isValidMailAddress($comment['userid']))\r
+                               $comment['userlinkraw'] = 'mailto:'.$comment['userid'];\r
+               }\r
+\r
+               $this->currentComment =& $comment;\r
+       }\r
+\r
+       /**\r
+        * Parse templatevar authtext\r
+        */\r
+       function parse_authtext() {\r
+               if ($this->currentComment['memberid'] != 0)\r
+                       $this->parser->parse($this->template['COMMENTS_AUTH']);\r
+       }\r
+\r
+       /**\r
+        * Parse templatevar blogid\r
+        */\r
+       function parse_blogid() {\r
+               echo $this->currentComment['blogid'];\r
+       }\r
+\r
+       /**\r
+        * Parse templatevar blogurl\r
+        */\r
+       function parse_blogurl() {\r
+               global $manager;\r
+               $blogid = getBlogIDFromItemID($this->commentsObj->itemid);\r
+               $blog =& $manager->getBlog($blogid);\r
+               echo $blog->getURL();\r
+       }\r
+\r
+       /**\r
+        * Parse templatevar body\r
+        */\r
+       function parse_body() {\r
+               echo $this->highlight($this->currentComment['body']);\r
+       }\r
+\r
+       /**\r
+        * Parse templatevar commentcount\r
+        */\r
+       function parse_commentcount() {\r
+                       echo $this->commentsObj->commentcount;\r
+       }\r
+\r
+       /**\r
+        * Parse templatevar commentid\r
+        */\r
+       function parse_commentid() {\r
+               echo $this->currentComment['commentid'];\r
+       }\r
+\r
+       /**\r
+        * Parse templatevar commentword\r
+        */\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
+       /**\r
+        * Parse templatevar date\r
+        */\r
+       function parse_date($format = '') {\r
+               echo formatDate($format, $this->currentComment['timestamp'], $this->template['FORMAT_DATE'], $this->commentsObj->itemActions->blog);\r
+       }\r
+       \r
+       /**\r
+        * Parse templatevar email\r
+        */\r
+       function parse_email() {\r
+               $email = $this->currentComment['email'];\r
+               $email = str_replace('@', ' (at) ', $email);\r
+               $email = str_replace('.', ' (dot) ', $email);\r
+               echo $email;\r
+       }\r
+\r
+       /**\r
+        * Parse templatevar excerpt\r
+        */\r
+       function parse_excerpt() {\r
+               echo stringToXML(shorten($this->currentComment['body'], 60, '...'));\r
+       }\r
+\r
+       /**\r
+        * Parse templatevar host\r
+        */\r
+       function parse_host() {\r
+               echo $this->currentComment['host'];\r
+       }\r
+\r
+       /**\r
+        * Parse templatevar ip\r
+        */\r
+       function parse_ip() {\r
+               echo $this->currentComment['ip'];\r
+       }\r
+\r
+       /**\r
+        * Parse templatevar itemid\r
+        */\r
+       function parse_itemid() {\r
+               echo $this->commentsObj->itemid;\r
+       }\r
+\r
+       /**\r
+        * Parse templatevar itemlink\r
+        */\r
+       function parse_itemlink() {\r
+               echo createLink(\r
+                       'item',\r
+                       array(\r
+                               'itemid' => $this->commentsObj->itemid,\r
+                               'timestamp' => $this->commentsObj->itemActions->currentItem->timestamp,\r
+                               'title' => $this->commentsObj->itemActions->currentItem->title,\r
+                               'extra' => $this->commentsObj->itemActions->linkparams\r
+                       )\r
+               );\r
+       }\r
+\r
+       /**\r
+        * Parse templatevar itemtitle\r
+        */\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
+       /**\r
+        * Parse templatevar memberid\r
+        */\r
+       function parse_memberid() {\r
+               echo $this->currentComment['memberid'];\r
+       }\r
+\r
+       /**\r
+        * Parse templatevar short\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
+\r
+       /**\r
+        * Parse templatevar time\r
+        */\r
+       function parse_time($format = '') {\r
+               echo strftime(\r
+                               ($format == '') ? $this->template['FORMAT_TIME'] : $format,\r
+                               $this->currentComment['timestamp']\r
+                       );\r
+       }\r
+\r
+       /**\r
+        * Parse templatevar timestamp\r
+        */\r
+       function parse_timestamp() {\r
+               echo $this->currentComment['timestamp'];\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
+        * Parse templatevar user\r
+        */\r
+       function parse_user($mode='') {\r
+               global $manager;\r
+               if ($mode == 'realname' && $this->currentComment['memberid'] > 0) {\r
+                       $member =& $manager->getMember($this->currentComment['memberid']);\r
+                       echo $member->getRealName();\r
+               } else {\r
+                       echo $this->currentComment['user'];\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Parse templatevar useremail\r
+        */\r
+       function parse_useremail() {\r
+               global $manager;\r
+               if ($this->currentComment['memberid'] > 0)\r
+               {\r
+                       $member =& $manager->getMember($this->currentComment['memberid']);\r
+\r
+                       if ($member->email != '')\r
+                               echo $member->email;\r
+               }\r
+               else\r
+               {\r
+                       if (isValidMailAddress($this->currentComment['email']))\r
+                               echo $this->currentComment['email'];\r
+                       elseif (isValidMailAddress($this->currentComment['userid']))\r
+                               echo $this->currentComment['userid'];\r
+//                     if (!(strpos($this->currentComment['userlinkraw'], 'mailto:') === false))\r
+//                             echo str_replace('mailto:', '', $this->currentComment['userlinkraw']);\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Parse templatevar userid\r
+        */\r
+       function parse_userid() {\r
+                       echo $this->currentComment['userid'];\r
+       }\r
+\r
+\r
+       /**\r
+        * Parse templatevar userlink\r
+        */\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
+\r
+       /**\r
+        * Parse templatevar userlinkraw\r
+        */\r
+       function parse_userlinkraw() {\r
+               echo $this->currentComment['userlinkraw'];\r
+       }\r
+       \r
+       /**\r
+        * Parse templatevar userwebsite\r
+        */\r
+       function parse_userwebsite() {\r
+               if (!(strpos($this->currentComment['userlinkraw'], 'http://') === false))\r
+                       echo $this->currentComment['userlinkraw'];\r
+       }\r
+\r
+}\r
+?>
\ No newline at end of file
index ec2ecc4..2154946 100755 (executable)
@@ -2,7 +2,7 @@
 
 /*
  * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/)
- * Copyright (C) 2002-2007 The Nucleus Group
+ * Copyright (C) 2002-2009 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
  * 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.10 2008-02-08 09:31:22 kimitake Exp $
+ * @copyright Copyright (C) 2002-2009 The Nucleus Group
+ * @version $Id$
  * $NucleusJP: COMMENTS.php,v 1.9.2.1 2007/08/08 05:32:21 kimitake 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;
-
-               // email required protection
-               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;
-       }
-
-}
-
-?>
+\r
+if ( !function_exists('requestVar') ) exit;\r
+require_once dirname(__FILE__) . '/COMMENTACTIONS.php';\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
+       /**\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.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'\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
+        * Adds a new comment to the database\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
+               // email required protection\r
+               if ($settings->emailRequired() && strlen($comment['email']) == 0 && !$member->isLoggedIn()) {\r
+                       return _ERROR_EMAIL_REQUIRED;\r
+               }\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
+                       $comment['email'] = '';\r
+               } else {\r
+                       $comment['memberid'] = 0;\r
+               }\r
+\r
+               // spam check\r
+               $continue = false;\r
+               $plugins = array();\r
+\r
+               if (isset($manager->subscriptions['ValidateForm']))\r
+                       $plugins = array_merge($plugins, $manager->subscriptions['ValidateForm']);\r
+\r
+               if (isset($manager->subscriptions['PreAddComment']))\r
+                       $plugins = array_merge($plugins, $manager->subscriptions['PreAddComment']);\r
+\r
+               if (isset($manager->subscriptions['PostAddComment']))\r
+                       $plugins = array_merge($plugins, $manager->subscriptions['PostAddComment']);\r
+\r
+               $plugins = array_unique($plugins);\r
+\r
+               while (list(,$plugin) = each($plugins)) {\r
+                       $p = $manager->getPlugin($plugin);\r
+                       $continue = $continue || $p->supportsFeature('handleSpam');\r
+               }\r
+\r
+               $spamcheck = array (\r
+                       'type'          => 'comment',\r
+                       'body'          => $comment['body'],\r
+                       'id'        => $comment['itemid'],\r
+                       'live'          => true,\r
+                       'return'        => $continue\r
+               );\r
+\r
+               if ($member->isLoggedIn()) {\r
+                       $spamcheck['author'] = $member->displayname;\r
+                       $spamcheck['email'] = $member->email;\r
+               } else {\r
+                       $spamcheck['author'] = $comment['user'];\r
+                       $spamcheck['email'] = $comment['email'];\r
+                       $spamcheck['url'] = $comment['userid'];\r
+               }\r
+\r
+               $manager->notify('SpamCheck', array ('spamcheck' => &$spamcheck));\r
+\r
+               if (!$continue && isset($spamcheck['result']) && $spamcheck['result'] == true)\r
+                       return _ERROR_COMMENTS_SPAM;\r
+\r
+\r
+               // isValidComment returns either "1" or an error message\r
+               $isvalid = $this->isValidComment($comment, $spamcheck);\r
+               if ($isvalid != 1)\r
+                       return $isvalid;\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
+                       $temp = parse_url($CONF['Self']);\r
+                       if ($temp['scheme']) {\r
+                               $mailto_msg .= createItemLink($this->itemid) . "\n\n";\r
+                       } else {\r
+                               $tempurl = $settings->getURL();\r
+                               if (substr($tempurl, -1) == '/' || substr($tempurl, -4) == '.php') {\r
+                                       $mailto_msg .= $tempurl . '?itemid=' . $this->itemid . "\n\n";\r
+                               } else {\r
+                                       $mailto_msg .= $tempurl . '/?itemid=' . $this->itemid . "\n\n";\r
+                               }\r
+                       }\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['email']);\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, 'spamcheck' => &$spamcheck));\r
+\r
+               $name           = addslashes($comment['user']);\r
+               $url            = addslashes($comment['userid']);\r
+               $email      = addslashes($comment['email']);\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
+               $qSql       = 'SELECT COUNT(*) AS result '\r
+                                       . 'FROM ' . sql_table('comment')\r
+                                       . ' WHERE '\r
+                                       .      'cmail   = "' . $url . '"'\r
+                                       . ' AND cmember = "' . $memberid . '"'\r
+                                       . ' AND cbody   = "' . $body . '"'\r
+                                       . ' AND citem   = "' . $itemid . '"'\r
+                                       . ' AND cblog   = "' . $blogid . '"';\r
+               $result     = (integer) quickQuery($qSql);\r
+               if ($result > 0) {\r
+                       return _ERROR_BADACTION;\r
+               }\r
+\r
+               $query = 'INSERT INTO '.sql_table('comment').' (CUSER, CMAIL, CEMAIL, CMEMBER, CBODY, CITEM, CTIME, CHOST, CIP, CBLOG) '\r
+                          . "VALUES ('$name', '$url', '$email', $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, 'spamcheck' => &$spamcheck));\r
+\r
+               // succeeded !\r
+               return true;\r
+       }\r
+\r
+       /**\r
+        * Checks if a comment is valid and call plugins\r
+        * that can check if the comment is a spam comment        \r
+        */\r
+       function isValidComment(&$comment, & $spamcheck) {\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
+               if ((strlen($comment['email']) != 0) && !(isValidMailAddress($comment['email']))) {\r
+                       return _ERROR_BADMAILADDRESS;\r
+               }\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, 'spamcheck' => &$spamcheck));\r
+\r
+               return $result;\r
+       }\r
+\r
+}\r
+\r
+?>
\ No newline at end of file
index 5bcaafd..d0a7604 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 /*
  * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/)
- * Copyright (C) 2002-2007 The Nucleus Group
+ * Copyright (C) 2002-2009 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
@@ -14,8 +14,8 @@
  * Part of the code for the Nucleus admin area
  *
  * @license http://nucleuscms.org/license.txt GNU General Public License
- * @copyright Copyright (C) 2002-2007 The Nucleus Group
- * @version $Id: ENCAPSULATE.php,v 1.5 2008-02-08 09:31:22 kimitake Exp $
+ * @copyright Copyright (C) 2002-2009 The Nucleus Group
+ * @version $Id$
  * @version $NucleusJP: ENCAPSULATE.php,v 1.4.2.1 2007/08/08 05:32:54 kimitake Exp $
  */
 
@@ -28,7 +28,7 @@ class ENCAPSULATE {
          *
          * Passes on the amount of results found (for further encapsulation)
          */
-       function doEncapsulate($call, $params, $errorMessage = 'No entries') {
+       function doEncapsulate($call, $params, $errorMessage = _ENCAPSULATE_ENCAPSULATE_NOENTRY) {
                // start output buffering
                ob_start();
 
index 3a55fef..7d25d63 100755 (executable)
@@ -2,7 +2,7 @@
 \r
 /*\r
  * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/)\r
- * Copyright (C) 2002-2007 The Nucleus Group\r
+ * Copyright (C) 2002-2009 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
  * A class representing an item\r
  *\r
  * @license http://nucleuscms.org/license.txt GNU General Public License\r
- * @copyright Copyright (C) 2002-2007 The Nucleus Group\r
- * @version $Id: ITEM.php,v 1.8 2008-02-08 09:31:22 kimitake Exp $\r
+ * @copyright Copyright (C) 2002-2009 The Nucleus Group\r
+ * @version $Id$\r
  * $NucleusJP: ITEM.php,v 1.7.2.3 2008/02/07 06:13:30 kimitake Exp $\r
  */\r
 class ITEM {\r
 \r
        var $itemid;\r
 \r
+       /**\r
+         * Constructor of an ITEM object\r
+         * \r
+         * @param integer $itemid id of the item\r
+         */\r
        function ITEM($itemid) {\r
                $this->itemid = $itemid;\r
        }\r
 \r
        /**\r
          * Returns one item with the specific itemid\r
-         * (static)\r
+         * \r
+         * @param integer $itemid id of the item\r
+         * @param boolean $allowdraft\r
+         * @param boolean $allowfuture\r
+         * @static\r
          */\r
        function getitem($itemid, $allowdraft, $allowfuture) {\r
                global $manager;\r
@@ -71,9 +80,10 @@ class ITEM {
         * 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
+        * Returns an array with status info:\r
+        * status = 'added', 'error', 'newcategory'\r
         *\r
-        * (static)\r
+        * @static\r
         */\r
        function createFromRequest() {\r
                 global $member, $manager;\r
@@ -170,7 +180,9 @@ class ITEM {
 \r
 \r
        /**\r
-         * Updates an item (static)\r
+         * Updates an item\r
+         *\r
+         * @static\r
          */\r
        function update($itemid, $catid, $title, $body, $more, $closed, $wasdraft, $publish, $timestamp = 0) {\r
                global $manager;\r
@@ -235,6 +247,13 @@ class ITEM {
                                $blog->sendNewItemNotification($itemid, $title, $body);\r
                }\r
 \r
+               // save back to drafts          \r
+               if (!$wasdraft && !$publish) {\r
+                       $query .= ', idraft=1';\r
+                       // set timestamp back to zero for a draft\r
+                       $query .= ", itime=" . mysqldate($timestamp);\r
+               }\r
+\r
                // update timestamp when needed\r
                if ($timestamp != 0)\r
                        $query .= ", itime=" . mysqldate($timestamp);\r
@@ -258,7 +277,11 @@ class ITEM {
 \r
        }\r
 \r
-       // move an item to another blog (no checks, static)\r
+       /**\r
+        * Move an item to another blog (no checks)\r
+        *\r
+        * @static\r
+        */\r
        function move($itemid, $new_catid) {\r
                global $manager;\r
 \r
@@ -302,12 +325,14 @@ class ITEM {
                global $manager, $member;\r
 \r
                $itemid = intval($itemid);\r
+\r
                // check to ensure only those allow to alter the item can\r
                // proceed\r
                if (!$member->canAlterItem($itemid)) {\r
                        return 1;\r
                }\r
 \r
+\r
                $manager->notify('PreDeleteItem', array('itemid' => $itemid));\r
 \r
                // delete item\r
@@ -322,9 +347,15 @@ class ITEM {
                NucleusPlugin::_deleteOptionValues('item', $itemid);\r
 \r
                $manager->notify('PostDeleteItem', array('itemid' => $itemid));\r
+\r
+               return 0;\r
        }\r
 \r
-       // returns true if there is an item with the given ID (static)\r
+       /**\r
+        * Returns true if there is an item with the given ID\r
+        *\r
+        * @static\r
+        */\r
        function exists($id,$future,$draft) {\r
                global $manager;\r
 \r
@@ -349,9 +380,10 @@ class ITEM {
         * Tries to create an draft 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
+        * Returns an array with status info:\r
+        * status = 'added', 'error', 'newcategory'\r
         *\r
-        * (static)\r
+        * @static\r
         *\r
         * Used by xmlHTTPRequest AutoDraft\r
         */\r
@@ -364,9 +396,9 @@ class ITEM {
                $i_more = postVar('more');\r
 \r
                if(_CHARSET != 'UTF-8'){\r
-                       $i_body = mb_convert_encoding($i_body, _CHARSET, "UTF-8");\r
+                       $i_body  = mb_convert_encoding($i_body, _CHARSET, "UTF-8");\r
                        $i_title = mb_convert_encoding($i_title, _CHARSET, "UTF-8");\r
-                       $i_more = mb_convert_encoding($i_more, _CHARSET, "UTF-8");\r
+                       $i_more  = mb_convert_encoding($i_more, _CHARSET, "UTF-8");\r
                }\r
                //$i_actiontype = postVar('actiontype');\r
                $i_closed = intPostVar('closed');\r
@@ -428,4 +460,4 @@ class ITEM {
 \r
 }\r
 \r
-?>\r
+?>
\ No newline at end of file
index 2cbef56..f069a5d 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 /*
  * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/)
- * Copyright (C) 2002-2007 The Nucleus Group
+ * Copyright (C) 2002-2009 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
  * (see nucleus/documentation/index.html#license for more info)
  */
 /**
- * This class to parse item templates
+ * This class is used to parse item templates
  *
  * @license http://nucleuscms.org/license.txt GNU General Public License
- * @copyright Copyright (C) 2002-2007 The Nucleus Group
- * @version $Id: ITEMACTIONS.php,v 1.6 2008-02-08 09:31:22 kimitake Exp $
+ * @copyright Copyright (C) 2002-2009 The Nucleus Group
+ * @version $Id$
  * @version $NucleusJP: ITEMACTIONS.php,v 1.5.2.3 2007/10/30 19:05:20 kmorimatsu Exp $
  */
-class ITEMACTIONS extends BaseActions {
-
-       // contains an assoc array with parameters that need to be included when
-       // generating links to items/archives/... (e.g. catid)
-       var $linkparams;
-
-       // true when the current user is a blog admin (and thus allowed to edit all items)
-       var $allowEditAll;
-
-       // timestamp of last visit
-       var $lastVisit;
-
-       // item currently being handled (mysql result object, see BLOG::showUsingQuery)
-       var $currentItem;
-
-       // reference to the blog currently being displayed
-       var $blog;
-
-       // associative array with template info (part name => contents)
-       var $template;
-
-       // true when comments need to be displayed
-       var $showComments;
-
-       function ITEMACTIONS(&$blog) {
-               // call constructor of superclass first
-               $this->BaseActions();
-
-               // extra parameters for created links
-               global $catid;
-               if ($catid)
-                       $this->linkparams = array('catid' => $catid);
-
-               // check if member is blog admin (and thus allowed to edit all items)
-               global $member;
-               $this->allowEditAll = ($member->isLoggedIn() && $member->blogAdminRights($blog->getID()));
-               $this->setBlog($blog);
-       }
-
-       function getDefinedActions() {
-               return array(
-                       'blogid',
-                       'title',
-                       'body',
-                       'more',
-                       'smartbody',
-                       'itemid',
-                       'morelink',
-                       'category',
-                       'categorylink',
-                       'author',
-                       'authorid',
-                       'authorlink',
-                       'catid',
-                       'karma',
-                       'date',
-                       'time',
-                       'query',
-                       'itemlink',
-                       'blogurl',
-                       'closed',
-                       'syndicate_title',
-                       'syndicate_description',
-                       'karmaposlink',
-                       'karmaneglink',
-                       'new',
-                       'image',
-                       'popup',
-                       'media',
-                       'daylink',
-                       'query',
-                       'include',
-                       'phpinclude',
-                       'parsedinclude',
-                       'skinfile',
-                       'set',
-                       'plugin',
-                       'edit',
-                       'editlink',
-                       'editpopupcode',
-                       'comments',
-                       'relevance'/*,
-                       'if',
-                       'else',
-                       'endif',
-                       'elseif',
-                       'ifnot',
-                       'elseifnot'*/
-               );
-       }
-
-       function setLastVisit($lastVisit) {
-               $this->lastVisit = $lastVisit;
-       }
-       
-       function setParser(&$parser) {
-               $this->parser =& $parser;
-       }
-       
-       function setCurrentItem(&$item) {
-               $this->currentItem =& $item;
-       }
-       
-       function setBlog(&$blog) {
-               $this->blog =& $blog;
-       }
-       
-       function setTemplate($template) {
-               $this->template =& $template;
-       }
-       
-       function setShowComments($val) {
-               $this->showComments = $val;
-       }
-
-       // methods used by parser to insert content
-
-       function parse_blogid() {
-               echo $this->blog->getID();
-       }
-       
-       function parse_body() {
-               $this->highlightAndParse($this->currentItem->body);
-       }
-       
-       function parse_more() {
-               $this->highlightAndParse($this->currentItem->more);
-       }
-       
-       function parse_itemid() {
-               echo $this->currentItem->itemid;
-       }
-       
-       function parse_category() {
-               echo $this->currentItem->category;
-       }
-       
-       function parse_categorylink() {
-               echo createLink('category', array('catid' => $this->currentItem->catid, 'name' => $this->currentItem->category));
-       }
-       
-       function parse_catid() {
-               echo $this->currentItem->catid;
-       }
-       
-       function parse_authorid() {
-               echo $this->currentItem->authorid;
-       }
-       
-       function parse_authorlink() {
-               echo createLink(
-                       'member',
-                       array(
-                               'memberid' => $this->currentItem->authorid,
-                               'name' => $this->currentItem->author,
-                               'extra' => $this->linkparams
-                       )
-               );
-       }
-       
-       function parse_query() {
-               echo $this->strHighlight;
-       }
-       
-       function parse_itemlink() {
-               echo createLink(
-                       'item',
-                       array(
-                               'itemid' => $this->currentItem->itemid,
-                               'title' => $this->currentItem->title,
-                               'timestamp' => $this->currentItem->timestamp,
-                               'extra' => $this->linkparams
-                       )
-               );
-       }
-       
-       function parse_blogurl() {
-               echo $this->blog->getURL();
-       }
-       
-       function parse_closed() {
-               echo $this->currentItem->closed;
-       }
-       
-       function parse_relevance() {
-               echo round($this->currentItem->score,2);
-       }
-
-       function parse_title($format = '') {
-               if (is_array($this->currentItem)) {
-                       $itemtitle = $this->currentItem['title'];
-               } elseif (is_object($this->currentItem)) {
-                       $itemtitle = $this->currentItem->title;
-               }
-               switch ($format) {
-                       case 'xml':
-//                             echo stringToXML ($this->currentItem->title);
-                               echo stringToXML ($itemtitle);
-                               break;
-                       case 'attribute':
-//                             echo stringToAttribute ($this->currentItem->title);
-                               echo stringToAttribute ($itemtitle);
-                               break;
-                       case 'raw':
-//                             echo $this->currentItem->title;
-                               echo $itemtitle;
-                               break;
-                       default:
-//                             $this->highlightAndParse($this->currentItem->title);
-                               $this->highlightAndParse($itemtitle);
-                               break;
-               }
-       }
-
-       function parse_karma($type = 'totalscore') {
-               global $manager;
-
-               // get karma object
-               $karma =& $manager->getKarma($this->currentItem->itemid);
-
-               switch($type) {
-                       case 'pos':
-                               echo $karma->getNbPosVotes();
-                               break;
-                       case 'neg':
-                               echo $karma->getNbNegVotes();
-                               break;
-                       case 'votes':
-                               echo $karma->getNbOfVotes();
-                               break;
-                       case 'posp':
-                               $percentage = $karma->getNbOfVotes() ? 100 * ($karma->getNbPosVotes() / $karma->getNbOfVotes()) : 50;
-                               echo number_format($percentage,2), '%';
-                               break;
-                       case 'negp':
-                               $percentage = $karma->getNbOfVotes() ? 100 * ($karma->getNbNegVotes() / $karma->getNbOfVotes()) : 50;
-                               echo number_format($percentage,2), '%';
-                               break;
-                       case 'totalscore':
-                       default:
-                               echo $karma->getTotalScore();
-                               break;
-               }
-
-       }
-
-       function parse_author($which = '') {
-               switch($which)
-               {
-                       case 'realname':
-                               echo $this->currentItem->authorname;
-                               break;
-                       case 'id':
-                               echo $this->currentItem->authorid;
-                               break;
-                       case 'email':
-                               echo $this->currentItem->authormail;
-                               break;
-                       case 'url':
-                               echo $this->currentItem->authorurl;
-                               break;
-                       case 'name':
-                       default:
-                               echo $this->currentItem->author;
-               }
-       }
-
-       function parse_smartbody() {
-               if (!$this->currentItem->more) {
-                       $this->highlightAndParse($this->currentItem->body);
-               } else {
-                       $this->highlightAndParse($this->currentItem->more);
-               }
-       }
-
-       function parse_morelink() {
-               if ($this->currentItem->more)
-                       $this->parser->parse($this->template['MORELINK']);
-       }
-
-       function parse_date($format = '') {
-               echo formatDate($format, $this->currentItem->timestamp, $this->template['FORMAT_DATE'], $this->blog);
-       }
-
-       /**
-         * @param format optional strftime format
-         */
-       function parse_time($format = '') {
-               echo strftime($format ? $format : $this->template['FORMAT_TIME'],$this->currentItem->timestamp);
-       }
-
-       /**
-         * @param maxLength optional maximum length
-         */
-       function parse_syndicate_title($maxLength = 100) {
-               $syndicated = strip_tags($this->currentItem->title);
-               echo htmlspecialchars(shorten($syndicated,$maxLength,'...'),ENT_QUOTES);
-       }
-
-       /**
-         * @param maxLength optional maximum length
-         */
-       function parse_syndicate_description($maxLength = 250, $addHighlight = 0) {
-               $syndicated = strip_tags($this->currentItem->body);
-               if ($addHighlight) {
-                       $tmp_highlight = htmlspecialchars(shorten($syndicated,$maxLength,'...'),ENT_QUOTES);
-                       echo $this->highlightAndParse($tmp_highlight);
-               } else {
-                       echo htmlspecialchars(shorten($syndicated,$maxLength,'...'),ENT_QUOTES);
-               }
-       }
-
-       function parse_karmaposlink($text = '') {
-               global $CONF;
-               $link = $CONF['ActionURL'] . '?action=votepositive&amp;itemid='.$this->currentItem->itemid;
-               echo $text ? '<a href="'.$link.'">'.$text.'</a>' : $link;
-       }
-
-       function parse_karmaneglink($text = '') {
-               global $CONF;
-               $link = $CONF['ActionURL'] . '?action=votenegative&amp;itemid='.$this->currentItem->itemid;
-               echo $text ? '<a href="'.$link.'">'.$text.'</a>' : $link;
-       }
-
-       function parse_new() {
-               if (($this->lastVisit != 0) && ($this->currentItem->timestamp > $this->lastVisit))
-                       echo $this->template['NEW'];
-       }
-
-
-       function parse_daylink() {
-               echo createArchiveLink($this->blog->getID(), strftime('%Y-%m-%d',$this->currentItem->timestamp), $this->linkparams);
-       }
-
-       function parse_comments($maxToShow = 0) {
-               if ($maxToShow == 0)
-                       $maxToShow = $this->blog->getMaxComments();
-
-               // add comments
-               if ($this->showComments && $this->blog->commentsEnabled()) {
-                       $comments =& new COMMENTS($this->currentItem->itemid);
-                       $comments->setItemActions($this);
-                       $comments->showComments($this->template, $maxToShow, $this->currentItem->closed ? 0 : 1, $this->strHighlight);
-               }
-       }
-
-       /**
-         * Executes a plugin templatevar
-         *
-         * @param pluginName name of plugin (without the NP_)
-         *
-         * extra parameters can be added
-         */
-       function parse_plugin($pluginName) {
-               global $manager;
-
-               // only continue when the plugin is really installed
-               if (!$manager->pluginInstalled('NP_' . $pluginName))
-                       return;
-
-               $plugin =& $manager->getPlugin('NP_' . $pluginName);
-               if (!$plugin) return;
-
-               // get arguments
-               $params = func_get_args();
-
-               // remove plugin name
-               array_shift($params);
-
-               // add item reference (array_unshift didn't work)
-               $params = array_merge(array(&$this->currentItem),$params);
-
-               call_user_func_array(array(&$plugin,'doTemplateVar'), $params);
-       }
-
-       function parse_edit() {
-               global $member, $CONF;
-               if ($this->allowEditAll || ($member->isLoggedIn() && ($member->getID() == $this->currentItem->authorid)) ) {
-                       $this->parser->parse($this->template['EDITLINK']);
-               }
-       }
-
-       function parse_editlink() {
-               global $CONF;
-               echo $CONF['AdminURL'],'bookmarklet.php?action=edit&amp;itemid=',$this->currentItem->itemid;
-       }
-
-       function parse_editpopupcode() {
-               echo "if (event &amp;&amp; event.preventDefault) event.preventDefault();winbm=window.open(this.href,'nucleusbm','scrollbars=yes,width=600,height=550,left=10,top=10,status=yes,resizable=yes');winbm.focus();return false;";
-       }
-
-       // helper functions
-
-       /**
-        * Parses highlighted text, with limited actions only (to prevent not fully trusted team members
-        * from hacking your weblog.
-        * 'plugin variables in items' implementation by Andy
-        */
-       function highlightAndParse(&$data) {
-               $actions =& new BODYACTIONS($this->blog);
-               $parser =& new PARSER($actions->getDefinedActions(), $actions);
-               $actions->setTemplate($this->template);
-               $actions->setHighlight($this->strHighlight);
-               $actions->setCurrentItem($this->currentItem);
-               //$actions->setParser($parser);
-               $parser->parse($actions->highlight($data));
-       }
-
-       /*
-       // this is the function previous to the 'plugin variables in items' implementation by Andy
-       function highlightAndParse(&$data) {
-               // allow only a limited subset of actions (do not allow includes etc, they might be evil)
-               $this->parser->actions = array('image','media','popup');
-               $tmp_highlight = $this->highlight($data);
-               $this->parser->parse($tmp_highlight);
-               $this->parser->actions = $this->getDefinedActions();
-       }
-       */
-
-}
-       
-
-
-?>
+class ITEMACTIONS extends BaseActions {\r
+\r
+       // contains an assoc array with parameters that need to be included when\r
+       // generating links to items/archives/... (e.g. catid)\r
+       var $linkparams;\r
+\r
+       // true when the current user is a blog admin (and thus allowed to edit all items)\r
+       var $allowEditAll;\r
+\r
+       // timestamp of last visit\r
+       var $lastVisit;\r
+\r
+       // item currently being handled (mysql result object, see BLOG::showUsingQuery)\r
+       var $currentItem;\r
+\r
+       // reference to the blog currently being displayed\r
+       var $blog;\r
+\r
+       // associative array with template info (part name => contents)\r
+       var $template;\r
+\r
+       // true when comments need to be displayed\r
+       var $showComments;\r
+\r
+       function ITEMACTIONS(&$blog) {\r
+               // call constructor of superclass first\r
+               $this->BaseActions();\r
+\r
+               // extra parameters for created links\r
+               global $catid;\r
+               if ($catid)\r
+                       $this->linkparams = array('catid' => $catid);\r
+\r
+               // check if member is blog admin (and thus allowed to edit all items)\r
+               global $member;\r
+               $this->allowEditAll = ($member->isLoggedIn() && $member->blogAdminRights($blog->getID()));\r
+               $this->setBlog($blog);\r
+       }\r
+\r
+       /**\r
+         * Returns an array with the actions that are defined\r
+         * in the ITEMACTIONS class \r
+         */\r
+       function getDefinedActions() {\r
+               return array(\r
+                       'blogid',\r
+                       'title',\r
+                       'body',\r
+                       'more',\r
+                       'smartbody',\r
+                       'itemid',\r
+                       'morelink',\r
+                       'category',\r
+                       'categorylink',\r
+                       'author',\r
+                       'authorid',\r
+                       'authorlink',\r
+                       'catid',\r
+                       'karma',\r
+                       'date',\r
+                       'time',\r
+                       'query',\r
+                       'itemlink',\r
+                       'blogurl',\r
+                       'closed',\r
+                       'syndicate_title',\r
+                       'syndicate_description',\r
+                       'karmaposlink',\r
+                       'karmaneglink',\r
+                       'new',\r
+                       'image',\r
+                       'popup',\r
+                       'media',\r
+                       'daylink',\r
+                       'query',\r
+                       'include',\r
+                       'phpinclude',\r
+                       'parsedinclude',\r
+                       'skinfile',\r
+                       'set',\r
+                       'plugin',\r
+                       'edit',\r
+                       'editlink',\r
+                       'editpopupcode',\r
+                       'comments',\r
+                       'relevance'/*,\r
+                       'if',\r
+                       'else',\r
+                       'endif',\r
+                       'elseif',\r
+                       'ifnot',\r
+                       'elseifnot'*/\r
+               );\r
+       }\r
+\r
+       function setLastVisit($lastVisit) {\r
+               $this->lastVisit = $lastVisit;\r
+       }\r
+       \r
+       function setParser(&$parser) {\r
+               $this->parser =& $parser;\r
+       }\r
+       \r
+       function setCurrentItem(&$item) {\r
+               $this->currentItem =& $item;\r
+       }\r
+       \r
+       function setBlog(&$blog) {\r
+               $this->blog =& $blog;\r
+       }\r
+       \r
+       function setTemplate($template) {\r
+               $this->template =& $template;\r
+       }\r
+       \r
+       function setShowComments($val) {\r
+               $this->showComments = $val;\r
+       }\r
+\r
+       // methods used by parser to insert content\r
+\r
+\r
+       /**\r
+        * Parse templatevar blogid\r
+        */\r
+       function parse_blogid() {\r
+               echo $this->blog->getID();\r
+       }\r
+       \r
+       /**\r
+        * Parse templatevar body\r
+        */\r
+       function parse_body() {\r
+               $this->highlightAndParse($this->currentItem->body);\r
+       }\r
+       \r
+       /**\r
+        * Parse templatevar more\r
+        */\r
+       function parse_more() {\r
+               $this->highlightAndParse($this->currentItem->more);\r
+       }\r
+       \r
+       /**\r
+        * Parse templatevar itemid\r
+        */\r
+       function parse_itemid() {\r
+               echo $this->currentItem->itemid;\r
+       }\r
+\r
+       /**\r
+        * Parse templatevar category\r
+        */     \r
+       function parse_category() {\r
+               echo $this->currentItem->category;\r
+       }\r
+       \r
+       /**\r
+        * Parse templatevar categorylink\r
+        */\r
+       function parse_categorylink() {\r
+               echo createLink('category', array('catid' => $this->currentItem->catid, 'name' => $this->currentItem->category));\r
+       }\r
+       \r
+       /**\r
+        * Parse templatevar catid\r
+        */\r
+       function parse_catid() {\r
+               echo $this->currentItem->catid;\r
+       }\r
+       \r
+       /**\r
+        * Parse templatevar authorid\r
+        */\r
+       function parse_authorid() {\r
+               echo $this->currentItem->authorid;\r
+       }\r
+       \r
+       /**\r
+        * Parse templatevar authorlink\r
+        */\r
+       function parse_authorlink() {\r
+               echo createLink(\r
+                       'member',\r
+                       array(\r
+                               'memberid' => $this->currentItem->authorid,\r
+                               'name' => $this->currentItem->author,\r
+                               'extra' => $this->linkparams\r
+                       )\r
+               );\r
+       }\r
+       \r
+       /**\r
+        * Parse templatevar query\r
+        */\r
+       function parse_query() {\r
+               echo $this->strHighlight;\r
+       }\r
+       \r
+       /**\r
+        * Parse templatevar itemlink\r
+        */\r
+       function parse_itemlink() {\r
+               echo createLink(\r
+                       'item',\r
+                       array(\r
+                               'itemid' => $this->currentItem->itemid,\r
+                               'title' => $this->currentItem->title,\r
+                               'timestamp' => $this->currentItem->timestamp,\r
+                               'extra' => $this->linkparams\r
+                       )\r
+               );\r
+       }\r
+       \r
+       /**\r
+        * Parse templatevar blogurl\r
+        */\r
+       function parse_blogurl() {\r
+               echo $this->blog->getURL();\r
+       }\r
+       \r
+       /**\r
+        * Parse templatevar closed\r
+        */\r
+       function parse_closed() {\r
+               echo $this->currentItem->closed;\r
+       }\r
+       \r
+       /**\r
+        * Parse templatevar relevance\r
+        */\r
+       function parse_relevance() {\r
+               echo round($this->currentItem->score,2);\r
+       }\r
+\r
+       /**\r
+        * Parse templatevar title\r
+        * \r
+        * @param string $format defines in which format the title is shown              \r
+        */\r
+       function parse_title($format = '') {\r
+               if (is_array($this->currentItem)) {\r
+                       $itemtitle = $this->currentItem['title'];\r
+               } elseif (is_object($this->currentItem)) {\r
+                       $itemtitle = $this->currentItem->title;\r
+               }\r
+               switch ($format) {\r
+                       case 'xml':\r
+//                             echo stringToXML ($this->currentItem->title);\r
+                               echo stringToXML ($itemtitle);\r
+                               break;\r
+                       case 'attribute':\r
+//                             echo stringToAttribute ($this->currentItem->title);\r
+                               echo stringToAttribute ($itemtitle);\r
+                               break;\r
+                       case 'raw':\r
+//                             echo $this->currentItem->title;\r
+                               echo $itemtitle;\r
+                               break;\r
+                       default:\r
+//                             $this->highlightAndParse($this->currentItem->title);\r
+                               $this->highlightAndParse($itemtitle);\r
+                               break;\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Parse templatevar karma\r
+        */\r
+       function parse_karma($type = 'totalscore') {\r
+               global $manager;\r
+\r
+               // get karma object\r
+               $karma =& $manager->getKarma($this->currentItem->itemid);\r
+\r
+               switch($type) {\r
+                       case 'pos':\r
+                               echo $karma->getNbPosVotes();\r
+                               break;\r
+                       case 'neg':\r
+                               echo $karma->getNbNegVotes();\r
+                               break;\r
+                       case 'votes':\r
+                               echo $karma->getNbOfVotes();\r
+                               break;\r
+                       case 'posp':\r
+                               $percentage = $karma->getNbOfVotes() ? 100 * ($karma->getNbPosVotes() / $karma->getNbOfVotes()) : 50;\r
+                               echo number_format($percentage,2), '%';\r
+                               break;\r
+                       case 'negp':\r
+                               $percentage = $karma->getNbOfVotes() ? 100 * ($karma->getNbNegVotes() / $karma->getNbOfVotes()) : 50;\r
+                               echo number_format($percentage,2), '%';\r
+                               break;\r
+                       case 'totalscore':\r
+                       default:\r
+                               echo $karma->getTotalScore();\r
+                               break;\r
+               }\r
+\r
+       }\r
+\r
+       /**\r
+        * Parse templatevar author\r
+        */\r
+       function parse_author($which = '') {\r
+               switch($which)\r
+               {\r
+                       case 'realname':\r
+                               echo $this->currentItem->authorname;\r
+                               break;\r
+                       case 'id':\r
+                               echo $this->currentItem->authorid;\r
+                               break;\r
+                       case 'email':\r
+                               echo $this->currentItem->authormail;\r
+                               break;\r
+                       case 'url':\r
+                               echo $this->currentItem->authorurl;\r
+                               break;\r
+                       case 'name':\r
+                       default:\r
+                               echo $this->currentItem->author;\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Parse templatevar smartbody\r
+        */\r
+       function parse_smartbody() {\r
+               if (!$this->currentItem->more) {\r
+                       $this->highlightAndParse($this->currentItem->body);\r
+               } else {\r
+                       $this->highlightAndParse($this->currentItem->more);\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Parse templatevar morelink\r
+        */\r
+       function parse_morelink() {\r
+               if ($this->currentItem->more)\r
+                       $this->parser->parse($this->template['MORELINK']);\r
+       }\r
+\r
+       /**\r
+        * Parse templatevar date\r
+        * \r
+        * @param format optional strftime format                \r
+        */\r
+       function parse_date($format = '') {\r
+               echo formatDate($format, $this->currentItem->timestamp, $this->template['FORMAT_DATE'], $this->blog);\r
+       }\r
+\r
+       /**\r
+         * Parse templatevar time\r
+         *       \r
+         * @param format optional strftime format\r
+         */\r
+       function parse_time($format = '') {\r
+               echo strftime($format ? $format : $this->template['FORMAT_TIME'],$this->currentItem->timestamp);\r
+       }\r
+\r
+       /**\r
+         * Parse templatevar syndicate_title\r
+         *\r
+         * @param maxLength optional maximum length\r
+         */\r
+       function parse_syndicate_title($maxLength = 100) {\r
+               $syndicated = strip_tags($this->currentItem->title);\r
+               echo htmlspecialchars(shorten($syndicated,$maxLength,'...'),ENT_QUOTES);\r
+       }\r
+\r
+       /**\r
+         * Parse templatevar syndicate_description\r
+         *\r
+         * @param maxLength optional maximum length\r
+         */\r
+       function parse_syndicate_description($maxLength = 250, $addHighlight = 0) {\r
+               $syndicated = strip_tags($this->currentItem->body);\r
+               if ($addHighlight) {\r
+                       $tmp_highlight = htmlspecialchars(shorten($syndicated,$maxLength,'...'),ENT_QUOTES);\r
+                       echo $this->highlightAndParse($tmp_highlight);\r
+               } else {\r
+                       echo htmlspecialchars(shorten($syndicated,$maxLength,'...'),ENT_QUOTES);\r
+               }\r
+       }\r
+\r
+       /**\r
+         * Parse templatevar karmaposlink\r
+         *\r
+         * @param string text\r
+         */\r
+       function parse_karmaposlink($text = '') {\r
+               global $CONF;\r
+               $link = $CONF['ActionURL'] . '?action=votepositive&amp;itemid='.$this->currentItem->itemid;\r
+               echo $text ? '<a href="'.$link.'">'.$text.'</a>' : $link;\r
+       }\r
+\r
+       /**\r
+         * Parse templatevar karmaneglink\r
+         *\r
+         * @param string text\r
+         */\r
+       function parse_karmaneglink($text = '') {\r
+               global $CONF;\r
+               $link = $CONF['ActionURL'] . '?action=votenegative&amp;itemid='.$this->currentItem->itemid;\r
+               echo $text ? '<a href="'.$link.'">'.$text.'</a>' : $link;\r
+       }\r
+\r
+       /**\r
+         * Parse templatevar new\r
+         */\r
+       function parse_new() {\r
+               if (($this->lastVisit != 0) && ($this->currentItem->timestamp > $this->lastVisit))\r
+                       echo $this->template['NEW'];\r
+       }\r
+\r
+       /**\r
+         * Parse templatevar daylink\r
+         */\r
+       function parse_daylink() {\r
+               echo createArchiveLink($this->blog->getID(), strftime('%Y-%m-%d',$this->currentItem->timestamp), $this->linkparams);\r
+       }\r
+\r
+       /**\r
+         * Parse templatevar comments\r
+         */\r
+       function parse_comments($maxToShow = 0) {\r
+               if ($maxToShow == 0)\r
+                       $maxToShow = $this->blog->getMaxComments();\r
+\r
+               // add comments\r
+               if ($this->showComments && $this->blog->commentsEnabled()) {\r
+                       $comments =& new COMMENTS($this->currentItem->itemid);\r
+                       $comments->setItemActions($this);\r
+                       $comments->showComments($this->template, $maxToShow, $this->currentItem->closed ? 0 : 1, $this->strHighlight);\r
+               }\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
+               // should be already tested from the parser (PARSER.php)\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
+               // add item reference (array_unshift didn't work)\r
+               $params = array_merge(array(&$this->currentItem),$params);\r
+\r
+               call_user_func_array(array(&$plugin,'doTemplateVar'), $params);\r
+       }\r
+\r
+       /**\r
+         * Parse templatevar edit\r
+         */\r
+       function parse_edit() {\r
+               global $member, $CONF;\r
+               if ($this->allowEditAll || ($member->isLoggedIn() && ($member->getID() == $this->currentItem->authorid)) ) {\r
+                       $this->parser->parse($this->template['EDITLINK']);\r
+               }\r
+       }\r
+\r
+       /**\r
+         * Parse templatevar editlink\r
+         */\r
+       function parse_editlink() {\r
+               global $CONF;\r
+               echo $CONF['AdminURL'],'bookmarklet.php?action=edit&amp;itemid=',$this->currentItem->itemid;\r
+       }\r
+\r
+       /**\r
+         * Parse templatevar editpopupcode\r
+         */\r
+       function parse_editpopupcode() {\r
+               echo "if (event &amp;&amp; event.preventDefault) event.preventDefault();winbm=window.open(this.href,'nucleusbm','scrollbars=yes,width=600,height=550,left=10,top=10,status=yes,resizable=yes');winbm.focus();return false;";\r
+       }\r
+\r
+       // helper functions\r
+\r
+       /**\r
+        * Parses highlighted text, with limited actions only (to prevent not fully trusted team members\r
+        * from hacking your weblog.\r
+        * 'plugin variables in items' implementation by Andy\r
+        */\r
+       function highlightAndParse(&$data) {\r
+               $actions =& new BODYACTIONS($this->blog);\r
+               $parser =& new PARSER($actions->getDefinedActions(), $actions);\r
+               $actions->setTemplate($this->template);\r
+               $actions->setHighlight($this->strHighlight);\r
+               $actions->setCurrentItem($this->currentItem);\r
+               //$actions->setParser($parser);\r
+               $parser->parse($actions->highlight($data));\r
+       }\r
+\r
+       /*\r
+       // this is the function previous to the 'plugin variables in items' implementation by Andy\r
+       function highlightAndParse(&$data) {\r
+               // allow only a limited subset of actions (do not allow includes etc, they might be evil)\r
+               $this->parser->actions = array('image','media','popup');\r
+               $tmp_highlight = $this->highlight($data);\r
+               $this->parser->parse($tmp_highlight);\r
+               $this->parser->actions = $this->getDefinedActions();\r
+       }\r
+       */\r
+\r
+}\r
+\r
+?>
\ No newline at end of file
index 0d7ad95..eb36370 100755 (executable)
@@ -1,7 +1,7 @@
 <?php
 /*
  * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/)
- * Copyright (C) 2002-2007 The Nucleus Group
+ * Copyright (C) 2002-2009 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
@@ -13,8 +13,8 @@
  * 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.6 2007-02-04 06:28:46 kimitake Exp $
+ * @copyright Copyright (C) 2002-2009 The Nucleus Group
+ * @version $Id$
  * $NucleusJP: KARMA.php,v 1.5 2006/07/17 20:03:44 kimitake Exp $
  */
 class KARMA {
index 4176a58..c5b39ba 100755 (executable)
@@ -1,7 +1,7 @@
 <?php
 /*
  * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/)
- * Copyright (C) 2002-2007 The Nucleus Group
+ * Copyright (C) 2002-2009 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
  * 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.9 2008-02-08 09:31:22 kimitake Exp $
+ * @copyright Copyright (C) 2002-2009 The Nucleus Group
+ * @version $Id$
  * $NucleusJP: MANAGER.php,v 1.8.2.1 2007/09/05 07:00:18 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 loaded or not
-         */
-       function &pluginLoaded($name) {
-               $plugin =& $this->plugins[$name];
-               return $plugin;
-       }
-       function &pidLoaded($pid) {
-               $plugin=false;
-               reset($this->plugins);
-               while (list($name) = each($this->plugins)) {
-                       if ($pid!=$this->plugins[$name]->getId()) continue;
-                       $plugin= & $this->plugins[$name];
-                       break;
-               }
-               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;
-       }
-
-}
-
+class MANAGER {\r
+\r
+       /**\r
+        * Cached ITEM, BLOG, PLUGIN, KARMA and MEMBER 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
+       var $members;\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 = array();\r
+               if (empty($instance)) {\r
+                       $instance[0] =& new MANAGER();\r
+               }\r
+               return $instance[0];\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
+       /**\r
+         * Returns the blog object for a given blogid\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
+       /**\r
+         * Checks if a blog exists\r
+         */\r
+       function existsBlog($name) {\r
+               $this->_loadClass('BLOG','BLOG.php');\r
+               return BLOG::exists($name);\r
+       }\r
+\r
+       /**\r
+         * Checks if a blog id exists\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
+        * Returns a MEMBER object\r
+        */\r
+       function &getMember($memberid) {\r
+               $mem =& $this->members[$memberid];\r
+\r
+               if (!$mem) {\r
+                       // load class if needed\r
+                       $this->_loadClass('MEMBER','MEMBER.php');\r
+                       // create MEMBER object\r
+                       $mem =& MEMBER::createFromID($memberid);\r
+                       $this->members[$memberid] =& $mem;\r
+               }\r
+               return $mem;\r
+       }\r
+\r
+       /**\r
+        * Set the global parser preferences\r
+        */\r
+       function setParserProperty($name, $value) {\r
+               $this->parserPrefs[$name] = $value;\r
+       }\r
+\r
+       /**\r
+        * Get the global parser preferences\r
+        */\r
+       function getParserProperty($name) {\r
+               return $this->parserPrefs[$name];\r
+       }\r
+\r
+       /**\r
+         * A helper function to load a class\r
+         * \r
+         * private\r
+         */\r
+       function _loadClass($name, $filename) {\r
+               if (!class_exists($name)) {\r
+                               global $DIR_LIBS;\r
+                               include($DIR_LIBS . $filename);\r
+               }\r
+       }\r
+\r
+       /**\r
+         * A helper function to load a plugin\r
+         * \r
+         *     private\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, sprintf(_MANAGER_PLUGINFILE_NOTFOUND, $name));\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, sprintf(_MANAGER_PLUGINFILE_NOCLASS, $name));\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, sprintf(_MANAGER_PLUGINTABLEPREFIX_NOTSUPPORT, $name));\r
+                                       return 0;\r
+                               }\r
+\r
+                               // call init method\r
+                               $this->plugins[$name]->init();\r
+\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Returns a PLUGIN object\r
+        */\r
+       function &getPlugin($name) {\r
+               // retrieve the name of the plugin in the right capitalisation\r
+               $name = $this->getUpperCaseName ($name);\r
+               // get the plugin       \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 loaded or not\r
+         */\r
+       function &pluginLoaded($name) {\r
+               $plugin =& $this->plugins[$name];\r
+               return $plugin;\r
+       }\r
+\r
+       function &pidLoaded($pid) {\r
+               $plugin=false;\r
+               reset($this->plugins);\r
+               while (list($name) = each($this->plugins)) {\r
+                       if ($pid!=$this->plugins[$name]->getId()) continue;\r
+                       $plugin= & $this->plugins[$name];\r
+                       break;\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
+\r
+       function pidInstalled($pid) {\r
+               $this->_initCacheInfo('installedPlugins');\r
+               return ($this->cachedInfo['installedPlugins'][$pid] != '');\r
+       }\r
+\r
+       function getPidFromName($name) {\r
+               $this->_initCacheInfo('installedPlugins');\r
+               foreach ($this->cachedInfo['installedPlugins'] as $pid => $pfile)\r
+               {\r
+                       if (strtolower($pfile) == strtolower($name))\r
+                               return $pid;\r
+               }\r
+               return -1;\r
+       }\r
+\r
+       /**\r
+         * Retrieve the name of a plugin in the right capitalisation\r
+         */\r
+       function getUpperCaseName ($name) {\r
+               $this->_initCacheInfo('installedPlugins');\r
+               foreach ($this->cachedInfo['installedPlugins'] as $pid => $pfile)\r
+               {\r
+                       if (strtolower($pfile) == strtolower($name))\r
+                               return $pfile;\r
+               }\r
+               return -1;\r
+       }\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 (isset($this->cachedInfo[$what]) && 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 = false;\r
+               if (isset($this->subscriptions[$eventName])) {\r
+                       $listeners = $this->subscriptions[$eventName];\r
+               }\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
+        * Get a new ticket\r
+        * (xmlHTTPRequest AutoSaveDraft uses this to refresh the ticket)\r
+        */\r
+       function getNewTicket()\r
+       {\r
+               $this->currentRequestTicket = '';\r
+               return $this->_generateTicket();\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
 ?>
\ No newline at end of file
index 433a10a..49be54c 100755 (executable)
@@ -1,7 +1,7 @@
 <?php
 /*
  * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/)
- * Copyright (C) 2002-2007 The Nucleus Group
+ * Copyright (C) 2002-2009 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
@@ -13,8 +13,8 @@
  * 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.6 2007-02-04 06:28:46 kimitake Exp $
+ * @copyright Copyright (C) 2002-2009 The Nucleus Group
+ * @version $Id$
  * $NucleusJP: MEDIA.php,v 1.5 2006/07/17 20:03:44 kimitake Exp $
  */
 
index 0cf7230..03e5665 100755 (executable)
@@ -2,7 +2,7 @@
 
 /*
  * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/)
- * Copyright (C) 2002-2007 The Nucleus Group
+ * Copyright (C) 2002-2009 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
  * 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.7 2007-02-04 06:28:46 kimitake Exp $
+ * @copyright Copyright (C) 2002-2009 The Nucleus Group
+ * @version $Id$
  * $NucleusJP: MEMBER.php,v 1.6 2006/07/17 20:03:44 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) . '\'');
-       }
-
-}
-
-?>
+class MEMBER {\r
+\r
+       // 1 when authenticated, 0 when not\r
+       var $loggedin = 0;\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 = -1;\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 = 0;                 // (either 0 or 1)\r
+       var $canlogin = 0;              // (either 0 or 1)\r
+       var $notes;\r
+       var $autosave = 1;              // if the member use the autosave draft function\r
+\r
+       /**\r
+        * Constructor for a member object\r
+        */             \r
+       function MEMBER() {\r
+               // do nothing\r
+       }\r
+\r
+       /**\r
+        * Create a member object for a given displayname\r
+        *\r
+        * @static\r
+        */\r
+       function &createFromName($displayname) {\r
+               $mem =& new MEMBER();\r
+               $mem->readFromName($displayname);\r
+               return $mem;\r
+       }\r
+\r
+       /**\r
+        * Create a member object for a given ID\r
+        *\r
+        * @static\r
+        */\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.\r
+         * Returns true when succeeded, returns false when failed\r
+         * 3.40 adds CustomLogin event\r
+         */\r
+       function login($login, $password) {\r
+               global $manager;\r
+               $this->loggedin = 0;\r
+               $success = 0;\r
+               $allowlocal = 1;\r
+               $manager->notify('CustomLogin', array('login' => &$login, 'password'=>&$password, 'success'=>&$success, 'allowlocal'=>&$allowlocal) );\r
+               if ($success && $this->readFromName($login)) {\r
+                       $this->loggedin = 1;\r
+                       return $this->isLoggedIn();\r
+               } elseif (!$success && $allowlocal) {\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
+               } else {\r
+                       return 0;\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Login using cookie key\r
+        */             \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
+       /**\r
+        * Read member information from the database \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
+               $this->setAutosave($obj->mautosave);\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
+               $res = sql_query($query);\r
+               return (mysql_num_rows($res) != 0);\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
+         * 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
+               $res = sql_query($query);\r
+               $obj = mysql_fetch_object($res);\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
+               $res = sql_query($query);\r
+               $obj = mysql_fetch_object($res);\r
+               return ($obj->iauthor == $this->getID()) or $this->isBlogAdmin($obj->iblog);\r
+       }\r
+\r
+       /**\r
+         * Return true if member can be deleted. This means that there are no items\r
+         * posted by the member left\r
+         */\r
+       function canBeDeleted() {\r
+               $res = sql_query('SELECT * FROM '.sql_table('item').' WHERE iauthor=' . $this->getID());\r
+               return (mysql_num_rows($res) == 0);\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
+       /**\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
+                          . "     mautosave=" . addslashes($this->getAutosave()) . ""\r
+                          . " WHERE mnumber=" . $this->getID();\r
+               sql_query($query);\r
+       }\r
+\r
+       function checkCookieKey($key) {\r
+               return (($key != '') && ($key == $this->getCookieKey()));\r
+       }\r
+\r
+       function checkPassword($pw) {\r
+               return (md5($pw) == $this->getPassword());\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 getAutosave() {\r
+               return $this->autosave;\r
+       }\r
+\r
+       function setAutosave($val) {\r
+               $this->autosave = $val;\r
+       }\r
+\r
+       function getID() {\r
+               return $this->id;\r
+       }\r
+\r
+       /**\r
+        * Returns true if there is a member with the given login name\r
+        * \r
+        * @static\r
+        */\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
+       /**\r
+        * Returns true if there is a member with the given ID\r
+        *\r
+        * @static\r
+        */\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
+       /**\r
+        *  Checks if a username is protected. \r
+        *  If so, it can not be used on anonymous comments\r
+        */\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
+       /**\r
+        * Adds a new member\r
+        * \r
+        * @static\r
+        */\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
+?>
\ No newline at end of file
index d8e656b..f9abf5b 100755 (executable)
@@ -1,7 +1,7 @@
 <?php
 /*
  * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/)
- * Copyright (C) 2002-2007 The Nucleus Group
+ * Copyright (C) 2002-2009 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
@@ -14,8 +14,8 @@
  * 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.7 2007-02-04 06:28:46 kimitake Exp $
+ * @copyright Copyright (C) 2002-2009 The Nucleus Group
+ * @version $Id$
  * $NucleusJP: NOTIFICATION.php,v 1.6 2006/07/17 20:03:44 kimitake Exp $
  */
 class NOTIFICATION {
index 73adef0..8552488 100755 (executable)
@@ -1,7 +1,7 @@
 <?php
 /*
  * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/)
- * Copyright (C) 2002-2007 The Nucleus Group
+ * Copyright (C) 2002-2009 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
@@ -11,8 +11,8 @@
  */
 /**
  * @license http://nucleuscms.org/license.txt GNU General Public License
- * @copyright Copyright (C) 2002-2007 The Nucleus Group
- * @version $Id: PAGEFACTORY.php,v 1.9 2008-02-08 09:31:22 kimitake Exp $
+ * @copyright Copyright (C) 2002-2009 The Nucleus Group
+ * @version $Id$
  * $NucleusJP: PAGEFACTORY.php,v 1.8.2.2 2007/10/30 16:12:27 shizuki Exp $
  */
 
  * 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()).'">'.htmlspecialchars($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()",_ADD_BOLD_TT);
-                                       $this->_jsbutton('italic',"italicThis()",_ADD_ITALIC_TT);
-                                       $this->_jsbutton('link',"ahrefThis()",_ADD_HREF_TT);
-                                       $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>';
-       }
-
-}
-
+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
+                       'autosave',\r
+                       'autosaveinfo',\r
+                       'ifautosave'\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()).'">'.htmlspecialchars($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_ifautosave($name,$value=1) {\r
+               global $member;\r
+               $this->_addIfCondition($member->getAutosave() == $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],ENT_QUOTES);\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?>'); doMonitor();"\r
+                       onclick="storeCaret(this);"\r
+                       onselect="storeCaret(this);"\r
+\r
+       <?php\r
+               }\r
+               else if ($CONF['DisableJsTools'] == 0) {\r
+       ?>\r
+                       onkeyup="doMonitor();"\r
+                       onkeypress="shortCuts();"\r
+       <?php\r
+               }\r
+               else {\r
+       ?>\r
+                       onkeyup="doMonitor();"\r
+       <?php\r
+               }\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()",_ADD_BOLD_TT);\r
+                                       $this->_jsbutton('italic',"italicThis()",_ADD_ITALIC_TT);\r
+                                       $this->_jsbutton('link',"ahrefThis()",_ADD_HREF_TT);\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);\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
  ?>
\ No newline at end of file
index 79a2ad2..cd14a3b 100755 (executable)
@@ -1,7 +1,7 @@
 <?php
 /*
  * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/)
- * Copyright (C) 2002-2007 The Nucleus Group
+ * Copyright (C) 2002-2009 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
  */
 /**
  * @license http://nucleuscms.org/license.txt GNU General Public License
- * @copyright Copyright (C) 2002-2007 The Nucleus Group
- * @version $Id: PARSER.php,v 1.8 2008-02-08 09:31:22 kimitake Exp $
+ * @copyright Copyright (C) 2002-2009 The Nucleus Group
+ * @version $Id$
  * $NucleusJP: PARSER.php,v 1.7.2.1 2007/09/05 07:35:59 kimitake 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);
-       }
-
-
-}
-
+if ( !function_exists('requestVar') ) exit;\r
+require_once dirname(__FILE__) . '/BaseActions.php';\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
+                       if ($idx < $maxidx) {\r
+                               $this->doAction($pieces[$idx]);\r
+                       }\r
+               }\r
+       }\r
+\r
+\r
+       /**\r
+         * handle an action\r
+         */\r
+       function doAction($action) {\r
+               global $manager, $CONF;\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 != 'elseif') && ($actionlc != 'endif') && ($actionlc != 'ifnot') && ($actionlc != 'elseifnot') && (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
+                               if ($CONF['DebugVars']==true) {\r
+                                       echo '&lt;%' , $action , '(', implode($this->pdelim, $params), ')%&gt;';\r
+                               }\r
+                       }\r
+\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
 ?>
\ No newline at end of file
index 9827705..df75eaa 100755 (executable)
@@ -1,7 +1,7 @@
 <?php
        /*
         * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/)
-        * Copyright (C) 2002-2007 The Nucleus Group
+        * Copyright (C) 2002-2009 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
         * plugins.html file that is included with the Nucleus documenation
         *
         * @license http://nucleuscms.org/license.txt GNU General Public License
-        * @copyright Copyright (C) 2002-2007 The Nucleus Group
-        * @version $Id: PLUGIN.php,v 1.13 2008-02-08 09:31:22 kimitake Exp $
+        * @copyright Copyright (C) 2002-2009 The Nucleus Group
+        * @version $Id$
         * $NucleusJP: PLUGIN.php,v 1.12.2.3 2007/12/03 02:22:42 kmorimatsu Exp $
         */
-       class NucleusPlugin {
-
-               // these functions _have_ to be redefined in your plugin
-
-               function getName() { return 'Undefined'; }
-               function getAuthor()  { return 'Undefined'; }
-               function getURL()  { return 'Undefined'; }
-               function getVersion() { return '0.0'; }
-               function getDescription() { return 'Undefined';}
-
-               // these function _may_ be redefined in your plugin
-
-               function getMinNucleusVersion() { return 150; }
-               function getMinNucleusPatchLevel() { return 0; }
-               function getEventList() { return array(); }
-               function getTableList() { return array(); }
-               function hasAdminArea() { return 0; }
-
-               function install() {}
-               function unInstall() {}
-
-               function init() {}
-
-               function doSkinVar($skinType) {}
-               function doTemplateVar(&$item) {
-                       $args = func_get_args();
-                       array_shift($args);
-                       array_unshift($args, 'template');
-                       call_user_func_array(array(&$this,'doSkinVar'),$args);
-               }
-               function doTemplateCommentsVar(&$item, &$comment) {
-                       $args = func_get_args();
-                       array_shift($args);
-                       array_shift($args);
-                       array_unshift($args, 'template');
-                       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.
-                *
-                * @returns 1 if the feature is reported, 0 if not
-                * @param $feature
-                *              Name of the feature. See plugin documentation for more info
-                *                      'SqlTablePrefix' -> if the plugin uses the sql_table() method to get table names
-                *                      'HelpPage' -> if the plugin provides a helppage
-                */
-               function supportsFeature($feature) {
-                       return 0;
-               }
-
-               /**
-                * Report a list of plugin that is required to function
-                *
-                * @returns an array of names of plugin, an empty array indicates no dependency
-                */
-               function getPluginDep() { return array(); }
-
-               // these helper functions should not be redefined in your plugin
-
-               /**
-                 * Creates a new option for this plugin
-                 *
-                 * @param name
-                 *             A string uniquely identifying your option. (max. length is 20 characters)
-                 * @param description
-                 *             A description that will show up in the nucleus admin area (max. length: 255 characters)
-                 * @param type
-                 *             Either 'text', 'yesno' or 'password'
-                 *             This info is used when showing 'edit plugin options' screens
-                 * @param value
-                 *             Initial value for the option (max. value length is 128 characters)
-                 */
-               function createOption($name, $desc, $type, $defValue = '', $typeExtras = '') {
-                       return $this->_createOption('global', $name, $desc, $type, $defValue, $typeExtras);
-               }
-               function createBlogOption($name, $desc, $type, $defValue = '', $typeExtras = '') {
-                       return $this->_createOption('blog', $name, $desc, $type, $defValue, $typeExtras);
-               }
-               function createMemberOption($name, $desc, $type, $defValue = '', $typeExtras = '') {
-                       return $this->_createOption('member', $name, $desc, $type, $defValue, $typeExtras);
-               }
-               function createCategoryOption($name, $desc, $type, $defValue = '', $typeExtras = '') {
-                       return $this->_createOption('category', $name, $desc, $type, $defValue, $typeExtras);
-               }
-               function createItemOption($name, $desc, $type, $defValue = '', $typeExtras = '') {
-                       return $this->_createOption('item', $name, $desc, $type, $defValue, $typeExtras);
-               }
-
-               /**
-                 * Removes the option from the database
-                 *
-                 * Note: Options get erased automatically on plugin uninstall
-                 */
-               function deleteOption($name) {
-                       return $this->_deleteOption('global', $name);
-               }
-               function deleteBlogOption($name) {
-                       return $this->_deleteOption('blog', $name);
-               }
-               function deleteMemberOption($name) {
-                       return $this->_deleteOption('member', $name);
-               }
-               function deleteCategoryOption($name) {
-                       return $this->_deleteOption('category', $name);
-               }
-               function deleteItemOption($name) {
-                       return $this->_deleteOption('item', $name);
-               }
-
-               /**
-                 * Sets the value of an option to something new
-                 */
-               function setOption($name, $value) {
-                       return $this->_setOption('global', 0, $name, $value);
-               }
-               function setBlogOption($blogid, $name, $value) {
-                       return $this->_setOption('blog', $blogid, $name, $value);
-               }
-               function setMemberOption($memberid, $name, $value) {
-                       return $this->_setOption('member', $memberid, $name, $value);
-               }
-               function setCategoryOption($catid, $name, $value) {
-                       return $this->_setOption('category', $catid, $name, $value);
-               }
-               function setItemOption($itemid, $name, $value) {
-                       return $this->_setOption('item', $itemid, $name, $value);
-               }
-
-               /**
-                 * Retrieves the current value for an option
-                 */
-               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 = sql_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) {
-                       return $this->_getOption('blog', $blogid, $name);
-               }
-               function getMemberOption($memberid, $name) {
-                       return $this->_getOption('member', $memberid, $name);
-               }
-               function getCategoryOption($catid, $name) {
-                       return $this->_getOption('category', $catid, $name);
-               }
-               function getItemOption($itemid, $name) {
-                       return $this->_getOption('item', $itemid, $name);
-               }
-
-               /**
-                * Retrieves an associative array with the option value for each
-                * context id
-                */
-               function getAllBlogOptions($name) {
-                       return $this->_getAllOptions('blog', $name);
-               }
-               function getAllMemberOptions($name) {
-                       return $this->_getAllOptions('member', $name);
-               }
-               function getAllCategoryOptions($name) {
-                       return $this->_getAllOptions('category', $name);
-               }
-               function getAllItemOptions($name) {
-                       return $this->_getAllOptions('item', $name);
-               }
-
-               /**
-                * Retrieves an indexed array with the top (or bottom) of an option
-                * (delegates to _getOptionTop())
-                */
-               function getBlogOptionTop($name, $amount = 10, $sort = 'desc') {
-                       return $this->_getOptionTop('blog', $name, $amount, $sort);
-               }
-               function getMemberOptionTop($name, $amount = 10, $sort = 'desc') {
-                       return $this->_getOptionTop('member', $name, $amount, $sort);
-               }
-               function getCategoryOptionTop($name, $amount = 10, $sort = 'desc') {
-                       return $this->_getOptionTop('category', $name, $amount, $sort);
-               }
-               function getItemOptionTop($name, $amount = 10, $sort = 'desc') {
-                       return $this->_getOptionTop('item', $name, $amount, $sort);
-               }
-
-               /**
-                * Retrieves an array of the top (or bottom) of an option from a plugin.
-                * @author TeRanEX
-                * @param  string $context the context for the option: item, blog, member,...
-                * @param  string $name    the name of the option
-                * @param  int    $amount  how many rows must be returned
-                * @param  string $sort    desc or asc
-                * @return array           array with both values and contextid's
-                * @access private
-                */
-               function _getOptionTop($context, $name, $amount = 10, $sort = 'desc') {
-                       if (($sort != 'desc') && ($sort != 'asc')) {
-                               $sort= 'desc';
-                       }
-
-                       $oid = $this->_getOID($context, $name);
-
-                       // retrieve the data and return
-                       $q = 'SELECT otype, oextra FROM '.sql_table('plugin_option_desc').' WHERE oid = '.$oid;
-                       $query = sql_query($q);
-
-                       $o = mysql_fetch_array($query);
-
-                       if (($this->optionCanBeNumeric($o['otype'])) && ($o['oextra'] == 'number' )) {
-                               $orderby = 'CAST(ovalue AS SIGNED)';
-                       } else {
-                               $orderby = 'ovalue';
-                       }
-                       $q = 'SELECT ovalue value, ocontextid id FROM '.sql_table('plugin_option').' WHERE oid = '.$oid.' ORDER BY '.$orderby.' '.$sort.' LIMIT 0,'.intval($amount);
-                       $query = sql_query($q);
-
-                       // create the array
-                       $i = 0;
-                       $top = array();
-                       while($row = mysql_fetch_array($query)) {
-                               $top[$i++] = $row;
-                       }
-
-                       // return the array (duh!)
-                       return $top;
-               }
-
-               /**
-                 * Returns the plugin ID
-                 */
-               function getID() {
-                       return $this->plugid;
-               }
-
-               /**
-                 * returns the URL of the admin area for this plugin (in case there's
-                 * no such area, the returned information is invalid)
-                 */
-               function getAdminURL() {
-                       global $CONF;
-                       return $CONF['PluginURL'] . $this->getShortName() . '/';
-               }
-
-               /**
-                 * Returns the directory where the admin directory is located and
-                 * where the plugin can maintain his extra files
-                 */
-               function getDirectory() {
-                       global $DIR_PLUGINS;
-                       return $DIR_PLUGINS . $this->getShortName() . '/';
-               }
-
-               /**
-                 * Derives the short name for the plugin from the classname (all lowercase)
-                 */
-               function getShortName() {
-                       return str_replace('np_','',strtolower(get_class($this)));
-               }
-
-               var $_aOptionValues;    // oid_contextid => value
-               var $_aOptionToInfo;    // context_name => array('oid' => ..., 'default' => ...)
-               var $plugin_options;    // see getOption()
-               var $plugid;                    // plugin id
-
-
-               // constructor. Initializes some internal data
-               function NucleusPlugin() {
-                       $this->_aOptionValues = array();        // oid_contextid => value
-                       $this->_aOptionToInfo = array();        // context_name => array('oid' => ..., 'default' => ...)
-                       $this->plugin_options = 0;
-               }
-
-               function clearOptionValueCache(){
-                       $this->_aOptionValues = array();
-               }
-
-               // private
-               function _createOption($context, $name, $desc, $type, $defValue, $typeExtras = '') {
-                       // create in plugin_option_desc
-                       $query = 'INSERT INTO ' . sql_table('plugin_option_desc')
-                                  .' (opid, oname, ocontext, odesc, otype, odef, oextra)'
-                                  .' VALUES ('.intval($this->plugid)
-                                                        .', \''.addslashes($name).'\''
-                                                        .', \''.addslashes($context).'\''
-                                                        .', \''.addslashes($desc).'\''
-                                                        .', \''.addslashes($type).'\''
-                                                        .', \''.addslashes($defValue).'\''
-                                                        .', \''.addslashes($typeExtras).'\')';
-                       sql_query($query);
-                       $oid = mysql_insert_id();
-
-                       $key = $context . '_' . $name;
-                       $this->_aOptionToInfo[$key] = array('oid' => $oid, 'default' => $defValue);
-                       return 1;
-               }
-
-
-               // private
-               function _deleteOption($context, $name) {
-                       $oid = $this->_getOID($context, $name);
-                       if (!$oid) return 0; // no such option
-
-                       // delete all things from plugin_option
-                       sql_query('DELETE FROM ' . sql_table('plugin_option') . ' WHERE oid=' . $oid);
-
-                       // delete entry from plugin_option_desc
-                       sql_query('DELETE FROM ' . sql_table('plugin_option_desc') . ' WHERE oid=' . $oid);
-
-                       // clear from cache
-                       unset($this->_aOptionToInfo[$context . '_' . $name]);
-                       $this->_aOptionValues = array();
-                       return 1;
-               }
-
-               /**
-                * private
-                * returns: 1 on success, 0 on failure
-                */
-               function _setOption($context, $contextid, $name, $value) {
-                       global $manager;
-
-                       $oid = $this->_getOID($context, $name);
-                       if (!$oid) return 0;
-
-                       // check if context id exists
-                       switch ($context) {
-                               case 'member':
-                                       if (!MEMBER::existsID($contextid)) return 0;
-                                       break;
-                               case 'blog':
-                                       if (!$manager->existsBlogID($contextid)) return 0;
-                                       break;
-                               case 'category':
-                                       if (!$manager->existsCategory($contextid)) return 0;
-                                       break;
-                               case 'item':
-                                       if (!$manager->existsItem($contextid, true, true)) return 0;
-                                       break;
-                               case 'global':
-                                       if ($contextid != 0) return 0;
-                                       break;
-                       }
-
-
-                       // 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) . ')');
-
-                       // update cache
-                       $this->_aOptionValues[$oid . '_' . $contextid] = $value;
-
-                       return 1;
-               }
-
-               // private
-               function _getOption($context, $contextid, $name) {
-                       $oid = $this->_getOID($context, $name);
-                       if (!$oid) return '';
-
-
-                       $key = $oid . '_' . $contextid;
-
-                       if (isset($this->_aOptionValues[$key]))
-                               return $this->_aOptionValues[$key];
-
-                       // get from DB
-                       $res = sql_query('SELECT ovalue FROM ' . sql_table('plugin_option') . ' WHERE oid='.intval($oid).' and ocontextid=' . intval($contextid));
-
-                       if (!$res || (mysql_num_rows($res) == 0)) {
-                               $defVal = $this->_getDefVal($context, $name);
-                               $this->_aOptionValues[$key] = $defVal;
-
-                               // fill DB with default value
-                               $query = 'INSERT INTO ' . sql_table('plugin_option') . ' (oid,ocontextid,ovalue)'
-                                          .' VALUES ('.intval($oid).', '.intval($contextid).', \''.addslashes($defVal).'\')';
-                               sql_query($query);
-                       }
-                       else {
-                               $o = mysql_fetch_object($res);
-                               $this->_aOptionValues[$key] = $o->ovalue;
-                       }
-
-                       return $this->_aOptionValues[$key];
-               }
-
-               /**
-                * Returns assoc array with all values for a given option (one option per
-                * possible context id)
-                */
-               function _getAllOptions($context, $name) {
-                       $oid = $this->_getOID($context, $name);
-                       if (!$oid) return array();
-                       $defVal = $this->_getDefVal($context, $name);
-
-                       $aOptions = array();
-                       switch ($context) {
-                               case 'blog':
-                                       $r = sql_query('SELECT bnumber as contextid FROM ' . sql_table('blog'));
-                                       break;
-                               case 'category':
-                                       $r = sql_query('SELECT catid as contextid FROM ' . sql_table('category'));
-                                       break;
-                               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))
-                                       $aOptions[$o->contextid] = $defVal;
-                       }
-
-                       $res = sql_query('SELECT ocontextid, ovalue FROM ' . sql_table('plugin_option') . ' WHERE oid=' . $oid);
-                       while ($o = mysql_fetch_object($res))
-                               $aOptions[$o->ocontextid] = $o->ovalue;
-
-                       return $aOptions;
-               }
-
-               /**
-                * Gets the 'option identifier' that corresponds to a given option name.
-                * When this method is called for the first time, all the OIDs for the plugin
-                * are loaded into memory, to avoid re-doing the same query all over.
-                */
-               function _getOID($context, $name) {
-                       $key = $context . '_' . $name;
-                       $info = @$this->_aOptionToInfo[$key];
-                       if (is_array($info)) return $info['oid'];
-
-                       // load all OIDs for this plugin from the database
-                       $this->_aOptionToInfo = array();
-                       $query = 'SELECT oid, oname, ocontext, odef FROM ' . sql_table('plugin_option_desc') . ' WHERE opid=' . intval($this->plugid);
-                       $res = sql_query($query);
-                       while ($o = mysql_fetch_object($res)) {
-                               $k = $o->ocontext . '_' . $o->oname;
-                               $this->_aOptionToInfo[$k] = array('oid' => $o->oid, 'default' => $o->odef);
-                       }
-                       mysql_free_result($res);
-
-                       return @$this->_aOptionToInfo[$key]['oid'];
-               }
-               function _getDefVal($context, $name) {
-                       $key = $context . '_' . $name;
-                       $info = $this->_aOptionToInfo[$key];
-                       if (is_array($info)) return $info['default'];
-               }
-
-
-               /**
-                * Deletes all option values for a given context and contextid
-                * (used when e.g. a blog, member or category is deleted)
-                *
-                * (static method)
-                */
-               function _deleteOptionValues($context, $contextid) {
-                       // delete all associated plugin options
-                       $aOIDs = array();
-                               // find ids
-                       $query = 'SELECT oid FROM '.sql_table('plugin_option_desc') . ' WHERE ocontext=\''.addslashes($context).'\'';
-                       $res = sql_query($query);
-                       while ($o = mysql_fetch_object($res))
-                               array_push($aOIDs, $o->oid);
-                       mysql_free_result($res);
-                               // delete those options. go go go
-                       if (count($aOIDs) > 0) {
-                               $query = 'DELETE FROM ' . sql_table('plugin_option') . ' WHERE oid in ('.implode(',',$aOIDs).') and ocontextid=' . intval($contextid);
-                               sql_query($query);
-                       }
-               }
-
-               /**
-                * splits the option's typeextra field (at ;'s) to split the meta collection
-                * @param string $typeExtra the value of the typeExtra field of an option
-                * @return array array of the meta-key/value-pairs
-                * @author TeRanEX
-                * @static
-                */
-               function getOptionMeta($typeExtra) {
-                       $tmpMeta = explode(';', $typeExtra);
-                       $meta = array();
-                       for ($i = 0; $i < count($tmpMeta); $i++) {
-                               if (($i == 0) && (!strstr($tmpMeta[0], '='))) {
-                                       // we have the select-list
-                                       $meta['select'] = $tmpMeta[0];
-                               } else {
-                                       $tmp = explode('=', $tmpMeta[$i]);
-                                       $meta[$tmp[0]] = $tmp[1];
-                               }
-                       }
-                       return $meta;
-               }
-
-               /**
-                * filters the selectlists out of the meta collection
-                * @param string $typeExtra the value of the typeExtra field of an option
-                * @return string the selectlist
-                * @author TeRanEX
-                */
-               function getOptionSelectValues($typeExtra) {
-                       $meta = NucleusPlugin::getOptionMeta($typeExtra);
-                       //the select list must always be the first part
-                       return $meta['select'];
-               }
-
-               /**
-                * checks if the eventlist in the database is up-to-date
-                * @return bool if it is up-to-date it return true, else false
-                * @author TeRanEX
-                */
-               function subscribtionListIsUptodate() {
-                       $res = sql_query('SELECT event FROM '.sql_table('plugin_event').' WHERE pid = '.$this->getID());
-                       $ev = array();
-                       while($a = mysql_fetch_array($res)) {
-                               array_push($ev, $a['event']);
-                       }
-                       if (count($ev) != count($this->getEventList())) {
-                               return false;
-                       }
-                       $d = array_diff($ev, $this->getEventList());
-                       if (count($d) > 0) {
-                               // there are differences so the db is not up-to-date
-                               return false;
-                       }
-                       return true;
-               }
-
-               /**
-                * @param $aOptions: array ( 'oid' => array( 'contextid' => 'value'))
-                *        (taken from request using requestVar())
-                * @param $newContextid: integer (accepts a contextid when it is for a new
-                *        contextid there was no id available at the moment of writing the
-                *        formcontrols into the page (by ex: itemOptions for new item)
-                * @static
-                */
-               function _applyPluginOptions(&$aOptions, $newContextid = 0) {
-                       global $manager;
-                       if (!is_array($aOptions)) return;
-
-                       foreach ($aOptions as $oid => $values) {
-
-                               // get option type info
-                               $query = 'SELECT opid, oname, ocontext, otype, oextra, odef FROM ' . sql_table('plugin_option_desc') . ' WHERE oid=' . intval($oid);
-                               $res = sql_query($query);
-                               if ($o = mysql_fetch_object($res))
-                               {
-                                       foreach ($values as $key => $value) {
-                                               // avoid overriding the key used by foreach statement
-                                               $contextid=$key;
-
-                                               // retreive any metadata
-                                               $meta = NucleusPlugin::getOptionMeta($o->oextra);
-
-                                               // if the option is readonly or hidden it may not be saved
-                                               if ((@$meta['access'] != 'readonly') && (@$meta['access'] != 'hidden')) {
-
-                                                       $value = undoMagic($value);     // value comes from request
-
-                                                       switch($o->otype) {
-                                                               case 'yesno':
-                                                                       if (($value != 'yes') && ($value != 'no')) $value = 'no';
-                                                                       break;
-                                                               default:
-                                                                       break;
-                                                       }
-
-                                                       // check the validity of numerical options
-                                                       if ((@$meta['datatype'] == 'numerical') && (!is_numeric($value))) {
-                                                               //the option must be numeric, but the it isn't
-                                                               //use the default for this option
-                                                               $value = $o->odef;
-                                                       }
-
-                                                       // decide wether we are using the contextid of newContextid
-                                                       if ($newContextid != 0) {
-                                                               $contextid = $newContextid;
-                                                       }
-
-                                                       //trigger event PrePluginOptionsUpdate to give the plugin the
-                                                       //possibility to change/validate the new value for the option
-                                                       $manager->notify('PrePluginOptionsUpdate',array('context' => $o->ocontext, 'plugid' => $o->opid, 'optionname' => $o->oname, 'contextid' => $contextid, 'value' => &$value));
-
-                                                       // 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) . "')");
-                                               }
-                                       }
-                               }
-                               // clear option value cache if the plugin object is already loaded
-                               if (is_object($o)) {
-                                       $plugin=& $manager->pidLoaded($o->opid);
-                                       if ($plugin) $plugin->clearOptionValueCache();
-                               }
-                       }
-               }
-       }
-?>
+       class NucleusPlugin {\r
+\r
+               // these functions _have_ to be redefined in your plugin\r
+\r
+               function getName() { return 'Undefined'; }\r
+               function getAuthor()  { return 'Undefined'; }\r
+               function getURL()  { return 'Undefined'; }\r
+               function getVersion() { return '0.0'; }\r
+               function getDescription() { return 'Undefined';}\r
+\r
+               // these function _may_ be redefined in your plugin\r
+\r
+               function getMinNucleusVersion() { return 150; }\r
+               function getMinNucleusPatchLevel() { return 0; }\r
+               function getEventList() { return array(); }\r
+               function getTableList() { return array(); }\r
+               function hasAdminArea() { return 0; }\r
+\r
+               function install() {}\r
+               function unInstall() {}\r
+\r
+               function init() {}\r
+\r
+               function doSkinVar($skinType) {}\r
+               function doTemplateVar(&$item) {\r
+                       $args = func_get_args();\r
+                       array_shift($args);\r
+                       array_unshift($args, 'template');\r
+                       call_user_func_array(array(&$this,'doSkinVar'),$args);\r
+               }\r
+               function doTemplateCommentsVar(&$item, &$comment) {\r
+                       $args = func_get_args();\r
+                       array_shift($args);\r
+                       array_shift($args);\r
+                       array_unshift($args, 'template');\r
+                       call_user_func_array(array(&$this,'doSkinVar'),$args);\r
+               }\r
+               function doAction($type) { return _ERROR_PLUGIN_NOSUCHACTION; }\r
+               function doIf($key,$value) { return false; }\r
+               function doItemVar () {}\r
+\r
+               /**\r
+                * Checks if a plugin supports a certain feature.\r
+                *\r
+                * @returns 1 if the feature is reported, 0 if not\r
+                * @param $feature\r
+                *              Name of the feature. See plugin documentation for more info\r
+                *                      'SqlTablePrefix' -> if the plugin uses the sql_table() method to get table names\r
+                *                      'HelpPage' -> if the plugin provides a helppage\r
+                */\r
+               function supportsFeature($feature) {\r
+                       return 0;\r
+               }\r
+\r
+               /**\r
+                * Report a list of plugin that is required to function\r
+                *\r
+                * @returns an array of names of plugin, an empty array indicates no dependency\r
+                */\r
+               function getPluginDep() { return array(); }\r
+\r
+               // these helper functions should not be redefined in your plugin\r
+\r
+               /**\r
+                 * Creates a new option for this plugin\r
+                 *\r
+                 * @param name\r
+                 *             A string uniquely identifying your option. (max. length is 20 characters)\r
+                 * @param description\r
+                 *             A description that will show up in the nucleus admin area (max. length: 255 characters)\r
+                 * @param type\r
+                 *             Either 'text', 'yesno' or 'password'\r
+                 *             This info is used when showing 'edit plugin options' screens\r
+                 * @param value\r
+                 *             Initial value for the option (max. value length is 128 characters)\r
+                 */\r
+               function createOption($name, $desc, $type, $defValue = '', $typeExtras = '') {\r
+                       return $this->_createOption('global', $name, $desc, $type, $defValue, $typeExtras);\r
+               }\r
+               function createBlogOption($name, $desc, $type, $defValue = '', $typeExtras = '') {\r
+                       return $this->_createOption('blog', $name, $desc, $type, $defValue, $typeExtras);\r
+               }\r
+               function createMemberOption($name, $desc, $type, $defValue = '', $typeExtras = '') {\r
+                       return $this->_createOption('member', $name, $desc, $type, $defValue, $typeExtras);\r
+               }\r
+               function createCategoryOption($name, $desc, $type, $defValue = '', $typeExtras = '') {\r
+                       return $this->_createOption('category', $name, $desc, $type, $defValue, $typeExtras);\r
+               }\r
+               function createItemOption($name, $desc, $type, $defValue = '', $typeExtras = '') {\r
+                       return $this->_createOption('item', $name, $desc, $type, $defValue, $typeExtras);\r
+               }\r
+\r
+               /**\r
+                 * Removes the option from the database\r
+                 *\r
+                 * Note: Options get erased automatically on plugin uninstall\r
+                 */\r
+               function deleteOption($name) {\r
+                       return $this->_deleteOption('global', $name);\r
+               }\r
+               function deleteBlogOption($name) {\r
+                       return $this->_deleteOption('blog', $name);\r
+               }\r
+               function deleteMemberOption($name) {\r
+                       return $this->_deleteOption('member', $name);\r
+               }\r
+               function deleteCategoryOption($name) {\r
+                       return $this->_deleteOption('category', $name);\r
+               }\r
+               function deleteItemOption($name) {\r
+                       return $this->_deleteOption('item', $name);\r
+               }\r
+\r
+               /**\r
+                 * Sets the value of an option to something new\r
+                 */\r
+               function setOption($name, $value) {\r
+                       return $this->_setOption('global', 0, $name, $value);\r
+               }\r
+               function setBlogOption($blogid, $name, $value) {\r
+                       return $this->_setOption('blog', $blogid, $name, $value);\r
+               }\r
+               function setMemberOption($memberid, $name, $value) {\r
+                       return $this->_setOption('member', $memberid, $name, $value);\r
+               }\r
+               function setCategoryOption($catid, $name, $value) {\r
+                       return $this->_setOption('category', $catid, $name, $value);\r
+               }\r
+               function setItemOption($itemid, $name, $value) {\r
+                       return $this->_setOption('item', $itemid, $name, $value);\r
+               }\r
+\r
+               /**\r
+                 * Retrieves the current value for an option\r
+                 */\r
+               function getOption($name)\r
+               {\r
+                       // only request the options the very first time. On subsequent requests\r
+                       // the static collection is used to save SQL queries.\r
+                       if ($this->plugin_options == 0)\r
+                       {\r
+                               $this->plugin_options = array();\r
+                               $query = sql_query(\r
+                                        'SELECT d.oname as name, o.ovalue as value '.\r
+                                        'FROM '.\r
+                                        sql_table('plugin_option').' o, '.\r
+                                        sql_table('plugin_option_desc').' d '.\r
+                                        'WHERE d.opid='. intval($this->getID()).' AND d.oid=o.oid'\r
+                               );\r
+                               while ($row = mysql_fetch_object($query))\r
+                                       $this->plugin_options[strtolower($row->name)] = $row->value;\r
+                 }\r
+                 if (isset($this->plugin_options[strtolower($name)]))\r
+                               return $this->plugin_options[strtolower($name)];\r
+                 else\r
+                               return $this->_getOption('global', 0, $name);\r
+               }\r
+\r
+               function getBlogOption($blogid, $name) {\r
+                       return $this->_getOption('blog', $blogid, $name);\r
+               }\r
+               function getMemberOption($memberid, $name) {\r
+                       return $this->_getOption('member', $memberid, $name);\r
+               }\r
+               function getCategoryOption($catid, $name) {\r
+                       return $this->_getOption('category', $catid, $name);\r
+               }\r
+               function getItemOption($itemid, $name) {\r
+                       return $this->_getOption('item', $itemid, $name);\r
+               }\r
+\r
+               /**\r
+                * Retrieves an associative array with the option value for each\r
+                * context id\r
+                */\r
+               function getAllBlogOptions($name) {\r
+                       return $this->_getAllOptions('blog', $name);\r
+               }\r
+               function getAllMemberOptions($name) {\r
+                       return $this->_getAllOptions('member', $name);\r
+               }\r
+               function getAllCategoryOptions($name) {\r
+                       return $this->_getAllOptions('category', $name);\r
+               }\r
+               function getAllItemOptions($name) {\r
+                       return $this->_getAllOptions('item', $name);\r
+               }\r
+\r
+               /**\r
+                * Retrieves an indexed array with the top (or bottom) of an option\r
+                * (delegates to _getOptionTop())\r
+                */\r
+               function getBlogOptionTop($name, $amount = 10, $sort = 'desc') {\r
+                       return $this->_getOptionTop('blog', $name, $amount, $sort);\r
+               }\r
+               function getMemberOptionTop($name, $amount = 10, $sort = 'desc') {\r
+                       return $this->_getOptionTop('member', $name, $amount, $sort);\r
+               }\r
+               function getCategoryOptionTop($name, $amount = 10, $sort = 'desc') {\r
+                       return $this->_getOptionTop('category', $name, $amount, $sort);\r
+               }\r
+               function getItemOptionTop($name, $amount = 10, $sort = 'desc') {\r
+                       return $this->_getOptionTop('item', $name, $amount, $sort);\r
+               }\r
+\r
+               /**\r
+                 * Returns the plugin ID\r
+                 * \r
+                 * public                                \r
+                 */\r
+               function getID() {\r
+                       return $this->plugid;\r
+               }\r
+\r
+               /**\r
+                 * Returns the URL of the admin area for this plugin (in case there's\r
+                 * no such area, the returned information is invalid)\r
+                 * \r
+                 * public                                \r
+                 */\r
+               function getAdminURL() {\r
+                       global $CONF;\r
+                       return $CONF['PluginURL'] . $this->getShortName() . '/';\r
+               }\r
+\r
+               /**\r
+                 * Returns the directory where the admin directory is located and\r
+                 * where the plugin can maintain his extra files\r
+                 * \r
+                 * public                                \r
+                 */\r
+               function getDirectory() {\r
+                       global $DIR_PLUGINS;\r
+                       return $DIR_PLUGINS . $this->getShortName() . '/';\r
+               }\r
+\r
+               /**\r
+                 * Derives the short name for the plugin from the classname (all \r
+                 * lowercase)\r
+                 * \r
+                 * public                                \r
+                 */\r
+               function getShortName() {\r
+                       return str_replace('np_','',strtolower(get_class($this)));\r
+               }\r
+\r
+               /**\r
+                *      Clears the option value cache which saves the option values during\r
+                *      the plugin execution. This function is usefull if the options has \r
+                *      changed during the plugin execution (especially in association with\r
+                *      the PrePluginOptionsUpdate and the PostPluginOptionsUpdate events)\r
+                *      \r
+                *  public                               \r
+                **/                            \r
+               function clearOptionValueCache(){\r
+                       $this->_aOptionValues = array();\r
+                       $this->plugin_options = 0;\r
+               }\r
+\r
+               // internal functions of the class starts here\r
+\r
+               var $_aOptionValues;    // oid_contextid => value\r
+               var $_aOptionToInfo;    // context_name => array('oid' => ..., 'default' => ...)\r
+               var $plugin_options;    // see getOption()\r
+               var $plugid;                    // plugin id\r
+\r
+\r
+               /**\r
+                * Class constructor: Initializes some internal data\r
+                */                                             \r
+               function NucleusPlugin() {\r
+                       $this->_aOptionValues = array();        // oid_contextid => value\r
+                       $this->_aOptionToInfo = array();        // context_name => array('oid' => ..., 'default' => ...)\r
+                       $this->plugin_options = 0;\r
+               }\r
+\r
+               /**\r
+                * Retrieves an array of the top (or bottom) of an option from a plugin.\r
+                * @author TeRanEX\r
+                * @param  string $context the context for the option: item, blog, member,...\r
+                * @param  string $name    the name of the option\r
+                * @param  int    $amount  how many rows must be returned\r
+                * @param  string $sort    desc or asc\r
+                * @return array           array with both values and contextid's\r
+                * @access private\r
+                */\r
+               function _getOptionTop($context, $name, $amount = 10, $sort = 'desc') {\r
+                       if (($sort != 'desc') && ($sort != 'asc')) {\r
+                               $sort= 'desc';\r
+                       }\r
+\r
+                       $oid = $this->_getOID($context, $name);\r
+\r
+                       // retrieve the data and return\r
+                       $q = 'SELECT otype, oextra FROM '.sql_table('plugin_option_desc').' WHERE oid = '.$oid;\r
+                       $query = sql_query($q);\r
+\r
+                       $o = mysql_fetch_array($query);\r
+\r
+                       if (($this->optionCanBeNumeric($o['otype'])) && ($o['oextra'] == 'number' )) {\r
+                               $orderby = 'CAST(ovalue AS SIGNED)';\r
+                       } else {\r
+                               $orderby = 'ovalue';\r
+                       }\r
+                       $q = 'SELECT ovalue value, ocontextid id FROM '.sql_table('plugin_option').' WHERE oid = '.$oid.' ORDER BY '.$orderby.' '.$sort.' LIMIT 0,'.intval($amount);\r
+                       $query = sql_query($q);\r
+\r
+                       // create the array\r
+                       $i = 0;\r
+                       $top = array();\r
+                       while($row = mysql_fetch_array($query)) {\r
+                               $top[$i++] = $row;\r
+                       }\r
+\r
+                       // return the array (duh!)\r
+                       return $top;\r
+               }\r
+\r
+               /**\r
+                * Creates an option in the database table plugin_option_desc\r
+                *               \r
+                * private\r
+                */                                             \r
+               function _createOption($context, $name, $desc, $type, $defValue, $typeExtras = '') {\r
+                       // create in plugin_option_desc\r
+                       $query = 'INSERT INTO ' . sql_table('plugin_option_desc')\r
+                                  .' (opid, oname, ocontext, odesc, otype, odef, oextra)'\r
+                                  .' VALUES ('.intval($this->plugid)\r
+                                                        .', \''.addslashes($name).'\''\r
+                                                        .', \''.addslashes($context).'\''\r
+                                                        .', \''.addslashes($desc).'\''\r
+                                                        .', \''.addslashes($type).'\''\r
+                                                        .', \''.addslashes($defValue).'\''\r
+                                                        .', \''.addslashes($typeExtras).'\')';\r
+                       sql_query($query);\r
+                       $oid = mysql_insert_id();\r
+\r
+                       $key = $context . '_' . $name;\r
+                       $this->_aOptionToInfo[$key] = array('oid' => $oid, 'default' => $defValue);\r
+                       return 1;\r
+               }\r
+\r
+\r
+               /**\r
+                * Deletes an option from the database tables\r
+                * plugin_option and plugin_option_desc \r
+                *\r
+                * private               \r
+                */                                             \r
+               function _deleteOption($context, $name) {\r
+                       $oid = $this->_getOID($context, $name);\r
+                       if (!$oid) return 0; // no such option\r
+\r
+                       // delete all things from plugin_option\r
+                       sql_query('DELETE FROM ' . sql_table('plugin_option') . ' WHERE oid=' . $oid);\r
+\r
+                       // delete entry from plugin_option_desc\r
+                       sql_query('DELETE FROM ' . sql_table('plugin_option_desc') . ' WHERE oid=' . $oid);\r
+\r
+                       // clear from cache\r
+                       unset($this->_aOptionToInfo[$context . '_' . $name]);\r
+                       $this->_aOptionValues = array();\r
+                       return 1;\r
+               }\r
+\r
+               /**\r
+                * Update an option in the database table plugin_option\r
+                *               \r
+                * returns: 1 on success, 0 on failure\r
+                * private\r
+                */\r
+               function _setOption($context, $contextid, $name, $value) {\r
+                       global $manager;\r
+\r
+                       $oid = $this->_getOID($context, $name);\r
+                       if (!$oid) return 0;\r
+\r
+                       // check if context id exists\r
+                       switch ($context) {\r
+                               case 'member':\r
+                                       if (!MEMBER::existsID($contextid)) return 0;\r
+                                       break;\r
+                               case 'blog':\r
+                                       if (!$manager->existsBlogID($contextid)) return 0;\r
+                                       break;\r
+                               case 'category':\r
+                                       if (!$manager->existsCategory($contextid)) return 0;\r
+                                       break;\r
+                               case 'item':\r
+                                       if (!$manager->existsItem($contextid, true, true)) return 0;\r
+                                       break;\r
+                               case 'global':\r
+                                       if ($contextid != 0) return 0;\r
+                                       break;\r
+                       }\r
+\r
+\r
+                       // update plugin_option\r
+                       sql_query('DELETE FROM ' . sql_table('plugin_option') . ' WHERE oid='.intval($oid) . ' and ocontextid='. intval($contextid));\r
+                       sql_query('INSERT INTO ' . sql_table('plugin_option') . ' (ovalue, oid, ocontextid) VALUES (\''.addslashes($value).'\', '. intval($oid) . ', ' . intval($contextid) . ')');\r
+\r
+                       // update cache\r
+                       $this->_aOptionValues[$oid . '_' . $contextid] = $value;\r
+\r
+                       return 1;\r
+               }\r
+\r
+               /**\r
+                * Get an option from Cache or database\r
+                *       - if not in the option Cache read it from the database\r
+                *   - if not in the database write default values into the database\r
+                *                \r
+                * private               \r
+                */                                             \r
+               function _getOption($context, $contextid, $name) {\r
+                       $oid = $this->_getOID($context, $name);\r
+                       if (!$oid) return '';\r
+\r
+\r
+                       $key = $oid . '_' . $contextid;\r
+\r
+                       if (isset($this->_aOptionValues[$key]))\r
+                               return $this->_aOptionValues[$key];\r
+\r
+                       // get from DB\r
+                       $res = sql_query('SELECT ovalue FROM ' . sql_table('plugin_option') . ' WHERE oid='.intval($oid).' and ocontextid=' . intval($contextid));\r
+\r
+                       if (!$res || (mysql_num_rows($res) == 0)) {\r
+                               $defVal = $this->_getDefVal($context, $name);\r
+                               $this->_aOptionValues[$key] = $defVal;\r
+\r
+                               // fill DB with default value\r
+                               $query = 'INSERT INTO ' . sql_table('plugin_option') . ' (oid,ocontextid,ovalue)'\r
+                                          .' VALUES ('.intval($oid).', '.intval($contextid).', \''.addslashes($defVal).'\')';\r
+                               sql_query($query);\r
+                       }\r
+                       else {\r
+                               $o = mysql_fetch_object($res);\r
+                               $this->_aOptionValues[$key] = $o->ovalue;\r
+                       }\r
+\r
+                       return $this->_aOptionValues[$key];\r
+               }\r
+\r
+               /**\r
+                * Returns assoc array with all values for a given option \r
+                * (one option per possible context id)\r
+                * \r
+                * private                               \r
+                */\r
+               function _getAllOptions($context, $name) {\r
+                       $oid = $this->_getOID($context, $name);\r
+                       if (!$oid) return array();\r
+                       $defVal = $this->_getDefVal($context, $name);\r
+\r
+                       $aOptions = array();\r
+                       switch ($context) {\r
+                               case 'blog':\r
+                                       $r = sql_query('SELECT bnumber as contextid FROM ' . sql_table('blog'));\r
+                                       break;\r
+                               case 'category':\r
+                                       $r = sql_query('SELECT catid as contextid FROM ' . sql_table('category'));\r
+                                       break;\r
+                               case 'member':\r
+                                       $r = sql_query('SELECT mnumber as contextid FROM ' . sql_table('member'));\r
+                                       break;\r
+                               case 'item':\r
+                                       $r = sql_query('SELECT inumber as contextid FROM ' . sql_table('item'));\r
+                                       break;\r
+                       }\r
+                       if ($r) {\r
+                               while ($o = mysql_fetch_object($r))\r
+                                       $aOptions[$o->contextid] = $defVal;\r
+                       }\r
+\r
+                       $res = sql_query('SELECT ocontextid, ovalue FROM ' . sql_table('plugin_option') . ' WHERE oid=' . $oid);\r
+                       while ($o = mysql_fetch_object($res))\r
+                               $aOptions[$o->ocontextid] = $o->ovalue;\r
+\r
+                       return $aOptions;\r
+               }\r
+\r
+               /**\r
+                * Gets the 'option identifier' that corresponds to a given option name.\r
+                * When this method is called for the first time, all the OIDs for the plugin\r
+                * are loaded into memory, to avoid re-doing the same query all over.\r
+                */\r
+               function _getOID($context, $name) {\r
+                       $key = $context . '_' . $name;\r
+                       $info = @$this->_aOptionToInfo[$key];\r
+                       if (is_array($info)) return $info['oid'];\r
+\r
+                       // load all OIDs for this plugin from the database\r
+                       $this->_aOptionToInfo = array();\r
+                       $query = 'SELECT oid, oname, ocontext, odef FROM ' . sql_table('plugin_option_desc') . ' WHERE opid=' . intval($this->plugid);\r
+                       $res = sql_query($query);\r
+                       while ($o = mysql_fetch_object($res)) {\r
+                               $k = $o->ocontext . '_' . $o->oname;\r
+                               $this->_aOptionToInfo[$k] = array('oid' => $o->oid, 'default' => $o->odef);\r
+                       }\r
+                       mysql_free_result($res);\r
+\r
+                       return @$this->_aOptionToInfo[$key]['oid'];\r
+               }\r
+               function _getDefVal($context, $name) {\r
+                       $key = $context . '_' . $name;\r
+                       $info = $this->_aOptionToInfo[$key];\r
+                       if (is_array($info)) return $info['default'];\r
+               }\r
+\r
+\r
+               /**\r
+                * Deletes all option values for a given context and contextid\r
+                * (used when e.g. a blog, member or category is deleted)\r
+                *\r
+                * (static method)\r
+                */\r
+               function _deleteOptionValues($context, $contextid) {\r
+                       // delete all associated plugin options\r
+                       $aOIDs = array();\r
+                               // find ids\r
+                       $query = 'SELECT oid FROM '.sql_table('plugin_option_desc') . ' WHERE ocontext=\''.addslashes($context).'\'';\r
+                       $res = sql_query($query);\r
+                       while ($o = mysql_fetch_object($res))\r
+                               array_push($aOIDs, $o->oid);\r
+                       mysql_free_result($res);\r
+                               // delete those options. go go go\r
+                       if (count($aOIDs) > 0) {\r
+                               $query = 'DELETE FROM ' . sql_table('plugin_option') . ' WHERE oid in ('.implode(',',$aOIDs).') and ocontextid=' . intval($contextid);\r
+                               sql_query($query);\r
+                       }\r
+               }\r
+\r
+               /**\r
+                * splits the option's typeextra field (at ;'s) to split the meta collection\r
+                * @param string $typeExtra the value of the typeExtra field of an option\r
+                * @return array array of the meta-key/value-pairs\r
+                * @author TeRanEX\r
+                * @static\r
+                */\r
+               function getOptionMeta($typeExtra) {\r
+                       $tmpMeta = explode(';', $typeExtra);\r
+                       $meta = array();\r
+                       for ($i = 0; $i < count($tmpMeta); $i++) {\r
+                               if (($i == 0) && (!strstr($tmpMeta[0], '='))) {\r
+                                       // we have the select-list\r
+                                       $meta['select'] = $tmpMeta[0];\r
+                               } else {\r
+                                       $tmp = explode('=', $tmpMeta[$i]);\r
+                                       $meta[$tmp[0]] = $tmp[1];\r
+                               }\r
+                       }\r
+                       return $meta;\r
+               }\r
+\r
+               /**\r
+                * filters the selectlists out of the meta collection\r
+                * @param string $typeExtra the value of the typeExtra field of an option\r
+                * @return string the selectlist\r
+                * @author TeRanEX\r
+                */\r
+               function getOptionSelectValues($typeExtra) {\r
+                       $meta = NucleusPlugin::getOptionMeta($typeExtra);\r
+                       //the select list must always be the first part\r
+                       return $meta['select'];\r
+               }\r
+\r
+               /**\r
+                * checks if the eventlist in the database is up-to-date\r
+                * @return bool if it is up-to-date it return true, else false\r
+                * @author TeRanEX\r
+                */\r
+               function subscribtionListIsUptodate() {\r
+                       $res = sql_query('SELECT event FROM '.sql_table('plugin_event').' WHERE pid = '.$this->getID());\r
+                       $ev = array();\r
+                       while($a = mysql_fetch_array($res)) {\r
+                               array_push($ev, $a['event']);\r
+                       }\r
+                       if (count($ev) != count($this->getEventList())) {\r
+                               return false;\r
+                       }\r
+                       $d = array_diff($ev, $this->getEventList());\r
+                       if (count($d) > 0) {\r
+                               // there are differences so the db is not up-to-date\r
+                               return false;\r
+                       }\r
+                       return true;\r
+               }\r
+\r
+               /**\r
+                * @param $aOptions: array ( 'oid' => array( 'contextid' => 'value'))\r
+                *        (taken from request using requestVar())\r
+                * @param $newContextid: integer (accepts a contextid when it is for a new\r
+                *        contextid there was no id available at the moment of writing the\r
+                *        formcontrols into the page (by ex: itemOptions for new item)\r
+                * @static\r
+                */\r
+               function _applyPluginOptions(&$aOptions, $newContextid = 0) {\r
+                       global $manager;\r
+                       if (!is_array($aOptions)) return;\r
+\r
+                       foreach ($aOptions as $oid => $values) {\r
+\r
+                               // get option type info\r
+                               $query = 'SELECT opid, oname, ocontext, otype, oextra, odef FROM ' . sql_table('plugin_option_desc') . ' WHERE oid=' . intval($oid);\r
+                               $res = sql_query($query);\r
+                               if ($o = mysql_fetch_object($res))\r
+                               {\r
+                                       foreach ($values as $key => $value) {\r
+                                               // avoid overriding the key used by foreach statement\r
+                                               $contextid=$key;\r
+\r
+                                               // retreive any metadata\r
+                                               $meta = NucleusPlugin::getOptionMeta($o->oextra);\r
+\r
+                                               // if the option is readonly or hidden it may not be saved\r
+                                               if ((@$meta['access'] != 'readonly') && (@$meta['access'] != 'hidden')) {\r
+\r
+                                                       $value = undoMagic($value);     // value comes from request\r
+\r
+                                                       switch($o->otype) {\r
+                                                               case 'yesno':\r
+                                                                       if (($value != 'yes') && ($value != 'no')) $value = 'no';\r
+                                                                       break;\r
+                                                               default:\r
+                                                                       break;\r
+                                                       }\r
+\r
+                                                       // check the validity of numerical options\r
+                                                       if ((@$meta['datatype'] == 'numerical') && (!is_numeric($value))) {\r
+                                                               //the option must be numeric, but the it isn't\r
+                                                               //use the default for this option\r
+                                                               $value = $o->odef;\r
+                                                       }\r
+\r
+                                                       // decide wether we are using the contextid of newContextid\r
+                                                       if ($newContextid != 0) {\r
+                                                               $contextid = $newContextid;\r
+                                                       }\r
+\r
+                                                       //trigger event PrePluginOptionsUpdate to give the plugin the\r
+                                                       //possibility to change/validate the new value for the option\r
+                                                       $manager->notify('PrePluginOptionsUpdate',array('context' => $o->ocontext, 'plugid' => $o->opid, 'optionname' => $o->oname, 'contextid' => $contextid, 'value' => &$value));\r
+\r
+                                                       // delete the old value for the option\r
+                                                       sql_query('DELETE FROM '.sql_table('plugin_option').' WHERE oid='.intval($oid).' AND ocontextid='.intval($contextid));\r
+                                                       sql_query('INSERT INTO '.sql_table('plugin_option')." (oid, ocontextid, ovalue) VALUES (".intval($oid).",".intval($contextid).",'" . addslashes($value) . "')");\r
+                                               }\r
+                                       }\r
+                               }\r
+                               // clear option value cache if the plugin object is already loaded\r
+                               if (is_object($o)) {\r
+                                       $plugin=& $manager->pidLoaded($o->opid);\r
+                                       if ($plugin) $plugin->clearOptionValueCache();\r
+                               }\r
+                       }\r
+               }\r
+       }\r
+?>
\ No newline at end of file
index ac940fa..230c21b 100755 (executable)
@@ -2,7 +2,7 @@
 
 /*
  * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/)
- * Copyright (C) 2002-2007 The Nucleus Group
+ * Copyright (C) 2002-2009 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
  * 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.9 2008-02-08 09:31:22 kimitake Exp $
+ * @copyright Copyright (C) 2002-2009 The Nucleus Group
+ * @version $Id$
  * $NucleusJP: PLUGINADMIN.php,v 1.8.2.2 2007/10/23 22:48:56 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 during 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
-       }
-}
-
-
-
+global $HTTP_GET_VARS, $HTTP_POST_VARS, $HTTP_COOKIE_VARS, $HTTP_ENV_VARS, $HTTP_POST_FILES, $HTTP_SESSION_VARS;\r
+$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');\r
+\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
+if (!isset($DIR_LIBS)) {\r
+       die('Sorry.');\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(_ERROR_INVALID_PLUGIN);\r
+\r
+               $this->plugin =& $manager->getPlugin($this->strFullName);\r
+               $this->bValid = $this->plugin;\r
+\r
+               if (!$this->bValid)\r
+                       doError(_ERROR_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->_AddTicketByJS();\r
+               $this->admin->pagefoot();\r
+       }\r
+\r
+/** \r
+ * Add ticket when not used in plugin's admin page\r
+ * to avoid CSRF.\r
+ */\r
+       function _AddTicketByJS(){\r
+               global $CONF,$ticketforplugin;\r
+               if (!($ticket=$ticketforplugin['ticket'])) {\r
+                       //echo "\n<!--TicketForPlugin skipped-->\n";\r
+                       return;\r
+               }\r
+               $ticket=htmlspecialchars($ticket,ENT_QUOTES);\r
\r
+?><script type="text/javascript">\r
+/*<![CDATA[*/\r
+/* Add tickets for available links (outside blog excluded) */\r
+for (i=0;document.links[i];i++){\r
+  if (document.links[i].href.indexOf('<?php echo $CONF['PluginURL']; ?>',0)<0\r
+    && !(document.links[i].href.indexOf('//',0)<0)) continue;\r
+  if ((j=document.links[i].href.indexOf('?',0))<0) continue;\r
+  if (document.links[i].href.indexOf('ticket=',j)>=0) continue;\r
+  document.links[i].href=document.links[i].href.substring(0,j+1)+'ticket=<?php echo $ticket; ?>&'+document.links[i].href.substring(j+1);\r
+}\r
+/* Add tickets for forms (outside blog excluded) */\r
+for (i=0;document.forms[i];i++){\r
+  /* check if ticket is already used */\r
+  for (j=0;document.forms[i].elements[j];j++) {\r
+    if (document.forms[i].elements[j].name=='ticket') {\r
+      j=-1;\r
+      break;\r
+    }\r
+  }\r
+  if (j==-1) continue;\r
\r
+  /* check if the modification works */\r
+  try{document.forms[i].innerHTML+='';}catch(e){\r
+    /* Modificaion falied: this sometime happens on IE */\r
+    if (!document.forms[i].action.name && document.forms[i].method.toUpperCase()=="POST") {\r
+      /* <input name="action"/> is not used for POST method*/\r
+      if (document.forms[i].action.indexOf('<?php echo $CONF['PluginURL']; ?>',0)<0\r
+        && !(document.forms[i].action.indexOf('//',0)<0)) continue;\r
+      if (0<(j=document.forms[i].action.indexOf('?',0))) if (0<document.forms[i].action.indexOf('ticket=',j)) continue;\r
+      if (j<0) document.forms[i].action+='?'+'ticket=<?php echo $ticket; ?>';\r
+      else document.forms[i].action+='&'+'ticket=<?php echo $ticket; ?>';\r
+      continue;\r
+    }\r
+    document.write('<?php echo _PLUGINADMIN_TICKETS_JAVASCRIPT ?>');\r
+    j=document.forms[i].outerHTML;\r
+    while (j!=j.replace('<','&lt;')) j=j.replace('<','&lt;');\r
+    document.write('<p>'+j+'</p>');\r
+    continue;\r
+  }\r
+  /* check the action paramer in form tag */\r
+  /* note that <input name="action"/> may be used here */\r
+  j=document.forms[i].innerHTML;\r
+  document.forms[i].innerHTML='';\r
+  if ((document.forms[i].action+'').indexOf('<?php echo $CONF['PluginURL']; ?>',0)<0\r
+      && !((document.forms[i].action+'').indexOf('//',0)<0)) {\r
+    document.forms[i].innerHTML=j;\r
+    continue;\r
+  }\r
+  /* add ticket */\r
+  document.forms[i].innerHTML=j+'<input type="hidden" name="ticket" value="<?php echo $ticket; ?>"/>';\r
+}\r
+/*]]>*/\r
+</script><?php\r
\r
+       }\r
+}\r
+\r
+\r
+\r
 ?>
\ No newline at end of file
index db838ba..2032770 100755 (executable)
@@ -2,7 +2,7 @@
 
 /*
  * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/)
- * Copyright (C) 2003-2007 The Nucleus Group
+ * Copyright (C) 2003-2009 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
@@ -19,8 +19,8 @@
  * 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.8 2007-02-04 06:28:46 kimitake Exp $
+ * @copyright Copyright (C) 2002-2009 The Nucleus Group
+ * @version $Id$
  * @version $NucleusJP: SEARCH.php,v 1.7 2006/07/20 08:01:52 kimitake Exp $
  */
 
index 612b500..746889e 100755 (executable)
@@ -1,7 +1,7 @@
 <?php
 /*
  * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/)
- * Copyright (C) 2002-2007 The Nucleus Group
+ * Copyright (C) 2002-2009 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
@@ -13,8 +13,8 @@
  * Class representing a skin
  *
  * @license http://nucleuscms.org/license.txt GNU General Public License
- * @copyright Copyright (C) 2002-2007 The Nucleus Group
- * @version $Id: SKIN.php,v 1.9 2008-02-08 09:31:22 kimitake Exp $
+ * @copyright Copyright (C) 2002-2009 The Nucleus Group
+ * @version $Id$
  * @version $NucleusJP: SKIN.php,v 1.8.2.1 2007/09/05 07:45:01 kimitake Exp $
  */
 
@@ -298,7 +298,9 @@ class SKIN {
                                                                'ifnot',
                                                                'elseifnot',
                                                                'charset',
-                                                               'bloglist'
+                                                               'bloglist',\r
+                                                               'addlink',\r
+                                                               'addpopupcode'\r
                                                                );
 
                // extra actions specific for a certain skin type
index 985f9d9..bff289c 100755 (executable)
@@ -2,7 +2,7 @@
 
 /*
  * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/)
- * Copyright (C) 2002-2007 The Nucleus Group
+ * Copyright (C) 2002-2009 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
  * A class representing a template
  *
  * @license http://nucleuscms.org/license.txt GNU General Public License
- * @copyright Copyright (C) 2002-2007 The Nucleus Group
- * @version $Id: TEMPLATE.php,v 1.7 2007-02-04 06:28:46 kimitake Exp $
+ * @copyright Copyright (C) 2002-2009 The Nucleus Group
+ * @version $Id$
  * @version $NucleusJP: TEMPLATE.php,v 1.6 2006/07/20 08:01:52 kimitake Exp $
  */
-class TEMPLATE {
-
-       var $id;
-
-       function TEMPLATE($templateid) {
-               $this->id = intval($templateid);
-       }
-
-       function getID() {
-               return intval($this->id);
-       }
-
-       // (static)
-       function createFromName($name) {
-               return new TEMPLATE(TEMPLATE::getIdFromName($name));
-       }
-
-       // (static)
-       function getIdFromName($name) {
-               $query =  'SELECT tdnumber'
-                          . ' FROM '.sql_table('template_desc')
-                          . ' WHERE tdname="'.addslashes($name).'"';
-               $res = sql_query($query);
-               $obj = mysql_fetch_object($res);
-               return $obj->tdnumber;
-       }
-
-       /**
-        * Updates the general information about the template
-        */
-       function updateGeneralInfo($name, $desc) {
-               $query =  'UPDATE '.sql_table('template_desc').' SET'
-                          . " tdname='" . addslashes($name) . "',"
-                          . " tddesc='" . addslashes($desc) . "'"
-                          . " WHERE tdnumber=" . $this->getID();
-               sql_query($query);
-       }
-
-       /**
-        * Updates the contents of one part of the template
-        */
-       function update($type, $content) {
-               $id = $this->getID();
-
-               // delete old thingie
-               sql_query('DELETE FROM '.sql_table('template')." WHERE tpartname='". addslashes($type) ."' and tdesc=" . intval($id));
-
-               // write new thingie
-               if ($content) {
-                       sql_query('INSERT INTO '.sql_table('template')." SET tcontent='" . addslashes($content) . "', tpartname='" . addslashes($type) . "', tdesc=" . intval($id));
-               }
-       }
-
-
-       /**
-        * Deletes all template parts from the database
-        */
-       function deleteAllParts() {
-               sql_query('DELETE FROM '.sql_table('template').' WHERE tdesc='.$this->getID());
-       }
-
-       /**
-        * Creates a new template
-        *
-        * (static)
-        */
-       function createNew($name, $desc) {
-               global $manager;
-
-               $manager->notify(
-                       'PreAddTemplate',
-                       array(
-                               'name' => &$name,
-                               'description' => &$desc
-                       )
-               );
-
-               sql_query('INSERT INTO '.sql_table('template_desc')." (tdname, tddesc) VALUES ('" . addslashes($name) . "','" . addslashes($desc) . "')");
-               $newId = mysql_insert_id();
-
-               $manager->notify(
-                       'PostAddTemplate',
-                       array(
-                               'templateid' => $newId,
-                               'name' => $name,
-                               'description' => $desc
-                       )
-               );
-
-               return $newId;
-       }
-
-
-
-       /**
-        * Reads a template and returns an array with the parts.
-        * (static)
-        *
-        * @param $name name of the template file
-        */
-       function read($name) {
-               $query = 'SELECT tpartname, tcontent'
-                          . ' FROM '.sql_table('template_desc').', '.sql_table('template')
-                          . ' WHERE tdesc=tdnumber and tdname="' . addslashes($name) . '"';
-               $res = sql_query($query);
-               while ($obj = mysql_fetch_object($res))
-                       $template[$obj->tpartname] = $obj->tcontent;
-
-               // set locale according to template:
-               if ($template['LOCALE'])
-                       setlocale(LC_TIME,$template['LOCALE']);
-               else
-                       setlocale(LC_TIME,'');
-
-               return $template;
-       }
-
-       /**
-         * fills a template with values
-         * (static)
-         *
-         * @param $template
-         *             Template to be used
-         * @param $values
-         *             Array of all the values
-         */
-       function fill($template, $values) {
-
-               if (sizeof($values) != 0) {
-                       // go through all the values
-                       for(reset($values); $key = key($values); next($values)) {
-                               $template = str_replace("<%$key%>",$values[$key],$template);
-                       }
-               }
-
-               // remove non matched template-tags
-               return preg_replace('/<%[a-zA-Z]+%>/','',$template);
-       }
-
-       // returns true if there is a template with the given shortname
-       // (static)
-       function exists($name) {
-               $r = sql_query('select * FROM '.sql_table('template_desc').' WHERE tdname="'.addslashes($name).'"');
-               return (mysql_num_rows($r) != 0);
-       }
-
-       // returns true if there is a template with the given ID
-       // (static)
-       function existsID($id) {
-               $r = sql_query('select * FROM '.sql_table('template_desc').' WHERE tdnumber='.intval($id));
-               return (mysql_num_rows($r) != 0);
-       }
-
-       // (static)
-       function getNameFromId($id) {
-               return quickQuery('SELECT tdname as result FROM '.sql_table('template_desc').' WHERE tdnumber=' . intval($id));
-       }
-
-       // (static)
-       function getDesc($id) {
-               $query = 'SELECT tddesc FROM '.sql_table('template_desc').' WHERE tdnumber='. intval($id);
-               $res = sql_query($query);
-               $obj = mysql_fetch_object($res);
-               return $obj->tddesc;
-       }
-
-
-
-}
-
+class TEMPLATE {\r
+\r
+       var $id;\r
+\r
+       function TEMPLATE($templateid) {\r
+               $this->id = intval($templateid);\r
+       }\r
+\r
+       function getID() {\r
+               return intval($this->id);\r
+       }\r
+\r
+       // (static)\r
+       function createFromName($name) {\r
+               return new TEMPLATE(TEMPLATE::getIdFromName($name));\r
+       }\r
+\r
+       // (static)\r
+       function getIdFromName($name) {\r
+               $query =  'SELECT tdnumber'\r
+                          . ' FROM '.sql_table('template_desc')\r
+                          . ' WHERE tdname="'.addslashes($name).'"';\r
+               $res = sql_query($query);\r
+               $obj = mysql_fetch_object($res);\r
+               return $obj->tdnumber;\r
+       }\r
+\r
+       /**\r
+        * Updates the general information about the template\r
+        */\r
+       function updateGeneralInfo($name, $desc) {\r
+               $query =  'UPDATE '.sql_table('template_desc').' SET'\r
+                          . " tdname='" . addslashes($name) . "',"\r
+                          . " tddesc='" . addslashes($desc) . "'"\r
+                          . " WHERE tdnumber=" . $this->getID();\r
+               sql_query($query);\r
+       }\r
+\r
+       /**\r
+        * Updates the contents of one part of the template\r
+        */\r
+       function update($type, $content) {\r
+               $id = $this->getID();\r
+\r
+               // delete old thingie\r
+               sql_query('DELETE FROM '.sql_table('template')." WHERE tpartname='". addslashes($type) ."' and tdesc=" . intval($id));\r
+\r
+               // write new thingie\r
+               if ($content) {\r
+                       sql_query('INSERT INTO '.sql_table('template')." SET tcontent='" . addslashes($content) . "', tpartname='" . addslashes($type) . "', tdesc=" . intval($id));\r
+               }\r
+       }\r
+\r
+\r
+       /**\r
+        * Deletes all template parts from the database\r
+        */\r
+       function deleteAllParts() {\r
+               sql_query('DELETE FROM '.sql_table('template').' WHERE tdesc='.$this->getID());\r
+       }\r
+\r
+       /**\r
+        * Creates a new template\r
+        *\r
+        * (static)\r
+        */\r
+       function createNew($name, $desc) {\r
+               global $manager;\r
+\r
+               $manager->notify(\r
+                       'PreAddTemplate',\r
+                       array(\r
+                               'name' => &$name,\r
+                               'description' => &$desc\r
+                       )\r
+               );\r
+\r
+               sql_query('INSERT INTO '.sql_table('template_desc')." (tdname, tddesc) VALUES ('" . addslashes($name) . "','" . addslashes($desc) . "')");\r
+               $newId = mysql_insert_id();\r
+\r
+               $manager->notify(\r
+                       'PostAddTemplate',\r
+                       array(\r
+                               'templateid' => $newId,\r
+                               'name' => $name,\r
+                               'description' => $desc\r
+                       )\r
+               );\r
+\r
+               return $newId;\r
+       }\r
+\r
+\r
+\r
+       /**\r
+        * Reads a template and returns an array with the parts.\r
+        * (static)\r
+        *\r
+        * @param $name name of the template file\r
+        */\r
+       function read($name) {\r
+               global $manager;\r
+               $manager->notify(\r
+                       'PreTemplateRead',\r
+                       array(\r
+                               'template' => &$name\r
+                       )\r
+               );\r
+\r
+               $query = 'SELECT tpartname, tcontent'\r
+                          . ' FROM '.sql_table('template_desc').', '.sql_table('template')\r
+                          . ' WHERE tdesc=tdnumber and tdname="' . addslashes($name) . '"';\r
+               $res = sql_query($query);\r
+               while ($obj = mysql_fetch_object($res))\r
+                       $template[$obj->tpartname] = $obj->tcontent;\r
+\r
+               // set locale according to template:\r
+               if ($template['LOCALE'])\r
+                       setlocale(LC_TIME,$template['LOCALE']);\r
+               else\r
+                       setlocale(LC_TIME,'');\r
+\r
+               return $template;\r
+       }\r
+\r
+       /**\r
+         * fills a template with values\r
+         * (static)\r
+         *\r
+         * @param $template\r
+         *             Template to be used\r
+         * @param $values\r
+         *             Array of all the values\r
+         */\r
+       function fill($template, $values) {\r
+\r
+               if (sizeof($values) != 0) {\r
+                       // go through all the values\r
+                       for(reset($values); $key = key($values); next($values)) {\r
+                               $template = str_replace("<%$key%>",$values[$key],$template);\r
+                       }\r
+               }\r
+\r
+               // remove non matched template-tags\r
+               return preg_replace('/<%[a-zA-Z]+%>/','',$template);\r
+       }\r
+\r
+       // returns true if there is a template with the given shortname\r
+       // (static)\r
+       function exists($name) {\r
+               $r = sql_query('select * FROM '.sql_table('template_desc').' WHERE tdname="'.addslashes($name).'"');\r
+               return (mysql_num_rows($r) != 0);\r
+       }\r
+\r
+       // returns true if there is a template with the given ID\r
+       // (static)\r
+       function existsID($id) {\r
+               $r = sql_query('select * FROM '.sql_table('template_desc').' WHERE tdnumber='.intval($id));\r
+               return (mysql_num_rows($r) != 0);\r
+       }\r
+\r
+       // (static)\r
+       function getNameFromId($id) {\r
+               return quickQuery('SELECT tdname as result FROM '.sql_table('template_desc').' WHERE tdnumber=' . intval($id));\r
+       }\r
+\r
+       // (static)\r
+       function getDesc($id) {\r
+               $query = 'SELECT tddesc FROM '.sql_table('template_desc').' WHERE tdnumber='. intval($id);\r
+               $res = sql_query($query);\r
+               $obj = mysql_fetch_object($res);\r
+               return $obj->tddesc;\r
+       }\r
+\r
+\r
+\r
+}\r
+\r
 ?>
\ No newline at end of file
index 5968f06..e84d455 100755 (executable)
-<?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)
- */
-/**
- * Scripts to create/restore a backup of the Nucleus database
- *
- * Based on code in phpBB (http://phpBB.sourceforge.net)
- *
- * @license http://nucleuscms.org/license.txt GNU General Public License
- * @copyright Copyright (C) 2002-2007 The Nucleus Group
- * @version $Id: backup.php,v 1.9 2008-02-08 09:31:22 kimitake Exp $
- * $NucleusJP: backup.php,v 1.8.2.1 2007/08/08 05:23:31 kimitake Exp $
- */
-
-
-/**
-  * This function creates an sql dump of the database and sends it to
-  * the user as a file (can be gzipped if they want)
-  *
-  * @requires
-  *            no output may have preceded (new headers are sent)
-  * @param gzip
-  *            1 = compress backup file, 0 = no compression (default)
-  */
-function do_backup($gzip = 0) {
-       global $manager;
-
-       // tables of which backup is needed
-       $tables = array(
-                                       sql_table('actionlog'),
-                                       sql_table('ban'),
-                                       sql_table('blog'),
-                                       sql_table('comment'),
-                                       sql_table('config'),
-                                       sql_table('item'),
-                                       sql_table('karma'),
-                                       sql_table('member'),
-                                       sql_table('skin'),
-                                       sql_table('skin_desc'),
-                                       sql_table('team'),
-                                       sql_table('template'),
-                                       sql_table('template_desc'),
-                                       sql_table('plugin'),
-                                       sql_table('plugin_event'),
-                                       sql_table('plugin_option'),
-                                       sql_table('plugin_option_desc'),
-                                       sql_table('category'),
-                                       sql_table('activation'),
-                                       sql_table('tickets'),
-                         );
-
-       // add tables that plugins want to backup to the list
-       // catch all output generated by plugins
-       ob_start();
-       $res = sql_query('SELECT pfile FROM '.sql_table('plugin'));
-       while ($plugName = mysql_fetch_object($res)) {
-               $plug =& $manager->getPlugin($plugName->pfile);
-               if ($plug) $tables = array_merge($tables, (array) $plug->getTableList());
-       }
-       ob_end_clean();
-
-       // remove duplicates
-       $tables = array_unique($tables);
-
-       // make sure browsers don't cache the backup
-       header("Pragma: no-cache");
-
-       // don't allow gzip compression when extension is not loaded
-       if (($gzip != 0) && !extension_loaded("zlib"))
-               $gzip = 0;
-
-
-
-       if ($gzip) {
-               // use an output buffer
-               @ob_start();
-               @ob_implicit_flush(0);
-
-               // set filename
-               $filename = 'nucleus_db_backup_'.strftime("%Y%m%d", time()).".sql.gz";
-       } else {
-               $filename = 'nucleus_db_backup_'.strftime("%Y%m%d", time()).".sql";
-       }
-
-
-       // send headers that tell the browser a file is coming
-       header("Content-Type: text/x-delimtext; name=\"$filename\"");
-       header("Content-disposition: attachment; filename=$filename");
-
-       // dump header
-       echo "#\n";
-       echo "# This is a backup file generated by Nucleus \n";
-       echo "# http://www.nucleuscms.org/\n";
-       echo "#\n";
-       echo "# backup-date: " .  gmdate("d-m-Y H:i:s", time()) . " GMT\n";
-       global $nucleus;
-       echo "# Nucleus CMS version: " . $nucleus['version'] . "\n";
-       echo "#\n";
-       echo "# WARNING: Only try to restore on servers running the exact same version of Nucleus\n";
-       echo "#\n";
-
-       // dump all tables
-       reset($tables);
-       array_walk($tables, '_backup_dump_table');
-
-       if($gzip)
-       {
-               $Size = ob_get_length();
-               $Crc = crc32(ob_get_contents());
-               $contents = gzcompress(ob_get_contents());
-               ob_end_clean();
-               echo "\x1f\x8b\x08\x00\x00\x00\x00\x00".substr($contents, 0, strlen($contents) - 4).gzip_PrintFourChars($Crc).gzip_PrintFourChars($Size);
-       }
-
-       exit;
-
-}
-
-
-/**
-  * Creates a dump for a single table
-  * ($tablename and $key are filled in by array_walk)
-  */
-function _backup_dump_table($tablename, $key) {
-
-       echo "#\n";
-       echo "# TABLE: " . $tablename . "\n";
-       echo "#\n";
-
-       // dump table structure
-       _backup_dump_structure($tablename);
-
-       // dump table contents
-       _backup_dump_contents($tablename);
-}
-
-function _backup_dump_structure($tablename) {
-
-       // add command to drop table on restore
-       echo "DROP TABLE IF EXISTS $tablename;\n";
-       echo "CREATE TABLE $tablename(\n";
-
-       //
-       // Ok lets grab the fields...
-       //
-       $result = mysql_query("SHOW FIELDS FROM $tablename");
-       $row = mysql_fetch_array($result);
-       while ($row) {
-
-               echo '  ' . $row['Field'] . ' ' . $row['Type'];
-
-               if(isset($row['Default']))
-                       echo ' DEFAULT \'' . $row['Default'] . '\'';
-
-               if($row['Null'] != "YES")
-                       echo ' NOT NULL';
-
-               if($row['Extra'] != "")
-                       echo ' ' . $row['Extra'];
-
-               $row = mysql_fetch_array($result);
-
-               // add comma's except for last one
-               if ($row)
-                       echo ",\n";
-       }
-
-       //
-       // Get any Indexed fields from the database...
-       //
-       $result = mysql_query("SHOW KEYS FROM $tablename");
-       while($row = mysql_fetch_array($result)) {
-               $kname = $row['Key_name'];
-
-               if(($kname != 'PRIMARY') && ($row['Non_unique'] == 0))
-                       $kname = "UNIQUE|$kname";
-               if(($kname != 'PRIMARY') && ($row['Index_type'] == 'FULLTEXT'))
-                       $kname = "FULLTEXT|$kname";
-
-               if(!is_array($index[$kname]))
-                       $index[$kname] = array();
-
-               $index[$kname][] = $row['Column_name'] . ( ($row['Sub_part']) ? ' (' . $row['Sub_part'] . ')' : '');
-       }
-
-       while(list($x, $columns) = @each($index)) {
-               echo ", \n";
-
-               if($x == 'PRIMARY')
-                       echo '  PRIMARY KEY (' . implode($columns, ', ') . ')';
-               elseif (substr($x,0,6) == 'UNIQUE')
-                       echo '  UNIQUE KEY ' . substr($x,7) . ' (' . implode($columns, ', ') . ')';
-               elseif (substr($x,0,8) == 'FULLTEXT')
-                       echo '  FULLTEXT KEY ' . substr($x,9) . ' (' . implode($columns, ', ') . ')';
-               elseif (($x == 'ibody') || ($x == 'cbody'))                     // karma 2004-05-30 quick and dirty fix. fulltext keys were not in SQL correctly.
-                       echo '  FULLTEXT KEY ' . substr($x,9) . ' (' . implode($columns, ', ') . ')';
-               else
-                       echo "  KEY $x (" . implode($columns, ', ') . ')';
-       }
-
-       echo "\n);\n\n";
-}
-
-/**
- * Returns the field named for the given table in the 
- * following format:
- *
- * (column1, column2, ..., columnn)
- */
-function _backup_get_field_names($result, $num_fields) {
-
-/*     if (function_exists('mysqli_fetch_fields') ) {
-               
-               $fields = mysqli_fetch_fields($result);
-               for ($j = 0; $j < $num_fields; $j++)
-                       $fields[$j] = $fields[$j]->name;
-
-       } else {*/
-
-               $fields = array();
-               for ($j = 0; $j < $num_fields; $j++) {
-                       $fields[] = mysql_field_name($result, $j);
-               }
-
-/*     }*/
-       
-       return '(' . implode(', ', $fields) . ')';      
-}
-
-function _backup_dump_contents($tablename) {
-       //
-       // Grab the data from the table.
-       //
-       $result = mysql_query("SELECT * FROM $tablename");
-
-       if(mysql_num_rows($result) > 0)
-               echo "\n#\n# Table Data for $tablename\n#\n";
-               
-       $num_fields = mysql_num_fields($result);
-       
-       //
-       // Compose fieldname list
-       //
-       $tablename_list = _backup_get_field_names($result, $num_fields);
-               
-       //
-       // Loop through the resulting rows and build the sql statement.
-       //
-       while ($row = mysql_fetch_array($result))
-       {
-               // Start building the SQL statement.
-
-               echo "INSERT INTO $tablename $tablename_list VALUES(";
-
-               // Loop through the rows and fill in data for each column
-               for ($j = 0; $j < $num_fields; $j++) {
-                       if(!isset($row[$j])) {
-                               // no data for column
-                               echo ' NULL';
-                       } elseif ($row[$j] != '') {
-                               // data
-                               echo " '" . addslashes($row[$j]) . "'";
-                       } else {
-                               // empty column (!= no data!)
-                               echo "''";
-                       }
-
-                       // only add comma when not last column
-                       if ($j != ($num_fields - 1))
-                               echo ",";
-               }
-
-               echo ");\n";
-
-       }
-
-
-       echo "\n";
-
-}
-
-// copied from phpBB
-function gzip_PrintFourChars($Val)
-{
-       for ($i = 0; $i < 4; $i ++)
-       {
-               $return .= chr($Val % 256);
-               $Val = floor($Val / 256);
-       }
-       return $return;
-}
-
-function do_restore() {
-
-       $uploadInfo = postFileInfo('backup_file');
-
-       // first of all: get uploaded file:
-       if (empty($uploadInfo['name']))
-               return 'No file uploaded';
-       if (!is_uploaded_file($uploadInfo['tmp_name']))
-               return 'No file uploaded';
-
-       $backup_file_name = $uploadInfo['name'];
-       $backup_file_tmpname = $uploadInfo['tmp_name'];
-       $backup_file_type = $uploadInfo['type'];
-
-       if (!file_exists($backup_file_tmpname))
-               return 'File Upload Error';
-
-       if (!preg_match("/^(text\/[a-zA-Z]+)|(application\/(x\-)?gzip(\-compressed)?)|(application\/octet-stream)$/is", $backup_file_type) )
-               return 'The uploaded file is not of the correct type';
-
-
-
-       if (preg_match("/\.gz/is",$backup_file_name))
-               $gzip = 1;
-       else
-               $gzip = 0;
-
-       if (!extension_loaded("zlib") && $gzip)
-               return "Cannot decompress gzipped backup (zlib package not installed)";
-
-       // get sql query according to gzip setting (either decompress, or not)
-       if($gzip)
-       {
-               // decompress and read
-               $gz_ptr = gzopen($backup_file_tmpname, 'rb');
-               $sql_query = "";
-               while( !gzeof($gz_ptr) )
-                       $sql_query .= gzgets($gz_ptr, 100000);
-       } else {
-               // just read
-               $fsize = filesize($backup_file_tmpname);
-               if ($fsize <= 0)
-                       $sql_query = '';
-               else
-                       $sql_query = fread(fopen($backup_file_tmpname, 'r'), $fsize);
-       }
-
-       // time to execute the query
-       _execute_queries($sql_query);
-}
-
-function _execute_queries($sql_query) {
-       if (!$sql_query) return;
-
-       // Strip out sql comments...
-       $sql_query = remove_remarks($sql_query);
-       $pieces = split_sql_file($sql_query);
-
-       $sql_count = count($pieces);
-       for($i = 0; $i < $sql_count; $i++)
-       {
-               $sql = trim($pieces[$i]);
-
-               if(!empty($sql) and $sql[0] != "#")
-               {
-                       // DEBUG
-//                     debug("Executing: " . htmlspecialchars($sql) . "\n");
-
-                       $result = mysql_query($sql);
-                       if (!$result) debug('SQL Error: ' . mysql_error());
-
-               }
-       }
-
-}
-
-//
-// remove_remarks will strip the sql comment lines out of an uploaded sql file
-//
-function remove_remarks($sql)
-{
-       $lines = explode("\n", $sql);
-
-       // try to keep mem. use down
-       $sql = "";
-
-       $linecount = count($lines);
-       $output = "";
-
-       for ($i = 0; $i < $linecount; $i++)
-       {
-               if (($i != ($linecount - 1)) || (strlen($lines[$i]) > 0))
-               {
-                       if ($lines[$i][0] != "#")
-                       {
-                               $output .= $lines[$i] . "\n";
-                       }
-                       else
-                       {
-                               $output .= "\n";
-                       }
-                       // Trading a bit of speed for lower mem. use here.
-                       $lines[$i] = "";
-               }
-       }
-
-       return $output;
-
-}
-
-
-//
-// split_sql_file will split an uploaded sql file into single sql statements.
-// Note: expects trim() to have already been run on $sql.
-//
-// taken from phpBB
-//
-function split_sql_file($sql)
-{
-       // Split up our string into "possible" SQL statements.
-       $tokens = explode( ";", $sql);
-
-       // try to save mem.
-       $sql = "";
-       $output = array();
-
-       // we don't actually care about the matches preg gives us.
-       $matches = array();
-
-       // this is faster than calling count($tokens) every time thru the loop.
-       $token_count = count($tokens);
-       for ($i = 0; $i < $token_count; $i++)
-       {
-               // Don't wanna add an empty string as the last thing in the array.
-               if (($i != ($token_count - 1)) || (strlen($tokens[$i] > 0)))
-               {
-
-                       // even number of quotes means a complete SQL statement
-                       if (_evenNumberOfQuotes($tokens[$i]))
-                       {
-                               $output[] = $tokens[$i];
-                               $tokens[$i] = "";       // save memory.
-                       }
-                       else
-                       {
-                               // incomplete sql statement. keep adding tokens until we have a complete one.
-                               // $temp will hold what we have so far.
-                               $temp = $tokens[$i] .  ";";
-                               $tokens[$i] = "";       // save memory..
-
-                               // Do we have a complete statement yet?
-                               $complete_stmt = false;
-
-                               for ($j = $i + 1; (!$complete_stmt && ($j < $token_count)); $j++)
-                               {
-                                       // odd number of quotes means a completed statement
-                                       // (in combination with the odd number we had already)
-                                       if (!_evenNumberOfQuotes($tokens[$j]))
-                                       {
-                                               $output[] = $temp . $tokens[$j];
-
-                                               // save memory.
-                                               $tokens[$j] = "";
-                                               $temp = "";
-
-                                               // exit the loop.
-                                               $complete_stmt = true;
-                                               // make sure the outer loop continues at the right point.
-                                               $i = $j;
-                                       }
-                                       else
-                                       {
-                                               // even number of unescaped quotes. We still don't have a complete statement.
-                                               // (1 odd and 1 even always make an odd)
-                                               $temp .= $tokens[$j] .  ";";
-                                               // save memory.
-                                               $tokens[$j] = "";
-                                       }
-
-                               } // for..
-                       } // else
-               }
-       }
-
-       return $output;
-}
-
-
-function _evenNumberOfQuotes($text) {
-               // This is the total number of single quotes in the token.
-               $total_quotes = preg_match_all("/'/", $text, $matches);
-               // Counts single quotes that are preceded by an odd number of backslashes,
-               // which means they're escaped quotes.
-               $escaped_quotes = preg_match_all("/(?<!\\\\)(\\\\\\\\)*\\\\'/", $text, $matches);
-
-               $unescaped_quotes = $total_quotes - $escaped_quotes;
-//             debug($total_quotes . "-" . $escaped_quotes . "-" . $unescaped_quotes);
-               return (($unescaped_quotes % 2) == 0);
-}
-
-?>
+<?php\r
+/*\r
+ * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/)\r
+ * Copyright (C) 2002-2009 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
+/**\r
+ * Scripts to create/restore a backup of the Nucleus database\r
+ *\r
+ * Based on code in phpBB (http://phpBB.sourceforge.net)\r
+ *\r
+ * @license http://nucleuscms.org/license.txt GNU General Public License\r
+ * @copyright Copyright (C) 2002-2009 The Nucleus Group\r
+ * @version $Id$\r
+ * $NucleusJP: backup.php,v 1.8.2.1 2007/08/08 05:23:31 kimitake Exp $\r
+ */\r
+\r
+\r
+class Backup\r
+{ \r
+\r
+       /**\r
+        * Constructor\r
+        */\r
+       function Backup()\r
+       {\r
+               // do nothing\r
+       }\r
+       \r
+       \r
+       /**\r
+         * This function creates an sql dump of the database and sends it to\r
+         * the user as a file (can be gzipped if they want)\r
+         *\r
+         * @requires\r
+         *             no output may have preceded (new headers are sent)\r
+         * @param gzip\r
+         *             1 = compress backup file, 0 = no compression (default)\r
+         */\r
+       function do_backup($gzip = 0) {\r
+               global $manager;\r
+               \r
+               // tables of which backup is needed\r
+               $tables = array(\r
+                                               sql_table('actionlog'),\r
+                                               sql_table('ban'),\r
+                                               sql_table('blog'),\r
+                                               sql_table('comment'),\r
+                                               sql_table('config'),\r
+                                               sql_table('item'),\r
+                                               sql_table('karma'),\r
+                                               sql_table('member'),\r
+                                               sql_table('skin'),\r
+                                               sql_table('skin_desc'),\r
+                                               sql_table('team'),\r
+                                               sql_table('template'),\r
+                                               sql_table('template_desc'),\r
+                                               sql_table('plugin'),\r
+                                               sql_table('plugin_event'),\r
+                                               sql_table('plugin_option'),\r
+                                               sql_table('plugin_option_desc'),\r
+                                               sql_table('category'),\r
+                                               sql_table('activation'),\r
+                                               sql_table('tickets'),\r
+                                 );\r
+               \r
+               // add tables that plugins want to backup to the list\r
+               // catch all output generated by plugins\r
+               ob_start();\r
+               $res = sql_query('SELECT pfile FROM '.sql_table('plugin'));\r
+               while ($plugName = mysql_fetch_object($res)) {\r
+                       $plug =& $manager->getPlugin($plugName->pfile);\r
+                       if ($plug) $tables = array_merge($tables, (array) $plug->getTableList());\r
+               }\r
+               ob_end_clean();\r
+               \r
+               // remove duplicates\r
+               $tables = array_unique($tables);\r
+               \r
+               // make sure browsers don't cache the backup\r
+               header("Pragma: no-cache");\r
+               \r
+               // don't allow gzip compression when extension is not loaded\r
+               if (($gzip != 0) && !extension_loaded("zlib")) {\r
+                       $gzip = 0;\r
+               }\r
+               \r
+               if ($gzip) {\r
+                       // use an output buffer\r
+                       @ob_start();\r
+                       @ob_implicit_flush(0);\r
+               \r
+               // set filename\r
+               $filename = 'nucleus_db_backup_'.strftime("%Y-%m-%d-%H-%M-%S", time()).".sql.gz";\r
+               } else {\r
+               $filename = 'nucleus_db_backup_'.strftime("%Y-%m-%d-%H-%M-%S", time()).".sql";\r
+               }\r
+               \r
+               \r
+               // send headers that tell the browser a file is coming\r
+               header("Content-Type: text/x-delimtext; name=\"$filename\"");\r
+               header("Content-disposition: attachment; filename=$filename");\r
+               \r
+               // dump header\r
+               echo "#\n";\r
+               echo "# This is a backup file generated by Nucleus \n";\r
+               echo "# http://www.nucleuscms.org/\n";\r
+               echo "#\n";\r
+               echo "# backup-date: " .  gmdate("d-m-Y H:i:s", time()) . " GMT\n";\r
+               global $nucleus;\r
+               echo "# Nucleus CMS version: " . $nucleus['version'] . "\n";\r
+               echo "#\n";\r
+               echo "# WARNING: Only try to restore on servers running the exact same version of Nucleus\n";\r
+               echo "#\n";\r
+               \r
+               // dump all tables\r
+               reset($tables);\r
+               array_walk($tables, array(&$this, '_backup_dump_table'));\r
+               \r
+               if($gzip) {\r
+                       $Size = ob_get_length();\r
+                       $Crc = crc32(ob_get_contents());\r
+                       $contents = gzcompress(ob_get_contents());\r
+                       ob_end_clean();\r
+                       echo "\x1f\x8b\x08\x00\x00\x00\x00\x00".substr($contents, 0, strlen($contents) - 4).$this->gzip_PrintFourChars($Crc).$this->gzip_PrintFourChars($Size);\r
+               }\r
+               \r
+               exit;\r
+       \r
+       }\r
+       \r
+       \r
+       /**\r
+         * Creates a dump for a single table\r
+         * ($tablename and $key are filled in by array_walk)\r
+         */\r
+       function _backup_dump_table($tablename, $key) {\r
+       \r
+               echo "#\n";\r
+               echo "# TABLE: " . $tablename . "\n";\r
+               echo "#\n";\r
+       \r
+               // dump table structure\r
+               $this->_backup_dump_structure($tablename);\r
+       \r
+               // dump table contents\r
+               $this->_backup_dump_contents($tablename);\r
+       }\r
+\r
+       /**\r
+         * Creates a dump of the table structure for one table\r
+         */\r
+       function _backup_dump_structure($tablename) {\r
+       \r
+               // add command to drop table on restore\r
+               echo "DROP TABLE IF EXISTS $tablename;\n";\r
+               echo "CREATE TABLE $tablename(\n";\r
+       \r
+               //\r
+               // Ok lets grab the fields...\r
+               //\r
+               $result = mysql_query("SHOW FIELDS FROM $tablename");\r
+               $row = mysql_fetch_array($result);\r
+               while ($row) {\r
+       \r
+                       echo '  `' . $row['Field'] . '` ' . $row['Type'];\r
+       \r
+                       if(isset($row['Default']))\r
+                               echo ' DEFAULT \'' . $row['Default'] . '\'';\r
+       \r
+                       if($row['Null'] != "YES")\r
+                               echo ' NOT NULL';\r
+       \r
+                       if($row['Extra'] != "")\r
+                               echo ' ' . $row['Extra'];\r
+       \r
+                       $row = mysql_fetch_array($result);\r
+       \r
+                       // add comma's except for last one\r
+                       if ($row)\r
+                               echo ",\n";\r
+               }\r
+               \r
+               //\r
+               // Get any Indexed fields from the database...\r
+               //\r
+               $result = mysql_query("SHOW KEYS FROM $tablename");\r
+               while($row = mysql_fetch_array($result)) {\r
+                       $kname = $row['Key_name'];\r
+       \r
+                       if(($kname != 'PRIMARY') && ($row['Non_unique'] == 0))\r
+                               $kname = "UNIQUE|$kname";\r
+                       if(($kname != 'PRIMARY') && ($row['Index_type'] == 'FULLTEXT'))\r
+                               $kname = "FULLTEXT|$kname";\r
+       \r
+                       if(!is_array($index[$kname]))\r
+                               $index[$kname] = array();\r
+       \r
+                       $index[$kname][] = $row['Column_name'] . ( ($row['Sub_part']) ? ' (' . $row['Sub_part'] . ')' : '');\r
+               }\r
+\r
+               while(list($x, $columns) = @each($index)) {\r
+                       echo ", \n";\r
+       \r
+                       if($x == 'PRIMARY')\r
+                               echo '  PRIMARY KEY (`' . implode($columns, '`, `') . '`)';\r
+                       elseif (substr($x,0,6) == 'UNIQUE')\r
+                               echo '  UNIQUE KEY ' . substr($x,7) . ' (`' . implode($columns, '`, `') . '`)';\r
+                       elseif (substr($x,0,8) == 'FULLTEXT')\r
+                               echo '  FULLTEXT KEY ' . substr($x,9) . ' (`' . implode($columns, '`, `') . '`)';\r
+                       elseif (($x == 'ibody') || ($x == 'cbody'))                     // karma 2004-05-30 quick and dirty fix. fulltext keys were not in SQL correctly.\r
+                               echo '  FULLTEXT KEY ' . substr($x,9) . ' (`' . implode($columns, '`, `') . '`)';\r
+                       else\r
+                               echo "  KEY $x (`" . implode($columns, '`, `') . '`)';\r
+               }\r
+       \r
+               echo "\n);\n\n";\r
+       }\r
+\r
+       /**\r
+        * Returns the field named for the given table in the \r
+        * following format:\r
+        *\r
+        * (column1, column2, ..., columnn)\r
+        */\r
+       function _backup_get_field_names($result, $num_fields) {\r
+       \r
+       /*      if (function_exists('mysqli_fetch_fields') ) {\r
+                       \r
+                       $fields = mysqli_fetch_fields($result);\r
+                       for ($j = 0; $j < $num_fields; $j++)\r
+                               $fields[$j] = $fields[$j]->name;\r
+       \r
+               } else {*/\r
+       \r
+                       $fields = array();\r
+                       for ($j = 0; $j < $num_fields; $j++) {\r
+                               $fields[] = mysql_field_name($result, $j);\r
+                       }\r
+       \r
+       /*      }*/\r
+               \r
+               return '(`' . implode('`, `', $fields) . '`)';  \r
+       }\r
+\r
+       /**\r
+         * Creates a dump of the table content for one table     \r
+         */\r
+       function _backup_dump_contents($tablename) {\r
+               //\r
+               // Grab the data from the table.\r
+               //\r
+               $result = mysql_query("SELECT * FROM $tablename");\r
+       \r
+               if(mysql_num_rows($result) > 0)\r
+                       echo "\n#\n# Table Data for $tablename\n#\n";\r
+                       \r
+               $num_fields = mysql_num_fields($result);\r
+               \r
+               //\r
+               // Compose fieldname list\r
+               //\r
+               $tablename_list = $this->_backup_get_field_names($result, $num_fields);\r
+                       \r
+               //\r
+               // Loop through the resulting rows and build the sql statement.\r
+               //\r
+               while ($row = mysql_fetch_array($result))\r
+               {\r
+                       // Start building the SQL statement.\r
+       \r
+                       echo "INSERT INTO `".$tablename."` $tablename_list VALUES(";\r
+       \r
+                       // Loop through the rows and fill in data for each column\r
+                       for ($j = 0; $j < $num_fields; $j++) {\r
+                               if(!isset($row[$j])) {\r
+                                       // no data for column\r
+                                       echo ' NULL';\r
+                               } elseif ($row[$j] != '') {\r
+                                       // data\r
+                                       echo " '" . addslashes($row[$j]) . "'";\r
+                               } else {\r
+                                       // empty column (!= no data!)\r
+                                       echo "''";\r
+                               }\r
+       \r
+                               // only add comma when not last column\r
+                               if ($j != ($num_fields - 1))\r
+                                       echo ",";\r
+                       }\r
+       \r
+                       echo ");\n";\r
+       \r
+               }\r
+       \r
+       \r
+               echo "\n";\r
+       \r
+       }\r
+\r
+       /**\r
+        * copied from phpBB\r
+        */             \r
+       function gzip_PrintFourChars($Val)\r
+       {\r
+               for ($i = 0; $i < 4; $i ++)\r
+               {\r
+                       $return .= chr($Val % 256);\r
+                       $Val = floor($Val / 256);\r
+               }\r
+               return $return;\r
+       }\r
+\r
+       /**\r
+        * Restores a database backup\r
+        */     \r
+       function do_restore() {\r
+       \r
+               $uploadInfo = postFileInfo('backup_file');\r
+       \r
+               // first of all: get uploaded file:\r
+               if (empty($uploadInfo['name']))\r
+                       return 'No file uploaded';\r
+               if (!is_uploaded_file($uploadInfo['tmp_name']))\r
+                       return 'No file uploaded';\r
+       \r
+               $backup_file_name = $uploadInfo['name'];\r
+               $backup_file_tmpname = $uploadInfo['tmp_name'];\r
+               $backup_file_type = $uploadInfo['type'];\r
+       \r
+               if (!file_exists($backup_file_tmpname))\r
+                       return 'File Upload Error';\r
+       \r
+               if (!preg_match("/^(text\/[a-zA-Z]+)|(application\/(x\-)?gzip(\-compressed)?)|(application\/octet-stream)$/is", $backup_file_type) )\r
+                       return 'The uploaded file is not of the correct type';\r
+       \r
+       \r
+               if (preg_match("/\.gz/is",$backup_file_name))\r
+                       $gzip = 1;\r
+               else\r
+                       $gzip = 0;\r
+       \r
+               if (!extension_loaded("zlib") && $gzip)\r
+                       return "Cannot decompress gzipped backup (zlib package not installed)";\r
+       \r
+               // get sql query according to gzip setting (either decompress, or not)\r
+               if($gzip)\r
+               {\r
+                       // decompress and read\r
+                       $gz_ptr = gzopen($backup_file_tmpname, 'rb');\r
+                       $sql_query = "";\r
+                       while( !gzeof($gz_ptr) )\r
+                               $sql_query .= gzgets($gz_ptr, 100000);\r
+               } else {\r
+                       // just read\r
+                       $fsize = filesize($backup_file_tmpname);\r
+                       if ($fsize <= 0)\r
+                               $sql_query = '';\r
+                       else\r
+                               $sql_query = fread(fopen($backup_file_tmpname, 'r'), $fsize);\r
+               }\r
+       \r
+               // time to execute the query\r
+               $this->_execute_queries($sql_query);\r
+       }\r
+\r
+       /**\r
+        * Executes a SQL query\r
+        */     \r
+       function _execute_queries($sql_query) {\r
+               if (!$sql_query) return;\r
+       \r
+               // Strip out sql comments...\r
+               $sql_query = $this->remove_remarks($sql_query);\r
+               $pieces = $this->split_sql_file($sql_query);\r
+       \r
+               $sql_count = count($pieces);\r
+               for($i = 0; $i < $sql_count; $i++)\r
+               {\r
+                       $sql = trim($pieces[$i]);\r
+       \r
+                       if(!empty($sql) and $sql[0] != "#")\r
+                       {\r
+                               // DEBUG\r
+       //                      debug("Executing: " . htmlspecialchars($sql) . "\n");\r
+       \r
+                               $result = mysql_query($sql);\r
+                               if (!$result) debug('SQL Error: ' . mysql_error());\r
+       \r
+                       }\r
+               }\r
+       \r
+       }\r
+\r
+       /**\r
+        * remove_remarks will strip the sql comment lines\r
+        * out of an uploaded sql file\r
+        */     \r
+       function remove_remarks($sql)\r
+       {\r
+               $lines = explode("\n", $sql);\r
+       \r
+               // try to keep mem. use down\r
+               $sql = "";\r
+       \r
+               $linecount = count($lines);\r
+               $output = "";\r
+       \r
+               for ($i = 0; $i < $linecount; $i++)\r
+               {\r
+                       if (($i != ($linecount - 1)) || (strlen($lines[$i]) > 0))\r
+                       {\r
+                               if ($lines[$i][0] != "#")\r
+                               {\r
+                                       $output .= $lines[$i] . "\n";\r
+                               }\r
+                               else\r
+                               {\r
+                                       $output .= "\n";\r
+                               }\r
+                               // Trading a bit of speed for lower mem. use here.\r
+                               $lines[$i] = "";\r
+                       }\r
+               }\r
+       \r
+               return $output;\r
+       \r
+       }\r
+\r
+       /**\r
+        * split_sql_file will split an uploaded sql file\r
+        * into single sql statements.\r
+        *       \r
+        * Note: expects trim() to have already been run on $sql.        \r
+        * taken from phpBB\r
+        */      \r
+       function split_sql_file($sql)\r
+       {\r
+               // Split up our string into "possible" SQL statements.\r
+               $tokens = explode( ";", $sql);\r
+       \r
+               // try to save mem.\r
+               $sql = "";\r
+               $output = array();\r
+       \r
+               // we don't actually care about the matches preg gives us.\r
+               $matches = array();\r
+       \r
+               // this is faster than calling count($tokens) every time thru the loop.\r
+               $token_count = count($tokens);\r
+               for ($i = 0; $i < $token_count; $i++)\r
+               {\r
+                       // Don't wanna add an empty string as the last thing in the array.\r
+                       if (($i != ($token_count - 1)) || (strlen($tokens[$i] > 0)))\r
+                       {\r
+       \r
+                               // even number of quotes means a complete SQL statement\r
+                               if ($this->_evenNumberOfQuotes($tokens[$i]))\r
+                               {\r
+                                       $output[] = $tokens[$i];\r
+                                       $tokens[$i] = "";       // save memory.\r
+                               }\r
+                               else\r
+                               {\r
+                                       // incomplete sql statement. keep adding tokens until we have a complete one.\r
+                                       // $temp will hold what we have so far.\r
+                                       $temp = $tokens[$i] .  ";";\r
+                                       $tokens[$i] = "";       // save memory..\r
+       \r
+                                       // Do we have a complete statement yet?\r
+                                       $complete_stmt = false;\r
+       \r
+                                       for ($j = $i + 1; (!$complete_stmt && ($j < $token_count)); $j++)\r
+                                       {\r
+                                               // odd number of quotes means a completed statement\r
+                                               // (in combination with the odd number we had already)\r
+                                               if (!$this->_evenNumberOfQuotes($tokens[$j]))\r
+                                               {\r
+                                                       $output[] = $temp . $tokens[$j];\r
+       \r
+                                                       // save memory.\r
+                                                       $tokens[$j] = "";\r
+                                                       $temp = "";\r
+       \r
+                                                       // exit the loop.\r
+                                                       $complete_stmt = true;\r
+                                                       // make sure the outer loop continues at the right point.\r
+                                                       $i = $j;\r
+                                               }\r
+                                               else\r
+                                               {\r
+                                                       // even number of unescaped quotes. We still don't have a complete statement.\r
+                                                       // (1 odd and 1 even always make an odd)\r
+                                                       $temp .= $tokens[$j] .  ";";\r
+                                                       // save memory.\r
+                                                       $tokens[$j] = "";\r
+                                               }\r
+       \r
+                                       } // for..\r
+                               } // else\r
+                       }\r
+               }\r
+       \r
+               return $output;\r
+       }\r
+\r
+       /**\r
+        * sub function of split_sql_file\r
+        *       \r
+        * taken from phpBB\r
+        */      \r
+       function _evenNumberOfQuotes($text) {\r
+                       // This is the total number of single quotes in the token.\r
+                       $total_quotes = preg_match_all("/'/", $text, $matches);\r
+                       // Counts single quotes that are preceded by an odd number of backslashes,\r
+                       // which means they're escaped quotes.\r
+                       $escaped_quotes = preg_match_all("/(?<!\\\\)(\\\\\\\\)*\\\\'/", $text, $matches);\r
+       \r
+                       $unescaped_quotes = $total_quotes - $escaped_quotes;\r
+       //              debug($total_quotes . "-" . $escaped_quotes . "-" . $unescaped_quotes);\r
+                       return (($unescaped_quotes % 2) == 0);\r
+       }\r
+\r
+}\r
+\r
+?>
\ No newline at end of file
index 2ae695a..2b7aa02 100755 (executable)
@@ -2,7 +2,7 @@
 \r
 /*\r
  * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/)\r
- * Copyright (C) 2002-2007 The Nucleus Group\r
+ * Copyright (C) 2002-2009 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
  */\r
 /**\r
  * @license http://nucleuscms.org/license.txt GNU General Public License\r
- * @copyright Copyright (C) 2002-2007 The Nucleus Group\r
- * @version $Id: globalfunctions.php,v 1.24 2008-02-08 09:31:22 kimitake Exp $\r
+ * @copyright Copyright (C) 2002-2009 The Nucleus Group\r
+ * @version $Id$\r
  * $NucleusJP: globalfunctions.php,v 1.23.2.7 2008/02/05 08:30:08 kimitake Exp $\r
  */\r
 \r
 // needed if we include globalfunctions from install.php\r
 global $nucleus, $CONF, $DIR_LIBS, $DIR_LANG, $manager, $member;\r
 \r
-$nucleus['version'] = 'v3.4';\r
+$nucleus['version'] = 'v3.40RC';\r
 $nucleus['codename'] = '';\r
 \r
 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'));\r
@@ -32,11 +32,6 @@ if ($CONF['debug']) {
        error_reporting(E_ERROR | E_WARNING | E_PARSE);\r
 }\r
 \r
-// Avoid notices\r
-if (!isset($CONF['Self'])) {\r
-       $CONF['Self'] = htmlspecialchars($_SERVER['PHP_SELF'],ENT_QUOTES);\r
-}\r
-\r
 /*\r
        Indicates when Nucleus should display startup errors. Set to 1 if you want\r
        the error enabled (default), false otherwise\r
@@ -51,15 +46,15 @@ if (!isset($CONF['Self'])) {
                more of the installation files (install.php, install.sql, upgrades/\r
                directory) are still on the server.\r
 */\r
-$CONF['alertOnHeadersSent'] = 1;\r
+$CONF['alertOnHeadersSent']  = 1;\r
 $CONF['alertOnSecurityRisk'] = 1;\r
-$CONF['ItemURL'] = $CONF['Self'];\r
-$CONF['ArchiveURL'] = $CONF['Self'];\r
-$CONF['ArchiveListURL'] = $CONF['Self'];\r
-$CONF['MemberURL'] = $CONF['Self'];\r
-$CONF['SearchURL'] = $CONF['Self'];\r
-$CONF['BlogURL'] = $CONF['Self'];\r
-$CONF['CategoryURL'] = $CONF['Self'];\r
+$CONF['ItemURL']             = $CONF['Self'];\r
+$CONF['ArchiveURL']          = $CONF['Self'];\r
+$CONF['ArchiveListURL']      = $CONF['Self'];\r
+$CONF['MemberURL']           = $CONF['Self'];\r
+$CONF['SearchURL']           = $CONF['Self'];\r
+$CONF['BlogURL']             = $CONF['Self'];\r
+$CONF['CategoryURL']         = $CONF['Self'];\r
 \r
 // switch URLMode back to normal when $CONF['Self'] ends in .php\r
 // this avoids urls like index.php/item/13/index.php/item/15\r
@@ -93,24 +88,24 @@ $orgRequestURI = serverVar('REQUEST_URI');
 sanitizeParams();\r
 \r
 // get all variables that can come from the request and put them in the global scope\r
-$blogid        = requestVar('blogid');\r
-$itemid        = intRequestVar('itemid');\r
-$catid = intRequestVar('catid');\r
-$skinid        = requestVar('skinid');\r
-$memberid = requestVar('memberid');\r
-$archivelist = requestVar('archivelist');\r
-$imagepopup = requestVar('imagepopup');\r
-$archive = requestVar('archive');\r
-$query = requestVar('query');\r
-$highlight = requestVar('highlight');\r
-$amount = requestVar('amount');\r
-$action = requestVar('action');\r
-$nextaction = requestVar('nextaction');\r
-$maxresults = requestVar('maxresults');\r
-$startpos = intRequestVar('startpos');\r
+$blogid       = requestVar('blogid');\r
+$itemid       = intRequestVar('itemid');\r
+$catid        = intRequestVar('catid');\r
+$skinid       = requestVar('skinid');\r
+$memberid     = requestVar('memberid');\r
+$archivelist  = requestVar('archivelist');\r
+$imagepopup   = requestVar('imagepopup');\r
+$archive      = requestVar('archive');\r
+$query        = requestVar('query');\r
+$highlight    = requestVar('highlight');\r
+$amount       = requestVar('amount');\r
+$action       = requestVar('action');\r
+$nextaction   = requestVar('nextaction');\r
+$maxresults   = requestVar('maxresults');\r
+$startpos     = intRequestVar('startpos');\r
 $errormessage = '';\r
-$error = '';\r
-$virtualpath = ((getVar('virtualpath') != null) ? getVar('virtualpath') : serverVar('PATH_INFO'));\r
+$error        = '';\r
+$virtualpath  = ((getVar('virtualpath') != null) ? getVar('virtualpath') : serverVar('PATH_INFO'));\r
 \r
 if (!headers_sent() ) {\r
        header('Generator: Nucleus CMS ' . $nucleus['version']);\r
@@ -161,6 +156,23 @@ register_shutdown_function('sql_disconnect');
 // read config\r
 getConfig();\r
 \r
+// Properly set $CONF['Self'] and others if it's not set... usually when we are access from admin menu\r
+if (!isset($CONF['Self'])) {\r
+       $CONF['Self'] = $CONF['IndexURL'];\r
+       // strip trailing /\r
+       if ($CONF['Self'][strlen($CONF['Self']) -1] == "/") {\r
+               $CONF['Self'] = substr($CONF['Self'], 0, strlen($CONF['Self']) -1);\r
+       }\r
+\r
+       $CONF['ItemURL']        = $CONF['Self'];\r
+       $CONF['ArchiveURL']     = $CONF['Self'];\r
+       $CONF['ArchiveListURL'] = $CONF['Self'];\r
+       $CONF['MemberURL']      = $CONF['Self'];\r
+       $CONF['SearchURL']      = $CONF['Self'];\r
+       $CONF['BlogURL']        = $CONF['Self'];\r
+       $CONF['CategoryURL']    = $CONF['Self'];\r
+}\r
+\r
 // automatically use simpler toolbar for mozilla\r
 if (($CONF['DisableJsTools'] == 0) && strstr(serverVar('HTTP_USER_AGENT'), 'Mozilla/5.0') && strstr(serverVar('HTTP_USER_AGENT'), 'Gecko') ) {\r
        $CONF['DisableJsTools'] = 2;\r
@@ -308,7 +320,7 @@ $language = getLanguageName();
 include($DIR_LANG . ereg_replace( '[\\|/]', '', $language) . '.php');\r
 \r
 // check if valid charset\r
-if (!encoding_check(false,false,_CHARSET)) {\r
+if (!encoding_check(false, false, _CHARSET)) {\r
        foreach(array($_REQUEST, $_SERVER) as $input) {\r
                array_walk($input, 'encoding_check');\r
        }\r
@@ -572,10 +584,10 @@ function sendContentType($contenttype, $pagetype = '', $charset = _CHARSET) {
  * Errors before the database connection has been made\r
  */\r
 function startUpError($msg, $title) {\r
-       if (!defined('_CHARSET')) define('_CHARSET','iso-8859-1');\r
+       if (!defined('_CHARSET')) define('_CHARSET', 'iso-8859-1');\r
        header('Content-Type: text/html; charset=' . _CHARSET);\r
        ?>\r
-       <html xmlns="http://www.w3.org/1999/xhtml">\r
+       <html <?php echo _HTML_XML_NAME_SPACE_AND_LANG_CODE; ?>>\r
                <head><meta http-equiv="Content-Type" content="text/html; charset=<?php echo _CHARSET?>" />\r
                <title><?php echo htmlspecialchars($title)?></title></head>\r
                <body>\r
@@ -929,11 +941,11 @@ function selector() {
                global $startpos;\r
                $type = 'search';\r
                $query = stripslashes($query);\r
-               if(preg_match("/^(\xA1{2}|\xe3\x80{2}|\x20)+$/",$query)){\r
+               if(preg_match("/^(\xA1{2}|\xe3\x80{2}|\x20)+$/", $query)){\r
                                        $type = 'index';\r
                }\r
                $order = (_CHARSET == 'EUC-JP') ? 'EUC-JP, UTF-8,' : 'UTF-8, EUC-JP,';\r
-               $query = mb_convert_encoding($query, _CHARSET, $order.' JIS, SJIS, ASCII');\r
+               $query = mb_convert_encoding($query, _CHARSET, $order . ' JIS, SJIS, ASCII');\r
                if (is_numeric($blogid)) {\r
                        $blogid = intVal($blogid);\r
                } else {\r
@@ -1085,7 +1097,7 @@ function shorten($text, $maxlength, $toadd) {
 //     $trans = get_html_translation_table(HTML_ENTITIES);\r
        $trans = get_html_translation_table(HTML_SPECIALCHARS); // for Japanese\r
        $trans = array_flip($trans);\r
-       $text = strtr($text, $trans);\r
+       $text  = strtr($text, $trans);\r
 \r
        // 2. the actual shortening\r
        if (strlen($text) > $maxlength)\r
@@ -1922,7 +1934,7 @@ function revertArrayForSanitizing($array, &$dst)
  * - the URL will be stripped of illegal or dangerous characters\r
  */\r
 function redirect($url) {\r
-       $url = preg_replace('|[^a-z0-9-~+_.?#=&;,/:@%]|i', '', $url);\r
+       $url = preg_replace('|[^a-z0-9-~+_.?#=&;,/:@%*]|i', '', $url);\r
        header('Location: ' . $url);\r
        exit;\r
 }\r
@@ -2024,10 +2036,10 @@ function encode_desc(&$data)
     {   //_$to_entities = get_html_translation_table(HTML_ENTITIES);\r
         $to_entities = get_html_translation_table(HTML_SPECIALCHARS);\r
         $from_entities = array_flip($to_entities);\r
-        $data = str_replace('<br />','\n',$data); //hack\r
+        $data = str_replace('<br />', '\n', $data); //hack\r
         $data = strtr($data,$from_entities);\r
         $data = strtr($data,$to_entities);\r
-        $data = str_replace('\n','<br />',$data); //hack\r
+        $data = str_replace('\n', '<br />', $data); //hack\r
         return $data;\r
     }\r
  \r
@@ -2076,4 +2088,4 @@ function numberOfEventSubscriber($event) {
        return $obj->count;\r
 }\r
 \r
-?>\r
+?>
\ No newline at end of file
index 5861a3e..e7c9bdd 100644 (file)
@@ -2,7 +2,7 @@
 
 /*
  * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/)
- * Copyright (C) 2002-2007 The Nucleus Group
+ * Copyright (C) 2002-2009 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
@@ -12,8 +12,8 @@
  */
 /**
  * @license http://nucleuscms.org/license.txt GNU General Public License
- * @copyright Copyright (C) 2002-2007 The Nucleus Group
- * @version $Id: mysql.php,v 1.3 2007-02-04 06:28:46 kimitake Exp $
+ * @copyright Copyright (C) 2002-2009 The Nucleus Group
+ * @version $Id$
  * @version $NucleusJP: mysql.php,v 1.2 2006/07/20 08:01:52 kimitake Exp $
  */
  
@@ -27,7 +27,7 @@ if (!function_exists('mysql_query'))
 {
        if (!function_exists('mysqli_query') && function_exists('startUpError'))
        {
-               startUpError('<p>No suitable mySQL library was found to run Nucleus</p>');
+               startUpError(_NO_SUITABLE_MYSQL_LIBRARY);
        }
        
        function mysql_query($query) 
index 372e101..03ca937 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 /*
  * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/)
- * Copyright (C) 2002-2007 The Nucleus Group
+ * Copyright (C) 2002-2009 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
  * Functions to create lists of things inside the admin are
  *
  * @license http://nucleuscms.org/license.txt GNU General Public License
- * @copyright Copyright (C) 2002-2007 The Nucleus Group
- * @version $Id: showlist.php,v 1.8 2008-02-08 09:31:22 kimitake Exp $
+ * @copyright Copyright (C) 2002-2009 The Nucleus Group
+ * @version $Id$
  * @version $NucleusJP: showlist.php,v 1.7.2.3 2007/12/03 00:01:48 kmorimatsu Exp $
  */
 
 
-// can take either an array of objects, or an SQL query
-function showlist($query, $type, $template) {
-
-       if (is_array($query)) {
-               if (sizeof($query) == 0)
-                       return 0;
-
-               call_user_func('listplug_' . $type, $template, 'HEAD');
-
-               foreach ($query as $currentObj) {
-                       $template['current'] = $currentObj;
-                       call_user_func('listplug_' . $type, $template, 'BODY');
-               }
-
-               call_user_func('listplug_' . $type, $template, 'FOOT');
-
-               return sizeof($query);
-
-       } else {
-               $res = sql_query($query);
-
-               // don't do anything if there are no results
-               $numrows = mysql_num_rows($res);
-               if ($numrows == 0)
-                       return 0;
-
-               call_user_func('listplug_' . $type, $template, 'HEAD');
-
-               while($template['current'] = mysql_fetch_object($res))
-                       call_user_func('listplug_' . $type, $template, 'BODY');
-
-               call_user_func('listplug_' . $type, $template, 'FOOT');
-
-               mysql_free_result($res);
-
-               // return amount of results
-               return $numrows;
-       }
-}
-
-function listplug_select($template, $type) {
-       switch($type) {
-               case 'HEAD':
-                       echo '<select name="' . ifset($template['name']) . '" tabindex="' . ifset($template['tabindex']) . '" ' . ifset($template['javascript']) . '>';
-
-                       // add extra row if needed
-                       if (ifset($template['extra'])) {
-                               echo '<option value="', ifset($template['extraval']), '">', $template['extra'], '</option>';
-                       }
-
-                       break;
-               case 'BODY':
-                       $current = $template['current'];
-
-                       echo '<option value="' . htmlspecialchars($current->value) . '"';
-                       if ($template['selected'] == $current->value)
-                               echo ' selected="selected" ';
-                       if (isset($template['shorten']) && $template['shorten'] > 0) {
-                               echo ' title="'. htmlspecialchars($current->text).'"';
-                               $current->text = shorten($current->text, $template['shorten'], $template['shortenel']);
-                       }
-                       echo '>' . htmlspecialchars($current->text) . '</option>';
-                       break;
-               case 'FOOT':
-                       echo '</select>';
-                       break;
-       }
-}
-
-function listplug_table($template, $type) {
-       switch($type) {
-               case 'HEAD':
-                       echo "<table>";
-                       echo "<thead><tr>";
-                       // print head
-                       call_user_func("listplug_table_" . $template['content'] , $template, 'HEAD');
-                       echo "</tr></thead><tbody>";
-                       break;
-               case 'BODY':
-                       // print tabletype specific thingies
-                       echo "<tr onmouseover='focusRow(this);' onmouseout='blurRow(this);'>";
-                       call_user_func("listplug_table_" . $template['content'] , $template,  'BODY');
-                       echo "</tr>";
-                       break;
-               case 'FOOT':
-                       call_user_func("listplug_table_" . $template['content'] , $template,  'FOOT');
-                       echo "</tbody></table>";
-                       break;
-       }
-}
-
-function listplug_table_memberlist($template, $type) {
-       switch($type) {
-               case 'HEAD':
-                       echo '<th>' . _LIST_MEMBER_NAME . '</th><th>' . _LIST_MEMBER_RNAME . '</th><th>' . _LIST_MEMBER_URL . '</th><th>' . _LIST_MEMBER_ADMIN;
-                       help('superadmin');
-                       echo "</th><th>" . _LIST_MEMBER_LOGIN;
-                       help('canlogin');
-                       echo "</th><th colspan='2'>" . _LISTS_ACTIONS. "</th>";
-                       break;
-               case 'BODY':
-                       $current = $template['current'];
-
-                       echo '<td>';
-                       $id = listplug_nextBatchId();
-                       echo '<input type="checkbox" id="batch',$id,'" name="batch[',$id,']" value="',$current->mnumber,'" />';
-                       echo '<label for="batch',$id,'">';
-                       echo "<a href='mailto:", htmlspecialchars($current->memail), "' tabindex='".$template['tabindex']."'>", htmlspecialchars($current->mname), "</a>";
-                       echo '</label>';
-                       echo '</td>';
-                       echo '<td>', htmlspecialchars($current->mrealname), '</td>';
-                       echo "<td><a href='", htmlspecialchars($current->murl), "' tabindex='", $template['tabindex'] , "'>", htmlspecialchars($current->murl), "</a></td>";
-                       echo '<td>', ($current->madmin ? _YES : _NO),'</td>';
-                       echo '<td>', ($current->mcanlogin ? _YES : _NO), '</td>';
-                       echo "<td><a href='index.php?action=memberedit&amp;memberid=$current->mnumber' tabindex='".$template['tabindex']."'>"._LISTS_EDIT."</a></td>";
-                       echo "<td><a href='index.php?action=memberdelete&amp;memberid=$current->mnumber' tabindex='".$template['tabindex']."'>"._LISTS_DELETE."</a></td>";
-                       break;
-       }
-}
-
-function listplug_table_teamlist($template, $type) {
-       global $manager;
-       switch($type) {
-               case 'HEAD':
-                       echo "<th>"._LIST_MEMBER_NAME."</th><th>"._LIST_MEMBER_RNAME."</th><th>"._LIST_TEAM_ADMIN;
-                       help('teamadmin');
-                       echo "</th><th colspan='2'>"._LISTS_ACTIONS."</th>";
-                       break;
-               case 'BODY':
-                       $current = $template['current'];
-
-                       echo '<td>';
-                       $id = listplug_nextBatchId();
-                       echo '<input type="checkbox" id="batch',$id,'" name="batch[',$id,']" value="',$current->tmember,'" />';
-                       echo '<label for="batch',$id,'">';
-                       echo "<a href='mailto:", htmlspecialchars($current->memail), "' tabindex='".$template['tabindex']."'>", htmlspecialchars($current->mname), "</a>";
-                       echo '</label>';
-                       echo '</td>';
-                       echo '<td>', htmlspecialchars($current->mrealname), '</td>';
-                       echo '<td>', ($current->tadmin ? _YES : _NO) , '</td>';
-                       echo "<td><a href='index.php?action=teamdelete&amp;memberid=$current->tmember&amp;blogid=$current->tblog' tabindex='".$template['tabindex']."'>"._LISTS_DELETE."</a></td>";
-
-                       $url = 'index.php?action=teamchangeadmin&memberid=' . intval($current->tmember) . '&blogid=' . intval($current->tblog);
-                       $url = $manager->addTicketToUrl($url);
-                       echo "<td><a href='",htmlspecialchars($url),"' tabindex='".$template['tabindex']."'>"._LIST_TEAM_CHADMIN."</a></td>";
-                       break;
-       }
-}
-
-function listplug_table_pluginlist($template, $type) {
-       global $manager;
-       switch($type) {
-               case 'HEAD':
-                       echo '<th>'._LISTS_INFO.'</th><th>'._LISTS_DESC.'</th>';
-                       echo '<th style="white-space:nowrap">'._LISTS_ACTIONS.'</th>';
-                       break;
-               case 'BODY':
-                       $current = $template['current'];
-
-                       $plug =& $manager->getPlugin($current->pfile);
-                       if ($plug) {
-                               echo '<td>';
-                                       echo '<strong>' , htmlspecialchars($plug->getName()) , '</strong><br />';
-                                       echo _LIST_PLUGS_AUTHOR, ' ' , htmlspecialchars($plug->getAuthor()) , '<br />';
-                                       echo _LIST_PLUGS_VER, ' ' , htmlspecialchars($plug->getVersion()) , '<br />';
-                                       if ($plug->getURL())
-                                       echo '<a href="',htmlspecialchars($plug->getURL()),'" tabindex="'.$template['tabindex'].'">',_LIST_PLUGS_SITE,'</a><br />';
-                               echo '</td>';
-                               echo '<td>';
-                                       echo _LIST_PLUGS_DESC .'<br/>'. encode_desc($plug->getDescription());
-                                       if (sizeof($plug->getEventList()) > 0) {
-                                               echo '<br /><br />',_LIST_PLUGS_SUBS,'<br />',htmlspecialchars(implode($plug->getEventList(),', '));
-                                               // check the database to see if it is up-to-date and notice the user if not
-                                       }
-                                       if (!$plug->subscribtionListIsUptodate()) {
-                                               echo '<br /><br /><strong>',_LIST_PLUG_SUBS_NEEDUPDATE,'</strong>';
-                                       }
-                                       if (sizeof($plug->getPluginDep()) > 0)
-                                               echo '<br /><br />',_LIST_PLUGS_DEP,'<br />',htmlspecialchars(implode($plug->getPluginDep(),', '));
-                               echo '</td>';
-                       } else {
-                               echo '<td colspan="2">Error: plugin file <b>',htmlspecialchars($current->pfile),'.php</b> could not be loaded, or it has been set inactive because it does not support some features (check the <a href="?action=actionlog">actionlog</a> for more info)</td>';
-                       }
-                       echo '<td>';
-
-                               $baseUrl = 'index.php?plugid=' . intval($current->pid) . '&action=';
-                               $url = $manager->addTicketToUrl($baseUrl . 'pluginup');
-                               echo "<a href='",htmlspecialchars($url),"' tabindex='".$template['tabindex']."'>",_LIST_PLUGS_UP,"</a>";
-                               $url = $manager->addTicketToUrl($baseUrl . 'plugindown');
-                               echo "<br /><a href='",htmlspecialchars($url),"' tabindex='".$template['tabindex']."'>",_LIST_PLUGS_DOWN,"</a>";
-                               echo "<br /><a href='index.php?action=plugindelete&amp;plugid=$current->pid' tabindex='".$template['tabindex']."'>",_LIST_PLUGS_UNINSTALL,"</a>";
-                               if ($plug && ($plug->hasAdminArea() > 0))
-                                       echo "<br /><a href='".htmlspecialchars($plug->getAdminURL())."'  tabindex='".$template['tabindex']."'>",_LIST_PLUGS_ADMIN,"</a>";
-                               if ($plug && ($plug->supportsFeature('HelpPage') > 0))
-                                       echo "<br /><a href='index.php?action=pluginhelp&amp;plugid=$current->pid'  tabindex='".$template['tabindex']."'>",_LIST_PLUGS_HELP,"</a>";
-                               if (quickQuery('SELECT COUNT(*) AS result FROM '.sql_table('plugin_option_desc').' WHERE ocontext=\'global\' and opid='.$current->pid) > 0)
-                                       echo "<br /><a href='index.php?action=pluginoptions&amp;plugid=$current->pid'  tabindex='".$template['tabindex']."'>",_LIST_PLUGS_OPTIONS,"</a>";
-                       echo '</td>';
-                       break;
-       }
-}
-
-function listplug_table_plugoptionlist($template, $type) {
-       global $manager;
-       switch($type) {
-               case 'HEAD':
-                       echo '<th>'._LISTS_INFO.'</th><th>'._LISTS_VALUE.'</th>';
-                       break;
-               case 'BODY':
-                       $current = $template['current'];
-                       listplug_plugOptionRow($current);
-                       break;
-               case 'FOOT':
-                       ?>
-                       <tr>
-                               <th colspan="2"><?php echo _PLUGS_SAVE?></th>
-                       </tr><tr>
-                               <td><?php echo _PLUGS_SAVE?></td>
-                               <td><input type="submit" value="<?php echo _PLUGS_SAVE?>" /></td>
-                       </tr>
-                       <?php                   break;
-       }
-}
-
-function listplug_plugOptionRow($current) {
-       $varname = 'plugoption['.$current['oid'].']['.$current['contextid'].']';
-       // retreive the optionmeta
-       $meta = NucleusPlugin::getOptionMeta($current['typeinfo']);
-
-       // only if it is not a hidden option write the controls to the page
-       if (@$meta['access'] != 'hidden') {
-               echo '<td>',htmlspecialchars($current['description']?$current['description']:$current['name']),'</td>';
-               echo '<td>';
-               switch($current['type']) {
-                       case 'yesno':
-                               ADMIN::input_yesno($varname, $current['value'], 0, 'yes', 'no');
-                               break;
-                       case 'password':
-                               echo '<input type="password" size="40" maxlength="128" name="',htmlspecialchars($varname),'" value="',htmlspecialchars($current['value']),'" />';
-                               break;
-                       case 'select':
-                               echo '<select name="'.htmlspecialchars($varname).'">';
-                               $aOptions = NucleusPlugin::getOptionSelectValues($current['typeinfo']);
-                               $aOptions = explode('|', $aOptions);
-                               for ($i=0; $i<(count($aOptions)-1); $i+=2) {
-                                       echo '<option value="'.htmlspecialchars($aOptions[$i+1]).'"';
-                                       if ($aOptions[$i+1] == $current['value'])
-                                               echo ' selected="selected"';
-                                       echo '>'.htmlspecialchars($aOptions[$i]).'</option>';
-                               }
-                               echo '</select>';
-                               break;
-                       case 'textarea':
-                               //$meta = NucleusPlugin::getOptionMeta($current['typeinfo']);
-                               echo '<textarea class="pluginoption" cols="30" rows="5" name="',htmlspecialchars($varname),'"';
-                               if (@$meta['access'] == 'readonly') {
-                                       echo ' readonly="readonly"';
-                               }
-                               echo '>',htmlspecialchars($current['value']),'</textarea>';
-                               break;
-                       case 'text':
-                       default:
-                               //$meta = NucleusPlugin::getOptionMeta($current['typeinfo']);
-
-                               echo '<input type="text" size="40" maxlength="128" name="',htmlspecialchars($varname),'" value="',htmlspecialchars($current['value']),'"';
-                               if (@$meta['datatype'] == 'numerical') {
-                                       echo ' onkeyup="checkNumeric(this)" onblur="checkNumeric(this)"';
-                               }
-                               if (@$meta['access'] == 'readonly') {
-                                       echo ' readonly="readonly"';
-                               }
-                               echo ' />';
-               }
-               echo @$current['extra'];
-               echo '</td>';
-       }
-}
-
-function listplug_table_itemlist($template, $type) {
-       $cssclass = null;
-
-       switch($type) {
-               case 'HEAD':
-                       echo "<th>"._LIST_ITEM_INFO."</th><th>"._LIST_ITEM_CONTENT."</th><th style=\"white-space:nowrap\" colspan='1'>"._LISTS_ACTIONS."</th>";
-                       break;
-               case 'BODY':
-                       $current = $template['current'];
-                       $current->itime = strtotime($current->itime);   // string -> unix timestamp
-
-                       if ($current->idraft == 1)
-                               $cssclass = "class='draft'";
-
-                       // (can't use offset time since offsets might vary between blogs)
-                       if ($current->itime > $template['now'])
-                               $cssclass = "class='future'";
-
-                       echo "<td $cssclass>",_LIST_ITEM_BLOG,' ', htmlspecialchars($current->bshortname);
-                       echo "    <br />",_LIST_ITEM_CAT,' ', htmlspecialchars($current->cname);
-                       echo "    <br />",_LIST_ITEM_AUTHOR, ' ', htmlspecialchars($current->mname);
-                       echo "    <br />",_LIST_ITEM_DATE," " . date("Y-m-d",$current->itime);
-                       echo "<br />",_LIST_ITEM_TIME," " . date("H:i",$current->itime);
-                       echo "</td>";
-                       echo "<td $cssclass>";
-
-                       $id = listplug_nextBatchId();
-
-                       echo '<input type="checkbox" id="batch',$id,'" name="batch[',$id,']" value="',$current->inumber,'" />';
-                       echo '<label for="batch',$id,'">';
-                       echo "<b>" . htmlspecialchars(strip_tags($current->ititle)) . "</b>";
-                       echo '</label>';
-                       echo "<br />";
-
-
-                       $current->ibody = strip_tags($current->ibody);
-                       $current->ibody = htmlspecialchars(shorten($current->ibody,300,'...'));
-
-                       echo "$current->ibody</td>";
-                       echo "<td  style=\"white-space:nowrap\" $cssclass>";
-                       echo    "<a href='index.php?action=itemedit&amp;itemid=$current->inumber'>"._LISTS_EDIT."</a>";
-                       echo    "<br /><a href='index.php?action=itemcommentlist&amp;itemid=$current->inumber'>"._LISTS_COMMENTS."</a>";
-                       echo    "<br /><a href='index.php?action=itemmove&amp;itemid=$current->inumber'>"._LISTS_MOVE."</a>";
-                       echo    "<br /><a href='index.php?action=itemdelete&amp;itemid=$current->inumber'>"._LISTS_DELETE."</a>";
-                       echo "</td>";
-                       break;
-       }
-}
-
-// for batch operations: generates the index numbers for checkboxes
-function listplug_nextBatchId() {
-       static $id = 0;
-       return $id++;
-}
-
-function listplug_table_commentlist($template, $type) {
-       switch($type) {
-               case 'HEAD':
-                       echo "<th>"._LISTS_INFO."</th><th>"._LIST_COMMENT."</th><th colspan='3'>"._LISTS_ACTIONS."</th>";
-                       break;
-               case 'BODY':
-                       $current = $template['current'];
-                       $current->ctime = strtotime($current->ctime);   // string -> unix timestamp
-
-                       echo '<td>';
-                       echo date("Y-m-d@H:i",$current->ctime);
-                       echo '<br />';
-                       if ($current->mname)
-                               echo htmlspecialchars($current->mname) ,' ', _LIST_COMMENTS_MEMBER;
-                       else
-                               echo htmlspecialchars($current->cuser);
-                       if ($current->cmail != '') {
-                                echo '<br />';
-                                echo htmlspecialchars($current->cmail);
-                        }
-                       if ($current->cemail != '') {
-                                echo '<br />';
-                                echo htmlspecialchars($current->cemail);
-                        }
-                       echo '</td>';
-
-                       $current->cbody = strip_tags($current->cbody);
-                       $current->cbody = htmlspecialchars(shorten($current->cbody, 300, '...'));
-
-                       echo '<td>';
-                       $id = listplug_nextBatchId();
-                       echo '<input type="checkbox" id="batch',$id,'" name="batch[',$id,']" value="',$current->cnumber,'" />';
-                       echo '<label for="batch',$id,'">';
-                       echo $current->cbody;
-                       echo '</label>';
-                       echo '</td>';
-
-                       echo "<td style=\"white-space:nowrap\"><a href='index.php?action=commentedit&amp;commentid=$current->cnumber'>"._LISTS_EDIT."</a></td>";
-                       echo "<td style=\"white-space:nowrap\"><a href='index.php?action=commentdelete&amp;commentid=$current->cnumber'>"._LISTS_DELETE."</a></td>";
-                       if ($template['canAddBan'])
-                               echo "<td style=\"white-space:nowrap\"><a href='index.php?action=banlistnewfromitem&amp;itemid=$current->citem&amp;ip=", htmlspecialchars($current->cip), "' title='", htmlspecialchars($current->chost), "'>"._LIST_COMMENT_BANIP."</a></td>";
-                       break;
-       }
-}
-
-
-function listplug_table_bloglist($template, $type) {
-       switch($type) {
-               case 'HEAD':
-                       echo "<th>" . _NAME . "</th><th colspan='7'>" ._LISTS_ACTIONS. "</th>";
-                       break;
-               case 'BODY':
-                       $current = $template['current'];
-
-                       echo "<td title='blogid:$current->bnumber shortname:$current->bshortname'><a href='$current->burl'><img src='images/globe.gif' width='13' height='13' alt='". _BLOGLIST_TT_VISIT."' /></a> " . htmlspecialchars($current->bname) . "</td>";
-                       echo "<td><a href='index.php?action=createitem&amp;blogid=$current->bnumber' title='" . _BLOGLIST_TT_ADD ."'>" . _BLOGLIST_ADD . "</a></td>";
-                       echo "<td><a href='index.php?action=itemlist&amp;blogid=$current->bnumber' title='". _BLOGLIST_TT_EDIT."'>". _BLOGLIST_EDIT."</a></td>";
-                       echo "<td><a href='index.php?action=blogcommentlist&amp;blogid=$current->bnumber' title='". _BLOGLIST_TT_COMMENTS."'>". _BLOGLIST_COMMENTS."</a></td>";
-                       echo "<td><a href='index.php?action=bookmarklet&amp;blogid=$current->bnumber' title='". _BLOGLIST_TT_BMLET."'>". _BLOGLIST_BMLET . "</a></td>";
-
-                       if ($current->tadmin == 1) {
-                               echo "<td><a href='index.php?action=blogsettings&amp;blogid=$current->bnumber' title='" . _BLOGLIST_TT_SETTINGS . "'>" ._BLOGLIST_SETTINGS. "</a></td>";
-                               echo "<td><a href='index.php?action=banlist&amp;blogid=$current->bnumber' title='" . _BLOGLIST_TT_BANS. "'>". _BLOGLIST_BANS."</a></td>";
-                       }
-
-                       if ($template['superadmin']) {
-                               echo "<td><a href='index.php?action=deleteblog&amp;blogid=$current->bnumber' title='". _BLOGLIST_TT_DELETE."'>" ._BLOGLIST_DELETE. "</a></td>";
-                       }
-
-
-
-                       break;
-       }
-}
-
-function listplug_table_shortblognames($template, $type) {
-       switch($type) {
-               case 'HEAD':
-                       echo "<th>" . _NAME . "</th><th>" . _NAME. "</th>";
-                       break;
-               case 'BODY':
-                       $current = $template['current'];
-
-                       echo '<td>' , htmlspecialchars($current->bshortname) , '</td>';
-                       echo '<td>' , htmlspecialchars($current->bname) , '</td>';
-
-                       break;
-       }
-}
-
-function listplug_table_shortnames($template, $type) {
-       switch($type) {
-               case 'HEAD':
-                       echo "<th>" . _NAME . "</th><th>" . _LISTS_DESC. "</th>";
-                       break;
-               case 'BODY':
-                       $current = $template['current'];
-
-                       echo '<td>' , htmlspecialchars($current->name) , '</td>';
-                       echo '<td>' , htmlspecialchars($current->description) , '</td>';
-
-                       break;
-       }
-}
-
-
-function listplug_table_categorylist($template, $type) {
-       switch($type) {
-               case 'HEAD':
-                       echo "<th>"._LISTS_NAME."</th><th>"._LISTS_DESC."</th><th colspan='2'>"._LISTS_ACTIONS."</th>";
-                       break;
-               case 'BODY':
-                       $current = $template['current'];
-
-                       echo '<td>';
-                       $id = listplug_nextBatchId();
-                       echo '<input type="checkbox" id="batch',$id,'" name="batch[',$id,']" value="',$current->catid,'" />';
-                       echo '<label for="batch',$id,'">';
-                       echo htmlspecialchars($current->cname);
-                       echo '</label>';
-                       echo '</td>';
-
-                       echo '<td>', htmlspecialchars($current->cdesc), '</td>';
-                       echo "<td><a href='index.php?action=categorydelete&amp;blogid=$current->cblog&amp;catid=$current->catid' tabindex='".$template['tabindex']."'>"._LISTS_DELETE."</a></td>";
-                       echo "<td><a href='index.php?action=categoryedit&amp;blogid=$current->cblog&amp;catid=$current->catid' tabindex='".$template['tabindex']."'>"._LISTS_EDIT."</a></td>";
-
-                       break;
-       }
-}
-
-
-function listplug_table_templatelist($template, $type) {
-       global $manager;
-       switch($type) {
-               case 'HEAD':
-                       echo "<th>"._LISTS_NAME."</th><th>"._LISTS_DESC."</th><th colspan='3'>"._LISTS_ACTIONS."</th>";
-                       break;
-               case 'BODY':
-                       $current = $template['current'];
-
-                       echo "<td>" , htmlspecialchars($current->tdname), "</td>";
-                       echo "<td>" , htmlspecialchars($current->tddesc), "</td>";
-                       echo "<td style=\"white-space:nowrap\"><a href='index.php?action=templateedit&amp;templateid=$current->tdnumber' tabindex='".$template['tabindex']."'>"._LISTS_EDIT."</a></td>";
-
-                       $url = $manager->addTicketToUrl('index.php?action=templateclone&templateid=' . intval($current->tdnumber));
-                       echo "<td style=\"white-space:nowrap\"><a href='",htmlspecialchars($url),"' tabindex='".$template['tabindex']."'>"._LISTS_CLONE."</a></td>";
-                       echo "<td style=\"white-space:nowrap\"><a href='index.php?action=templatedelete&amp;templateid=$current->tdnumber' tabindex='".$template['tabindex']."'>"._LISTS_DELETE."</a></td>";
-
-                       break;
-       }
-}
-
-function listplug_table_skinlist($template, $type) {
-       global $CONF, $DIR_SKINS, $manager;
-       switch($type) {
-               case 'HEAD':
-                       echo "<th>"._LISTS_NAME."</th><th>"._LISTS_DESC."</th><th colspan='3'>"._LISTS_ACTIONS."</th>";
-                       break;
-               case 'BODY':
-                       $current = $template['current'];
-
-                       echo '<td>';
-
-                       // use a special style for the default skin
-                       if ($current->sdnumber == $CONF['BaseSkin']) {
-                               echo '<strong>',htmlspecialchars($current->sdname),'</strong>';
-                       } else {
-                               echo htmlspecialchars($current->sdname);
-                       }
-
-                       echo '<br /><br />';
-                       echo _LISTS_TYPE ,': ' , htmlspecialchars($current->sdtype);
-                       echo '<br />', _LIST_SKINS_INCMODE , ' ' , (($current->sdincmode=='skindir') ?_PARSER_INCMODE_SKINDIR:_PARSER_INCMODE_NORMAL);
-                       if ($current->sdincpref) echo '<br />' , _LIST_SKINS_INCPREFIX , ' ', htmlspecialchars($current->sdincpref);
-
-                       // add preview image when present
-                       if ($current->sdincpref && @file_exists($DIR_SKINS . $current->sdincpref . 'preview.png'))
-                       {
-                               echo '<br /><br />';
-
-                               $hasEnlargement = @file_exists($DIR_SKINS . $current->sdincpref . 'preview-large.png');
-                               if ($hasEnlargement)
-                                       echo '<a href="',$CONF['SkinsURL'], htmlspecialchars($current->sdincpref),'preview-large.png" title="View larger">';
-
-                               echo '<img class="skinpreview" src="',$CONF['SkinsURL'], htmlspecialchars($current->sdincpref),'preview.png" width="100" height="75" alt="Preview for \'',htmlspecialchars($current->sdname),'\' skin" />';
-
-                               if ($hasEnlargement)
-                                       echo '</a>';
-
-                               if (@file_exists($DIR_SKINS . $current->sdincpref . 'readme.html'))
-                               {
-                                       echo '<br /><a href="',$CONF['SkinsURL'], htmlspecialchars($current->sdincpref),'readme.html" title="More info on the \'',htmlspecialchars($current->sdname),'\' skin">Readme</a>';
-                               }
-
-
-                       }
-
-                       echo "</td>";
-
-
-                       echo "<td>" , htmlspecialchars($current->sddesc);
-                               // show list of defined parts
-                               $r = sql_query('SELECT stype FROM '.sql_table('skin').' WHERE sdesc='.$current->sdnumber . ' ORDER BY stype');
-                               $types = array();
-                               while ($o = mysql_fetch_object($r))
-                                       array_push($types,$o->stype);
-                               if (sizeof($types) > 0) {
-                                       $friendlyNames = SKIN::getFriendlyNames();
-                                       for ($i=0;$i<sizeof($types);$i++) {
-                                               $type = $types[$i];
-                                               if (in_array($type, array('index', 'item', 'archivelist', 'archive', 'search', 'error', 'member', 'imagepopup'))) {
-                                                       $types[$i] = '<li>' . helpHtml('skinpart'.$type) . ' <a href="index.php?action=skinedittype&amp;skinid='.$current->sdnumber.'&amp;type='.$type.'" tabindex="'.$template['tabindex'].'">' . htmlspecialchars($friendlyNames[$type]) . "</a></li>";
-                                               } else {
-                                                       $types[$i] = '<li>' . helpHtml('skinpartspecial') . ' <a href="index.php?action=skinedittype&amp;skinid='.$current->sdnumber.'&amp;type='.$type.'" tabindex="'.$template['tabindex'].'">' . htmlspecialchars($friendlyNames[$type]) . "</a></li>";
-                                               }
-                                       }
-                                       echo '<br /><br />',_LIST_SKINS_DEFINED,' <ul>',implode($types,'') ,'</ul>';
-                               }
-                       echo "</td>";
-                       echo "<td style=\"white-space:nowrap\"><a href='index.php?action=skinedit&amp;skinid=$current->sdnumber' tabindex='".$template['tabindex']."'>"._LISTS_EDIT."</a></td>";
-
-                       $url = $manager->addTicketToUrl('index.php?action=skinclone&skinid=' . intval($current->sdnumber));
-                       echo "<td style=\"white-space:nowrap\"><a href='",htmlspecialchars($url),"' tabindex='".$template['tabindex']."'>"._LISTS_CLONE."</a></td>";
-                       echo "<td style=\"white-space:nowrap\"><a href='index.php?action=skindelete&amp;skinid=$current->sdnumber' tabindex='".$template['tabindex']."'>"._LISTS_DELETE."</a></td>";
-
-                       break;
-       }
-}
-
-function listplug_table_draftlist($template, $type) {
-       switch($type) {
-               case 'HEAD':
-                       echo "<th>"._LISTS_BLOG."</th><th>"._LISTS_TITLE."</th><th colspan='2'>"._LISTS_ACTIONS."</th>";
-                       break;
-               case 'BODY':
-                       $current = $template['current'];
-
-                       echo '<td>', htmlspecialchars($current->bshortname) , '</td>';
-                       echo '<td>', htmlspecialchars(strip_tags($current->ititle)) , '</td>';
-                       echo "<td><a href='index.php?action=itemedit&amp;itemid=$current->inumber'>"._LISTS_EDIT."</a></td>";
-                       echo "<td><a href='index.php?action=itemdelete&amp;itemid=$current->inumber'>"._LISTS_DELETE."</a></td>";
-
-                       break;
-       }
-}
-
-
-function listplug_table_actionlist($template, $type) {
-       switch($type) {
-               case 'HEAD':
-                       echo '<th>'._LISTS_TIME.'</th><th>'._LIST_ACTION_MSG.'</th>';
-                       break;
-               case 'BODY':
-                       $current = $template['current'];
-
-                       echo '<td>' , htmlspecialchars($current->timestamp), '</td>';
-                       echo '<td>' , htmlspecialchars($current->message), '</td>';
-
-                       break;
-       }
-}
-
-function listplug_table_banlist($template, $type) {
-       switch($type) {
-               case 'HEAD':
-                       echo '<th>'._LIST_BAN_IPRANGE.'</th><th>'. _LIST_BAN_REASON.'</th><th>'._LISTS_ACTIONS.'</th>';
-                       break;
-               case 'BODY':
-                       $current = $template['current'];
-
-                       echo '<td>' , htmlspecialchars($current->iprange) , '</td>';
-                       echo '<td>' , htmlspecialchars($current->reason) , '</td>';
-                       echo "<td><a href='index.php?action=banlistdelete&amp;blogid=", intval($current->blogid) , "&amp;iprange=" , htmlspecialchars($current->iprange) , "'>",_LISTS_DELETE,"</a></td>";
-                       break;
-       }
-}
-
+// can take either an array of objects, or an SQL query\r
+function showlist($query, $type, $template) {\r
+\r
+       if (is_array($query)) {\r
+               if (sizeof($query) == 0)\r
+                       return 0;\r
+\r
+               call_user_func('listplug_' . $type, $template, 'HEAD');\r
+\r
+               foreach ($query as $currentObj) {\r
+                       $template['current'] = $currentObj;\r
+                       call_user_func('listplug_' . $type, $template, 'BODY');\r
+               }\r
+\r
+               call_user_func('listplug_' . $type, $template, 'FOOT');\r
+\r
+               return sizeof($query);\r
+\r
+       } else {\r
+               $res = sql_query($query);\r
+\r
+               // don't do anything if there are no results\r
+               $numrows = mysql_num_rows($res);\r
+               if ($numrows == 0)\r
+                       return 0;\r
+\r
+               call_user_func('listplug_' . $type, $template, 'HEAD');\r
+\r
+               while($template['current'] = mysql_fetch_object($res))\r
+                       call_user_func('listplug_' . $type, $template, 'BODY');\r
+\r
+               call_user_func('listplug_' . $type, $template, 'FOOT');\r
+\r
+               mysql_free_result($res);\r
+\r
+               // return amount of results\r
+               return $numrows;\r
+       }\r
+}\r
+\r
+function listplug_select($template, $type) {\r
+       switch($type) {\r
+               case 'HEAD':\r
+                       echo '<select name="' . ifset($template['name']) . '" tabindex="' . ifset($template['tabindex']) . '" ' . ifset($template['javascript']) . '>';\r
+\r
+                       // add extra row if needed\r
+                       if (ifset($template['extra'])) {\r
+                               echo '<option value="', ifset($template['extraval']), '">', $template['extra'], '</option>';\r
+                       }\r
+\r
+                       break;\r
+               case 'BODY':\r
+                       $current = $template['current'];\r
+\r
+                       echo '<option value="' . htmlspecialchars($current->value) . '"';\r
+                       if ($template['selected'] == $current->value)\r
+                               echo ' selected="selected" ';\r
+                       if (isset($template['shorten']) && $template['shorten'] > 0) {\r
+                               echo ' title="'. htmlspecialchars($current->text).'"';\r
+                               $current->text = shorten($current->text, $template['shorten'], $template['shortenel']);\r
+                       }\r
+                       echo '>' . htmlspecialchars($current->text) . '</option>';\r
+                       break;\r
+               case 'FOOT':\r
+                       echo '</select>';\r
+                       break;\r
+       }\r
+}\r
+\r
+function listplug_table($template, $type) {\r
+       switch($type) {\r
+               case 'HEAD':\r
+                       echo "<table>";\r
+                       echo "<thead><tr>";\r
+                       // print head\r
+                       call_user_func("listplug_table_" . $template['content'] , $template, 'HEAD');\r
+                       echo "</tr></thead><tbody>";\r
+                       break;\r
+               case 'BODY':\r
+                       // print tabletype specific thingies\r
+                       echo "<tr onmouseover='focusRow(this);' onmouseout='blurRow(this);'>";\r
+                       call_user_func("listplug_table_" . $template['content'] , $template,  'BODY');\r
+                       echo "</tr>";\r
+                       break;\r
+               case 'FOOT':\r
+                       call_user_func("listplug_table_" . $template['content'] , $template,  'FOOT');\r
+                       echo "</tbody></table>";\r
+                       break;\r
+       }\r
+}\r
+\r
+function listplug_table_memberlist($template, $type) {\r
+       switch($type) {\r
+               case 'HEAD':\r
+                       echo '<th>' . _LIST_MEMBER_NAME . '</th><th>' . _LIST_MEMBER_RNAME . '</th><th>' . _LIST_MEMBER_URL . '</th><th>' . _LIST_MEMBER_ADMIN;\r
+                       help('superadmin');\r
+                       echo "</th><th>" . _LIST_MEMBER_LOGIN;\r
+                       help('canlogin');\r
+                       echo "</th><th colspan='2'>" . _LISTS_ACTIONS. "</th>";\r
+                       break;\r
+               case 'BODY':\r
+                       $current = $template['current'];\r
+\r
+                       echo '<td>';\r
+                       $id = listplug_nextBatchId();\r
+                       echo '<input type="checkbox" id="batch',$id,'" name="batch[',$id,']" value="',$current->mnumber,'" />';\r
+                       echo '<label for="batch',$id,'">';\r
+                       echo "<a href='mailto:", htmlspecialchars($current->memail), "' tabindex='".$template['tabindex']."'>", htmlspecialchars($current->mname), "</a>";\r
+                       echo '</label>';\r
+                       echo '</td>';\r
+                       echo '<td>', htmlspecialchars($current->mrealname), '</td>';\r
+                       echo "<td><a href='", htmlspecialchars($current->murl), "' tabindex='", $template['tabindex'] , "'>", htmlspecialchars($current->murl), "</a></td>";\r
+                       echo '<td>', ($current->madmin ? _YES : _NO),'</td>';\r
+                       echo '<td>', ($current->mcanlogin ? _YES : _NO), '</td>';\r
+                       echo "<td><a href='index.php?action=memberedit&amp;memberid=$current->mnumber' tabindex='".$template['tabindex']."'>"._LISTS_EDIT."</a></td>";\r
+                       echo "<td><a href='index.php?action=memberdelete&amp;memberid=$current->mnumber' tabindex='".$template['tabindex']."'>"._LISTS_DELETE."</a></td>";\r
+                       break;\r
+       }\r
+}\r
+\r
+function listplug_table_teamlist($template, $type) {\r
+       global $manager;\r
+       switch($type) {\r
+               case 'HEAD':\r
+                       echo "<th>"._LIST_MEMBER_NAME."</th><th>"._LIST_MEMBER_RNAME."</th><th>"._LIST_TEAM_ADMIN;\r
+                       help('teamadmin');\r
+                       echo "</th><th colspan='2'>"._LISTS_ACTIONS."</th>";\r
+                       break;\r
+               case 'BODY':\r
+                       $current = $template['current'];\r
+\r
+                       echo '<td>';\r
+                       $id = listplug_nextBatchId();\r
+                       echo '<input type="checkbox" id="batch',$id,'" name="batch[',$id,']" value="',$current->tmember,'" />';\r
+                       echo '<label for="batch',$id,'">';\r
+                       echo "<a href='mailto:", htmlspecialchars($current->memail), "' tabindex='".$template['tabindex']."'>", htmlspecialchars($current->mname), "</a>";\r
+                       echo '</label>';\r
+                       echo '</td>';\r
+                       echo '<td>', htmlspecialchars($current->mrealname), '</td>';\r
+                       echo '<td>', ($current->tadmin ? _YES : _NO) , '</td>';\r
+                       echo "<td><a href='index.php?action=teamdelete&amp;memberid=$current->tmember&amp;blogid=$current->tblog' tabindex='".$template['tabindex']."'>"._LISTS_DELETE."</a></td>";\r
+\r
+                       $url = 'index.php?action=teamchangeadmin&memberid=' . intval($current->tmember) . '&blogid=' . intval($current->tblog);\r
+                       $url = $manager->addTicketToUrl($url);\r
+                       echo "<td><a href='",htmlspecialchars($url),"' tabindex='".$template['tabindex']."'>"._LIST_TEAM_CHADMIN."</a></td>";\r
+                       break;\r
+       }\r
+}\r
+\r
+function listplug_table_pluginlist($template, $type) {\r
+       global $manager;\r
+       switch($type) {\r
+               case 'HEAD':\r
+                       echo '<th>'._LISTS_INFO.'</th><th>'._LISTS_DESC.'</th>';\r
+                       echo '<th style="white-space:nowrap">'._LISTS_ACTIONS.'</th>';\r
+                       break;\r
+               case 'BODY':\r
+                       $current = $template['current'];\r
+\r
+                       $plug =& $manager->getPlugin($current->pfile);\r
+                       if ($plug) {\r
+                               echo '<td>';\r
+                                       echo '<strong>' , htmlspecialchars($plug->getName()) , '</strong><br />';\r
+                                       echo _LIST_PLUGS_AUTHOR, ' ' , htmlspecialchars($plug->getAuthor()) , '<br />';\r
+                                       echo _LIST_PLUGS_VER, ' ' , htmlspecialchars($plug->getVersion()) , '<br />';\r
+                                       if ($plug->getURL())\r
+                                       echo '<a href="',htmlspecialchars($plug->getURL()),'" tabindex="'.$template['tabindex'].'">',_LIST_PLUGS_SITE,'</a><br />';\r
+                               echo '</td>';\r
+                               echo '<td>';\r
+                                       echo _LIST_PLUGS_DESC .'<br/>'. encode_desc($plug->getDescription());\r
+                                       if (sizeof($plug->getEventList()) > 0) {\r
+                                               echo '<br /><br />',_LIST_PLUGS_SUBS,'<br />',htmlspecialchars(implode($plug->getEventList(),', '));\r
+                                               // check the database to see if it is up-to-date and notice the user if not\r
+                                       }\r
+                                       if (!$plug->subscribtionListIsUptodate()) {\r
+                                               echo '<br /><br /><strong>',_LIST_PLUG_SUBS_NEEDUPDATE,'</strong>';\r
+                                       }\r
+                                       if (sizeof($plug->getPluginDep()) > 0) {\r
+                                               echo '<br /><br />',_LIST_PLUGS_DEP,'<br />',htmlspecialchars(implode($plug->getPluginDep(),', '));\r
+                                       }\r
+// <add by shizuki>\r
+                               // check dependency require\r
+                               $req = array();\r
+                               $res = sql_query('SELECT pfile FROM ' . sql_table('plugin'));\r
+                               while($o = mysql_fetch_object($res)) {\r
+                                       $preq =& $manager->getPlugin($o->pfile);\r
+                                       if ($plug) {\r
+                                               $depList = $preq->getPluginDep();\r
+                                               foreach ($depList as $depName) {\r
+                                                       if ($current->pfile == $depName) {\r
+                                                               $req[] = $o->pfile;\r
+                                                       }\r
+                                               }\r
+                                       }\r
+                               }\r
+                               if (count($req) > 0) {\r
+                                       echo '<h4 class="plugin_dependreq_title">' . _LIST_PLUGS_DEPREQ . "</h4>\n";\r
+                                       echo '<p class="plugin_dependreq_text">';\r
+                                       echo htmlspecialchars(implode(', ', $req), ENT_QUOTES);\r
+                                       echo "</p>\n";\r
+                               }\r
+// </add by shizuki>\r
+                               echo '</td>';\r
+                       } else {\r
+                               echo '<td colspan="2">' . sprintf(_PLUGINFILE_COULDNT_BELOADED, htmlspecialchars($current->pfile, ENT_QUOTES)) . '</td>';\r
+                       }\r
+                       echo '<td>';\r
+\r
+                               $baseUrl = 'index.php?plugid=' . intval($current->pid) . '&action=';\r
+                               $url = $manager->addTicketToUrl($baseUrl . 'pluginup');\r
+                               echo "<a href='",htmlspecialchars($url),"' tabindex='".$template['tabindex']."'>",_LIST_PLUGS_UP,"</a>";\r
+                               $url = $manager->addTicketToUrl($baseUrl . 'plugindown');\r
+                               echo "<br /><a href='",htmlspecialchars($url),"' tabindex='".$template['tabindex']."'>",_LIST_PLUGS_DOWN,"</a>";\r
+                               echo "<br /><a href='index.php?action=plugindelete&amp;plugid=$current->pid' tabindex='".$template['tabindex']."'>",_LIST_PLUGS_UNINSTALL,"</a>";\r
+                               if ($plug && ($plug->hasAdminArea() > 0))\r
+                                       echo "<br /><a href='".htmlspecialchars($plug->getAdminURL())."'  tabindex='".$template['tabindex']."'>",_LIST_PLUGS_ADMIN,"</a>";\r
+                               if ($plug && ($plug->supportsFeature('HelpPage') > 0))\r
+                                       echo "<br /><a href='index.php?action=pluginhelp&amp;plugid=$current->pid'  tabindex='".$template['tabindex']."'>",_LIST_PLUGS_HELP,"</a>";\r
+                               if (quickQuery('SELECT COUNT(*) AS result FROM '.sql_table('plugin_option_desc').' WHERE ocontext=\'global\' and opid='.$current->pid) > 0)\r
+                                       echo "<br /><a href='index.php?action=pluginoptions&amp;plugid=$current->pid'  tabindex='".$template['tabindex']."'>",_LIST_PLUGS_OPTIONS,"</a>";\r
+                       echo '</td>';\r
+                       break;\r
+       }\r
+}\r
+\r
+function listplug_table_plugoptionlist($template, $type) {\r
+       global $manager;\r
+       switch($type) {\r
+               case 'HEAD':\r
+                       echo '<th>'._LISTS_INFO.'</th><th>'._LISTS_VALUE.'</th>';\r
+                       break;\r
+               case 'BODY':\r
+                       $current = $template['current'];\r
+                       listplug_plugOptionRow($current);\r
+                       break;\r
+               case 'FOOT':\r
+                       ?>\r
+                       <tr>\r
+                               <th colspan="2"><?php echo _PLUGS_SAVE?></th>\r
+                       </tr><tr>\r
+                               <td><?php echo _PLUGS_SAVE?></td>\r
+                               <td><input type="submit" value="<?php echo _PLUGS_SAVE?>" /></td>\r
+                       </tr>\r
+                       <?php                   break;\r
+       }\r
+}\r
+\r
+function listplug_plugOptionRow($current) {\r
+       $varname = 'plugoption['.$current['oid'].']['.$current['contextid'].']';\r
+       // retreive the optionmeta\r
+       $meta = NucleusPlugin::getOptionMeta($current['typeinfo']);\r
+\r
+       // only if it is not a hidden option write the controls to the page\r
+       if (@$meta['access'] != 'hidden') {\r
+               echo '<td>',htmlspecialchars($current['description']?$current['description']:$current['name']),'</td>';\r
+               echo '<td>';\r
+               switch($current['type']) {\r
+                       case 'yesno':\r
+                               ADMIN::input_yesno($varname, $current['value'], 0, 'yes', 'no');\r
+                               break;\r
+                       case 'password':\r
+                               echo '<input type="password" size="40" maxlength="128" name="',htmlspecialchars($varname),'" value="',htmlspecialchars($current['value']),'" />';\r
+                               break;\r
+                       case 'select':\r
+                               echo '<select name="'.htmlspecialchars($varname).'">';\r
+                               $aOptions = NucleusPlugin::getOptionSelectValues($current['typeinfo']);\r
+                               $aOptions = explode('|', $aOptions);\r
+                               for ($i=0; $i<(count($aOptions)-1); $i+=2) {\r
+                                       echo '<option value="'.htmlspecialchars($aOptions[$i+1]).'"';\r
+                                       if ($aOptions[$i+1] == $current['value'])\r
+                                               echo ' selected="selected"';\r
+                                       echo '>'.htmlspecialchars($aOptions[$i]).'</option>';\r
+                               }\r
+                               echo '</select>';\r
+                               break;\r
+                       case 'textarea':\r
+                               //$meta = NucleusPlugin::getOptionMeta($current['typeinfo']);\r
+                               echo '<textarea class="pluginoption" cols="30" rows="5" name="',htmlspecialchars($varname),'"';\r
+                               if (@$meta['access'] == 'readonly') {\r
+                                       echo ' readonly="readonly"';\r
+                               }\r
+                               echo '>',htmlspecialchars($current['value']),'</textarea>';\r
+                               break;\r
+                       case 'text':\r
+                       default:\r
+                               //$meta = NucleusPlugin::getOptionMeta($current['typeinfo']);\r
+\r
+                               echo '<input type="text" size="40" maxlength="128" name="',htmlspecialchars($varname),'" value="',htmlspecialchars($current['value']),'"';\r
+                               if (@$meta['datatype'] == 'numerical') {\r
+                                       echo ' onkeyup="checkNumeric(this)" onblur="checkNumeric(this)"';\r
+                               }\r
+                               if (@$meta['access'] == 'readonly') {\r
+                                       echo ' readonly="readonly"';\r
+                               }\r
+                               echo ' />';\r
+               }\r
+               echo @$current['extra'];\r
+               echo '</td>';\r
+       }\r
+}\r
+\r
+function listplug_table_itemlist($template, $type) {\r
+       $cssclass = null;\r
+\r
+       switch($type) {\r
+               case 'HEAD':\r
+                       echo "<th>"._LIST_ITEM_INFO."</th><th>"._LIST_ITEM_CONTENT."</th><th style=\"white-space:nowrap\" colspan='1'>"._LISTS_ACTIONS."</th>";\r
+                       break;\r
+               case 'BODY':\r
+                       $current = $template['current'];\r
+                       $current->itime = strtotime($current->itime);   // string -> unix timestamp\r
+\r
+                       if ($current->idraft == 1)\r
+                               $cssclass = "class='draft'";\r
+\r
+                       // (can't use offset time since offsets might vary between blogs)\r
+                       if ($current->itime > $template['now'])\r
+                               $cssclass = "class='future'";\r
+\r
+                       echo "<td $cssclass>",_LIST_ITEM_BLOG,' ', htmlspecialchars($current->bshortname);\r
+                       echo "    <br />",_LIST_ITEM_CAT,' ', htmlspecialchars($current->cname);\r
+                       echo "    <br />",_LIST_ITEM_AUTHOR, ' ', htmlspecialchars($current->mname);\r
+                       echo "    <br />",_LIST_ITEM_DATE," " . date("Y-m-d",$current->itime);\r
+                       echo "<br />",_LIST_ITEM_TIME," " . date("H:i",$current->itime);\r
+                       echo "</td>";\r
+                       echo "<td $cssclass>";\r
+\r
+                       $id = listplug_nextBatchId();\r
+\r
+                       echo '<input type="checkbox" id="batch',$id,'" name="batch[',$id,']" value="',$current->inumber,'" />';\r
+                       echo '<label for="batch',$id,'">';\r
+                       echo "<b>" . htmlspecialchars(strip_tags($current->ititle)) . "</b>";\r
+                       echo '</label>';\r
+                       echo "<br />";\r
+\r
+\r
+                       $current->ibody = strip_tags($current->ibody);\r
+                       $current->ibody = htmlspecialchars(shorten($current->ibody,300,'...'));\r
+\r
+                       $COMMENTS = new COMMENTS($current->inumber);\r
+                       echo "$current->ibody</td>";\r
+                       echo "<td  style=\"white-space:nowrap\" $cssclass>";\r
+                       echo    "<a href='index.php?action=itemedit&amp;itemid=$current->inumber'>"._LISTS_EDIT."</a>";\r
+                       // evaluate amount of comments for the item\r
+                       $camount = $COMMENTS->amountComments();\r
+                       if ($camount>0) {\r
+                               echo    "<br /><a href='index.php?action=itemcommentlist&amp;itemid=$current->inumber'>"._LISTS_COMMENTS;\r
+                               echo '(' . $COMMENTS->amountComments() . ')'."</a>";\r
+                       }\r
+                       else {\r
+                               echo "<br />"._TEMPLATE_CNONE;\r
+                       }\r
+                       echo    "<br /><a href='index.php?action=itemmove&amp;itemid=$current->inumber'>"._LISTS_MOVE."</a>";\r
+                       echo    "<br /><a href='index.php?action=itemdelete&amp;itemid=$current->inumber'>"._LISTS_DELETE."</a>";\r
+                       echo "</td>";\r
+                       break;\r
+       }\r
+}\r
+\r
+// for batch operations: generates the index numbers for checkboxes\r
+function listplug_nextBatchId() {\r
+       static $id = 0;\r
+       return $id++;\r
+}\r
+\r
+function listplug_table_commentlist($template, $type) {\r
+       switch($type) {\r
+               case 'HEAD':\r
+                       echo "<th>"._LISTS_INFO."</th><th>"._LIST_COMMENT."</th><th colspan='3'>"._LISTS_ACTIONS."</th>";\r
+                       break;\r
+               case 'BODY':\r
+                       $current = $template['current'];\r
+                       $current->ctime = strtotime($current->ctime);   // string -> unix timestamp\r
+\r
+                       echo '<td>';\r
+                       echo date("Y-m-d@H:i",$current->ctime);\r
+                       echo '<br />';\r
+                       if ($current->mname)\r
+                               echo htmlspecialchars($current->mname) ,' ', _LIST_COMMENTS_MEMBER;\r
+                       else\r
+                               echo htmlspecialchars($current->cuser);\r
+                       if ($current->cmail != '') {\r
+                                echo '<br />';\r
+                                echo htmlspecialchars($current->cmail);\r
+                        }\r
+                       if ($current->cemail != '') {\r
+                                echo '<br />';\r
+                                echo htmlspecialchars($current->cemail);\r
+                        }\r
+                       echo '</td>';\r
+\r
+                       $current->cbody = strip_tags($current->cbody);\r
+                       $current->cbody = htmlspecialchars(shorten($current->cbody, 300, '...'));\r
+\r
+                       echo '<td>';\r
+                       $id = listplug_nextBatchId();\r
+                       echo '<input type="checkbox" id="batch',$id,'" name="batch[',$id,']" value="',$current->cnumber,'" />';\r
+                       echo '<label for="batch',$id,'">';\r
+                       echo $current->cbody;\r
+                       echo '</label>';\r
+                       echo '</td>';\r
+\r
+                       echo "<td style=\"white-space:nowrap\"><a href='index.php?action=commentedit&amp;commentid=$current->cnumber'>"._LISTS_EDIT."</a></td>";\r
+                       echo "<td style=\"white-space:nowrap\"><a href='index.php?action=commentdelete&amp;commentid=$current->cnumber'>"._LISTS_DELETE."</a></td>";\r
+                       if ($template['canAddBan'])\r
+                               echo "<td style=\"white-space:nowrap\"><a href='index.php?action=banlistnewfromitem&amp;itemid=$current->citem&amp;ip=", htmlspecialchars($current->cip), "' title='", htmlspecialchars($current->chost), "'>"._LIST_COMMENT_BANIP."</a></td>";\r
+                       break;\r
+       }\r
+}\r
+\r
+\r
+function listplug_table_bloglist($template, $type) {\r
+       switch($type) {\r
+               case 'HEAD':\r
+                       echo "<th>" . _NAME . "</th><th colspan='7'>" ._LISTS_ACTIONS. "</th>";\r
+                       break;\r
+               case 'BODY':\r
+                       $current = $template['current'];\r
+\r
+                       echo "<td title='blogid:$current->bnumber shortname:$current->bshortname'><a href='$current->burl'><img src='images/globe.gif' width='13' height='13' alt='". _BLOGLIST_TT_VISIT."' /></a> " . htmlspecialchars($current->bname) . "</td>";\r
+                       echo "<td><a href='index.php?action=createitem&amp;blogid=$current->bnumber' title='" . _BLOGLIST_TT_ADD ."'>" . _BLOGLIST_ADD . "</a></td>";\r
+                       echo "<td><a href='index.php?action=itemlist&amp;blogid=$current->bnumber' title='". _BLOGLIST_TT_EDIT."'>". _BLOGLIST_EDIT."</a></td>";\r
+                       echo "<td><a href='index.php?action=blogcommentlist&amp;blogid=$current->bnumber' title='". _BLOGLIST_TT_COMMENTS."'>". _BLOGLIST_COMMENTS."</a></td>";\r
+                       echo "<td><a href='index.php?action=bookmarklet&amp;blogid=$current->bnumber' title='". _BLOGLIST_TT_BMLET."'>". _BLOGLIST_BMLET . "</a></td>";\r
+\r
+                       if ($current->tadmin == 1) {\r
+                               echo "<td><a href='index.php?action=blogsettings&amp;blogid=$current->bnumber' title='" . _BLOGLIST_TT_SETTINGS . "'>" ._BLOGLIST_SETTINGS. "</a></td>";\r
+                               echo "<td><a href='index.php?action=banlist&amp;blogid=$current->bnumber' title='" . _BLOGLIST_TT_BANS. "'>". _BLOGLIST_BANS."</a></td>";\r
+                       }\r
+\r
+                       if ($template['superadmin']) {\r
+                               echo "<td><a href='index.php?action=deleteblog&amp;blogid=$current->bnumber' title='". _BLOGLIST_TT_DELETE."'>" ._BLOGLIST_DELETE. "</a></td>";\r
+                       }\r
+\r
+\r
+\r
+                       break;\r
+       }\r
+}\r
+\r
+function listplug_table_shortblognames($template, $type) {\r
+       switch($type) {\r
+               case 'HEAD':\r
+                       echo "<th>" . _EBLOG_SHORTNAME . "</th><th>" . _EBLOG_NAME. "</th>";\r
+                       break;\r
+               case 'BODY':\r
+                       $current = $template['current'];\r
+\r
+                       echo '<td>' , htmlspecialchars($current->bshortname) , '</td>';\r
+                       echo '<td>' , htmlspecialchars($current->bname) , '</td>';\r
+\r
+                       break;\r
+       }\r
+}\r
+\r
+function listplug_table_shortnames($template, $type) {\r
+       switch($type) {\r
+               case 'HEAD':\r
+                       echo "<th>" . _NAME . "</th><th>" . _LISTS_DESC. "</th>";\r
+                       break;\r
+               case 'BODY':\r
+                       $current = $template['current'];\r
+\r
+                       echo '<td>' , htmlspecialchars($current->name) , '</td>';\r
+                       echo '<td>' , htmlspecialchars($current->description) , '</td>';\r
+\r
+                       break;\r
+       }\r
+}\r
+\r
+\r
+function listplug_table_categorylist($template, $type) {\r
+       switch($type) {\r
+               case 'HEAD':\r
+                       echo "<th>"._LISTS_NAME."</th><th>"._LISTS_DESC."</th><th colspan='2'>"._LISTS_ACTIONS."</th>";\r
+                       break;\r
+               case 'BODY':\r
+                       $current = $template['current'];\r
+\r
+                       echo '<td>';\r
+                       $id = listplug_nextBatchId();\r
+                       echo '<input type="checkbox" id="batch',$id,'" name="batch[',$id,']" value="',$current->catid,'" />';\r
+                       echo '<label for="batch',$id,'">';\r
+                       echo htmlspecialchars($current->cname);\r
+                       echo '</label>';\r
+                       echo '</td>';\r
+\r
+                       echo '<td>', htmlspecialchars($current->cdesc), '</td>';\r
+                       echo "<td><a href='index.php?action=categorydelete&amp;blogid=$current->cblog&amp;catid=$current->catid' tabindex='".$template['tabindex']."'>"._LISTS_DELETE."</a></td>";\r
+                       echo "<td><a href='index.php?action=categoryedit&amp;blogid=$current->cblog&amp;catid=$current->catid' tabindex='".$template['tabindex']."'>"._LISTS_EDIT."</a></td>";\r
+\r
+                       break;\r
+       }\r
+}\r
+\r
+\r
+function listplug_table_templatelist($template, $type) {\r
+       global $manager;\r
+       switch($type) {\r
+               case 'HEAD':\r
+                       echo "<th>"._LISTS_NAME."</th><th>"._LISTS_DESC."</th><th colspan='3'>"._LISTS_ACTIONS."</th>";\r
+                       break;\r
+               case 'BODY':\r
+                       $current = $template['current'];\r
+\r
+                       echo "<td>" , htmlspecialchars($current->tdname), "</td>";\r
+                       echo "<td>" , htmlspecialchars($current->tddesc), "</td>";\r
+                       echo "<td style=\"white-space:nowrap\"><a href='index.php?action=templateedit&amp;templateid=$current->tdnumber' tabindex='".$template['tabindex']."'>"._LISTS_EDIT."</a></td>";\r
+\r
+                       $url = $manager->addTicketToUrl('index.php?action=templateclone&templateid=' . intval($current->tdnumber));\r
+                       echo "<td style=\"white-space:nowrap\"><a href='",htmlspecialchars($url),"' tabindex='".$template['tabindex']."'>"._LISTS_CLONE."</a></td>";\r
+                       echo "<td style=\"white-space:nowrap\"><a href='index.php?action=templatedelete&amp;templateid=$current->tdnumber' tabindex='".$template['tabindex']."'>"._LISTS_DELETE."</a></td>";\r
+\r
+                       break;\r
+       }\r
+}\r
+\r
+function listplug_table_skinlist($template, $type) {\r
+       global $CONF, $DIR_SKINS, $manager;\r
+       switch($type) {\r
+               case 'HEAD':\r
+                       echo "<th>"._LISTS_NAME."</th><th>"._LISTS_DESC."</th><th colspan='3'>"._LISTS_ACTIONS."</th>";\r
+                       break;\r
+               case 'BODY':\r
+                       $current = $template['current'];\r
+\r
+                       echo '<td>';\r
+\r
+                       // use a special style for the default skin\r
+                       if ($current->sdnumber == $CONF['BaseSkin']) {\r
+                               echo '<strong>',htmlspecialchars($current->sdname),'</strong>';\r
+                       } else {\r
+                               echo htmlspecialchars($current->sdname);\r
+                       }\r
+\r
+                       echo '<br /><br />';\r
+                       echo _LISTS_TYPE ,': ' , htmlspecialchars($current->sdtype);\r
+                       echo '<br />', _LIST_SKINS_INCMODE , ' ' , (($current->sdincmode=='skindir') ?_PARSER_INCMODE_SKINDIR:_PARSER_INCMODE_NORMAL);\r
+                       if ($current->sdincpref) echo '<br />' , _LIST_SKINS_INCPREFIX , ' ', htmlspecialchars($current->sdincpref);\r
+\r
+                       // add preview image when present\r
+                       if ($current->sdincpref && @file_exists($DIR_SKINS . $current->sdincpref . 'preview.png'))\r
+                       {\r
+                               echo '<br /><br />';\r
+\r
+                               $hasEnlargement = @file_exists($DIR_SKINS . $current->sdincpref . 'preview-large.png');\r
+                               if ($hasEnlargement)\r
+                                       echo '<a href="',$CONF['SkinsURL'], htmlspecialchars($current->sdincpref),'preview-large.png" title="' . _LIST_SKIN_PREVIEW_VIEWLARGER . '">';\r
+\r
+                               $imgAlt = sprintf(_LIST_SKIN_PREVIEW, htmlspecialchars($current->sdname, ENT_QUOTES));\r
+                               echo '<img class="skinpreview" src="',$CONF['SkinsURL'], htmlspecialchars($current->sdincpref),'preview.png" width="100" height="75" alt="' . $imgAlt . '" />';\r
+\r
+                               if ($hasEnlargement)\r
+                                       echo '</a>';\r
+\r
+                               if (@file_exists($DIR_SKINS . $current->sdincpref . 'readme.html'))\r
+                               {\r
+                                       $url         = $CONF['SkinsURL'] . htmlspecialchars($current->sdincpref, ENT_QUOTES) . 'readme.html';\r
+                                       $readmeTitle = sprintf(_LIST_SKIN_README, htmlspecialchars($current->sdname, ENT_QUOTES));\r
+                                       echo '<br /><a href="' . $url . '" title="' . $readmeTitle . '">' . _LIST_SKIN_README_TXT . '</a>';\r
+                               }\r
+\r
+\r
+                       }\r
+\r
+                       echo "</td>";\r
+\r
+\r
+                       echo "<td>" , htmlspecialchars($current->sddesc);\r
+                               // show list of defined parts\r
+                               $r = sql_query('SELECT stype FROM '.sql_table('skin').' WHERE sdesc='.$current->sdnumber . ' ORDER BY stype');\r
+                               $types = array();\r
+                               while ($o = mysql_fetch_object($r))\r
+                                       array_push($types,$o->stype);\r
+                               if (sizeof($types) > 0) {\r
+                                       $friendlyNames = SKIN::getFriendlyNames();\r
+                                       for ($i=0;$i<sizeof($types);$i++) {\r
+                                               $type = $types[$i];\r
+                                               if (in_array($type, array('index', 'item', 'archivelist', 'archive', 'search', 'error', 'member', 'imagepopup'))) {\r
+                                                       $types[$i] = '<li>' . helpHtml('skinpart'.$type) . ' <a href="index.php?action=skinedittype&amp;skinid='.$current->sdnumber.'&amp;type='.$type.'" tabindex="'.$template['tabindex'].'">' . htmlspecialchars($friendlyNames[$type]) . "</a></li>";\r
+                                               } else {\r
+                                                       $types[$i] = '<li>' . helpHtml('skinpartspecial') . ' <a href="index.php?action=skinedittype&amp;skinid='.$current->sdnumber.'&amp;type='.$type.'" tabindex="'.$template['tabindex'].'">' . htmlspecialchars($friendlyNames[$type]) . "</a></li>";\r
+                                               }\r
+                                       }\r
+                                       echo '<br /><br />',_LIST_SKINS_DEFINED,' <ul>',implode($types,'') ,'</ul>';\r
+                               }\r
+                       echo "</td>";\r
+                       echo "<td style=\"white-space:nowrap\"><a href='index.php?action=skinedit&amp;skinid=$current->sdnumber' tabindex='".$template['tabindex']."'>"._LISTS_EDIT."</a></td>";\r
+\r
+                       $url = $manager->addTicketToUrl('index.php?action=skinclone&skinid=' . intval($current->sdnumber));\r
+                       echo "<td style=\"white-space:nowrap\"><a href='",htmlspecialchars($url),"' tabindex='".$template['tabindex']."'>"._LISTS_CLONE."</a></td>";\r
+                       echo "<td style=\"white-space:nowrap\"><a href='index.php?action=skindelete&amp;skinid=$current->sdnumber' tabindex='".$template['tabindex']."'>"._LISTS_DELETE."</a></td>";\r
+\r
+                       break;\r
+       }\r
+}\r
+\r
+function listplug_table_draftlist($template, $type) {\r
+       switch($type) {\r
+               case 'HEAD':\r
+                       echo "<th>"._LISTS_BLOG."</th><th>"._LISTS_TITLE."</th><th colspan='2'>"._LISTS_ACTIONS."</th>";\r
+                       break;\r
+               case 'BODY':\r
+                       $current = $template['current'];\r
+\r
+                       echo '<td>', htmlspecialchars($current->bshortname) , '</td>';\r
+                       echo '<td>', htmlspecialchars(strip_tags($current->ititle)) , '</td>';\r
+                       echo "<td><a href='index.php?action=itemedit&amp;itemid=$current->inumber'>"._LISTS_EDIT."</a></td>";\r
+                       echo "<td><a href='index.php?action=itemdelete&amp;itemid=$current->inumber'>"._LISTS_DELETE."</a></td>";\r
+\r
+                       break;\r
+       }\r
+}\r
+\r
+\r
+function listplug_table_actionlist($template, $type) {\r
+       switch($type) {\r
+               case 'HEAD':\r
+                       echo '<th>'._LISTS_TIME.'</th><th>'._LIST_ACTION_MSG.'</th>';\r
+                       break;\r
+               case 'BODY':\r
+                       $current = $template['current'];\r
+\r
+                       echo '<td>' , htmlspecialchars($current->timestamp), '</td>';\r
+                       echo '<td>' , htmlspecialchars($current->message), '</td>';\r
+\r
+                       break;\r
+       }\r
+}\r
+\r
+function listplug_table_banlist($template, $type) {\r
+       switch($type) {\r
+               case 'HEAD':\r
+                       echo '<th>'._LIST_BAN_IPRANGE.'</th><th>'. _LIST_BAN_REASON.'</th><th>'._LISTS_ACTIONS.'</th>';\r
+                       break;\r
+               case 'BODY':\r
+                       $current = $template['current'];\r
+\r
+                       echo '<td>' , htmlspecialchars($current->iprange) , '</td>';\r
+                       echo '<td>' , htmlspecialchars($current->reason) , '</td>';\r
+                       echo "<td><a href='index.php?action=banlistdelete&amp;blogid=", intval($current->blogid) , "&amp;iprange=" , htmlspecialchars($current->iprange) , "'>",_LISTS_DELETE,"</a></td>";\r
+                       break;\r
+       }\r
+}\r
+\r
 ?>
index 2e37bd0..938326f 100755 (executable)
@@ -1,7 +1,7 @@
 <?php
 /*
  * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/)
- * Copyright (C) 2002-2007 The Nucleus Group
+ * Copyright (C) 2002-2009 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
  *     exporting Nucleus skins: SKINIMPORT and SKINEXPORT
  *
  * @license http://nucleuscms.org/license.txt GNU General Public License
- * @copyright Copyright (C) 2002-2007 The Nucleus Group
- * @version $Id: skinie.php,v 1.10 2008-02-08 09:31:22 kimitake Exp $
+ * @copyright Copyright (C) 2002-2009 The Nucleus Group
+ * @version $Id$
  * @version $NucleusJP: skinie.php,v 1.9.2.1 2007/09/05 07:46:30 kimitake Exp $
  */
 
-class SKINIMPORT {
-
-       // hardcoded value (see constructor). When 1, interesting info about the
-       // parsing process is sent to the output
-       var $debug;
-
-       // parser/file pointer
-       var $parser;
-       var $fp;
-
-       // which data has been read?
-       var $metaDataRead;
-       var $allRead;
-
-       // extracted data
-       var $skins;
-       var $templates;
-       var $info;
-
-       // to maintain track of where we are inside the XML file
-       var $inXml;
-       var $inData;
-       var $inMeta;
-       var $inSkin;
-       var $inTemplate;
-       var $currentName;
-       var $currentPartName;
-       var $cdata;
-
-
-
-       /**
-        * constructor initializes data structures
-        */
-       function SKINIMPORT() {
-               // disable magic_quotes_runtime if it's turned on
-               set_magic_quotes_runtime(0);
-
-               // debugging mode?
-               $this->debug = 0;
-
-               $this->reset();
-
-       }
-
-       function reset() {
-               if ($this->parser)
-                       xml_parser_free($this->parser);
-
-               // XML file pointer
-               $this->fp = 0;
-
-               // which data has been read?
-               $this->metaDataRead = 0;
-               $this->allRead = 0;
-
-               // to maintain track of where we are inside the XML file
-               $this->inXml = 0;
-               $this->inData = 0;
-               $this->inMeta = 0;
-               $this->inSkin = 0;
-               $this->inTemplate = 0;
-               $this->currentName = '';
-               $this->currentPartName = '';
-
-               // character data pile
-               $this->cdata = '';
-
-               // list of skinnames and templatenames (will be array of array)
-               $this->skins = array();
-               $this->templates = array();
-
-               // extra info included in the XML files (e.g. installation notes)
-               $this->info = '';
-
-               // init XML parser
-               $this->parser = xml_parser_create();
-               xml_set_object($this->parser, $this);
-               xml_set_element_handler($this->parser, 'startElement', 'endElement');
-               xml_set_character_data_handler($this->parser, 'characterData');
-               xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0);
-
-       }
-
-       /**
-        * Reads an XML file into memory
-        *
-        * @param $filename
-        *              Which file to read
-        * @param $metaOnly
-        *              Set to 1 when only the metadata needs to be read (optional, default 0)
-        */
-       function readFile($filename, $metaOnly = 0) {
-               // open file
-               $this->fp = @fopen($filename, 'r');
-               if (!$this->fp) return 'Failed to open file/URL';
-
-               // here we go!
-               $this->inXml = 1;
-
-               $tempbuffer = null;
-
-               while (!feof($this->fp)) {
-                       $tempbuffer .= fread($this->fp, 4096);
-               }
-               fclose($this->fp);
-
-/*
-       [2004-08-04] dekarma - Took this out since it messes up good XML if it has skins/templates
-                                                  with CDATA sections. need to investigate consequences.
-                                                  see bug [ 999914 ] Import fails (multiple skins in XML/one of them with CDATA)
-
-               // backwards compatibility with the non-wellformed skinbackup.xml files
-               // generated by v2/v3 (when CDATA sections were present in skins)
-               // split up those CDATA sections into multiple ones
-               $tempbuffer = preg_replace_callback(
-                       "/(<!\[CDATA\[[^]]*?<!\[CDATA\[[^]]*)((?:\]\].*?<!\[CDATA.*?)*)(\]\])(.*\]\])/ms",
-                       create_function(
-                               '$matches',
-                               'return $matches[1] . preg_replace("/(\]\])(.*?<!\[CDATA)/ms","]]]]><![CDATA[$2",$matches[2])."]]]]><![CDATA[".$matches[4];'
-                       ),
-                       $tempbuffer
-               );
-*/
-               $temp = tmpfile();
-               fwrite($temp, $tempbuffer);
-               rewind($temp);
-
-               while ( ($buffer = fread($temp, 4096) ) && (!$metaOnly || ($metaOnly && !$this->metaDataRead))) {
-                       $err = xml_parse( $this->parser, $buffer, feof($temp) );
-                       if (!$err && $this->debug)
-                               echo 'ERROR: ', xml_error_string(xml_get_error_code($this->parser)), '<br />';
-               }
-
-               // all done
-               $this->inXml = 0;
-               fclose($temp);
-       }
-
-       /**
-        * Returns the list of skin names
-        */
-       function getSkinNames() {
-               return array_keys($this->skins);
-       }
-
-       /**
-        * Returns the list of template names
-        */
-       function getTemplateNames() {
-               return array_keys($this->templates);
-       }
-
-       /**
-        * Returns the extra information included in the XML file
-        */
-       function getInfo() {
-               return $this->info;
-       }
-
-       /**
-        * Writes the skins and templates to the database
-        *
-        * @param $allowOverwrite
-        *              set to 1 when allowed to overwrite existing skins with the same name
-        *              (default = 0)
-        */
-       function writeToDatabase($allowOverwrite = 0) {
-               $existingSkins = $this->checkSkinNameClashes();
-               $existingTemplates = $this->checkTemplateNameClashes();
-
-               // if not allowed to overwrite, check if any nameclashes exists
-               if (!$allowOverwrite) {
-                       if ((sizeof($existingSkins) > 0) || (sizeof($existingTemplates) > 0))
-                               return 'Name clashes detected, re-run with allowOverwrite = 1 to force overwrite';
-               }
-
-               foreach ($this->skins as $skinName => $data) {
-                       // 1. if exists: delete all part data, update desc data
-                       //    if not exists: create desc
-                       if (in_array($skinName, $existingSkins)) {
-                               $skinObj = SKIN::createFromName($skinName);
-
-                               // delete all parts of the skin
-                               $skinObj->deleteAllParts();
-
-                               // update general info
-                               $skinObj->updateGeneralInfo($skinName, $data['description'], $data['type'], $data['includeMode'], $data['includePrefix']);
-                       } else {
-                               $skinid = SKIN::createNew($skinName, $data['description'], $data['type'], $data['includeMode'], $data['includePrefix']);
-                               $skinObj = new SKIN($skinid);
-                       }
-
-                       // 2. add parts
-                       foreach ($data['parts'] as $partName => $partContent) {
-                               $skinObj->update($partName, $partContent);
-                       }
-               }
-
-               foreach ($this->templates as $templateName => $data) {
-                       // 1. if exists: delete all part data, update desc data
-                       //    if not exists: create desc
-                       if (in_array($templateName, $existingTemplates)) {
-                               $templateObj = TEMPLATE::createFromName($templateName);
-
-                               // delete all parts of the template
-                               $templateObj->deleteAllParts();
-
-                               // update general info
-                               $templateObj->updateGeneralInfo($templateName, $data['description']);
-                       } else {
-                               $templateid = TEMPLATE::createNew($templateName, $data['description']);
-                               $templateObj = new TEMPLATE($templateid);
-                       }
-
-                       // 2. add parts
-                       foreach ($data['parts'] as $partName => $partContent) {
-                               $templateObj->update($partName, $partContent);
-                       }
-               }
-
-
-       }
-
-       /**
-         * returns an array of all the skin nameclashes (empty array when no name clashes)
-         */
-       function checkSkinNameClashes() {
-               $clashes = array();
-
-               foreach ($this->skins as $skinName => $data) {
-                       if (SKIN::exists($skinName))
-                               array_push($clashes, $skinName);
-               }
-
-               return $clashes;
-       }
-
-       /**
-         * returns an array of all the template nameclashes
-         * (empty array when no name clashes)
-         */
-       function checkTemplateNameClashes() {
-               $clashes = array();
-
-               foreach ($this->templates as $templateName => $data) {
-                       if (TEMPLATE::exists($templateName))
-                               array_push($clashes, $templateName);
-               }
-
-               return $clashes;
-       }
-
-       /**
-        * Called by XML parser for each new start element encountered
-        */
-       function startElement($parser, $name, $attrs) {
-               foreach($attrs as $key=>$value) $attrs[$key]=htmlspecialchars($value,ENT_QUOTES);
-
-               if ($this->debug) echo 'START: ', htmlspecialchars($name), '<br />';
-
-               switch ($name) {
-                       case 'nucleusskin':
-                               $this->inData = 1;
-                               break;
-                       case 'meta':
-                               $this->inMeta = 1;
-                               break;
-                       case 'info':
-                               // no action needed
-                               break;
-                       case 'skin':
-                               if (!$this->inMeta) {
-                                       $this->inSkin = 1;
-                                       $this->currentName = $attrs['name'];
-                                       $this->skins[$this->currentName]['type'] = $attrs['type'];
-                                       $this->skins[$this->currentName]['includeMode'] = $attrs['includeMode'];
-                                       $this->skins[$this->currentName]['includePrefix'] = $attrs['includePrefix'];
-                                       $this->skins[$this->currentName]['parts'] = array();
-                               } else {
-                                       $this->skins[$attrs['name']] = array();
-                                       $this->skins[$attrs['name']]['parts'] = array();
-                               }
-                               break;
-                       case 'template':
-                               if (!$this->inMeta) {
-                                       $this->inTemplate = 1;
-                                       $this->currentName = $attrs['name'];
-                                       $this->templates[$this->currentName]['parts'] = array();
-                               } else {
-                                       $this->templates[$attrs['name']] = array();
-                                       $this->templates[$attrs['name']]['parts'] = array();
-                               }
-                               break;
-                       case 'description':
-                               // no action needed
-                               break;
-                       case 'part':
-                               $this->currentPartName = $attrs['name'];
-                               break;
-                       default:
-                               echo 'UNEXPECTED TAG: ' , htmlspecialchars($name) , '<br />';
-                               break;
-               }
-
-               // character data never contains other tags
-               $this->clearCharacterData();
-
-       }
-
-       /**
-         * Called by the XML parser for each closing tag encountered
-         */
-       function endElement($parser, $name) {
-               if ($this->debug) echo 'END: ', htmlspecialchars($name), '<br />';
-
-               switch ($name) {
-                       case 'nucleusskin':
-                               $this->inData = 0;
-                               $this->allRead = 1;
-                               break;
-                       case 'meta':
-                               $this->inMeta = 0;
-                               $this->metaDataRead = 1;
-                               break;
-                       case 'info':
-                               $this->info = $this->getCharacterData();
-                       case 'skin':
-                               if (!$this->inMeta) $this->inSkin = 0;
-                               break;
-                       case 'template':
-                               if (!$this->inMeta) $this->inTemplate = 0;
-                               break;
-                       case 'description':
-                               if ($this->inSkin) {
-                                       $this->skins[$this->currentName]['description'] = $this->getCharacterData();
-                               } else {
-                                       $this->templates[$this->currentName]['description'] = $this->getCharacterData();
-                               }
-                               break;
-                       case 'part':
-                               if ($this->inSkin) {
-                                       $this->skins[$this->currentName]['parts'][$this->currentPartName] = $this->getCharacterData();
-                               } else {
-                                       $this->templates[$this->currentName]['parts'][$this->currentPartName] = $this->getCharacterData();
-                               }
-                               break;
-                       default:
-                               echo 'UNEXPECTED TAG: ' , htmlspecialchars($name), '<br />';
-                               break;
-               }
-               $this->clearCharacterData();
-
-       }
-
-       /**
-        * Called by XML parser for data inside elements
-        */
-       function characterData ($parser, $data) {
-               if ($this->debug) echo 'NEW DATA: ', htmlspecialchars($data), '<br />';
-               $this->cdata .= $data;
-       }
-
-       /**
-        * Returns the data collected so far
-        */
-       function getCharacterData() {
-               return $this->cdata;
-       }
-
-       /**
-        * Clears the data buffer
-        */
-       function clearCharacterData() {
-               $this->cdata = '';
-       }
-
-       /**
-        * Static method that looks for importable XML files in subdirs of the given dir
-        */
-       function searchForCandidates($dir) {
-               $candidates = array();
-
-               $dirhandle = opendir($dir);
-               while ($filename = readdir($dirhandle)) {
-                       if (@is_dir($dir . $filename) && ($filename != '.') && ($filename != '..')) {
-                               $xml_file = $dir . $filename . '/skinbackup.xml';
-                               if (file_exists($xml_file) && is_readable($xml_file)) {
-                                       $candidates[$filename] = $filename; //$xml_file;
-                               }
-
-                               // backwards compatibility
-                               $xml_file = $dir . $filename . '/skindata.xml';
-                               if (file_exists($xml_file) && is_readable($xml_file)) {
-                                       $candidates[$filename] = $filename; //$xml_file;
-                               }
-                       }
-               }
-               closedir($dirhandle);
-
-               return $candidates;
-
-       }
-
-
-}
-
-
-class SKINEXPORT {
-
-       var $templates;
-       var $skins;
-       var $info;
-
-       /**
-        * Constructor initializes data structures
-        */
-       function SKINEXPORT() {
-               // list of templateIDs to export
-               $this->templates = array();
-
-               // list of skinIDs to export
-               $this->skins = array();
-
-               // extra info to be in XML file
-               $this->info = '';
-       }
-
-       /**
-        * Adds a template to be exported
-        *
-        * @param id
-        *              template ID
-        * @result false when no such ID exists
-        */
-       function addTemplate($id) {
-               if (!TEMPLATE::existsID($id)) return 0;
-
-               $this->templates[$id] = TEMPLATE::getNameFromId($id);
-
-               return 1;
-       }
-
-       /**
-        * Adds a skin to be exported
-        *
-        * @param id
-        *              skin ID
-        * @result false when no such ID exists
-        */
-       function addSkin($id) {
-               if (!SKIN::existsID($id)) return 0;
-
-               $this->skins[$id] = SKIN::getNameFromId($id);
-
-               return 1;
-       }
-
-       /**
-        * Sets the extra info to be included in the exported file
-        */
-       function setInfo($info) {
-               $this->info = $info;
-       }
-
-
-       /**
-        * Outputs the XML contents of the export file
-        *
-        * @param $setHeaders
-        *              set to 0 if you don't want to send out headers
-        *              (optional, default 1)
-        */
-       function export($setHeaders = 1) {
-               if ($setHeaders) {
-                       // make sure the mimetype is correct, and that the data does not show up
-                       // in the browser, but gets saved into and XML file (popup download window)
-                       header('Content-Type: text/xml');
-                       header('Content-Disposition: attachment; filename="skinbackup.xml"');
-                       header('Expires: 0');
-                       header('Pragma: no-cache');
-               }
-
-               echo "<nucleusskin>\n";
-
-               // meta
-               echo "\t<meta>\n";
-                       // skins
-                       foreach ($this->skins as $skinId => $skinName) {
-                               echo "\t\t", '<skin name="',htmlspecialchars($skinName),'" />',"\n";
-                       }
-                       // templates
-                       foreach ($this->templates as $templateId => $templateName) {
-                               echo "\t\t", '<template name="',htmlspecialchars($templateName),'" />',"\n";
-                       }
-                       // extra info
-                       if ($this->info)
-                               echo "\t\t<info><![CDATA[",$this->info,"]]></info>\n";
-               echo "\t</meta>\n\n\n";
-
-               // contents skins
-               foreach ($this->skins as $skinId => $skinName) {
-                       $skinId = intval($skinId);
-                       $skinObj = new SKIN($skinId);
-
-                       echo "\t", '<skin name="',htmlspecialchars($skinName),'" type="',htmlspecialchars($skinObj->getContentType()),'" includeMode="',htmlspecialchars($skinObj->getIncludeMode()),'" includePrefix="',htmlspecialchars($skinObj->getIncludePrefix()),'">',"\n";
-
-                       echo "\t\t", '<description>',htmlspecialchars($skinObj->getDescription()),'</description>',"\n";
-
-                       $res = sql_query('SELECT stype, scontent FROM '.sql_table('skin').' WHERE sdesc='.$skinId);
-                       while ($partObj = mysql_fetch_object($res)) {
-                               echo "\t\t",'<part name="',htmlspecialchars($partObj->stype),'">';
-                               echo '<![CDATA[', $this->escapeCDATA($partObj->scontent),']]>';
-                               echo "</part>\n\n";
-                       }
-
-                       echo "\t</skin>\n\n\n";
-               }
-
-               // contents templates
-               foreach ($this->templates as $templateId => $templateName) {
-                       $templateId = intval($templateId);
-
-                       echo "\t",'<template name="',htmlspecialchars($templateName),'">',"\n";
-
-                       echo "\t\t",'<description>',htmlspecialchars(TEMPLATE::getDesc($templateId)),'</description>',"\n";
-
-                       $res = sql_query('SELECT tpartname, tcontent FROM '.sql_table('template').' WHERE tdesc='.$templateId);
-                       while ($partObj = mysql_fetch_object($res)) {
-                               echo "\t\t",'<part name="',htmlspecialchars($partObj->tpartname),'">';
-                               echo '<![CDATA[', $this->escapeCDATA($partObj->tcontent) ,']]>';
-                               echo '</part>',"\n\n";
-                       }
-
-                       echo "\t</template>\n\n\n";
-               }
-
-               echo '</nucleusskin>';
-       }
-
-       /**
-        * Escapes CDATA content so it can be included in another CDATA section
-        */
-       function escapeCDATA($cdata)
-       {
-               return preg_replace('/]]>/', ']]]]><![CDATA[>', $cdata);
-
-       }
-}
-
+class SKINIMPORT {\r
+\r
+       // hardcoded value (see constructor). When 1, interesting info about the\r
+       // parsing process is sent to the output\r
+       var $debug;\r
+\r
+       // parser/file pointer\r
+       var $parser;\r
+       var $fp;\r
+\r
+       // which data has been read?\r
+       var $metaDataRead;\r
+       var $allRead;\r
+\r
+       // extracted data\r
+       var $skins;\r
+       var $templates;\r
+       var $info;\r
+\r
+       // to maintain track of where we are inside the XML file\r
+       var $inXml;\r
+       var $inData;\r
+       var $inMeta;\r
+       var $inSkin;\r
+       var $inTemplate;\r
+       var $currentName;\r
+       var $currentPartName;\r
+       var $cdata;\r
+\r
+\r
+\r
+       /**\r
+        * constructor initializes data structures\r
+        */\r
+       function SKINIMPORT() {\r
+               // disable magic_quotes_runtime if it's turned on\r
+               set_magic_quotes_runtime(0);\r
+\r
+               // debugging mode?\r
+               $this->debug = 0;\r
+\r
+               $this->reset();\r
+\r
+       }\r
+\r
+       function reset() {\r
+               if ($this->parser)\r
+                       xml_parser_free($this->parser);\r
+\r
+               // XML file pointer\r
+               $this->fp = 0;\r
+\r
+               // which data has been read?\r
+               $this->metaDataRead = 0;\r
+               $this->allRead = 0;\r
+\r
+               // to maintain track of where we are inside the XML file\r
+               $this->inXml = 0;\r
+               $this->inData = 0;\r
+               $this->inMeta = 0;\r
+               $this->inSkin = 0;\r
+               $this->inTemplate = 0;\r
+               $this->currentName = '';\r
+               $this->currentPartName = '';\r
+\r
+               // character data pile\r
+               $this->cdata = '';\r
+\r
+               // list of skinnames and templatenames (will be array of array)\r
+               $this->skins = array();\r
+               $this->templates = array();\r
+\r
+               // extra info included in the XML files (e.g. installation notes)\r
+               $this->info = '';\r
+\r
+               // init XML parser\r
+               $this->parser = xml_parser_create();\r
+               xml_set_object($this->parser, $this);\r
+               xml_set_element_handler($this->parser, 'startElement', 'endElement');\r
+               xml_set_character_data_handler($this->parser, 'characterData');\r
+               xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0);\r
+\r
+       }\r
+\r
+       /**\r
+        * Reads an XML file into memory\r
+        *\r
+        * @param $filename\r
+        *              Which file to read\r
+        * @param $metaOnly\r
+        *              Set to 1 when only the metadata needs to be read (optional, default 0)\r
+        */\r
+       function readFile($filename, $metaOnly = 0) {\r
+               // open file\r
+               $this->fp = @fopen($filename, 'r');\r
+               if (!$this->fp) {\r
+                       return _SKINIE_ERROR_FAILEDOPEN_FILEURL;\r
+               }\r
+\r
+               // here we go!\r
+               $this->inXml = 1;\r
+\r
+               $tempbuffer = null;\r
+\r
+               while (!feof($this->fp)) {\r
+                       $tempbuffer .= fread($this->fp, 4096);\r
+               }\r
+               fclose($this->fp);\r
+               $tempcharset = mb_detect_encoding($tempbuffer);\r
+               if ($tempcharset != 'UTF-8') {\r
+                       $tempbuffer = mb_convert_encoding($tempbuffer, 'UTF-8', $tempcharset);\r
+               }\r
+\r
+/*\r
+       [2004-08-04] dekarma - Took this out since it messes up good XML if it has skins/templates\r
+                                                  with CDATA sections. need to investigate consequences.\r
+                                                  see bug [ 999914 ] Import fails (multiple skins in XML/one of them with CDATA)\r
+\r
+               // backwards compatibility with the non-wellformed skinbackup.xml files\r
+               // generated by v2/v3 (when CDATA sections were present in skins)\r
+               // split up those CDATA sections into multiple ones\r
+               $tempbuffer = preg_replace_callback(\r
+                       "/(<!\[CDATA\[[^]]*?<!\[CDATA\[[^]]*)((?:\]\].*?<!\[CDATA.*?)*)(\]\])(.*\]\])/ms",\r
+                       create_function(\r
+                               '$matches',\r
+                               'return $matches[1] . preg_replace("/(\]\])(.*?<!\[CDATA)/ms","]]]]><![CDATA[$2",$matches[2])."]]]]><![CDATA[".$matches[4];'\r
+                       ),\r
+                       $tempbuffer\r
+               );\r
+*/\r
+               $temp = tmpfile();\r
+               fwrite($temp, $tempbuffer);\r
+               rewind($temp);\r
+\r
+               while ( ($buffer = fread($temp, 4096) ) && (!$metaOnly || ($metaOnly && !$this->metaDataRead))) {\r
+                       $err = xml_parse( $this->parser, $buffer, feof($temp) );\r
+                       if (!$err && $this->debug) {\r
+                               echo _ERROR . ': ' . xml_error_string(xml_get_error_code($this->parser)) . '<br />';\r
+                       }\r
+               }\r
+\r
+               // all done\r
+               $this->inXml = 0;\r
+               fclose($temp);\r
+       }\r
+\r
+       /**\r
+        * Returns the list of skin names\r
+        */\r
+       function getSkinNames() {\r
+               return array_keys($this->skins);\r
+       }\r
+\r
+       /**\r
+        * Returns the list of template names\r
+        */\r
+       function getTemplateNames() {\r
+               return array_keys($this->templates);\r
+       }\r
+\r
+       /**\r
+        * Returns the extra information included in the XML file\r
+        */\r
+       function getInfo() {\r
+               return $this->info;\r
+       }\r
+\r
+       /**\r
+        * Writes the skins and templates to the database\r
+        *\r
+        * @param $allowOverwrite\r
+        *              set to 1 when allowed to overwrite existing skins with the same name\r
+        *              (default = 0)\r
+        */\r
+       function writeToDatabase($allowOverwrite = 0) {\r
+               $existingSkins = $this->checkSkinNameClashes();\r
+               $existingTemplates = $this->checkTemplateNameClashes();\r
+\r
+               // if not allowed to overwrite, check if any nameclashes exists\r
+               if (!$allowOverwrite) {\r
+                       if ((sizeof($existingSkins) > 0) || (sizeof($existingTemplates) > 0)) {\r
+                               return _SKINIE_NAME_CLASHES_DETECTED;\r
+                       }\r
+               }\r
+\r
+               foreach ($this->skins as $skinName => $data) {\r
+                       // 1. if exists: delete all part data, update desc data\r
+                       //    if not exists: create desc\r
+                       if (in_array($skinName, $existingSkins)) {\r
+                               $skinObj = SKIN::createFromName($skinName);\r
+\r
+                               // delete all parts of the skin\r
+                               $skinObj->deleteAllParts();\r
+\r
+                               // update general info\r
+                               $skinObj->updateGeneralInfo(\r
+                                       $skinName,\r
+                                       $data['description'],\r
+                                       $data['type'],\r
+                                       $data['includeMode'],\r
+                                       $data['includePrefix']\r
+                               );\r
+                       } else {\r
+                               $skinid = SKIN::createNew(\r
+                                       $skinName,\r
+                                       $data['description'],\r
+                                       $data['type'],\r
+                                       $data['includeMode'],\r
+                                       $data['includePrefix']\r
+                               );\r
+                               $skinObj = new SKIN($skinid);\r
+                       }\r
+\r
+                       // 2. add parts\r
+                       foreach ($data['parts'] as $partName => $partContent) {\r
+                               $skinObj->update($partName, $partContent);\r
+                       }\r
+               }\r
+\r
+               foreach ($this->templates as $templateName => $data) {\r
+                       // 1. if exists: delete all part data, update desc data\r
+                       //    if not exists: create desc\r
+                       if (in_array($templateName, $existingTemplates)) {\r
+                               $templateObj = TEMPLATE::createFromName($templateName);\r
+\r
+                               // delete all parts of the template\r
+                               $templateObj->deleteAllParts();\r
+\r
+                               // update general info\r
+                               $templateObj->updateGeneralInfo($templateName, $data['description']);\r
+                       } else {\r
+                               $templateid = TEMPLATE::createNew($templateName, $data['description']);\r
+                               $templateObj = new TEMPLATE($templateid);\r
+                       }\r
+\r
+                       // 2. add parts\r
+                       foreach ($data['parts'] as $partName => $partContent) {\r
+                               $templateObj->update($partName, $partContent);\r
+                       }\r
+               }\r
+\r
+\r
+       }\r
+\r
+       /**\r
+         * returns an array of all the skin nameclashes (empty array when no name clashes)\r
+         */\r
+       function checkSkinNameClashes() {\r
+               $clashes = array();\r
+\r
+               foreach ($this->skins as $skinName => $data) {\r
+                       if (SKIN::exists($skinName)) {\r
+                               array_push($clashes, $skinName);\r
+                       }\r
+               }\r
+\r
+               return $clashes;\r
+       }\r
+\r
+       /**\r
+         * returns an array of all the template nameclashes\r
+         * (empty array when no name clashes)\r
+         */\r
+       function checkTemplateNameClashes() {\r
+               $clashes = array();\r
+\r
+               foreach ($this->templates as $templateName => $data) {\r
+                       if (TEMPLATE::exists($templateName)) {\r
+                               array_push($clashes, $templateName);\r
+                       }\r
+               }\r
+\r
+               return $clashes;\r
+       }\r
+\r
+       /**\r
+        * Called by XML parser for each new start element encountered\r
+        */\r
+       function startElement($parser, $name, $attrs) {\r
+               foreach($attrs as $key=>$value) [\r
+                       $attrs[$key] = htmlspecialchars($value, ENT_QUOTES);\r
+               }\r
+\r
+               if ($this->debug) {\r
+                       echo 'START: ' . htmlspecialchars($name, ENT_QUOTES) . '<br />';\r
+               }\r
+\r
+               switch ($name) {\r
+                       case 'nucleusskin':\r
+                               $this->inData = 1;\r
+                               break;\r
+                       case 'meta':\r
+                               $this->inMeta = 1;\r
+                               break;\r
+                       case 'info':\r
+                               // no action needed\r
+                               break;\r
+                       case 'skin':\r
+                               if (!$this->inMeta) {\r
+                                       $this->inSkin = 1;\r
+                                       $this->currentName = $attrs['name'];\r
+                                       $this->skins[$this->currentName]['type'] = $attrs['type'];\r
+                                       $this->skins[$this->currentName]['includeMode'] = $attrs['includeMode'];\r
+                                       $this->skins[$this->currentName]['includePrefix'] = $attrs['includePrefix'];\r
+                                       $this->skins[$this->currentName]['parts'] = array();\r
+                               } else {\r
+                                       $this->skins[$attrs['name']] = array();\r
+                                       $this->skins[$attrs['name']]['parts'] = array();\r
+                               }\r
+                               break;\r
+                       case 'template':\r
+                               if (!$this->inMeta) {\r
+                                       $this->inTemplate = 1;\r
+                                       $this->currentName = $attrs['name'];\r
+                                       $this->templates[$this->currentName]['parts'] = array();\r
+                               } else {\r
+                                       $this->templates[$attrs['name']] = array();\r
+                                       $this->templates[$attrs['name']]['parts'] = array();\r
+                               }\r
+                               break;\r
+                       case 'description':\r
+                               // no action needed\r
+                               break;\r
+                       case 'part':\r
+                               $this->currentPartName = $attrs['name'];\r
+                               break;\r
+                       default:\r
+                               echo _SKINIE_SEELEMENT_UNEXPECTEDTAG . htmlspecialchars($name, ENT_QUOTES) . '<br />';\r
+                               break;\r
+               }\r
+\r
+               // character data never contains other tags\r
+               $this->clearCharacterData();\r
+\r
+       }\r
+\r
+       /**\r
+         * Called by the XML parser for each closing tag encountered\r
+         */\r
+       function endElement($parser, $name) {\r
+               if ($this->debug) {\r
+                       echo 'END: ' . htmlspecialchars($name, ENT_QUOTES) . '<br />';\r
+               }\r
+\r
+               switch ($name) {\r
+                       case 'nucleusskin':\r
+                               $this->inData = 0;\r
+                               $this->allRead = 1;\r
+                               break;\r
+                       case 'meta':\r
+                               $this->inMeta = 0;\r
+                               $this->metaDataRead = 1;\r
+                               break;\r
+                       case 'info':\r
+                               $this->info = $this->getCharacterData();\r
+                       case 'skin':\r
+                               if (!$this->inMeta) {\r
+                                       $this->inSkin = 0;\r
+                               }\r
+                               break;\r
+                       case 'template':\r
+                               if (!$this->inMeta) {\r
+                                       $this->inTemplate = 0;\r
+                               }\r
+                               break;\r
+                       case 'description':\r
+                               if ($this->inSkin) {\r
+                                       $this->skins[$this->currentName]['description'] = $this->getCharacterData();\r
+                               } else {\r
+                                       $this->templates[$this->currentName]['description'] = $this->getCharacterData();\r
+                               }\r
+                               break;\r
+                       case 'part':\r
+                               if ($this->inSkin) {\r
+                                       $this->skins[$this->currentName]['parts'][$this->currentPartName] = $this->getCharacterData();\r
+                               } else {\r
+                                       $this->templates[$this->currentName]['parts'][$this->currentPartName] = $this->getCharacterData();\r
+                               }\r
+                               break;\r
+                       default:\r
+                               echo _SKINIE_SEELEMENT_UNEXPECTEDTAG . htmlspecialchars($name, ENT_QUOTES) . '<br />';\r
+                               break;\r
+               }\r
+               $this->clearCharacterData();\r
+\r
+       }\r
+\r
+       /**\r
+        * Called by XML parser for data inside elements\r
+        */\r
+       function characterData ($parser, $data) {\r
+               if ($this->debug) {\r
+                       echo 'NEW DATA: ' . htmlspecialchars($data, ENT_QUOTES) . '<br />';\r
+               }\r
+               $this->cdata .= $data;\r
+       }\r
+\r
+       /**\r
+        * Returns the data collected so far\r
+        */\r
+       function getCharacterData() {\r
+               if (_CHARSET != 'UTF-8') {\r
+                       return mb_convert_encoding($this->cdata, _CHARSET, 'UTF-8');\r
+               } else {\r
+                       return $this->cdata;\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Clears the data buffer\r
+        */\r
+       function clearCharacterData() {\r
+               $this->cdata = '';\r
+       }\r
+\r
+       /**\r
+        * Static method that looks for importable XML files in subdirs of the given dir\r
+        */\r
+       function searchForCandidates($dir) {\r
+               $candidates = array();\r
+\r
+               $dirhandle = opendir($dir);\r
+               while ($filename = readdir($dirhandle)) {\r
+                       if (@is_dir($dir . $filename) && ($filename != '.') && ($filename != '..')) {\r
+                               $xml_file = $dir . $filename . '/skinbackup.xml';\r
+                               if (file_exists($xml_file) && is_readable($xml_file)) {\r
+                                       $candidates[$filename] = $filename; //$xml_file;\r
+                               }\r
+\r
+                               // backwards compatibility\r
+                               $xml_file = $dir . $filename . '/skindata.xml';\r
+                               if (file_exists($xml_file) && is_readable($xml_file)) {\r
+                                       $candidates[$filename] = $filename; //$xml_file;\r
+                               }\r
+                       }\r
+               }\r
+               closedir($dirhandle);\r
+\r
+               return $candidates;\r
+\r
+       }\r
+\r
+\r
+}\r
+\r
+\r
+class SKINEXPORT {\r
+\r
+       var $templates;\r
+       var $skins;\r
+       var $info;\r
+\r
+       /**\r
+        * Constructor initializes data structures\r
+        */\r
+       function SKINEXPORT() {\r
+               // list of templateIDs to export\r
+               $this->templates = array();\r
+\r
+               // list of skinIDs to export\r
+               $this->skins = array();\r
+\r
+               // extra info to be in XML file\r
+               $this->info = '';\r
+       }\r
+\r
+       /**\r
+        * Adds a template to be exported\r
+        *\r
+        * @param id\r
+        *              template ID\r
+        * @result false when no such ID exists\r
+        */\r
+       function addTemplate($id) {\r
+               if (!TEMPLATE::existsID($id)) {\r
+                       return 0;\r
+               }\r
+\r
+\r
+               $this->templates[$id] = TEMPLATE::getNameFromId($id);\r
+\r
+               return 1;\r
+       }\r
+\r
+       /**\r
+        * Adds a skin to be exported\r
+        *\r
+        * @param id\r
+        *              skin ID\r
+        * @result false when no such ID exists\r
+        */\r
+       function addSkin($id) {\r
+               if (!SKIN::existsID($id)) {\r
+                       return 0;\r
+               }\r
+\r
+               $this->skins[$id] = SKIN::getNameFromId($id);\r
+\r
+               return 1;\r
+       }\r
+\r
+       /**\r
+        * Sets the extra info to be included in the exported file\r
+        */\r
+       function setInfo($info) {\r
+               $this->info = $info;\r
+       }\r
+\r
+\r
+       /**\r
+        * Outputs the XML contents of the export file\r
+        *\r
+        * @param $setHeaders\r
+        *              set to 0 if you don't want to send out headers\r
+        *              (optional, default 1)\r
+        */\r
+       function export($setHeaders = 1) {\r
+               if ($setHeaders) {\r
+                       // make sure the mimetype is correct, and that the data does not show up\r
+                       // in the browser, but gets saved into and XML file (popup download window)\r
+                       header('Content-Type: text/xml');\r
+                       header('Content-Disposition: attachment; filename="skinbackup.xml"');\r
+                       header('Expires: 0');\r
+                       header('Pragma: no-cache');\r
+               }\r
+\r
+               echo "<nucleusskin>\n";\r
+\r
+               // meta\r
+               echo "\t<meta>\n";\r
+                       // skins\r
+                       foreach ($this->skins as $skinId => $skinName) {\r
+                               $skinName = htmlspecialchars($skinName, ENT_QUOTES);\r
+                               echo "\t\t" . '<skin name="' . $skinName . '" />' . "\n";\r
+                       }\r
+                       // templates\r
+                       foreach ($this->templates as $templateId => $templateName) {\r
+                               $templateName = htmlspecialchars($templateName, ENT_QUOTES);\r
+                               echo "\t\t" . '<template name="' . $templateName . '" />' . "\n";\r
+                       }\r
+                       // extra info\r
+                       if ($this->info)\r
+                               echo "\t\t<info><![CDATA[" . $this->info . "]]></info>\n";\r
+               echo "\t</meta>\n\n\n";\r
+\r
+               // contents skins\r
+               foreach ($this->skins as $skinId => $skinName) {\r
+                       $skinId   = intval($skinId);\r
+                       $skinObj  = new SKIN($skinId);\r
+                       $skinName = htmlspecialchars($skinName, ENT_QUOTES);\r
+                       $contentT = htmlspecialchars($skinObj->getContentType(), ENT_QUOTES);\r
+                       $incMode  = htmlspecialchars($skinObj->getIncludeMode(), ENT_QUOTES);\r
+                       $incPrefx = htmlspecialchars($skinObj->getIncludePrefix(), ENT_QUOTES);\r
+                       $skinDesc = htmlspecialchars($skinObj->getDescription(), ENT_QUOTES);\r
+\r
+                       echo "\t" . '<skin name="' . $skinName . '" type="' . $contentT . '" includeMode="' . $incMode . '" includePrefix="' . $incPrefx . '">' . "\n";\r
+\r
+                       echo "\t\t" . '<description>' . $skinDesc . '</description>' . "\n";\r
+\r
+                       $que = 'SELECT'\r
+                                . '    stype,'\r
+                                . '    scontent '\r
+                                . 'FROM '\r
+                                .      sql_table('skin')\r
+                                . ' WHERE'\r
+                                . '    sdesc = ' . $skinId;\r
+                       $res = sql_query($que);\r
+                       while ($partObj = mysql_fetch_object($res)) {\r
+                               $type  = htmlspecialchars($partObj->stype, ENT_QUOTES);\r
+                               $cdata = $this->escapeCDATA($partObj->scontent);\r
+                               echo "\t\t" . '<part name="' . $type . '">';\r
+                               echo '<![CDATA[' . $cdata . ']]>';\r
+                               echo "</part>\n\n";\r
+                       }\r
+\r
+                       echo "\t</skin>\n\n\n";\r
+               }\r
+\r
+               // contents templates\r
+               foreach ($this->templates as $templateId => $templateName) {\r
+                       $templateId   = intval($templateId);\r
+                       $templateName = htmlspecialchars($templateName, ENT_QUOTES);\r
+                       $templateDesc = htmlspecialchars(TEMPLATE::getDesc($templateId), ENT_QUOTES);\r
+\r
+                       echo "\t" . '<template name="' . $templateName . '">' . "\n";\r
+\r
+                       echo "\t\t" . '<description>' . $templateDesc . "</description>\n";\r
+\r
+                       $que =  'SELECT'\r
+                                .     ' tpartname,'\r
+                                .     ' tcontent'\r
+                                . ' FROM '\r
+                                .     sql_table('template')\r
+                                . ' WHERE'\r
+                                .     ' tdesc = ' . $templateId;\r
+                       $res = sql_query($que);\r
+                       while ($partObj = mysql_fetch_object($res)) {\r
+                               $type  = htmlspecialchars($partObj->tpartname, ENT_QUOTES);\r
+                               $cdata = $this->escapeCDATA($partObj->tcontent);\r
+                               echo "\t\t" . '<part name="' . $type . '">';\r
+                               echo '<![CDATA[' .  $cdata . ']]>';\r
+                               echo '</part>' . "\n\n";\r
+                       }\r
+\r
+                       echo "\t</template>\n\n\n";\r
+               }\r
+\r
+               echo '</nucleusskin>';\r
+       }\r
+\r
+       /**\r
+        * Escapes CDATA content so it can be included in another CDATA section\r
+        */\r
+       function escapeCDATA($cdata)\r
+       {\r
+               return preg_replace('/]]>/', ']]]]><![CDATA[>', $cdata);\r
+\r
+       }\r
+}\r
+\r
 ?>
\ No newline at end of file
index c4ea1a0..0830da6 100755 (executable)
@@ -2,7 +2,7 @@
 
 /*
  * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/)
- * Copyright (C) 2002-2007 The Nucleus Group
+ * Copyright (C) 2002-2009 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
@@ -12,8 +12,8 @@
  */
 /**
  * @license http://nucleuscms.org/license.txt GNU General Public License
- * @copyright Copyright (C) 2002-2007 The Nucleus Group
- * @version $Id: vars4.0.6.php,v 1.11 2008-02-08 09:31:22 kimitake Exp $
+ * @copyright Copyright (C) 2002-2009 The Nucleus Group
+ * @version $Id$
  * @version $NucleusJP: vars4.0.6.php,v 1.10.2.1 2007/09/05 07:46:30 kimitake Exp $
  */
 
index 906b198..c1d67e0 100755 (executable)
@@ -2,7 +2,7 @@
 
 /*
  * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/)
- * Copyright (C) 2002-2007 The Nucleus Group
+ * Copyright (C) 2002-2009 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
@@ -12,8 +12,8 @@
  */
 /**
  * @license http://nucleuscms.org/license.txt GNU General Public License
- * @copyright Copyright (C) 2002-2007 The Nucleus Group
- * @version $Id: vars4.1.0.php,v 1.12 2008-02-08 09:31:22 kimitake Exp $
+ * @copyright Copyright (C) 2002-2009 The Nucleus Group
+ * @version $Id$
  * @version $NucleusJP: vars4.1.0.php,v 1.10.2.2 2007/10/30 19:01:33 kmorimatsu Exp $
  */
 
index a589e20..f04bab5 100755 (executable)
@@ -2,7 +2,7 @@
 // by Edd Dumbill (C) 1999-2002
 // <edd@usefulinc.com>
 // $Original: xmlrpc.inc,v 1.158 2007/03/01 21:21:02 ggiunta Exp $
-// $Id: xmlrpc.inc.php,v 1.7 2008-02-08 09:31:22 kimitake Exp $
+// $Id$
 // $NucleusJP: xmlrpc.inc.php,v 1.6.2.2 2007/09/07 07:04:24 kimitake Exp $
 
 
index ac95f2c..171e911 100755 (executable)
@@ -2,7 +2,7 @@
 // by Edd Dumbill (C) 1999-2002
 // <edd@usefulinc.com>
 // $Original: xmlrpcs.inc,v 1.66 2006/09/17 21:25:06 ggiunta Exp $
-// $Id: xmlrpcs.inc.php,v 1.10 2008-02-08 09:31:22 kimitake Exp $
+// $Id$
 // $NucleusJP: xmlrpcs.inc.php,v 1.9.2.2 2007/09/07 07:04:24 kimitake Exp $
 
 // Copyright (c) 1999,2000,2002 Edd Dumbill.