OSDN Git Service

Merge branch 'skinnable-master' of ssh://shizuki@git.sourceforge.jp/gitroot/nucleus...
[nucleus-jp/nucleus-next.git] / nucleus / libs / ITEM.php
1 <?php\r
2 \r
3 /*\r
4  * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/)\r
5  * Copyright (C) 2002-2012 The Nucleus Group\r
6  *\r
7  * This program is free software; you can redistribute it and/or\r
8  * modify it under the terms of the GNU General Public License\r
9  * as published by the Free Software Foundation; either version 2\r
10  * of the License, or (at your option) any later version.\r
11  * (see nucleus/documentation/index.html#license for more info)\r
12  */\r
13 /**\r
14  * @license http://nucleuscms.org/license.txt GNU General Public License\r
15  * @copyright Copyright (C) 2002-2012 The Nucleus Group\r
16  * @version $Id: ITEM.php 1668 2012-02-19 14:36:44Z sakamocchi $\r
17  */\r
18 \r
19 /**\r
20  * A class representing an item\r
21  *\r
22  */\r
23 class Item\r
24 {\r
25         /**\r
26          * Item::$actiontypes\r
27          * actiontype list for handling items\r
28          * \r
29          * @static\r
30          */\r
31         static private $actiontypes\r
32                 = array('addnow', 'adddraft', 'addfuture', 'edit', 'changedate', 'backtodrafts', 'delete');\r
33         \r
34         /**\r
35          * Item::$itemid\r
36          * item id\r
37          * @deprecated\r
38          * \r
39          */\r
40         public $itemid;\r
41         \r
42         /**\r
43          * Item::__construct()\r
44          * Creates a new ITEM object\r
45          * \r
46          * @deprecated\r
47          * @param integer       $item_id        id for item\r
48          * @return void\r
49          */\r
50         public function __construct($item_id)\r
51         {\r
52                 $this->itemid = $item_id;\r
53                 return;\r
54         }\r
55         \r
56         /**\r
57          * Item::getitem()\r
58          * Returns one item with the specific itemid\r
59          *\r
60          * @param int $item_id\r
61          * @param bool $allow_draft\r
62          * @param bool $allow_future\r
63          * @return mixed\r
64          * \r
65          */\r
66         static public function getitem($item_id, $allow_draft, $allow_future)\r
67         {\r
68                 global $manager;\r
69                 \r
70                 $item_id = (integer) $item_id;\r
71                 \r
72                 $query = 'SELECT ' .\r
73                         'i.idraft AS draft, ' .\r
74                         'i.inumber AS itemid, ' .\r
75                         'i.iclosed AS closed, ' .\r
76                         'i.ititle AS title, ' .\r
77                         'i.ibody AS body, ' .\r
78                         'm.mname AS author, ' .\r
79                         'i.iauthor AS authorid, ' .\r
80                         'i.itime, ' .\r
81                         'i.imore AS more, ' .\r
82                         'i.ikarmapos AS karmapos, ' .\r
83                         'i.ikarmaneg AS karmaneg, ' .\r
84                         'i.icat AS catid, ' .\r
85                         'i.iblog AS blogid ' .\r
86                         'FROM %s AS i, %s AS m, %s AS b ' .\r
87                         'WHERE i.inumber = %d ' .\r
88                         'AND i.iauthor = m.mnumber ' .\r
89                         'AND i.iblog = b.bnumber ';\r
90                 \r
91                 $query = sprintf($query, sql_table('item'), sql_table('member'), sql_table('blog'), $item_id);\r
92                 \r
93                 if ( !$allow_draft )\r
94                 {\r
95                         $query .= "AND i.idraft = 0 ";\r
96                 }\r
97                 \r
98                 if ( !$allow_future )\r
99                 {\r
100                         /* FIXME: should be rewritten! */\r
101                         $blog =& $manager->getBlog(getBlogIDFromItemID($item_id));\r
102                         $query .= 'AND i.itime <= ' . DB::formatDateTime($blog->getCorrectTime());\r
103                 }\r
104                 \r
105                 $query .= ' LIMIT 1';\r
106                 $result = DB::getResult($query);\r
107                 \r
108                 if ( $result->rowCount() != 1 )\r
109                 {\r
110                         return 0;\r
111                 }\r
112                 $aItemInfo = $result->fetch(PDO::FETCH_ASSOC);\r
113                 $aItemInfo['timestamp'] = strtotime($aItemInfo['itime']);\r
114                 return $aItemInfo;\r
115         }\r
116         \r
117         /**\r
118          * Item::createFromRequest()\r
119          * Tries to create an item from the data in the current request (comes from\r
120          * bookmarklet or admin area\r
121          *\r
122          * @static\r
123          * @param       void\r
124          * @return      array   (status = added/error/newcategory, message)\r
125          * \r
126          */\r
127         static public function createFromRequest()\r
128         {\r
129                 global $member, $manager;\r
130                 \r
131                 /*\r
132                  * TODO: these values from user agent should be validated but not implemented yet\r
133                  */\r
134                 $i_author               = $member->getID();\r
135                 $i_body                 = postVar('body');\r
136                 $i_title                = postVar('title');\r
137                 $i_more                 = postVar('more');\r
138                 $i_actiontype   = postVar('actiontype');\r
139                 $i_closed               = intPostVar('closed');\r
140                 $i_hour                 = intPostVar('hour');\r
141                 $i_minutes              = intPostVar('minutes');\r
142                 $i_month                = intPostVar('month');\r
143                 $i_day                  = intPostVar('day');\r
144                 $i_year                 = intPostVar('year');\r
145                 $i_catid                = postVar('catid');\r
146                 $i_draftid              = intPostVar('draftid');\r
147                 \r
148                 if ( !$member->canAddItem($i_catid) )\r
149                 {\r
150                         return array('status' => 'error', 'message' => _ERROR_DISALLOWED);\r
151                 }\r
152                 \r
153                 if ( !in_array($i_actiontype, self::$actiontypes) )\r
154                 {\r
155                         $i_actiontype = 'addnow';\r
156                 }\r
157                 \r
158                 $i_draft = (integer) ( $i_actiontype == 'adddraft' );\r
159                 \r
160                 if ( !trim($i_body) )\r
161                 {\r
162                         return array('status' => 'error', 'message' => _ERROR_NOEMPTYITEMS);\r
163                 }\r
164                 \r
165                 // create new category if needed\r
166                 if ( i18n::strpos($i_catid, 'newcat') === 0 )\r
167                 {\r
168                         // get blogid\r
169                         list($i_blogid) = sscanf($i_catid, "newcat-%d");\r
170                         \r
171                         // create\r
172                         $blog =& $manager->getBlog($i_blogid);\r
173                         $i_catid = $blog->createNewCategory();\r
174                         \r
175                         // show error when sth goes wrong\r
176                         if ( !$i_catid )\r
177                         {\r
178                                 return array('status' => 'error','message' => 'Could not create new category');\r
179                         }\r
180                 }\r
181                 else\r
182                 {\r
183                         // force blogid (must be same as category id)\r
184                         $i_blogid = getBlogIDFromCatID($i_catid);\r
185                         $blog =& $manager->getBlog($i_blogid);\r
186                 }\r
187                 \r
188                 if ( $i_actiontype == 'addfuture' )\r
189                 {\r
190                         $posttime = mktime($i_hour, $i_minutes, 0, $i_month, $i_day, $i_year);\r
191                         \r
192                         // make sure the date is in the future, unless we allow past dates\r
193                         if ( (!$blog->allowPastPosting()) && ($posttime < $blog->getCorrectTime()) )\r
194                         {\r
195                                 $posttime = $blog->getCorrectTime();\r
196                         }\r
197                 }\r
198                 else\r
199                 {\r
200                         if ( !$i_draft )\r
201                         {\r
202                                 $posttime = $blog->getCorrectTime();\r
203                         }\r
204                         else\r
205                         {\r
206                                 $posttime = 0;\r
207                         }\r
208                 }\r
209                 \r
210                 if ( $posttime > $blog->getCorrectTime() )\r
211                 {\r
212                         $posted = 0;\r
213                         $blog->setFuturePost();\r
214                 }\r
215                 else\r
216                 {\r
217                         $posted = 1;\r
218                 }\r
219                 \r
220                 $itemid = $blog->additem($i_catid, $i_title, $i_body, $i_more, $i_blogid, $i_author, $posttime, $i_closed, $i_draft, $posted);\r
221                 \r
222                 //Setting the itemOptions\r
223                 $aOptions = requestArray('plugoption');\r
224                 NucleusPlugin::apply_plugin_options($aOptions, $itemid);\r
225                 $manager->notify('PostPluginOptionsUpdate', array(\r
226                         'context' => 'item',\r
227                         'itemid' => $itemid,\r
228                         'item' => array(\r
229                                 'title' => $i_title,\r
230                                 'body' => $i_body,\r
231                                 'more' => $i_more,\r
232                                 'closed' => $i_closed,\r
233                                 'catid' => $i_catid\r
234                                 )\r
235                         )\r
236                 );\r
237                 \r
238                 if ( $i_draftid > 0 )\r
239                 {\r
240                         // delete permission is checked inside Item::delete()\r
241                         self::delete($i_draftid);\r
242                 }\r
243                 \r
244                 // success\r
245                 if ( $i_catid != intRequestVar('catid') )\r
246                 {\r
247                         return array('status' => 'newcategory', 'itemid' => $itemid, 'catid' => $i_catid);\r
248                 }\r
249                 else\r
250                 {\r
251                         return array('status' => 'added', 'itemid' => $itemid);\r
252                 }\r
253         }\r
254         \r
255         /**\r
256          * Item::update()\r
257          * Updates an item\r
258          *\r
259          * @static\r
260          * @param       integer $itemid item id\r
261          * @param       integer $catid  category id\r
262          * @param       string  $title  title\r
263          * @param       string  $body   body text\r
264          * @param       string  $more   more text\r
265          * @param       boolean $closed closed or not\r
266          * @param       boolean $wasdraft       previously draft or not\r
267          * @param       boolean $publish        published or not\r
268          * @param       timestamp       $timestamp      timestamp\r
269          * @return      void\r
270          * \r
271          */\r
272         static public function update($itemid, $catid, $title, $body, $more, $closed, $wasdraft, $publish, $timestamp = 0)\r
273         {\r
274                 global $manager;\r
275                 \r
276                 $itemid = (integer) $itemid;\r
277                 $closed = (boolean) $closed;\r
278                 \r
279                 // get destination blogid\r
280                 $new_blogid = getBlogIDFromCatID($catid);\r
281                 $old_blogid = getBlogIDFromItemID($itemid);\r
282                 \r
283                 // move will be done on end of method\r
284                 $moveNeeded = 0;\r
285                 if ( $new_blogid != $old_blogid )\r
286                 {\r
287                         $moveNeeded = 1;\r
288                 }\r
289                 \r
290                 $blog =& $manager->getBlog($new_blogid);\r
291                 \r
292                 // begin if: convert line breaks to <br/>\r
293                 if ( $blog->convertBreaks() )\r
294                 {\r
295                         $body = addBreaks($body);\r
296                         $more = addBreaks($more);\r
297                 }\r
298                 \r
299                 // call plugins\r
300                 $manager->notify('PreUpdateItem', array(\r
301                         'itemid'        => $itemid,\r
302                         'title'         => &$title,\r
303                         'body'          => &$body,\r
304                         'more'          => &$more,\r
305                         'blog'          => &$blog,\r
306                         'closed'        => &$closed,\r
307                         'catid'         => &$catid\r
308                         )\r
309                 );\r
310                 \r
311                 // update item itself\r
312                 $query =  'UPDATE ' . sql_table('item')\r
313                                 . ' SET'\r
314                                 . ' ibody = ' . DB::quoteValue($body) . ','\r
315                                 . ' ititle = ' . DB::quoteValue($title) . ','\r
316                                 . ' imore = ' . DB::quoteValue($more) . ','\r
317                                 . ' iclosed = ' . intval($closed) . ','\r
318                                 . ' icat = ' . intval($catid);\r
319                 \r
320                 // if we received an updated timestamp that is in the past, but past posting is not allowed, reject that date change (timestamp = 0 will make sure the current date is kept)\r
321                 if ( (!$blog->allowPastPosting()) && ($timestamp < $blog->getCorrectTime()) )\r
322                 {\r
323                         $timestamp = 0;\r
324                 }\r
325                 \r
326                 // begin if: post is in the future\r
327                 if ( $timestamp > $blog->getCorrectTime(time()) )\r
328                 {\r
329                         $isFuture = 1;\r
330                         $query .= ', iposted = 0';\r
331                 }\r
332                 else\r
333                 {\r
334                         $isFuture = 0;\r
335                         $query .= ', iposted = 1';\r
336                 }\r
337                 \r
338                 if ( $wasdraft && $publish )\r
339                 {\r
340                         // set timestamp to current date only if it's not a future item\r
341                         // draft items have timestamp == 0\r
342                         // don't allow timestamps in the past (unless otherwise defined in blogsettings)\r
343                         $query .= ', idraft = 0';\r
344                         \r
345                         if ( $timestamp == 0 )\r
346                         {\r
347                                 $timestamp = $blog->getCorrectTime();\r
348                         }\r
349                         \r
350                         // send new item notification\r
351                         if ( !$isFuture && $blog->getNotifyAddress() && $blog->notifyOnNewItem() )\r
352                         {\r
353                                 $blog->sendNewItemNotification($itemid, $title, $body);\r
354                         }\r
355                 }\r
356                 \r
357                 // save back to drafts\r
358                 if ( !$wasdraft && !$publish )\r
359                 {\r
360                         $query .= ', idraft = 1';\r
361                         // set timestamp back to zero for a draft\r
362                         $query .= ', itime = ' . DB::formatDateTime($timestamp);\r
363                 }\r
364                 \r
365                 // update timestamp when needed\r
366                 if ( $timestamp != 0 )\r
367                 {\r
368                         $query .= ', itime = ' . DB::formatDateTime($timestamp);\r
369                 }\r
370                 \r
371                 // make sure the correct item is updated\r
372                 $query .= ' WHERE inumber = ' . $itemid;\r
373                 \r
374                 // off we go!\r
375                 DB::execute($query);\r
376                 \r
377                 $manager->notify('PostUpdateItem', array('itemid' => $itemid));\r
378                 \r
379                 // when needed, move item and comments to new blog\r
380                 if ( $moveNeeded )\r
381                 {\r
382                         self::move($itemid, $catid);\r
383                 }\r
384                 \r
385                 //update the itemOptions\r
386                 $aOptions = requestArray('plugoption');\r
387                 NucleusPlugin::apply_plugin_options($aOptions);\r
388                 $manager->notify('PostPluginOptionsUpdate', array(\r
389                         'context' => 'item',\r
390                         'itemid' => $itemid,\r
391                         'item' => array(\r
392                                 'title' => $title,\r
393                                 'body' => $body,\r
394                                 'more' => $more,\r
395                                 'closed' => $closed,\r
396                                 'catid' => $catid\r
397                                 )\r
398                         )\r
399                 );\r
400                 return;\r
401         }\r
402         \r
403         /**\r
404          * Item::move()\r
405          * Move an item to another blog (no checks)\r
406          *\r
407          * @static\r
408          * @param       integer $itemid\r
409          * @param       integer $new_catid\r
410          * @return      void\r
411          */\r
412         static public function move($itemid, $new_catid)\r
413         {\r
414                 global $manager;\r
415                 \r
416                 $itemid                 = (integer) $itemid;\r
417                 $new_catid      = (integer) $new_catid;\r
418                 $new_blogid     = getBlogIDFromCatID($new_catid);\r
419                 \r
420                 $manager->notify(\r
421                         'PreMoveItem',\r
422                         array(\r
423                                 'itemid' => $itemid,\r
424                                 'destblogid' => $new_blogid,\r
425                                 'destcatid' => $new_catid\r
426                         )\r
427                 );\r
428                 \r
429                 // update item table\r
430                 $query = "UPDATE %s SET iblog=%d, icat=%d WHERE inumber=%d";\r
431                 $query = sprintf($query, sql_table('item'), $new_blogid, $new_catid, $itemid);\r
432                 DB::execute($query);\r
433                 \r
434                 // update comments\r
435                 $query = "UPDATE %s SET cblog=%d WHERE citem=%d";\r
436                 $query = sprintf($query, sql_table('comment'), $new_blogid, $itemid);\r
437                 DB::execute($query);\r
438                 \r
439                 $manager->notify(\r
440                         'PostMoveItem',\r
441                         array(\r
442                                 'itemid' => $itemid,\r
443                                 'destblogid' => $new_blogid,\r
444                                 'destcatid' => $new_catid\r
445                         )\r
446                 );\r
447                 return;\r
448         }\r
449         \r
450         /**\r
451          * Item::delete()\r
452          * Deletes an item\r
453          * \r
454          * @param       integer $itemid\r
455          * @return      void\r
456          */\r
457         static public function delete($itemid)\r
458         {\r
459                 global $manager, $member;\r
460                 \r
461                 $itemid = (integer) $itemid;\r
462                 \r
463                 // check permission\r
464                 if ( !$member->canAlterItem($itemid) )\r
465                 {\r
466                         return 1;\r
467                 }\r
468                 \r
469                 $manager->notify('PreDeleteItem', array('itemid' => $itemid));\r
470                 \r
471                 // delete item\r
472                 $query = "DELETE FROM %s WHERE inumber=%d";\r
473                 $query = sprintf($query, sql_table('item'), $itemid);\r
474                 DB::execute($query);\r
475                 \r
476                 // delete the comments associated with the item\r
477                 $query = "DELETE FROM %s WHERE citem=%d";\r
478                 $query = sprintf($query, sql_table('comment'), $itemid);\r
479                 DB::execute($query);\r
480                 \r
481                 // delete all associated plugin options\r
482                 NucleusPlugin::delete_option_values('item', $itemid);\r
483                 \r
484                 $manager->notify('PostDeleteItem', array('itemid' => $itemid));\r
485                 \r
486                 return 0;\r
487         }\r
488         \r
489         /**\r
490          * Item::exists()\r
491          * Returns true if there is an item with the given ID\r
492          *\r
493          * @static\r
494          * @param       integer $itemid\r
495          * @param       boolean $future\r
496          * @param       boolean $draft\r
497          * @return      boolean exists or not\r
498          * \r
499          */\r
500         static public function exists($itemid, $future, $draft)\r
501         {\r
502                 global $manager;\r
503                 \r
504                 $itemid = (integer) $itemid;\r
505                 $query = 'SELECT * FROM '.sql_table('item').' WHERE inumber='.$itemid;\r
506                 \r
507                 if ( !$future )\r
508                 {\r
509                         $blogid = getBlogIDFromItemID($itemid);\r
510                         if ( !$blogid )\r
511                         {\r
512                                 return 0;\r
513                         }\r
514                         $blog =& $manager->getBlog($blogid);\r
515                         $query .= ' and itime<=' . DB::formatDateTime($blog->getCorrectTime());\r
516                 }\r
517                 if ( !$draft )\r
518                 {\r
519                         $query .= ' and idraft=0';\r
520                 }\r
521                 $result = DB::getResult($query);\r
522                 return ( $result->rowCount() != 0 );\r
523         }\r
524         \r
525         /**\r
526          * Item::createDraftFromRequest()\r
527          * Tries to create an draft from the data\r
528          *  in the current request (comes from bookmarklet or admin area)\r
529          *   Used by xmlHTTPRequest AutoDraft\r
530          *\r
531          * Returns an array with status info:\r
532          * status = 'added', 'error', 'newcategory'\r
533          *\r
534          * @static\r
535          * @param       void\r
536          * @return      array   (status = added/error/newcategory, message)\r
537          *\r
538          */\r
539         static public function createDraftFromRequest()\r
540         {\r
541                 global $member, $manager;\r
542                 \r
543                 /*\r
544                  * TODO: these values from user agent should be validated but not implemented yet\r
545                  */\r
546                 $i_author               = $member->getID();\r
547                 $i_body                 = postVar('body');\r
548                 $i_title                = postVar('title');\r
549                 $i_more                 = postVar('more');\r
550                 $i_closed               = intPostVar('closed');\r
551                 $i_catid                = postVar('catid');\r
552                 $i_draft                = 1;\r
553                 $type                   = postVar('type');\r
554                 $i_draftid      = intPostVar('draftid');\r
555                 \r
556                 if ( $type == 'edit' )\r
557                 {\r
558                         $itemid = intPostVar('itemid');\r
559                         $item =& $manager->getItem($itemid, 0, 0);\r
560                         $i_blogid = $item['blogid'];\r
561                 }\r
562                 else\r
563                 {\r
564                         $i_blogid = intPostVar('blogid');\r
565                 }\r
566                 \r
567                 if ( !$member->canAddItem($i_catid) )\r
568                 {\r
569                         return array('status' => 'error', 'message' => _ERROR_DISALLOWED);\r
570                 }\r
571                 \r
572                 if ( !trim($i_body) )\r
573                 {\r
574                         return array('status' => 'error', 'message' => _ERROR_NOEMPTYITEMS);\r
575                 }\r
576                 \r
577                 // create new category if needed\r
578                 if ( i18n::strpos($i_catid,'newcat') === 0 )\r
579                 {\r
580                         // Set in default category\r
581                         $blog =& $manager->getBlog($i_blogid);\r
582                         $i_catid = $blog->getDefaultCategory();\r
583                 }\r
584                 else\r
585                 {\r
586                         // force blogid (must be same as category id)\r
587                         $i_blogid = getBlogIDFromCatID($i_catid);\r
588                         $blog =& $manager->getBlog($i_blogid);\r
589                 }\r
590                 \r
591                 $posttime = 0;\r
592                 \r
593                 if ( $i_draftid > 0 )\r
594                 {\r
595                         self::update($i_draftid, $i_catid, $i_title, $i_body, $i_more, $i_closed, 1, 0, 0);\r
596                         $itemid = $i_draftid;\r
597                 }\r
598                 else\r
599                 {\r
600                         $itemid = $blog->additem($i_catid, $i_title, $i_body, $i_more, $i_blogid, $i_author, $posttime, $i_closed, $i_draft);\r
601                 }\r
602                 \r
603                 return array('status' => 'added', 'draftid' => $itemid);\r
604         }\r
605 }\r