Exemplo n.º 1
0
 /**
  * 独立页处理
  *
  * @access private
  * @param Typecho_Db_Query $select 查询对象
  * @param boolean $hasPushed 是否已经压入队列
  * @return void
  * @throws Typecho_Widget_Exception
  */
 private function singleHandle(Typecho_Db_Query $select, &$hasPushed)
 {
     if ('comment_page' == $this->parameter->type) {
         $params = array();
         $matched = Typecho_Router::match($this->request->permalink);
         if ($matched && $matched instanceof Widget_Archive && $matched->is('single')) {
             $this->import($matched);
             $hasPushed = true;
             return;
         }
     }
     /** 将这两个设置提前是为了保证在调用query的plugin时可以在插件中使用is判断初步归档类型 */
     /** 如果需要更细判断,则可以使用singleHandle来实现 */
     $this->_archiveSingle = true;
     /** 默认归档类型 */
     $this->_archiveType = 'single';
     /** 匹配类型 */
     if ('single' != $this->parameter->type) {
         $select->where('table.contents.type = ?', $this->parameter->type);
     }
     /** 如果是单篇文章或独立页面 */
     if (isset($this->request->cid)) {
         $select->where('table.contents.cid = ?', $this->request->filter('int')->cid);
     }
     /** 匹配缩略名 */
     if (isset($this->request->slug)) {
         $select->where('table.contents.slug = ?', $this->request->slug);
     }
     /** 匹配时间 */
     if (isset($this->request->year)) {
         $year = $this->request->filter('int')->year;
         $fromMonth = 1;
         $toMonth = 12;
         $fromDay = 1;
         $toDay = 31;
         if (isset($this->request->month)) {
             $fromMonth = $this->request->filter('int')->month;
             $toMonth = $fromMonth;
             $fromDay = 1;
             $toDay = date('t', mktime(0, 0, 0, $toMonth, 1, $year));
             if (isset($this->request->day)) {
                 $fromDay = $this->request->filter('int')->day;
                 $toDay = $fromDay;
             }
         }
         /** 获取起始GMT时间的unix时间戳 */
         $from = mktime(0, 0, 0, $fromMonth, $fromDay, $year) - $this->options->timezone + $this->options->serverTimezone;
         $to = mktime(23, 59, 59, $toMonth, $toDay, $year) - $this->options->timezone + $this->options->serverTimezone;
         $select->where('table.contents.created > ? AND table.contents.created < ?', $from, $to);
     }
     /** 保存密码至cookie */
     if ($this->request->isPost() && isset($this->request->protectPassword)) {
         $this->security->protect();
         Typecho_Cookie::set('protectPassword', $this->request->protectPassword, 0);
     }
     /** 匹配类型 */
     $select->limit(1);
     $this->query($select);
     if (!$this->have() || isset($this->request->category) && $this->category != $this->request->category || isset($this->request->directory) && $this->request->directory != implode('/', $this->directory)) {
         if (!$this->_invokeFromOutside) {
             /** 对没有索引情况下的判断 */
             throw new Typecho_Widget_Exception(_t('请求的地址不存在'), 404);
         } else {
             $hasPushed = true;
             return;
         }
     }
     /** 设置模板 */
     if ($this->template) {
         /** 应用自定义模板 */
         $this->_themeFile = $this->template;
     }
     /** 设置头部feed */
     /** RSS 2.0 */
     //对自定义首页使用全局变量
     if (!$this->_makeSinglePageAsFrontPage) {
         $this->_feedUrl = $this->feedUrl;
         /** RSS 1.0 */
         $this->_feedRssUrl = $this->feedRssUrl;
         /** ATOM 1.0 */
         $this->_feedAtomUrl = $this->feedAtomUrl;
         /** 设置标题 */
         $this->_archiveTitle = $this->title;
         /** 设置关键词 */
         $this->_keywords = implode(',', Typecho_Common::arrayFlatten($this->tags, 'name'));
         /** 设置描述 */
         $this->_description = $this->description;
     }
     /** 设置归档类型 */
     $this->_archiveType = $this->type;
     /** 设置归档缩略名 */
     $this->_archiveSlug = 'post' == $this->type || 'attachment' == $this->type ? $this->cid : $this->slug;
     /** 设置403头 */
     if ($this->hidden) {
         $this->response->setStatus(403);
     }
     $hasPushed = true;
     /** 插件接口 */
     $this->pluginHandle()->singleHandle($this, $select);
 }
