Dotclear

source: inc/public/lib.urlhandlers.php @ 779:58c45f1b96e5

Revision 779:58c45f1b96e5, 16.3 KB checked in by Dsls <dsls@…>, 14 years ago (diff)

Small fixes since [777], notices should not appear now...

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

Sites map