Dotclear

source: inc/public/lib.urlhandlers.php @ 775:26f00250445c

Revision 775:26f00250445c, 16.3 KB checked in by Dsls <dsls@…>, 14 years ago (diff)

Fixed $url checking in getURLFor, thanks adjaya.

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

Sites map