Exemplo n.º 2
0
 /**
  * pingbackPing
  *
  * @param string $source
  * @param string $target
  * @access public
  * @return void
  */
 public function pingbackPing($source, $target)
 {
     /** 检查源地址是否存在*/
     if (!($http = Typecho_Http_Client::get())) {
         return new IXR_Error(16, _t('源地址服务器错误'));
     }
     try {
         $http->setTimeout(5)->send($source);
         $response = $http->getResponseBody();
         if (200 == $http->getResponseStatus()) {
             if (!$http->getResponseHeader('x-pingback')) {
                 preg_match_all("/<link[^>]*rel=[\"']([^\"']*)[\"'][^>]*href=[\"']([^\"']*)[\"'][^>]*>/i", $response, $out);
                 if (!isset($out[1]['pingback'])) {
                     return new IXR_Error(50, _t('源地址不支持PingBack'));
                 }
             }
         } else {
             return new IXR_Error(16, _t('源地址服务器错误'));
         }
     } catch (Exception $e) {
         return new IXR_Error(16, _t('源地址服务器错误'));
     }
     /** 检查目标地址是否正确*/
     $pathInfo = Typecho_Common::url(substr($target, strlen($this->options->index)), '/');
     $post = Typecho_Router::match($pathInfo);
     /** 这样可以得到cid或者slug*/
     if (!$post instanceof Widget_Archive || !$post->have() || !$post->is('single')) {
         return new IXR_Error(33, _t('这个目标地址不存在'));
     }
     if ($post) {
         /** 检查是否可以ping*/
         if ($post->allowPing) {
             /** 现在可以ping了,但是还得检查下这个pingback是否已经存在了*/
             $pingNum = $this->db->fetchObject($this->db->select(array('COUNT(coid)' => 'num'))->from('table.comments')->where('table.comments.cid = ? AND table.comments.url = ? AND table.comments.type <> ?', $post->cid, $source, 'comment'))->num;
             if ($pingNum <= 0) {
                 /** 现在开始插入以及邮件提示了 $response就是第一行请求时返回的数组*/
                 preg_match("/\\<title\\>([^<]*?)\\<\\/title\\>/is", $response, $matchTitle);
                 $finalTitle = Typecho_Common::removeXSS(trim(strip_tags($matchTitle[1])));
                 /** 干掉html tag,只留下<a>*/
                 $text = Typecho_Common::stripTags($response, '<a href="">');
                 /** 此处将$target quote,留着后面用*/
                 $pregLink = preg_quote($target);
                 /** 找出含有target链接的最长的一行作为$finalText*/
                 $finalText = '';
                 $lines = explode("\n", $text);
                 foreach ($lines as $line) {
                     $line = trim($line);
                     if (NULL != $line) {
                         if (preg_match("|<a[^>]*href=[\"']{$pregLink}[\"'][^>]*>(.*?)</a>|", $line)) {
                             if (strlen($line) > strlen($finalText)) {
                                 /** <a>也要干掉,*/
                                 $finalText = Typecho_Common::stripTags($line);
                             }
                         }
                     }
                 }
                 /** 截取一段字*/
                 if (NULL == trim($finalText)) {
                     return new IXR_Error('17', _t('源地址中不包括目标地址'));
                 }
                 $finalText = '[...]' . Typecho_Common::subStr($finalText, 0, 200, '') . '[...]';
                 $pingback = array('cid' => $post->cid, 'created' => $this->options->gmtTime, 'agent' => $this->request->getAgent(), 'ip' => $this->request->getIp(), 'author' => $finalTitle, 'url' => Typecho_Common::safeUrl($source), 'text' => $finalText, 'ownerId' => $post->author->uid, 'type' => 'pingback', 'status' => $this->options->commentsRequireModeration ? 'waiting' : 'approved');
                 /** 加入plugin */
                 $pingback = $this->pluginHandle()->pingback($pingback, $post);
                 /** 执行插入*/
                 $insertId = $this->singletonWidget('Widget_Abstract_Comments')->insert($pingback);
                 /** 评论完成接口 */
                 $this->pluginHandle()->finishPingback($this);
                 return $insertId;
                 /** todo:发送邮件提示*/
             } else {
                 return new IXR_Error(48, _t('PingBack已经存在'));
             }
         } else {
             return IXR_Error(49, _t('目标地址禁止Ping'));
         }
     } else {
         return new IXR_Error(33, _t('这个目标地址不存在'));
     }
 }
