Dotclear

Changeset 3692:9decf2422f49


Ignore:
Timestamp:
01/31/18 14:48:07 (6 years ago)
Author:
franck <carnet.franck.paul@…>
Branch:
default
Message:

PHP 7.2 compliance (deprecated each() replaced by foreach…)

Files:
2 edited

Legend:

Unmodified
Added
Removed
  • .hgsubstate

    r3691 r3692  
    1 78ca5055b490dca43fa8fbcc780343eb9a23531b inc/libs/clearbricks 
     1483f257f02e5236ed447e603e3496fdcd82676f8 inc/libs/clearbricks 
  • inc/public/lib.urlhandlers.php

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

Sites map