summaryrefslogtreecommitdiffstats
path: root/libs
diff options
context:
space:
mode:
authorEltrac <45323514+BigCoke233@users.noreply.github.com>2019-07-11 18:55:48 +0800
committerGitHub <noreply@github.com>2019-07-11 18:55:48 +0800
commit27efb0e429817141e6009f0aefc79bdea17890fa (patch)
tree219d496cd79eebc34e2926672c139d19fb761563 /libs
parent79f92a1658063b9edbe2a1a9bd7a3dc57e1ce420 (diff)
🙉 The first release of Miracles 🙉
Diffstat (limited to 'libs')
-rw-r--r--libs/Contents.php143
-rw-r--r--libs/Utils.php164
2 files changed, 307 insertions, 0 deletions
diff --git a/libs/Contents.php b/libs/Contents.php
new file mode 100644
index 0000000..a5a2da7
--- /dev/null
+++ b/libs/Contents.php
@@ -0,0 +1,143 @@
+<?php if (!defined('__TYPECHO_ROOT_DIR__')) exit;
+
+class Contents
+{
+ /**
+ * 内容解析器入口
+ * 传入的是经过 Markdown 解析后的文本
+ */
+ static public function parseContent($text)
+ {
+ $text = preg_replace('/<pre><code>/s','<pre><code class="language-html">',$text);
+ $text = preg_replace('/<img(.*?)src="(.*?)"(.*?)alt="(.*?)"(.*?)>/s','<center><a data-fancybox="gallery" href="${2}" class="gallery-link"><img${1}src="${2}"${3}></a></center>',$text);
+
+ //解析友链盒子
+ $reg = '/\[links\](.*?)\[\/links\]/s';
+ $rp = '<div class="links-box container-fluid"><div class="row">${1}</div></div>';
+ $text = preg_replace($reg,$rp,$text);
+
+ //解析友链项目
+ $reg = '/\[(.*?)\]\{(.*?)\}\((.*?)\)/s';
+ $rp = '<div class="col-md-2 col-xs-4 col-sm-3">
+ <a href="${2}" target="_blank" class="links-link">
+ <div class="links-item">
+ <div class="links-img" style="background:url(\'${3}\');width: 100%;padding-top: 100%;background-repeat: no-repeat;background-size: cover;"></div>
+ <div class="links-title">
+ <h4>${1}</h4>
+ </div>
+ </div>
+ </a>
+ </div>';
+ $text = preg_replace($reg,$rp,$text);
+
+ return $text;
+ }
+
+ /**
+ * 根据 id 返回对应的对象
+ * 此方法在 Typecho 1.2 以上可以直接调用 Helper::widgetById();
+ * 但是 1.1 版本尚有 bug,因此单独提出放在这里
+ *
+ * @param string $table 表名, 支持 contents, comments, metas, users
+ * @return Widget_Abstract
+ */
+ public static function widgetById($table, $pkId)
+ {
+ $table = ucfirst($table);
+ if (!in_array($table, array('Contents', 'Comments', 'Metas', 'Users'))) {
+ return NULL;
+ }
+ $keys = array(
+ 'Contents' => 'cid',
+ 'Comments' => 'coid',
+ 'Metas' => 'mid',
+ 'Users' => 'uid'
+ );
+ $className = "Widget_Abstract_{$table}";
+ $key = $keys[$table];
+ $db = Typecho_Db::get();
+ $widget = new $className(Typecho_Request::getInstance(), Typecho_Widget_Helper_Empty::getInstance());
+
+ $db->fetchRow(
+ $widget->select()->where("{$key} = ?", $pkId)->limit(1),
+ array($widget, 'push'));
+ return $widget;
+ }
+
+ /**
+ * 输出完备的标题
+ */
+ public static function title(Widget_Archive $archive)
+ {
+ $archive->archiveTitle(array(
+ 'category' => '分类 %s 下的文章',
+ 'search' => '包含关键字 %s 的文章',
+ 'tag' => '标签 %s 下的文章',
+ 'author' => '%s 发布的文章'
+ ), '', ' - ');
+ Helper::options()->title();
+ }
+
+ /**
+ * 返回上一篇文章
+ */
+ public static function getPrev($archive)
+ {
+ $db = Typecho_Db::get();
+ $content = $db->fetchRow($db->select()->from('table.contents')->where('table.contents.created < ?', $archive->created)
+ ->where('table.contents.status = ?', 'publish')
+ ->where('table.contents.type = ?', $archive->type)
+ ->where('table.contents.password IS NULL')
+ ->order('table.contents.created', Typecho_Db::SORT_DESC)
+ ->limit(1));
+
+ if($content) {
+ return self::widgetById('Contents', $content['cid']);
+ }else{
+ return NULL;
+ }
+ }
+
+ /**
+ * 返回下一篇文章
+ */
+ public static function getNext($archive)
+ {
+ $db = Typecho_Db::get();
+ $content = $db->fetchRow($db->select()->from('table.contents')->where('table.contents.created > ? AND table.contents.created < ?',
+ $archive->created, Helper::options()->gmtTime)
+ ->where('table.contents.status = ?', 'publish')
+ ->where('table.contents.type = ?', $archive->type)
+ ->where('table.contents.password IS NULL')
+ ->order('table.contents.created', Typecho_Db::SORT_ASC)
+ ->limit(1));
+
+ if($content) {
+ return self::widgetById('Contents', $content['cid']);
+ }else{
+ return NULL;
+ }
+ }
+
+ /**
+ * 最近评论,过滤引用通告,过滤博主评论
+ */
+ public static function getRecentComments($num = 10)
+ {
+ $comments = array();
+
+ $db = Typecho_Db::get();
+ $rows = $db->fetchAll($db->select()->from('table.comments')->where('table.comments.status = ?', 'approved')
+ ->where('type = ?', 'comment')
+ ->where('ownerId <> authorId')
+ ->order('table.comments.created', Typecho_Db::SORT_DESC)
+ ->limit($num));
+
+ foreach ($rows as $row) {
+ $comment = self::widgetById('Comments', $row['coid']);
+ $comments[] = $comment;
+ }
+
+ return $comments;
+ }
+} \ No newline at end of file
diff --git a/libs/Utils.php b/libs/Utils.php
new file mode 100644
index 0000000..7330122
--- /dev/null
+++ b/libs/Utils.php
@@ -0,0 +1,164 @@
+<?php
+/**
+ * Utils.php
+ *
+ * 提供某些 Typecho 方法的封装,以及一些常用方法实现
+ *
+ * @author 熊猫小A
+ */
+if (!defined('__TYPECHO_ROOT_DIR__')) exit;
+
+class Utils
+{
+ /**
+ * 输出相对首页路由,本方法会自适应伪静态,用于动态文件
+ */
+ public static function index($path = '')
+ {
+ Helper::options()->index($path);
+ }
+
+ /**
+ * 输出相对首页路径,本方法用于静态文件
+ */
+ public static function indexHome($path = '')
+ {
+ Helper::options()->siteUrl($path);
+ }
+
+ /**
+ * 输出相对主题目录路径,用于静态文件
+ */
+ public static function indexTheme($path = '')
+ {
+ Helper::options()->themeUrl($path);
+ }
+
+ /**
+ * 根据邮箱返回 Gravatar 头像链接
+ */
+ public static function gravatar($mail, $size = 64, $d = '')
+ {
+ return Typecho_Common::gravatarUrl($mail, $size, '', urlencode($d), true);
+ }
+
+ /**
+ * 判断插件是否可用(存在且已激活)
+ */
+ public static function hasPlugin($name)
+ {
+ $plugins = Typecho_Plugin::export();
+ $plugins = $plugins['activated'];
+ return is_array($plugins) && array_key_exists($name, $plugins);
+ }
+
+ /**
+ * 判断移动端请求
+ */
+ public static function isMobile()
+ {
+ if (isset ($_SERVER['HTTP_X_WAP_PROFILE'])){
+ return TRUE;
+ }
+
+ if (isset ($_SERVER['HTTP_USER_AGENT'])) {
+ $clientkeywords = array ('mobile','nokia','sony','ericsson','mot','samsung','htc','sgh','lg','sharp','sie-','philips','panasonic','alcatel','lenovo','iphone','ipod','blackberry','meizu','android','netfront','symbian','ucweb','windowsce','palm','operamini','operamobi','openwave','nexusone','cldc','midp','wap'
+ );
+ if (preg_match("/(" . implode('|', $clientkeywords) . ")/i", strtolower($_SERVER['HTTP_USER_AGENT']))){
+ return TRUE;
+ }
+ }
+ if (isset ($_SERVER['HTTP_ACCEPT'])){
+ if ((strpos($_SERVER['HTTP_ACCEPT'], 'vnd.wap.wml') !== FALSE) && (strpos($_SERVER['HTTP_ACCEPT'], 'text/html') === FALSE || (strpos($_SERVER['HTTP_ACCEPT'], 'vnd.wap.wml') < strpos($_SERVER['HTTP_ACCEPT'], 'text/html')))){
+ return TRUE;
+ }
+ }
+ return FALSE;
+ }
+
+ /**
+ * 判定电脑端微信内置浏览器
+ */
+ public static function isWeixin()
+ {
+ return !self::isMobile() && strpos($_SERVER['HTTP_USER_AGENT'], 'MicroMessenger') !== false;
+ }
+
+ /**
+ * 判定内容是否过时
+ * $timeout:过期时间,单位为天
+ */
+ public static function isOutdated($archive, $timeout)
+ {
+ date_default_timezone_set("Asia/Shanghai");
+ return round((time()- $archive->created) / 3600 / 24) > $timeout;
+ }
+
+ /**
+ * 输出建站时间(最早一篇文章的写作时间)
+ */
+ public static function getBuildTime()
+ {
+ date_default_timezone_set("Asia/Shanghai");
+ $db = Typecho_Db::get();
+ $content = $db->fetchRow($db->select()->from('table.contents')
+ ->where('table.contents.status = ?', 'publish')
+ ->where('table.contents.password IS NULL')
+ ->order('table.contents.created', Typecho_Db::SORT_ASC)
+ ->limit(1));
+ return $content['created'];
+ }
+
+ /**
+ * 已发布文章数量
+ */
+ public static function getPostNum()
+ {
+ $db = Typecho_Db::get();
+ return $db->fetchObject($db->select(array('COUNT(cid)' => 'num'))
+ ->from('table.contents')
+ ->where('table.contents.type = ?', 'post')
+ ->where('table.contents.status = ?', 'publish'))->num;
+ }
+
+ /**
+ * 分类数量
+ */
+ public static function getCatNum()
+ {
+ $db = Typecho_Db::get();
+ return $db->fetchObject($db->select(array('COUNT(mid)' => 'num'))
+ ->from('table.metas')
+ ->where('table.metas.type = ?', 'category'))->num;
+ }
+
+ /**
+ * 标签数量
+ */
+ public static function getTagNum()
+ {
+ $db = Typecho_Db::get();
+ return $db->fetchObject($db->select(array('COUNT(mid)' => 'num'))
+ ->from('table.metas')
+ ->where('table.metas.type = ?', 'tag'))->num;
+ }
+
+ /**
+ * 总字数
+ *
+ * @return int
+ */
+ public static function getWordCount()
+ {
+ $db = Typecho_Db::get();
+ $posts = $db->fetchAll($db->select('table.contents.text')
+ ->from('table.contents')
+ ->where('table.contents.type = ?', 'post')
+ ->where('table.contents.status = ?', 'publish'));
+ $total = 0;
+ foreach ($posts as $post) {
+ $total = $total + mb_strlen(preg_replace("/[^\x{4e00}-\x{9fa5}]/u", "", $post['text']), 'UTF-8');
+ }
+ return $total;
+ }
+}