Exemplo n.º 3
0
 /**
  * 初始化函数
  *
  * @access public
  * @return void
  * @throws Typecho_Widget_Exception
  */
 public function action()
 {
     /** 回调方法 */
     $callback = $this->request->type;
     $this->_content = Typecho_Router::match($this->request->permalink);
     /** 判断内容是否存在 */
     if (false !== $this->_content && $this->_content instanceof Widget_Archive && $this->_content->have() && $this->_content->is('single') && in_array($callback, array('comment', 'trackback'))) {
         /** 如果文章不允许反馈 */
         if ('comment' == $callback) {
             /** 评论关闭 */
             if (!$this->_content->allow('comment')) {
                 throw new Typecho_Widget_Exception(_t('对不起,此内容的反馈被禁止.'), 403);
             }
             /** 检查来源 */
             if ($this->options->commentsCheckReferer && 'false' != $this->parameter->checkReferer) {
                 $referer = $this->request->getReferer();
                 if (empty($referer)) {
                     throw new Typecho_Widget_Exception(_t('评论来源页错误.'), 403);
                 }
                 $refererPart = parse_url($referer);
                 $currentPart = parse_url($this->_content->permalink);
                 if ($refererPart['host'] != $currentPart['host'] || 0 !== strpos($refererPart['path'], $currentPart['path'])) {
                     //自定义首页支持
                     if ('page:' . $this->_content->cid == $this->options->frontPage) {
                         $currentPart = parse_url(rtrim($this->options->siteUrl, '/') . '/');
                         if ($refererPart['host'] != $currentPart['host'] || 0 !== strpos($refererPart['path'], $currentPart['path'])) {
                             throw new Typecho_Widget_Exception(_t('评论来源页错误.'), 403);
                         }
                     } else {
                         throw new Typecho_Widget_Exception(_t('评论来源页错误.'), 403);
                     }
                 }
             }
             /** 检查ip评论间隔 */
             if (!$this->user->pass('editor', true) && $this->_content->authorId != $this->user->uid && $this->options->commentsPostIntervalEnable) {
                 $latestComment = $this->db->fetchRow($this->db->select('created')->from('table.comments')->where('cid = ?', $this->_content->cid)->order('created', Typecho_Db::SORT_DESC)->limit(1));
                 if ($latestComment && ($this->options->gmtTime - $latestComment['created'] > 0 && $this->options->gmtTime - $latestComment['created'] < $this->options->commentsPostInterval)) {
                     throw new Typecho_Widget_Exception(_t('对不起, 您的发言过于频繁, 请稍侯再次发布.'), 403);
                 }
             }
         }
         /** 如果文章不允许引用 */
         if ('trackback' == $callback && !$this->_content->allow('ping')) {
             throw new Typecho_Widget_Exception(_t('对不起,此内容的引用被禁止.'), 403);
         }
         /** 调用函数 */
         $this->{$callback}();
     } else {
         throw new Typecho_Widget_Exception(_t('找不到内容'), 404);
     }
 }