Dotclear

source: inc/public/lib.urlhandlers.php @ 303:c7b69e7aec35

Revision 303:c7b69e7aec35, 15.1 KB checked in by Osku <popech@…>, 14 years ago (diff)

Changed strpos test in dcUrlHandlers(post) for better test. Adresses ticket #1177

Line 
1<?php
2# -- BEGIN LICENSE BLOCK ---------------------------------------
3#
4# This file is part of Dotclear 2.
5#
6# Copyright (c) 2003-2011 Olivier Meunier & Association Dotclear
7# Licensed under the GPL version 2.0 license.
8# See LICENSE file or
9# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
10#
11# -- END LICENSE BLOCK -----------------------------------------
12if (!defined('DC_RC_PATH')) { return; }
13
14class dcUrlHandlers extends urlHandler
15{
16     public $args;
17     
18     public static function p404()
19     {
20          throw new Exception ("Page not found",404);
21     }
22     
23     public static function default404($args,$type,$e)
24     {
25          if ($e->getCode() != 404) {
26               throw $e;
27          }
28          $_ctx =& $GLOBALS['_ctx'];
29          $core = $GLOBALS['core'];
30         
31          header('Content-Type: text/html; charset=UTF-8');
32          http::head(404,'Not Found');
33          $core->url->type = '404';
34          $_ctx->current_tpl = '404.html';
35          $_ctx->content_type = 'text/html';
36         
37          echo $core->tpl->getData($_ctx->current_tpl);
38         
39          # --BEHAVIOR-- publicAfterDocument
40          $core->callBehavior('publicAfterDocument',$core);
41          exit;
42     }
43     
44     protected static function getPageNumber(&$args)
45     {
46          if (preg_match('#(^|/)page/([0-9]+)$#',$args,$m)) {
47               $n = (integer) $m[2];
48               if ($n > 0) {
49                    $args = preg_replace('#(^|/)page/([0-9]+)$#','',$args);
50                    return $n;
51               }
52          }
53         
54          return false;
55     }
56     
57     protected static function serveDocument($tpl,$content_type='text/html',$http_cache=true,$http_etag=true)
58     {
59          $_ctx =& $GLOBALS['_ctx'];
60          $core =& $GLOBALS['core'];
61         
62          if ($_ctx->nb_entry_per_page === null) {
63               $_ctx->nb_entry_per_page = $core->blog->settings->system->nb_post_per_page;
64          }
65         
66          $tpl_file = $core->tpl->getFilePath($tpl);
67         
68          if (!$tpl_file) {
69               throw new Exception('Unable to find template ');
70          }
71         
72          $result = new ArrayObject;
73         
74          $_ctx->current_tpl = $tpl;
75          $_ctx->content_type = $content_type;
76          $_ctx->http_cache = $http_cache;
77          $_ctx->http_etag = $http_etag;
78          $core->callBehavior('urlHandlerBeforeGetData',$_ctx);
79         
80          if ($_ctx->http_cache) {
81               $GLOBALS['mod_files'][] = $tpl_file;
82               http::cache($GLOBALS['mod_files'],$GLOBALS['mod_ts']);
83          }
84
85          header('Content-Type: '.$_ctx->content_type.'; charset=UTF-8');
86          $result['content'] = $core->tpl->getData($_ctx->current_tpl);
87          $result['content_type'] = $_ctx->content_type;
88          $result['tpl'] = $_ctx->current_tpl;
89          $result['blogupddt'] = $core->blog->upddt;
90         
91          # --BEHAVIOR-- urlHandlerServeDocument
92          $core->callBehavior('urlHandlerServeDocument',$result);
93         
94          if ($_ctx->http_cache && $_ctx->http_etag) {
95               http::etag($result['content'],http::getSelfURI());
96          }
97          echo $result['content'];
98     }
99     
100     public function getDocument()
101     {
102          $core =& $GLOBALS['core'];
103         
104          $type = $args = '';
105         
106          if ($this->mode == 'path_info')
107          {
108               $part = substr($_SERVER['PATH_INFO'],1);
109          }
110          else
111          {
112               $part = '';
113               
114               $qs = $this->parseQueryString();
115               
116               # Recreates some _GET and _REQUEST pairs
117               if (!empty($qs))
118               {
119                    foreach ($_GET as $k => $v) {
120                         if (isset($_REQUEST[$k])) {
121                              unset($_REQUEST[$k]);
122                         }
123                    }
124                    $_GET = $qs;
125                    $_REQUEST = array_merge($qs,$_REQUEST);
126                   
127                    list($k,$v) = each($qs);
128                    if ($v === null) {
129                         $part = $k;
130                         unset($_GET[$k]);
131                         unset($_REQUEST[$k]);
132                    }
133               }
134          }
135         
136          $_SERVER['URL_REQUEST_PART'] = $part;
137         
138          $this->getArgs($part,$type,$this->args);
139         
140          # --BEHAVIOR-- urlHandlerGetArgsDocument
141          $core->callBehavior('urlHandlerGetArgsDocument',$this);
142         
143          if (!$type)
144          {
145               $this->type = 'default';
146               $this->callDefaultHandler($this->args);
147          }
148          else
149          {
150               $this->type = $type;
151               $this->callHandler($type,$this->args);
152          }
153     }
154     
155     public static function home($args)
156     {
157          $n = self::getPageNumber($args);
158         
159          if ($args && !$n)
160          {
161               # "Then specified URL went unrecognized by all URL handlers and
162               # defaults to the home page, but is not a page number.
163               self::p404();
164          }
165          else
166          {
167               $core =& $GLOBALS['core'];
168               
169               if ($n) {
170                    $GLOBALS['_page_number'] = $n;
171                    $core->url->type = $n > 1 ? 'default-page' : 'default';
172               }
173               
174               if (empty($_GET['q'])) {
175                    self::serveDocument('home.html');
176                    $core->blog->publishScheduledEntries();
177               } else {
178                    self::search();
179               }
180          }
181     }
182     
183     public static function search()
184     {
185          $_ctx =& $GLOBALS['_ctx'];
186          $core =& $GLOBALS['core'];
187         
188          $core->url->type='search';
189         
190          $GLOBALS['_search'] = !empty($_GET['q']) ? rawurldecode($_GET['q']) : '';
191          if ($GLOBALS['_search']) {
192               $params = new ArrayObject(array('search' => $GLOBALS['_search']));
193               $core->callBehavior('publicBeforeSearchCount',$params);
194               $GLOBALS['_search_count'] = $core->blog->getPosts($params,true)->f(0);
195          }
196         
197          self::serveDocument('search.html');
198     }
199     
200     public static function lang($args)
201     {
202          $_ctx =& $GLOBALS['_ctx'];
203          $core =& $GLOBALS['core'];
204         
205          $n = self::getPageNumber($args);
206         
207          $params['lang'] = $args;
208          $_ctx->langs = $core->blog->getLangs($params);
209         
210          if ($_ctx->langs->isEmpty()) {
211               # The specified language does not exist.
212               self::p404();
213          }
214          else
215          {
216               if ($n) {
217                    $GLOBALS['_page_number'] = $n;
218               }
219               $_ctx->cur_lang = $args;
220               self::home(null);
221          }
222     }
223     
224     public static function category($args)
225     {
226          $_ctx =& $GLOBALS['_ctx'];
227          $core =& $GLOBALS['core'];
228         
229          $n = self::getPageNumber($args);
230         
231          if ($args == '' && !$n) {
232               # No category was specified.
233               self::p404();
234          }
235          else
236          {
237               $params['cat_url'] = $args;
238               $params['post_type'] = 'post';
239               
240               $_ctx->categories = $core->blog->getCategories($params);
241               
242               if ($_ctx->categories->isEmpty()) {
243                    # The specified category does no exist.
244                    self::p404();
245               }
246               else
247               {
248                    if ($n) {
249                         $GLOBALS['_page_number'] = $n;
250                    }
251                    self::serveDocument('category.html');
252               }
253          }
254     }
255     
256     public static function archive($args)
257     {
258          $_ctx =& $GLOBALS['_ctx'];
259          $core =& $GLOBALS['core'];
260         
261          $year = $month = $cat_url = null;
262          # Nothing or year and month
263          if ($args == '')
264          {
265               self::serveDocument('archive.html');
266          }
267          elseif (preg_match('|^/([0-9]{4})/([0-9]{2})$|',$args,$m))
268          {
269               $params['year'] = $m[1];
270               $params['month'] = $m[2];
271               $params['type'] = 'month';
272               $_ctx->archives = $core->blog->getDates($params);
273               
274               if ($_ctx->archives->isEmpty()) {
275                    # There is no entries for the specified period.
276                    self::p404();
277               }
278               else
279               {
280                    self::serveDocument('archive_month.html');
281               }
282          }
283          else {
284               # The specified URL is not a date.
285               self::p404();
286          }
287     }
288     
289     public static function post($args)
290     {
291          if ($args == '') {
292               # No entry was specified.
293               self::p404();
294          }
295          else
296          {
297               $_ctx =& $GLOBALS['_ctx'];
298               $core =& $GLOBALS['core'];
299               
300               $core->blog->withoutPassword(false);
301               
302               $params = new ArrayObject();
303               $params['post_url'] = $args;
304               
305               $_ctx->posts = $core->blog->getPosts($params);
306               
307               $_ctx->comment_preview = new ArrayObject();
308               $_ctx->comment_preview['content'] = '';
309               $_ctx->comment_preview['rawcontent'] = '';
310               $_ctx->comment_preview['name'] = '';
311               $_ctx->comment_preview['mail'] = '';
312               $_ctx->comment_preview['site'] = '';
313               $_ctx->comment_preview['preview'] = false;
314               $_ctx->comment_preview['remember'] = false;
315               
316               $core->blog->withoutPassword(true);
317               
318               if ($_ctx->posts->isEmpty())
319               {
320                    # The specified entry does not exist.
321                    self::p404();
322               }
323               else
324               {
325                    $post_id = $_ctx->posts->post_id;
326                    $post_password = $_ctx->posts->post_password;
327                   
328                    # Password protected entry
329                    if ($post_password != '' && !$_ctx->preview)
330                    {
331                         # Get passwords cookie
332                         if (isset($_COOKIE['dc_passwd'])) {
333                              $pwd_cookie = unserialize($_COOKIE['dc_passwd']);
334                         } else {
335                              $pwd_cookie = array();
336                         }
337                         
338                         # Check for match
339                         if ((!empty($_POST['password']) && $_POST['password'] == $post_password)
340                         || (isset($pwd_cookie[$post_id]) && $pwd_cookie[$post_id] == $post_password))
341                         {
342                              $pwd_cookie[$post_id] = $post_password;
343                              setcookie('dc_passwd',serialize($pwd_cookie),0,'/');
344                         }
345                         else
346                         {
347                              self::serveDocument('password-form.html','text/html',false);
348                              return;
349                         }
350                    }
351                   
352                    $post_comment =
353                         isset($_POST['c_name']) && isset($_POST['c_mail']) &&
354                         isset($_POST['c_site']) && isset($_POST['c_content']) &&
355                         $_ctx->posts->commentsActive();
356                   
357                    # Posting a comment
358                    if ($post_comment)
359                    {
360                         # Spam trap
361                         if (!empty($_POST['f_mail'])) {
362                              http::head(412,'Precondition Failed');
363                              header('Content-Type: text/plain');
364                              echo "So Long, and Thanks For All the Fish";
365                              # Exits immediately the application to preserve the server.
366                              exit;
367                         }
368                         
369                         $name = $_POST['c_name'];
370                         $mail = $_POST['c_mail'];
371                         $site = $_POST['c_site'];
372                         $content = $_POST['c_content'];
373                         $preview = !empty($_POST['preview']);
374                         
375                         if ($content != '')
376                         {
377                              if ($core->blog->settings->system->wiki_comments) {
378                                   $core->initWikiComment();
379                              } else {
380                                   $core->initWikiSimpleComment();
381                              }
382                              $content = $core->wikiTransform($content);
383                              $content = $core->HTMLfilter($content);
384                         }
385                         
386                         $_ctx->comment_preview['content'] = $content;
387                         $_ctx->comment_preview['rawcontent'] = $_POST['c_content'];
388                         $_ctx->comment_preview['name'] = $name;
389                         $_ctx->comment_preview['mail'] = $mail;
390                         $_ctx->comment_preview['site'] = $site;
391                         
392                         if ($preview)
393                         {
394                              # --BEHAVIOR-- publicBeforeCommentPreview
395                              $core->callBehavior('publicBeforeCommentPreview',$_ctx->comment_preview);
396                             
397                              $_ctx->comment_preview['preview'] = true;
398                         }
399                         else
400                         {
401                              # Post the comment
402                              $cur = $core->con->openCursor($core->prefix.'comment');
403                              $cur->comment_author = $name;
404                              $cur->comment_site = html::clean($site);
405                              $cur->comment_email = html::clean($mail);
406                              $cur->comment_content = $content;
407                              $cur->post_id = $_ctx->posts->post_id;
408                              $cur->comment_status = $core->blog->settings->system->comments_pub ? 1 : -1;
409                              $cur->comment_ip = http::realIP();
410                             
411                              $redir = $_ctx->posts->getURL();
412                              $redir .= $core->blog->settings->system->url_scan == 'query_string' ? '&' : '?';
413                             
414                              try
415                              {
416                                   if (!text::isEmail($cur->comment_email)) {
417                                        throw new Exception(__('You must provide a valid email address.'));
418                                   }
419                                   
420                                   # --BEHAVIOR-- publicBeforeCommentCreate
421                                   $core->callBehavior('publicBeforeCommentCreate',$cur);
422                                   if ($cur->post_id) {                         
423                                        $comment_id = $core->blog->addComment($cur);
424                                       
425                                        # --BEHAVIOR-- publicAfterCommentCreate
426                                        $core->callBehavior('publicAfterCommentCreate',$cur,$comment_id);
427                                   }
428                                   
429                                   if ($cur->comment_status == 1) {
430                                        $redir_arg = 'pub=1';
431                                   } else {
432                                        $redir_arg = 'pub=0';
433                                   }
434                                   
435                                   header('Location: '.$redir.$redir_arg);
436                              }
437                              catch (Exception $e)
438                              {
439                                   $_ctx->form_error = $e->getMessage();
440                                   $_ctx->form_error;
441                              }
442                         }
443                    }
444                   
445                    # The entry
446                    self::serveDocument('post.html');
447               }
448          }
449     }
450     
451     public static function preview($args)
452     {
453          $core = $GLOBALS['core'];
454          $_ctx = $GLOBALS['_ctx'];
455         
456          if (!preg_match('#^(.+?)/([0-9a-z]{40})/(.+?)$#',$args,$m)) {
457               # The specified Preview URL is malformed.
458               self::p404();
459          }
460          else
461          {
462               $user_id = $m[1];
463               $user_key = $m[2];
464               $post_url = $m[3];
465               if (!$core->auth->checkUser($user_id,null,$user_key)) {
466                    # The user has no access to the entry.
467                    self::p404();
468               }
469               else
470               {
471                    $_ctx->preview = true;
472                    self::post($post_url);
473               }
474          }
475     }
476     
477     public static function feed($args)
478     {
479          $type = null;
480          $comments = false;
481          $cat_url = false;
482          $post_id = null;
483          $params = array();
484          $subtitle = '';
485         
486          $mime = 'application/xml';
487         
488          $_ctx =& $GLOBALS['_ctx'];
489          $core =& $GLOBALS['core'];
490         
491          if (preg_match('!^([a-z]{2}(-[a-z]{2})?)/(.*)$!',$args,$m)) {
492               $params['lang'] = $m[1];
493               $args = $m[3];
494               
495               $_ctx->langs = $core->blog->getLangs($params);
496               
497               if ($_ctx->langs->isEmpty()) {
498                    # The specified language does not exist.
499                    self::p404();
500                    return;
501               } else {
502                    $_ctx->cur_lang = $m[1];
503               }
504          }
505         
506          if (preg_match('#^rss2/xslt$#',$args,$m))
507          {
508               # RSS XSLT stylesheet
509               self::serveDocument('rss2.xsl','text/xml');
510               return;
511          }
512          elseif (preg_match('#^(atom|rss2)/comments/([0-9]+)$#',$args,$m))
513          {
514               # Post comments feed
515               $type = $m[1];
516               $comments = true;
517               $post_id = (integer) $m[2];
518          }
519          elseif (preg_match('#^(?:category/(.+)/)?(atom|rss2)(/comments)?$#',$args,$m))
520          {
521               # All posts or comments feed
522               $type = $m[2];
523               $comments = !empty($m[3]);
524               if (!empty($m[1])) {
525                    $cat_url = $m[1];
526               }
527          }
528          else
529          {
530               # The specified Feed URL is malformed.
531               self::p404();
532               return;
533          }
534         
535          if ($cat_url)
536          {
537               $params['cat_url'] = $cat_url;
538               $params['post_type'] = 'post';
539               $_ctx->categories = $core->blog->getCategories($params);
540               
541               if ($_ctx->categories->isEmpty()) {
542                    # The specified category does no exist.
543                    self::p404();
544                    return;
545               }
546               
547               $subtitle = ' - '.$_ctx->categories->cat_title;
548          }
549          elseif ($post_id)
550          {
551               $params['post_id'] = $post_id;
552               $params['post_type'] = '';
553               $_ctx->posts = $core->blog->getPosts($params);
554               
555               if ($_ctx->posts->isEmpty()) {
556                    # The specified post does not exist.
557                    self::p404();
558                    return;
559               }
560               
561               $subtitle = ' - '.$_ctx->posts->post_title;
562          }
563         
564          $tpl = $type;
565          if ($comments) {
566               $tpl .= '-comments';
567               $_ctx->nb_comment_per_page = $core->blog->settings->system->nb_comment_per_feed;
568          } else {
569               $_ctx->nb_entry_per_page = $core->blog->settings->system->nb_post_per_feed;
570               $_ctx->short_feed_items = $core->blog->settings->system->short_feed_items;
571          }
572          $tpl .= '.xml';
573         
574          if ($type == 'atom') {
575               $mime = 'application/atom+xml';
576          }
577         
578          $_ctx->feed_subtitle = $subtitle;
579         
580          header('X-Robots-Tag: '.context::robotsPolicy($core->blog->settings->system->robots_policy,''));
581          self::serveDocument($tpl,$mime);
582          if (!$comments && !$cat_url) {
583               $core->blog->publishScheduledEntries();
584          }
585     }
586     
587     public static function trackback($args)
588     {
589          if (!preg_match('/^[0-9]+$/',$args)) {
590               # The specified trackback URL is not an number
591               self::p404();
592          } else {
593               $tb = new dcTrackback($GLOBALS['core']);
594               $tb->receive($args);
595          }
596     }
597     
598     public static function rsd($args)
599     {
600          $core =& $GLOBALS['core'];
601          http::cache($GLOBALS['mod_files'],$GLOBALS['mod_ts']);
602         
603          header('Content-Type: text/xml; charset=UTF-8');
604          echo
605          '<?xml version="1.0" encoding="UTF-8"?>'."\n".
606          '<rsd version="1.0" xmlns="http://archipelago.phrasewise.com/rsd">'."\n".
607          "<service>\n".
608          "  <engineName>Dotclear</engineName>\n".
609          "  <engineLink>http://www.dotclear.org/</engineLink>\n".
610          '  <homePageLink>'.html::escapeHTML($core->blog->url)."</homePageLink>\n";
611         
612          if ($core->blog->settings->system->enable_xmlrpc)
613          {
614               $u = sprintf(DC_XMLRPC_URL,$core->blog->url,$core->blog->id);
615               
616               echo
617               "  <apis>\n".
618               '    <api name="WordPress" blogID="1" preferred="true" apiLink="'.$u.'"/>'."\n".
619               '    <api name="Movable Type" blogID="1" preferred="false" apiLink="'.$u.'"/>'."\n".
620               '    <api name="MetaWeblog" blogID="1" preferred="false" apiLink="'.$u.'"/>'."\n".
621               '    <api name="Blogger" blogID="1" preferred="false" apiLink="'.$u.'"/>'."\n".
622               "  </apis>\n";
623          }
624         
625          echo
626          "</service>\n".
627          "</rsd>\n";
628     }
629     
630     public static function xmlrpc($args)
631     {
632          $core =& $GLOBALS['core'];
633          $blog_id = preg_replace('#^([^/]*).*#','$1',$args);
634          $server = new dcXmlRpc($core,$blog_id);
635          $server->serve();
636     }
637}
638?>
Note: See TracBrowser for help on using the repository browser.

Sites map