summaryrefslogtreecommitdiffstats
path: root/libs
diff options
context:
space:
mode:
authorBigCoke233 <hi@guhub.cn>2020-07-30 23:49:46 +0800
committerBigCoke233 <hi@guhub.cn>2020-07-30 23:49:46 +0800
commit52ab9c1909f39c8854e8235cddd351ef72505e91 (patch)
tree0d8de56dc167919197d9567578430c106e996c1e /libs
parent23c8e8fed64c5995101cc9ceb08706d8849b0a3c (diff)
:fire: Del: 移除旧版本所有文件,准备 2.0 版本
Diffstat (limited to 'libs')
-rw-r--r--libs/Comments.php51
-rw-r--r--libs/Contents.php448
-rw-r--r--libs/Language.php41
-rwxr-xr-xlibs/Options.php213
-rw-r--r--libs/TableContents.php0
-rw-r--r--libs/TimThumb.php1251
-rw-r--r--libs/Utils.php281
-rw-r--r--libs/lang/en-us.php82
-rw-r--r--libs/lang/moe.php93
-rw-r--r--libs/lang/zh-cn.php92
-rw-r--r--libs/lang/zh-tw.php93
11 files changed, 0 insertions, 2645 deletions
diff --git a/libs/Comments.php b/libs/Comments.php
deleted file mode 100644
index 1e4cb7e..0000000
--- a/libs/Comments.php
+++ /dev/null
@@ -1,51 +0,0 @@
-<?php
-/**
- * Comments.php
- * 评论处理
- *
- * Author: Eltrac(BigCoke233)
- * License: MIT
- */
-if (!defined('__TYPECHO_ROOT_DIR__')) exit;
-class Comments
-{
- /**
- * 评论反垃圾
- * from ohmyga233/castle-Typecho-Theme
- *
- * @access public
- */
- public static function AntiSpam($id, $value) {
- echo '<!--<nocompress>-->';
- echo '<script>(function(){var a=document.addEventListener?{add:"addEventListener",focus:"focus",load:"DOMContentLoaded"}:{add:"attachEvent",focus:"onfocus",load:"onload"};var c,d,e,f,b=document.getElementById("'.$id.'");null!=b&&(c=b.getElementsByTagName("form"),c.length>0&&(d=c[0],e=d.getElementsByTagName("textarea")[0],f=!1,null!=e&&"text"==e.name&&e[a.add](a.focus,function(){if(!f){var a=document.createElement("input");a.type="hidden",a.name="_",d.appendChild(a),f=!0,a.value='.$value.'}})))})();</script>';
- echo '<!--</nocompress>-->';
- }
-
- /**
- * 获取上级评论人
- */
- public static function getCommentHF($coid){
- $db = Typecho_Db::get();
- $prow = $db->fetchRow($db->select('parent')
- ->from('table.comments')
- ->where('coid = ? AND status = ?', $coid, 'approved'));
- $parent = $prow['parent'];
- if ($parent != "0") {
- $arow = $db->fetchRow($db->select('text','author','status')
- ->from('table.comments')
- ->where('coid = ?', $parent));
- $author = $arow['author'];
- $status = $arow['status'];
- if($author){
- if($status=='approved'){
- $href = '<a class="at" uid="'.$parent.'" href="#li-comment-'.$parent.'">@'.$author.'</a>';;
- }else if($status=='waiting'){
- $href = '<a>评论审核中···</a>';
- }
- }
- echo $href;
- } else {
- echo "";
- }
- }
-}
diff --git a/libs/Contents.php b/libs/Contents.php
deleted file mode 100644
index b1b8db9..0000000
--- a/libs/Contents.php
+++ /dev/null
@@ -1,448 +0,0 @@
-<?php
-/**
- * Contents.php
- * 内容处理
- *
- * Author: Eltrac(BigCoke233)
- * License: MIT
- * Notice: Parts of codes are from AlanDecode/Typecho-Theme-VOID
- */
-
-if (!defined('__TYPECHO_ROOT_DIR__')) exit;
-class Contents
-{
- /* == 解析文章内容 == */
-
- /**
- * 内容解析器入口
- * 传入的是经过 Markdown 解析后的文本
- */
- static public function parseContent($data, $widget, $last){
- $db=Typecho_Db::get();
- $load_image = $db->fetchAll($db->select('value')->from('table.options')->where('name = %s', "theme:Miracles")->limit(1));
- $load_image = explode("\";",explode("\"",explode("\"loading_image\";",$load_image[0]["value"],2)[1],2)[1],2)[0];
- $text = empty($last) ? $data : $last;
- if ($widget instanceof Widget_Archive) {
- //ParseOther
- $text = Contents::parseDetails(Contents::parsePicShadow(Contents::parseNotice(Contents::parseKbd(Contents::parseCode(Contents::parseImages(Contents::parseHeadings(Contents::parseTextColor(Contents::parseRuby(Contents::parseTip($text))))))))));
- //LazyLoad
- $text = preg_replace('/<img (.*?)src(.*?)(\/)?>/','<img $1src="'.Utils::addLoadingImages($GLOBALS['miraclesOptions_CDN'], $GLOBALS['miraclesOptions_loading_image'], 'normal').'" data-gisrc$2 data-gazeimg />',$text);
- //owo
- $text = Contents::parseEmo($text);
- //Links
- $text = Contents::parseLink($text);
- //toc
- $text = preg_replace('/{:toc:}/s', '<div class="toc-box">'.Contents::tableOfContents($text).'</div>', $text);
- }
- return $text;
- }
-
- /**
- * 解析图片
- */
- static public function parseImages($text){
- //FancyBox & 图题
- $text = preg_replace('/<img(.*?)src="(.*?)"(.*?)alt="(.*?)"(.*?)>/s','<center><img${1}src="${2}"${3}><span class="post-img-alt">${4}</span></center>',$text);
-
- return $text;
- }
-
- /**
- * 解析 Text-Color
- */
- static public function parseTextColor($text){
- $text = preg_replace('/\&\{(.*?)\|(.*?)\|(.*?)\}/s','<span style="color:${2};background:${3}">${1}</span>',$text);
- return $text;
- }
-
- /**
- * 解析 Ruby
- */
- static public function parseRuby($text){
- $reg = '/\{\{(.*?):(.*?)\}\}/s';
- $rp = '<ruby>${1}<rp>(</rp><rt>${2}</rt><rp>)</rp></ruby>';
- $text = preg_replace($reg,$rp,$text);
-
- return $text;
- }
-
- /**
- * 解析 Tip
- */
- static public function parseTip($text){
- //Tip without var
- $text = preg_replace('/\[tip\](.*?)\[\/tip\]/s','<div class="tip"><div class="container-fluid"><div class="row"><div class="col-1 tip-icon"><i class="iconfont icon-info"></i></div><div class="col-11 tip-content">${1}</div></div></div></div>',$text);
- //Tip
- $text = preg_replace('/\[tip type="(.*?)"\](.*?)\[\/tip\]/s','<div class="tip ${1}"><div class="container-fluid"><div class="row"><div class="col-1 tip-icon"><i class="iconfont icon-info"></i></div><div class="col-11 tip-content">${2}</div></div></div></div>',$text);
- //Tip Group
- $text = preg_replace('/\[tip\-group\](.*?)\[\/tip\-group\]/s','<div class="tip-group">${1}</div>',$text);
-
- return $text;
- }
-
- /**
- * 解析 Notice
- */
- static public function parseNotice($text){
- $text = preg_replace('/\[notice\](.*?)\[\/notice\]/s','<div class="notice" role="note">${1}</div>',$text);
- return $text;
- }
-
- /**
- * 图片加阴影
- */
- static public function parsePicShadow($text){
- $text = preg_replace('/\[shadow\](.*?)\[\/shadow\]/s','<div class="post-img-shadow">${1}</div>',$text);
- return $text;
- }
-
- /**
- * 解析友链
- */
- static public function parseLink($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-lg-2 col-6 col-md-3 links-container">
- <a href="${2}" title="${4}" target="_blank" class="links-link">
- <div class="links-item">
- <div class="links-img"><img src="'.Utils::addLoadingImages($GLOBALS['miraclesOptions_CDN'], $GLOBALS['miraclesOptions_loading_image'], 'link').'" data-gisrc=\'${3}\'></div>
- <div class="links-title">
- <h4>${1}</h4>
- </div>
- </div>
- </a>
- </div>';
- $text = preg_replace($reg, $rp, $text);
- //解析外部友链
- $reg = '/\[links data="(.*?)"\]/';
- $dataLink = preg_match_all($reg, $text, $matches);
- if (!$dataLink) return $text; //普通文章别匹配!
- $http = Typecho_Http_Client::get();
- if (false == $http) {
- $text = str_replace($matches[0][0], '<br>对不起, 您的主机不支持 php-curl 扩展而且没有打开 allow_url_fopen 功能, 无法正常使 json 友链功能', $text);
- return $text;
- }
- for ($j = 0; $j <= $dataLink; $j++) {
- $match = $matches[1][$j];
- try {
- $result = $http->send($match);
- } catch (Typecho_Http_Client_Exception $ex) {
- $text = str_replace($matches[0][$j], '对不起,json外链请求失败! 错误信息:' . $ex->getMessage(), $text);
- continue;
- }
- $data = json_decode($result, true);
- if ($data == false) {//没获取到数据就别走了!赶紧返回免得搞出事情
- $text = str_replace($matches[0][$j], '对不起,json外链解析失败!', $text);
- continue;
- }
- $linkItemNum = count($data);
- $linksList = '';//先Define一下,IDE在报错QAQ
- for ($i = 0; $i < $linkItemNum; $i++) {
- $name = $data[$i]['name'];
- $link = $data[$i]['link'];
- $avatar = $data[$i]['avatar'];
- $des = $data[$i]['des'];
- //嵌入列表
- $linksList .= '<div class="col-lg-2 col-6 col-md-3 links-container">
- <a href="' . $link . '" title="' . $des . '" target="_blank" class="links-link">
- <div class="links-item">
- <div class="links-img"><img src="/usr/themes/Miracles/images/loading/avatar.jpg" data-gisrc=\''.$avatar.'\'></div>
- <div class="links-title">
- <h4>' . $name . '</h4>
- </div>
- </div>
- </a>
- </div>';
- }
- $text = str_replace($matches[0][$j], '<div class="links-box container-fluid"><div class="row">' . $linksList . '</div></div>', $text);
- }
- return $text;
- }
-
- /**
- * 解析 owo 表情
- */
- static public function parseEmo($content) {
- $content = preg_replace_callback('/\:\:\(\s*(呵呵|哈哈|吐舌|太开心|笑眼|花心|小乖|乖|捂嘴笑|滑稽|你懂的|不高兴|怒|汗|黑线|泪|真棒|喷|惊哭|阴险|鄙视|酷|啊|狂汗|what|疑问|酸爽|呀咩爹|委屈|惊讶|睡觉|笑尿|挖鼻|吐|犀利|小红脸|懒得理|勉强|爱心|心碎|玫瑰|礼物|彩虹|太阳|星星月亮|钱币|茶杯|蛋糕|大拇指|胜利|haha|OK|沙发|手纸|香蕉|便便|药丸|红领巾|蜡烛|音乐|灯泡|开心|钱|咦|呼|冷|生气|弱|吐血)\s*\)/is',
- array('Contents', 'parsePaopaoBiaoqingCallback'), $content);
- $content = preg_replace_callback('/\:\@\(\s*(高兴|小怒|脸红|内伤|装大款|赞一个|害羞|汗|吐血倒地|深思|不高兴|无语|亲亲|口水|尴尬|中指|想一想|哭泣|便便|献花|皱眉|傻笑|狂汗|吐|喷水|看不见|鼓掌|阴暗|长草|献黄瓜|邪恶|期待|得意|吐舌|喷血|无所谓|观察|暗地观察|肿包|中枪|大囧|呲牙|抠鼻|不说话|咽气|欢呼|锁眉|蜡烛|坐等|击掌|惊喜|喜极而泣|抽烟|不出所料|愤怒|无奈|黑线|投降|看热闹|扇耳光|小眼睛|中刀)\s*\)/is',
- array('Contents', 'parseAruBiaoqingCallback'), $content);
- $content = preg_replace_callback('/\:\&\(\s*(.*?)\s*\)/is',
- array('Contents', 'parseTweBiaoqingCallback'), $content);
-
- return $content;
- }
-
- /**
- * 泡泡表情回调函数
- *
- * @return string
- */
- private static function parsePaopaoBiaoqingCallback($match)
- {
- return '<img class="owo-img" src="'.Utils::addLoadingImages($GLOBALS['miraclesOptions_CDN'], $GLOBALS['miraclesOptions_loading_image'], 'owo').'" data-gisrc="/usr/themes/Miracles/images/biaoqing/paopao/'. str_replace('%', '', urlencode($match[1])) . '_2x.png">';
- }
-
- /**
- * 阿鲁表情回调函数
- *
- * @return string
- */
- private static function parseAruBiaoqingCallback($match)
- {
- return '<img class="owo-img" src="'.Utils::addLoadingImages($GLOBALS['miraclesOptions_CDN'], $GLOBALS['miraclesOptions_loading_image'], 'owo').'" data-gisrc="/usr/themes/Miracles/images/biaoqing/aru/'. str_replace('%', '', urlencode($match[1])) . '_2x.png">';
- }
-
- /**
- * 推特表情回调函数
- *
- * @return string
- */
- private static function parseTweBiaoqingCallback($match)
- {
- return '<img class="owo-img" src="'.Utils::addLoadingImages($GLOBALS['miraclesOptions_CDN'], $GLOBALS['miraclesOptions_loading_image'], 'owo').'" data-gisrc="/usr/themes/Miracles/images/biaoqing/twemoji/'. str_replace('%', '', $match[1]) . '.png">';
- }
-
- /**
- * 解析代码块
- */
- static public function parseCode($text) {
- $text = preg_replace('/<pre><code>/s','<pre><code class="language-html">',$text);
- return $text;
- }
-
- /**
- * 解析键盘按键
- */
- static public function parseKbd($text) {
- $text = preg_replace('/\[\[(.*?)\]\]/s','<kbd>${1}</kbd>',$text);
- return $text;
- }
-
- /**
- * 解析 <details>
- */
- static public function parseDetails($text) {
- $text = preg_replace('/\[details sum="(.*?)"\](.*?)\[\/details\]/s','<details><summary>${1}</summary>${2}</details>',$text);
- return $text;
- }
-
- /* == 文章目录 == */
-
- /**
- * 解析章节链接
- */
- static public function parseHeadings($text){
- $reg='/\<h([2-3])(.*?)\>(.*?)\<\/h.*?\>/s';
- $text = preg_replace_callback($reg, array('Contents', 'parseHeaderCallback'), $text);
-
- return $text;
- }
-
- /**
- * 为内容中的标题编号
- */
- static private $CurrentTocID = 0;
- static public function parseHeaderCallback($matchs)
- {
- $id = trim($matchs[3]);
- return '<h'.$matchs[1].$matchs[2].' id="'.$id.'">'.$matchs[3].'<a href="#'.$id.'" title="'.$GLOBALS['postTexts']['post_anchor'].'" class="post-toc-link no-line"><i class="iconfont icon-paragraph"></i></a></h'.$matchs[1].'>';
- }
-
- /**
- * 文章目录
- */
- public static function tableOfContents($html) {
- $pattern = '/<h([2-5]) id=["\'](.*?)["\'].*?>(.*?)<\/h\1>/';
- preg_match_all($pattern, $html, $matches, PREG_SET_ORDER);
- $output = "";
- foreach ($matches as $item) {
- $output .= '
- <li class="toc-level-' . $item[1] . '">
- <a href="#' . $item[2] . '">' . $item[3] . '</a>
- </li>';
- }
- return (!empty($output)) ?
- "<ul class='toc'>" . $output . "</ul>" :
- "";
- }
-
- /* == 其他内容 == */
-
- /**
- * 解析自定义导航栏
- */
- static public function parseNav($data, $type) {
- $de_json = json_decode($data, true);
- $count_json = count($de_json);
- for ($i = 0; $i < $count_json; $i++) {
- $title = $de_json[$i]['title'];
- $link = $de_json[$i]['link'];
- //输出导航
- if($type=="top-nav") {
- echo '<a href="'. $link .'">'. $title .'</a>';
- }
- elseif($type=="mobile") {
- echo '<div class="col-6"><a href="'. $link .'">'. $title .'</a></div>';
- }
- elseif($type=="drawer") {
- echo '<a href="'. $link .'" onclick="toggleDrawer()">'. $title .'</a>';
- }
- }
- }
-
- static public function parseNavIcon($data, $type) {
- $de_json = json_decode($data, true);
- $count_json = count($de_json);
- for ($i = 0; $i < $count_json; $i++) {
- $icon = $de_json[$i]['icon'];
- $link = $de_json[$i]['link'];
- $action = $de_json[$i]['action'];
- //定义 class
- if($type=="top-nav"){
- $class = 'nav-icon-button';
- }
- elseif($type=="drawer"){
- $class = 'drawer-icon';
- }
- elseif($type=="mobile"){
- $class = 'nav-mobile-icon';
- }
- else{
- $class= 'unknown';
- }
- if($de_json[$i]['class']) $class.= ' '.$de_json[$i]['class'];//自定义 class
- //计算 right 距离
- $right_more=$i*45;
- $right=20+$right_more;
- //添加 $other
- if($type=="top-nav") $other=' style="right: '.$right.'px"';
- //输出导航图标按钮
- if($type=="top-nav"||$type=="drawer"){
- if(!$action): echo '<a href="'.$link.'" class="'.$class.'"'.$other.'><i class="iconfont icon-'.$icon.'"></i></a>';
- else: echo '<button class="'.$class.'" onclick="'.$action.'"'.$other.'><i class="iconfont icon-'.$icon.'"></i></button>';
- endif;
- }
- elseif($type=="mobile"){
- if(!$action): echo '<a style="float:left" href="'.$link.'"'.$other.'><i class="iconfont icon-'.$icon.'"></i></a>';
- else: echo '<a style="float:left" onclick="'.$action.'"'.$other.'><i class="iconfont icon-'.$icon.'"></i></a>';
- endif;
- }
- }
- }
-
- /**
- * 根据 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 archives($widget) {
- $db = Typecho_Db::get();
- $rows = $db->fetchAll($db->select()
- ->from('table.contents')
- ->order('table.contents.created', Typecho_Db::SORT_DESC)
- ->where('table.contents.type = ?', 'post')
- ->where('table.contents.status = ?', 'publish'));
-
- $stat = array();
- foreach ($rows as $row) {
- $row = $widget->filter($row);
- $arr = array(
- 'title' => $row['title'],
- 'permalink' => $row['permalink']
- );
- $stat[date('Y', $row['created'])][$row['created']] = $arr;
- }
- return $stat;
- }
-
- /**
- * 统计文章浏览数
- * from:http://docs.qqdie.com/
- */
- public static function postViews($archive) {
- $cid = $archive->cid;
- $db = Typecho_Db::get();
- $prefix = $db->getPrefix();
- if (!array_key_exists('views', $db->fetchRow($db->select()->from('table.contents')))) {
- $db->query('ALTER TABLE `' . $prefix . 'contents` ADD `views` INT(10) DEFAULT 0;');
- echo 0;
- return;
- }
- $row = $db->fetchRow($db->select('views')->from('table.contents')->where('cid = ?', $cid));
- if ($archive->is('single')) {
- $views = Typecho_Cookie::get('extend_contents_views');
- if(empty($views)){
- $views = array();
- }else{
- $views = explode(',', $views);
- }
- if(!in_array($cid,$views)){
- $db->query($db->update('table.contents')->rows(array('views' => (int) $row['views'] + 1))->where('cid = ?', $cid));
- array_push($views, $cid);
- $views = implode(',', $views);
- Typecho_Cookie::set('extend_contents_views', $views); //记录查看cookie
- }
- }
- return $row['views'];
- }
-
- /**
- * 获取最早文章创建时间
- */
- public static function getOldestPostDate() {
- $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 date('Y-m-d', $content['created']);
- }
-} \ No newline at end of file
diff --git a/libs/Language.php b/libs/Language.php
deleted file mode 100644
index d24ae77..0000000
--- a/libs/Language.php
+++ /dev/null
@@ -1,41 +0,0 @@
-<?php
-if (!defined('__TYPECHO_ROOT_DIR__')) exit;
-
-/**
- * Language.php
- * 多语言 / 多語言 / Multi-Languages
- *
- * Author: Eltrac(BigCoke233)
- * License: MIT
- */
-
-class Lang
-{
- public static function getLang() {
- $provided_lang = glob(Helper::options()->themeFile("lang/*.php"));
- if(in_array($GLOBALS['miraclesLang'].'.php', $provided_lang)){
- require_once("lang/"+$GLOBALS['miraclesLang'].".php");
- $GLOBALS['miraclesLangError']=false;
- }else{
- require_once("lang/zh-cn.php");
- $GLOBALS['miraclesLangError']=true;
- }
- }
-}
-
-//快速获取对应语言文本
-function gt($a, $b) {
- return $GLOBALS[$a][$b];
-}
-function gtecho($a, $b) {
- echo $GLOBALS[$a][$b];
-}
-//有参数的文本获取
-function gta($a, $b, $c) {
- $content = str_replace('%s', $c, $GLOBALS[$a][$b]);
- return $content;
-}
-function gtaecho($a, $b, $c) {
- $content = str_replace('%s', $c, $GLOBALS[$a][$b]);
- echo $content;
-} \ No newline at end of file
diff --git a/libs/Options.php b/libs/Options.php
deleted file mode 100755
index cda0f9e..0000000
--- a/libs/Options.php
+++ /dev/null
@@ -1,213 +0,0 @@
-<?php
-/**
- * Options.php
- * 主题后台设置
- *
- * Author: Eltrac(BigCoke233)
- * License: MIT
- */
-function themeConfig($form) {
-
- /**
- * 主题设置备份
- * From https://qqdie.com/archives/typecho-templates-backup-and-restore.html
- */
- $str1 = explode('/themes/', Helper::options()->themeUrl);
- $str2 = explode('/', $str1[1]);
- $name=$str2[0];
- $db = Typecho_Db::get();
- $sjdq=$db->fetchRow($db->select()->from ('table.options')->where ('name = ?', 'theme:'.$name));
- $ysj = $sjdq['value'];
- if(isset($_POST['type'])){
- if($_POST["type"]=="备份模板设置数据"){
- if($db->fetchRow($db->select()->from ('table.options')->where ('name = ?', 'theme:'.$name.'bf'))){
- $update = $db->update('table.options')->rows(array('value'=>$ysj))->where('name = ?', 'theme:'.$name.'bf');
- $updateRows= $db->query($update);
- }else{
- if($ysj){
- $insert = $db->insert('table.options')
- ->rows(array('name' => 'theme:'.$name.'bf','user' => '0','value' => $ysj));
- $insertId = $db->query($insert);
- }
- }
- }
- if($_POST["type"]=="还原模板设置数据"){
- if($db->fetchRow($db->select()->from ('table.options')->where ('name = ?', 'theme:'.$name.'bf'))){
- $sjdub=$db->fetchRow($db->select()->from ('table.options')->where ('name = ?', 'theme:'.$name.'bf'));
- $bsj = $sjdub['value'];
- $update = $db->update('table.options')->rows(array('value'=>$bsj))->where('name = ?', 'theme:'.$name);
- $updateRows= $db->query($update);
- }
- }
- if($_POST["type"]=="删除备份数据"){
- if($db->fetchRow($db->select()->from ('table.options')->where ('name = ?', 'theme:'.$name.'bf'))){
- $delete = $db->delete('table.options')->where ('name = ?', 'theme:'.$name.'bf');
- $deletedRows = $db->query($delete);
- }
- }
- }
-
- /**
- * 设置样式+面板
- */
- $ver = themeVersion();
- $themeDir = "/usr/themes/Miracles/";
- echo '<link rel="stylesheet" href="'.$themeDir.'assets/css/setting.miracles.css">
- <link href="https://fonts.googleapis.com/css?family=Noto+Sans+SC:300|Noto+Serif+SC:300&display=swap" rel="stylesheet">
- <script>var version = "'. $ver .'";</script>
- <script src="'.$themeDir.'assets/js/jquery.js"></script>
- <script src="'.$themeDir.'assets/js/update.miracles.js"></script>';
- echo '<div class="miracles-pannel">
- <h1>Miracles 主题设置面板</h1>
- <p>欢迎使用 Miracles 主题,目前版本是:'. $ver .'<span id="miracles-update" class="waiting">,正在获取最新版本号......</span><br>
- 作者博客:<a href="https://guhub.cn">Eltrac\'s</a> |
- 帮助文档:<a href="https://www.notion.so/thememiracles/c7c631e21b3345caa2a09bd2fb5dd4b2">WIKI</a> |
- 问题反馈:<a href="https://github.com/BigCoke233/miracles/issues">issues</a></p>
- <form class="protected miracles-backup-div" action="?'.$name.'bf" method="post">
- <input type="submit" name="type" class="miracles-backup-button" value="备份模板设置数据" />&nbsp;&nbsp;
- <input type="submit" name="type" class="miracles-backup-button" value="还原模板设置数据" />&nbsp;&nbsp;
- <input type="submit" name="type" class="miracles-backup-button" value="删除备份数据" />
- </form>';
- if(isset($_POST['type'])){
- //备份数据提示
- if($_POST["type"]=="备份模板设置数据"){
- if($db->fetchRow($db->select()->from ('table.options')->where ('name = ?', 'theme:'.$name.'bf'))){
- echo '<div class="tongzhi col-mb-12 home">备份已更新,请等待自动刷新!如果等不到请点击';
- ?><a href="<?php Helper::options()->adminUrl('options-theme.php'); ?>">这里</a></div>
- <script language="JavaScript">window.setTimeout("location=\'<?php Helper::options()->adminUrl('options-theme.php'); ?>\'", 1500);</script><?php
- }else{
- echo '<div class="tongzhi col-mb-12 home">备份完成,请等待自动刷新!如果等不到请点击';
- ?> <a href="<?php Helper::options()->adminUrl('options-theme.php'); ?>">这里</a></div>
- <script language="JavaScript">window.setTimeout("location=\'<?php Helper::options()->adminUrl('options-theme.php'); ?>\'", 1500);</script><?php
- }
- }
- //还原数据提示
- if($_POST["type"]=="还原模板设置数据"){
- if($db->fetchRow($db->select()->from ('table.options')->where ('name = ?', 'theme:'.$name.'bf'))){
- echo '<div class="tongzhi col-mb-12 home">检测到模板备份数据,恢复完成,请等待自动刷新!如果等不到请点击';
- ?> <a href="<?php Helper::options()->adminUrl('options-theme.php'); ?>">这里</a></div>
- <script language="JavaScript">window.setTimeout("location=\'<?php Helper::options()->adminUrl('options-theme.php'); ?>\'", 1500);</script>
- <?php
- }else{
- echo '<div class="tongzhi col-mb-12 home">没有模板备份数据,恢复不了哦!</div>';
- }
- }
- //删除数据提示
- if($_POST["type"]=="删除备份数据"){
- if($db->fetchRow($db->select()->from ('table.options')->where ('name = ?', 'theme:'.$name.'bf'))){
- echo '<div class="tongzhi col-mb-12 home">删除成功,请等待自动刷新,如果等不到请点击';
- ?>
- <a href="<?php Helper::options()->adminUrl('options-theme.php'); ?>">这里</a></div>
- <script language="JavaScript">window.setTimeout("location=\'<?php Helper::options()->adminUrl('options-theme.php'); ?>\'", 1500);</script>
- <?php
- }else{
- echo '<div class="tongzhi col-mb-12 home">备份已经被删除了</div>';
- ?><script language="JavaScript">window.setTimeout("location=\'<?php Helper::options()->adminUrl('options-theme.php'); ?>\'", 1500);</script><?php
- }
- }
- }
- echo '<br></div>';
-
-
- /**
- * 设置项
- */
- //Info
- $bannerTitle = new Typecho_Widget_Helper_Form_Element_Text('bannerTitle', NULL, NULL, _t('<h2>站点信息 Information</h2>站点名称'), _t('输入你站点的名称,会显示在首页大图上'));
- $form->addInput($bannerTitle);
- $bannerIntro = new Typecho_Widget_Helper_Form_Element_Text('bannerIntro', NULL, NULL, _t('站点介绍'), _t('用一句话介绍你的站点,会显示在首页大图上'));
- $form->addInput($bannerIntro);
- $avatar = new Typecho_Widget_Helper_Form_Element_Text('avatar', NULL, NULL, _t('站长头像'), _t('输入一个图片 url 作为头像,若为空则调用 gravatar'));
- $form->addInput($avatar);
- $favicon = new Typecho_Widget_Helper_Form_Element_Text('favicon', NULL, NULL, _t('Favicon'), _t('输入一个图片 url 作为 Favicon,显示在浏览器标签页上,为空则调用主题目录下的 favicon.ico<hr>'));
- $form->addInput($favicon);
-
- //nav
- $navStyle = new Typecho_Widget_Helper_Form_Element_Select('navStyle',array('0'=>'顶部导航栏','1'=>'左侧抽屉栏'),'0','<h2>导航栏 Nav</h2>类型','选择导航栏的类型(若选择左侧抽屉蓝,则下一条设置失效)');
- $form->addInput($navStyle);
- $navAero = new Typecho_Widget_Helper_Form_Element_Select('navAero',array('0'=>'是','1'=>'否'),'1','顶部透明','视口处于最顶部时,顶部导航栏是否变为透明(BUG 比较多,不推荐)');
- $form->addInput($navAero);
- $navSlide = new Typecho_Widget_Helper_Form_Element_Select('navSlide',array('0'=>'是','1'=>'否'),'0','Headroom','开启后,访客向下滚动页面时导航栏收起,向上滚动时导航栏展示');
- $form->addInput($navSlide);
- $customNav = new Typecho_Widget_Helper_Form_Element_Textarea('customNav', NULL, NULL, _t('自定义导航栏'), _t('按照格式书写,自定义导航栏内容,留空则读取所有的独立页面,书写的格式请查看 wiki'));
- $form->addInput($customNav);
- $customNavIcon = new Typecho_Widget_Helper_Form_Element_Textarea('customNavIcon', NULL, NULL, _t('自定义导航小图标'), _t('按照格式书写,自定义内导航栏右侧的小图标,留空则展示默认的图标按钮,书写的格式请查看 wiki<hr>'));
- $form->addInput($customNavIcon);
-
- //index-banner
- $bannerUrl = new Typecho_Widget_Helper_Form_Element_Text('bannerUrl', NULL, NULL, _t('<h2>首页大图 Banner</h2>图片 Url'), _t('首页大图的图片地址'));
- $form->addInput($bannerUrl);
- $bannerFont = new Typecho_Widget_Helper_Form_Element_Select('bannerFont',array('0'=>'白色','1'=>'黑色'),'0','字体颜色','为了兼容不同的底色和背景色');
- $form->addInput($bannerFont);
- $bannerHeight = new Typecho_Widget_Helper_Form_Element_Text('bannerHeight', NULL, '60', _t('高度'), _t('首页大图所占屏幕的高度,100为最大,填入纯数字,如"35"<hr>'));
- $form->addInput($bannerHeight);
-
- //pjax
- $pjax = new Typecho_Widget_Helper_Form_Element_Select('pjax',array(
- '0'=>'关闭',
- '1'=>'开启'
- ),'1','<h2>Pjax 预加载</h2>是否开启','Pjax 预加载功能的开关');
- $form->addInput($pjax);
- $pjax_complete = new Typecho_Widget_Helper_Form_Element_Textarea('pjax_complete', NULL, NULL, _t('Pjax 回调函数'), _t('Pjax 跳转页面后执行的事件,写入 js 代码,一般将 Pjax 重载(回调)函数写在这里。<hr>'));
- $form->addInput($pjax_complete);
-
- //improve
- $CDN = new Typecho_Widget_Helper_Form_Element_Select('CDN',array(
- '0'=>'关闭',
- '1'=>'jsDelivr',
- '6'=>'jsDelivr(仅图片)',
- '5'=>'9jojo CDN',
- '2'=>'GitHack(实时更新)',
- '4'=>'GitHack CDN(较慢)',
- '3'=>'自定义'),'0','<h2>优化</h2>CDN 加速加载静态资源(Beta)',
- '开启后静态资源文件通过选择的 CDN 进行调用,加快网页加载速度。如果选择自定义则需要填写下一个设置项。<br>* 如果你使用开发版,请不要选择 jsDelivr/9jojo 作为 CDN<br>* GitHack 是实时更新的,如果你不是随时更新开发版,最好不要选用<br>* GitHack CDN 速度较慢,国内不建议使用,<del>就是拿来凑数的</del><br>在这里感谢<a href="https://github.com/SatoSouta/9jojo">小太</a>为 Miracles 提供 9jojo CDN');
- $form->addInput($CDN);
- $customCDN = new Typecho_Widget_Helper_Form_Element_Text('customCDN', NULL, '', _t('自定义 CDN'), _t('输入 CDN 的链接,要保证写入的路径下,目录结构和主题的 assets 目录下一致'));
- $form->addInput($customCDN);
- $ifShowRTA = new Typecho_Widget_Helper_Form_Element_Select('ifShowRTA',array('0'=>'不显示','1'=>'显示'),'0','阅读时长提示 RTA','在文章前加入阅读时长提示,增进用户体验');
- $form->addInput($ifShowRTA);
- $pangu = new Typecho_Widget_Helper_Form_Element_Select('pangu',array('0'=>'启用','1'=>'关闭'),'0','自动分割中英文(pangu.js)','自动分割网页中的中英文,在全角字符和半角字符之间加上空格,也会修复一些标点符号的错误(.=>。),可能会有误判或是有人不喜欢,所以在这里加个按钮<hr>');
- $form->addInput($pangu);
-
- //custom style
- $grayTheme = new Typecho_Widget_Helper_Form_Element_Select('grayTheme',array(
- '0'=>'关闭',
- '1'=>'开启'
- ),'0','<h2>个性化</h2>哀悼模式','打开后网站变为黑白');
- $form->addInput($grayTheme);
- $bodyFonts = new Typecho_Widget_Helper_Form_Element_Select('bodyFonts',array(
- '0'=>'无衬线字体',
- '1'=>'衬线字体'
- ),'0','网站字体','选择网站的字体,无衬线字体即“思源黑体”,衬线字体即“思源宋体”');
- $form->addInput($bodyFonts);
- $randomBanner = new Typecho_Widget_Helper_Form_Element_Textarea('randomBanner', NULL, NULL, _t('随机文章缩略图'), _t('文章没有独立设置头图时调用,写入图片链接,用半角逗号分割'));
- $form->addInput($randomBanner);
-
- //LoadingImage
- $LoadingOptions = [
- 'block' => "交错方块",
- 'octopus' => "旋转章鱼",
- 'bilibili' => "哔哩哔哩",
- 'shojo' => "少女祈祷",
- 'custom' => "自定义"
- ];
- $LoadingImage = new Typecho_Widget_Helper_Form_Element_Radio('loading_image', $LoadingOptions, 'block', _t('图片懒加载动画'),_t("选择懒加载动画的图片,若选择自定义,则需要在 images/loading 目录下添加名为 custom.gif 的文件"));
- $form->addInput($LoadingImage);
-
- //SiteBuildTime
- $buildTime = new Typecho_Widget_Helper_Form_Element_Text('build_time', NULL, NULL, _t('在页脚输出建站至今时间'), _t('填写格式如 2020-01-01 的时间,将输出在站点信息之前,不想开启请留空。'));
- $form->addInput($buildTime);
- //AnimeFace
- $AnimeFace = new Typecho_Widget_Helper_Form_Element_Text('anime_face', NULL, NULL, _t('在其之后输出一个蹦跶的颜文字'), _t('如果开启了建站时间将会输出在其之后,反之会输出在站点信息之后。在此写上你想展示的颜文字,多个颜文字用"&&"分割,每次刷新更换。如不想开启请留空。<hr>'));
- $form->addInput($AnimeFace);
-
- //developer
- $headerEcho = new Typecho_Widget_Helper_Form_Element_Textarea('headerEcho', NULL, NULL, _t('<h2>开发者设置</h2>自定义头部信息'), _t('填写 html 代码,将输出在 &lt;head&gt; 标签中,可以在这里写上统计代码'));
- $form->addInput($headerEcho);
- $footerEcho = new Typecho_Widget_Helper_Form_Element_Textarea('footerEcho', NULL, NULL, _t('自定义页脚部信息'), _t('填写 html 代码,将输出在页脚的版权信息之前'));
- $form->addInput($footerEcho);
- $cssEcho = new Typecho_Widget_Helper_Form_Element_Textarea('cssEcho', NULL, NULL, _t('自定义 CSS'), _t('填写 CSS 代码,输出在 head 标签结束之前的 style 标签内'));
- $form->addInput($cssEcho);
- $jsEcho = new Typecho_Widget_Helper_Form_Element_Textarea('jsEcho', NULL, NULL, _t('自定义 JavaScript'), _t('填写 JavaScript代码,输出在 body 标签结束之前'));
- $form->addInput($jsEcho);
-}
diff --git a/libs/TableContents.php b/libs/TableContents.php
deleted file mode 100644
index e69de29..0000000
--- a/libs/TableContents.php
+++ /dev/null
diff --git a/libs/TimThumb.php b/libs/TimThumb.php
deleted file mode 100644
index c51e866..0000000
--- a/libs/TimThumb.php
+++ /dev/null
@@ -1,1251 +0,0 @@
-<?php
-/**
- * TimThumb by Ben Gillbanks and Mark Maunder
- * Based on work done by Tim McDaniels and Darren Hoyt
- * http://code.google.com/p/timthumb/
- *
- * GNU General Public License, version 2
- * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
- *
- * Examples and documentation available on the project homepage
- * http://www.binarymoon.co.uk/projects/timthumb/
- *
- * $Rev$
- */
-
-/*
- * --- TimThumb CONFIGURATION ---
- * To edit the configs it is best to create a file called timthumb-config.php
- * and define variables you want to customize in there. It will automatically be
- * loaded by timthumb. This will save you having to re-edit these variables
- * everytime you download a new version
-*/
-define ('VERSION', '2.8.14'); // Version of this script
-//Load a config file if it exists. Otherwise, use the values below
-if( file_exists(dirname(__FILE__) . '/timthumb-config.php')) require_once('timthumb-config.php');
-if(! defined('DEBUG_ON') ) define ('DEBUG_ON', false); // Enable debug logging to web server error log (STDERR)
-if(! defined('DEBUG_LEVEL') ) define ('DEBUG_LEVEL', 1); // Debug level 1 is less noisy and 3 is the most noisy
-if(! defined('MEMORY_LIMIT') ) define ('MEMORY_LIMIT', '30M'); // Set PHP memory limit
-if(! defined('BLOCK_EXTERNAL_LEECHERS') ) define ('BLOCK_EXTERNAL_LEECHERS', false); // If the image or webshot is being loaded on an external site, display a red "No Hotlinking" gif.
-if(! defined('DISPLAYALLOW_ALL_EXTERNAL_SITES_ERROR_MESSAGES') ) define ('DISPLAY_ERROR_MESSAGES', true); // Display error messages. Set to false to turn off errors (good for production websites)
-//Image fetching and caching
-if(! defined('ALLOW_EXTERNAL') ) define ('ALLOW_EXTERNAL', TRUE); // Allow image fetching from external websites. Will check against ALLOWED_SITES if ALLOW_ALL_EXTERNAL_SITES is false
-if(! defined('ALLOW_ALL_EXTERNAL_SITES') ) define ('ALLOW_ALL_EXTERNAL_SITES', false); // Less secure.
-if(! defined('FILE_CACHE_ENABLED') ) define ('FILE_CACHE_ENABLED', TRUE); // Should we store resized/modified images on disk to speed things up?
-if(! defined('FILE_CACHE_TIME_BETWEEN_CLEANS')) define ('FILE_CACHE_TIME_BETWEEN_CLEANS', 86400); // How often the cache is cleaned
-
-if(! defined('FILE_CACHE_MAX_FILE_AGE') ) define ('FILE_CACHE_MAX_FILE_AGE', 86400); // How old does a file have to be to be deleted from the cache
-if(! defined('FILE_CACHE_SUFFIX') ) define ('FILE_CACHE_SUFFIX', '.timthumb.txt'); // What to put at the end of all files in the cache directory so we can identify them
-if(! defined('FILE_CACHE_PREFIX') ) define ('FILE_CACHE_PREFIX', 'timthumb'); // What to put at the beg of all files in the cache directory so we can identify them
-if(! defined('FILE_CACHE_DIRECTORY') ) define ('FILE_CACHE_DIRECTORY', './cache'); // Directory where images are cached. Left blank it will use the system temporary directory (which is better for security)
-if(! defined('MAX_FILE_SIZE') ) define ('MAX_FILE_SIZE', 10485760); // 10 Megs is 10485760. This is the max internal or external file size that we'll process.
-if(! defined('CURL_TIMEOUT') ) define ('CURL_TIMEOUT', 20); // Timeout duration for Curl. This only applies if you have Curl installed and aren't using PHP's default URL fetching mechanism.
-if(! defined('WAIT_BETWEEN_FETCH_ERRORS') ) define ('WAIT_BETWEEN_FETCH_ERRORS', 3600); // Time to wait between errors fetching remote file
-
-//Browser caching
-if(! defined('BROWSER_CACHE_MAX_AGE') ) define ('BROWSER_CACHE_MAX_AGE', 864000); // Time to cache in the browser
-if(! defined('BROWSER_CACHE_DISABLE') ) define ('BROWSER_CACHE_DISABLE', false); // Use for testing if you want to disable all browser caching
-
-//Image size and defaults
-if(! defined('MAX_WIDTH') ) define ('MAX_WIDTH', 1500); // Maximum image width
-if(! defined('MAX_HEIGHT') ) define ('MAX_HEIGHT', 1500); // Maximum image height
-if(! defined('NOT_FOUND_IMAGE') ) define ('NOT_FOUND_IMAGE', ''); // Image to serve if any 404 occurs
-if(! defined('ERROR_IMAGE') ) define ('ERROR_IMAGE', ''); // Image to serve if an error occurs instead of showing error message
-if(! defined('PNG_IS_TRANSPARENT') ) define ('PNG_IS_TRANSPARENT', FALSE); // Define if a png image should have a transparent background color. Use False value if you want to display a custom coloured canvas_colour
-if(! defined('DEFAULT_Q') ) define ('DEFAULT_Q', 90); // Default image quality. Allows overrid in timthumb-config.php
-if(! defined('DEFAULT_ZC') ) define ('DEFAULT_ZC', 1); // Default zoom/crop setting. Allows overrid in timthumb-config.php
-if(! defined('DEFAULT_F') ) define ('DEFAULT_F', ''); // Default image filters. Allows overrid in timthumb-config.php
-if(! defined('DEFAULT_S') ) define ('DEFAULT_S', 0); // Default sharpen value. Allows overrid in timthumb-config.php
-if(! defined('DEFAULT_CC') ) define ('DEFAULT_CC', 'ffffff'); // Default canvas colour. Allows overrid in timthumb-config.php
-if(! defined('DEFAULT_WIDTH') ) define ('DEFAULT_WIDTH', 100); // Default thumbnail width. Allows overrid in timthumb-config.php
-if(! defined('DEFAULT_HEIGHT') ) define ('DEFAULT_HEIGHT', 100); // Default thumbnail height. Allows overrid in timthumb-config.php
-
-/**
- * Additional Parameters:
- * LOCAL_FILE_BASE_DIRECTORY = Override the DOCUMENT_ROOT. This is best used in timthumb-config.php
- */
-
-//Image compression is enabled if either of these point to valid paths
-
-//These are now disabled by default because the file sizes of PNGs (and GIFs) are much smaller than we used to generate.
-//They only work for PNGs. GIFs and JPEGs are not affected.
-if(! defined('OPTIPNG_ENABLED') ) define ('OPTIPNG_ENABLED', false);
-if(! defined('OPTIPNG_PATH') ) define ('OPTIPNG_PATH', '/usr/bin/optipng'); //This will run first because it gives better compression than pngcrush.
-if(! defined('PNGCRUSH_ENABLED') ) define ('PNGCRUSH_ENABLED', false);
-if(! defined('PNGCRUSH_PATH') ) define ('PNGCRUSH_PATH', '/usr/bin/pngcrush'); //This will only run if OPTIPNG_PATH is not set or is not valid
-
-/*
- -------====Website Screenshots configuration - BETA====-------
-
- If you just want image thumbnails and don't want website screenshots, you can safely leave this as is.
-
- If you would like to get website screenshots set up, you will need root access to your own server.
- Enable ALLOW_ALL_EXTERNAL_SITES so you can fetch any external web page. This is more secure now that we're using a non-web folder for cache.
- Enable BLOCK_EXTERNAL_LEECHERS so that your site doesn't generate thumbnails for the whole Internet.
- Instructions to get website screenshots enabled on Ubuntu Linux:
- 1. Install Xvfb with the following command: sudo apt-get install subversion libqt4-webkit libqt4-dev g++ xvfb
- 2. Go to a directory where you can download some code
- 3. Check-out the latest version of CutyCapt with the following command: svn co https://cutycapt.svn.sourceforge.net/svnroot/cutycapt
- 4. Compile CutyCapt by doing: cd cutycapt/CutyCapt
- 5. qmake
- 6. make
- 7. cp CutyCapt /usr/local/bin/
- 8. Test it by running: xvfb-run --server-args="-screen 0, 1024x768x24" CutyCapt --url="http://markmaunder.com/" --out=test.png
- 9. If you get a file called test.png with something in it, it probably worked. Now test the script by accessing it as follows:
- 10. http://yoursite.com/path/to/timthumb.php?src=http://markmaunder.com/&webshot=1
- Notes on performance:
- The first time a webshot loads, it will take a few seconds.
- From then on it uses the regular timthumb caching mechanism with the configurable options above
- and loading will be very fast.
- --ADVANCED USERS ONLY--
- If you'd like a slight speedup (about 25%) and you know Linux, you can run the following command which will keep Xvfb running in the background.
- nohup Xvfb :100 -ac -nolisten tcp -screen 0, 1024x768x24 > /dev/null 2>&1 &
- Then set WEBSHOT_XVFB_RUNNING = true below. This will save your server having to fire off a new Xvfb server and shut it down every time a new shot is generated.
- You will need to take responsibility for keeping Xvfb running in case it crashes. (It seems pretty stable)
- You will also need to take responsibility for server security if you're running Xvfb as root.
-*/
-if(! defined('WEBSHOT_ENABLED') ) define ('WEBSHOT_ENABLED', false); //Beta feature. Adding webshot=1 to your query string will cause the script to return a browser screenshot rather than try to fetch an image.
-if(! defined('WEBSHOT_CUTYCAPT') ) define ('WEBSHOT_CUTYCAPT', '/usr/local/bin/CutyCapt'); //The path to CutyCapt.
-if(! defined('WEBSHOT_XVFB') ) define ('WEBSHOT_XVFB', '/usr/bin/xvfb-run'); //The path to the Xvfb server
-if(! defined('WEBSHOT_SCREEN_X') ) define ('WEBSHOT_SCREEN_X', '1024'); //1024 works ok
-if(! defined('WEBSHOT_SCREEN_Y') ) define ('WEBSHOT_SCREEN_Y', '768'); //768 works ok
-if(! defined('WEBSHOT_COLOR_DEPTH') ) define ('WEBSHOT_COLOR_DEPTH', '24'); //I haven't tested anything besides 24
-if(! defined('WEBSHOT_IMAGE_FORMAT') ) define ('WEBSHOT_IMAGE_FORMAT', 'png'); //png is about 2.5 times the size of jpg but is a LOT better quality
-if(! defined('WEBSHOT_TIMEOUT') ) define ('WEBSHOT_TIMEOUT', '20'); //Seconds to wait for a webshot
-if(! defined('WEBSHOT_USER_AGENT') ) define ('WEBSHOT_USER_AGENT', "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.9.2.18) Gecko/20110614 Firefox/3.6.18"); //I hate to do this, but a non-browser robot user agent might not show what humans see. So we pretend to be Firefox
-if(! defined('WEBSHOT_JAVASCRIPT_ON') ) define ('WEBSHOT_JAVASCRIPT_ON', true); //Setting to false might give you a slight speedup and block ads. But it could cause other issues.
-if(! defined('WEBSHOT_JAVA_ON') ) define ('WEBSHOT_JAVA_ON', false); //Have only tested this as fase
-if(! defined('WEBSHOT_PLUGINS_ON') ) define ('WEBSHOT_PLUGINS_ON', true); //Enable flash and other plugins
-if(! defined('WEBSHOT_PROXY') ) define ('WEBSHOT_PROXY', ''); //In case you're behind a proxy server.
-if(! defined('WEBSHOT_XVFB_RUNNING') ) define ('WEBSHOT_XVFB_RUNNING', false); //ADVANCED: Enable this if you've got Xvfb running in the background.
-
-
-// If ALLOW_EXTERNAL is true and ALLOW_ALL_EXTERNAL_SITES is false, then external images will only be fetched from these domains and their subdomains.
-if(! isset($ALLOWED_SITES)){
- require_once("../themeConfig.php");
- $ALLOWED_SITES = $GLOBALS['miraclesTimThumbAllowList'];
-}
-// -------------------------------------------------------------
-// -------------- STOP EDITING CONFIGURATION HERE --------------
-// -------------------------------------------------------------
-
-timthumb::start();
-
-class timthumb {
- protected $src = "";
- protected $is404 = false;
- protected $docRoot = "";
- protected $lastURLError = false;
- protected $localImage = "";
- protected $localImageMTime = 0;
- protected $url = false;
- protected $myHost = "";
- protected $isURL = false;
- protected $cachefile = '';
- protected $errors = array();
- protected $toDeletes = array();
- protected $cacheDirectory = '';
- protected $startTime = 0;
- protected $lastBenchTime = 0;
- protected $cropTop = false;
- protected $salt = "";
- protected $fileCacheVersion = 1; //Generally if timthumb.php is modifed (upgraded) then the salt changes and all cache files are recreated. This is a backup mechanism to force regen.
- protected $filePrependSecurityBlock = "<?php die('Execution denied!'); //"; //Designed to have three letter mime type, space, question mark and greater than symbol appended. 6 bytes total.
- protected static $curlDataWritten = 0;
- protected static $curlFH = false;
- public static function start(){
- $tim = new timthumb();
- $tim->handleErrors();
- $tim->securityChecks();
- if($tim->tryBrowserCache()){
- exit(0);
- }
- $tim->handleErrors();
- if(FILE_CACHE_ENABLED && $tim->tryServerCache()){
- exit(0);
- }
- $tim->handleErrors();
- $tim->run();
- $tim->handleErrors();
- exit(0);
- }
- public function __construct(){
- global $ALLOWED_SITES;
- $this->startTime = microtime(true);
- date_default_timezone_set('UTC');
- $this->debug(1, "Starting new request from " . $this->getIP() . " to " . $_SERVER['REQUEST_URI']);
- $this->calcDocRoot();
- //On windows systems I'm assuming fileinode returns an empty string or a number that doesn't change. Check this.
- $this->salt = @filemtime(__FILE__) . '-' . @fileinode(__FILE__);
- $this->debug(3, "Salt is: " . $this->salt);
- if(FILE_CACHE_DIRECTORY){
- if(! is_dir(FILE_CACHE_DIRECTORY)){
- @mkdir(FILE_CACHE_DIRECTORY);
- if(! is_dir(FILE_CACHE_DIRECTORY)){
- $this->error("Could not create the file cache directory.");
- return false;
- }
- }
- $this->cacheDirectory = FILE_CACHE_DIRECTORY;
- if (!touch($this->cacheDirectory . '/index.html')) {
- $this->error("Could not create the index.html file - to fix this create an empty file named index.html file in the cache directory.");
- }
- } else {
- $this->cacheDirectory = sys_get_temp_dir();
- }
- //Clean the cache before we do anything because we don't want the first visitor after FILE_CACHE_TIME_BETWEEN_CLEANS expires to get a stale image.
- $this->cleanCache();
-
- $this->myHost = preg_replace('/^www\./i', '', $_SERVER['HTTP_HOST']);
- $this->src = $this->param('src');
- $this->url = parse_url($this->src);
- $this->src = preg_replace('/https?:\/\/(?:www\.)?' . $this->myHost . '/i', '', $this->src);
-
- if(strlen($this->src) <= 3){
- $this->error("No image specified");
- return false;
- }
- if(BLOCK_EXTERNAL_LEECHERS && array_key_exists('HTTP_REFERER', $_SERVER) && (! preg_match('/^https?:\/\/(?:www\.)?' . $this->myHost . '(?:$|\/)/i', $_SERVER['HTTP_REFERER']))){
- // base64 encoded red image that says 'no hotlinkers'
- // nothing to worry about! :)
- $imgData = base64_decode("R0lGODlhUAAMAIAAAP8AAP///yH5BAAHAP8ALAAAAABQAAwAAAJpjI+py+0Po5y0OgAMjjv01YUZ\nOGplhWXfNa6JCLnWkXplrcBmW+spbwvaVr/cDyg7IoFC2KbYVC2NQ5MQ4ZNao9Ynzjl9ScNYpneb\nDULB3RP6JuPuaGfuuV4fumf8PuvqFyhYtjdoeFgAADs=");
- header('Content-Type: image/gif');
- header('Content-Length: ' . strlen($imgData));
- header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
- header("Pragma: no-cache");
- header('Expires: ' . gmdate ('D, d M Y H:i:s', time()));
- echo $imgData;
- return false;
- exit(0);
- }
- if(preg_match('/^https?:\/\/[^\/]+/i', $this->src)){
- $this->debug(2, "Is a request for an external URL: " . $this->src);
- $this->isURL = true;
- } else {
- $this->debug(2, "Is a request for an internal file: " . $this->src);
- }
- if($this->isURL && (! ALLOW_EXTERNAL)){
- $this->error("You are not allowed to fetch images from an external website.");
- return false;
- }
- if($this->isURL){
- if(ALLOW_ALL_EXTERNAL_SITES){
- $this->debug(2, "Fetching from all external sites is enabled.");
- } else {
- $this->debug(2, "Fetching only from selected external sites is enabled.");
- $allowed = false;
- foreach($ALLOWED_SITES as $site){
- if ((strtolower(substr($this->url['host'],-strlen($site)-1)) === strtolower(".$site")) || (strtolower($this->url['host'])===strtolower($site))) {
- $this->debug(3, "URL hostname {$this->url['host']} matches $site so allowing.");
- $allowed = true;
- }
- }
- if(! $allowed){
- return $this->error("You may not fetch images from that site. To enable this site in timthumb, you can either add it to \$ALLOWED_SITES and set ALLOW_EXTERNAL=true. Or you can set ALLOW_ALL_EXTERNAL_SITES=true, depending on your security needs.");
- }
- }
- }
-
- $cachePrefix = ($this->isURL ? '_ext_' : '_int_');
- if($this->isURL){
- $arr = explode('&', $_SERVER ['QUERY_STRING']);
- asort($arr);
- $this->cachefile = $this->cacheDirectory . '/' . FILE_CACHE_PREFIX . $cachePrefix . md5($this->salt . implode('', $arr) . $this->fileCacheVersion) . FILE_CACHE_SUFFIX;
- } else {
- $this->localImage = $this->getLocalImagePath($this->src);
- if(! $this->localImage){
- $this->debug(1, "Could not find the local image: {$this->localImage}");
- $this->error("Could not find the internal image you specified.");
- $this->set404();
- return false;
- }
- $this->debug(1, "Local image path is {$this->localImage}");
- $this->localImageMTime = @filemtime($this->localImage);
- //We include the mtime of the local file in case in changes on disk.
- $this->cachefile = $this->cacheDirectory . '/' . FILE_CACHE_PREFIX . $cachePrefix . md5($this->salt . $this->localImageMTime . $_SERVER ['QUERY_STRING'] . $this->fileCacheVersion) . FILE_CACHE_SUFFIX;
- }
- $this->debug(2, "Cache file is: " . $this->cachefile);
-
- return true;
- }
- public function __destruct(){
- foreach($this->toDeletes as $del){
- $this->debug(2, "Deleting temp file $del");
- @unlink($del);
- }
- }
- public function run(){
- if($this->isURL){
- if(! ALLOW_EXTERNAL){
- $this->debug(1, "Got a request for an external image but ALLOW_EXTERNAL is disabled so returning error msg.");
- $this->error("You are not allowed to fetch images from an external website.");
- return false;
- }
- $this->debug(3, "Got request for external image. Starting serveExternalImage.");
- if($this->param('webshot')){
- if(WEBSHOT_ENABLED){
- $this->debug(3, "webshot param is set, so we're going to take a webshot.");
- $this->serveWebshot();
- } else {
- $this->error("You added the webshot parameter but webshots are disabled on this server. You need to set WEBSHOT_ENABLED == true to enable webshots.");
- }
- } else {
- $this->debug(3, "webshot is NOT set so we're going to try to fetch a regular image.");
- $this->serveExternalImage();
-
- }
- } else {
- $this->debug(3, "Got request for internal image. Starting serveInternalImage()");
- $this->serveInternalImage();
- }
- return true;
- }
- protected function handleErrors(){
- if($this->haveErrors()){
- if(NOT_FOUND_IMAGE && $this->is404()){
- if($this->serveImg(NOT_FOUND_IMAGE)){
- exit(0);
- } else {
- $this->error("Additionally, the 404 image that is configured could not be found or there was an error serving it.");
- }
- }
- if(ERROR_IMAGE){
- if($this->serveImg(ERROR_IMAGE)){
- exit(0);
- } else {
- $this->error("Additionally, the error image that is configured could not be found or there was an error serving it.");
- }
- }
- $this->serveErrors();
- exit(0);
- }
- return false;
- }
- protected function tryBrowserCache(){
- if(BROWSER_CACHE_DISABLE){ $this->debug(3, "Browser caching is disabled"); return false; }
- if(!empty($_SERVER['HTTP_IF_MODIFIED_SINCE']) ){
- $this->debug(3, "Got a conditional get");
- $mtime = false;
- //We've already checked if the real file exists in the constructor
- if(! is_file($this->cachefile)){
- //If we don't have something cached, regenerate the cached image.
- return false;
- }
- if($this->localImageMTime){
- $mtime = $this->localImageMTime;
- $this->debug(3, "Local real file's modification time is $mtime");
- } else if(is_file($this->cachefile)){ //If it's not a local request then use the mtime of the cached file to determine the 304
- $mtime = @filemtime($this->cachefile);
- $this->debug(3, "Cached file's modification time is $mtime");
- }
- if(! $mtime){ return false; }
-
- $iftime = strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']);
- $this->debug(3, "The conditional get's if-modified-since unixtime is $iftime");
- if($iftime < 1){
- $this->debug(3, "Got an invalid conditional get modified since time. Returning false.");
- return false;
- }
- if($iftime < $mtime){ //Real file or cache file has been modified since last request, so force refetch.
- $this->debug(3, "File has been modified since last fetch.");
- return false;
- } else { //Otherwise serve a 304
- $this->debug(3, "File has not been modified since last get, so serving a 304.");
- header ($_SERVER['SERVER_PROTOCOL'] . ' 304 Not Modified');
- $this->debug(1, "Returning 304 not modified");
- return true;
- }
- }
- return false;
- }
- protected function tryServerCache(){
- $this->debug(3, "Trying server cache");
- if(file_exists($this->cachefile)){
- $this->debug(3, "Cachefile {$this->cachefile} exists");
- if($this->isURL){
- $this->debug(3, "This is an external request, so checking if the cachefile is empty which means the request failed previously.");
- if(filesize($this->cachefile) < 1){
- $this->debug(3, "Found an empty cachefile indicating a failed earlier request. Checking how old it is.");
- //Fetching error occured previously
- if(time() - @filemtime($this->cachefile) > WAIT_BETWEEN_FETCH_ERRORS){
- $this->debug(3, "File is older than " . WAIT_BETWEEN_FETCH_ERRORS . " seconds. Deleting and returning false so app can try and load file.");
- @unlink($this->cachefile);
- return false; //to indicate we didn't serve from cache and app should try and load
- } else {
- $this->debug(3, "Empty cachefile is still fresh so returning message saying we had an error fetching this image from remote host.");
- $this->set404();
- $this->error("An error occured fetching image.");
- return false;
- }
- }
- } else {
- $this->debug(3, "Trying to serve cachefile {$this->cachefile}");
- }
- if($this->serveCacheFile()){
- $this->debug(3, "Succesfully served cachefile {$this->cachefile}");
- return true;
- } else {
- $this->debug(3, "Failed to serve cachefile {$this->cachefile} - Deleting it from cache.");
- //Image serving failed. We can't retry at this point, but lets remove it from cache so the next request recreates it
- @unlink($this->cachefile);
- return true;
- }
- }
- }
- protected function error($err){
- $this->debug(3, "Adding error message: $err");
- $this->errors[] = $err;
- return false;
-
- }
- protected function haveErrors(){
- if(sizeof($this->errors) > 0){
- return true;
- }
- return false;
- }
- protected function serveErrors(){
- header ($_SERVER['SERVER_PROTOCOL'] . ' 400 Bad Request');
- if ( ! DISPLAY_ERROR_MESSAGES ) {
- return;
- }
- $html = '<ul>';
- foreach($this->errors as $err){
- $html .= '<li>' . htmlentities($err) . '</li>';
- }
- $html .= '</ul>';
- echo '<h1>A TimThumb error has occured</h1>The following error(s) occured:<br />' . $html . '<br />';
- echo '<br />Query String : ' . htmlentities( $_SERVER['QUERY_STRING'], ENT_QUOTES );
- echo '<br />TimThumb version : ' . VERSION . '</pre>';
- }
- protected function serveInternalImage(){
- $this->debug(3, "Local image path is $this->localImage");
- if(! $this->localImage){
- $this->sanityFail("localImage not set after verifying it earlier in the code.");
- return false;
- }
- $fileSize = filesize($this->localImage);
- if($fileSize > MAX_FILE_SIZE){
- $this->error("The file you specified is greater than the maximum allowed file size.");
- return false;
- }
- if($fileSize <= 0){
- $this->error("The file you specified is <= 0 bytes.");
- return false;
- }
- $this->debug(3, "Calling processImageAndWriteToCache() for local image.");
- if($this->processImageAndWriteToCache($this->localImage)){
- $this->serveCacheFile();
- return true;
- } else {
- return false;
- }
- }
- protected function cleanCache(){
- if (FILE_CACHE_TIME_BETWEEN_CLEANS < 0) {
- return;
- }
- $this->debug(3, "cleanCache() called");
- $lastCleanFile = $this->cacheDirectory . '/timthumb_cacheLastCleanTime.touch';
-
- //If this is a new timthumb installation we need to create the file
- if(! is_file($lastCleanFile)){
- $this->debug(1, "File tracking last clean doesn't exist. Creating $lastCleanFile");
- if (!touch($lastCleanFile)) {
- $this->error("Could not create cache clean timestamp file.");
- }
- return;
- }
- if(@filemtime($lastCleanFile) < (time() - FILE_CACHE_TIME_BETWEEN_CLEANS) ){ //Cache was last cleaned more than 1 day ago
- $this->debug(1, "Cache was last cleaned more than " . FILE_CACHE_TIME_BETWEEN_CLEANS . " seconds ago. Cleaning now.");
- // Very slight race condition here, but worst case we'll have 2 or 3 servers cleaning the cache simultaneously once a day.
- if (!touch($lastCleanFile)) {
- $this->error("Could not create cache clean timestamp file.");
- }
- $files = glob($this->cacheDirectory . '/*' . FILE_CACHE_SUFFIX);
- if ($files) {
- $timeAgo = time() - FILE_CACHE_MAX_FILE_AGE;
- foreach($files as $file){
- if(@filemtime($file) < $timeAgo){
- $this->debug(3, "Deleting cache file $file older than max age: " . FILE_CACHE_MAX_FILE_AGE . " seconds");
- @unlink($file);
- }
- }
- }
- return true;
- } else {
- $this->debug(3, "Cache was cleaned less than " . FILE_CACHE_TIME_BETWEEN_CLEANS . " seconds ago so no cleaning needed.");
- }
- return false;
- }
- protected function processImageAndWriteToCache($localImage){
- $sData = getimagesize($localImage);
- $origType = $sData[2];
- $mimeType = $sData['mime'];
-
- $this->debug(3, "Mime type of image is $mimeType");
- if(! preg_match('/^image\/(?:gif|jpg|jpeg|png)$/i', $mimeType)){
- return $this->error("The image being resized is not a valid gif, jpg or png.");
- }
-
- if (!function_exists ('imagecreatetruecolor')) {
- return $this->error('GD Library Error: imagecreatetruecolor does not exist - please contact your webhost and ask them to install the GD library');
- }
-
- if (function_exists ('imagefilter') && defined ('IMG_FILTER_NEGATE')) {
- $imageFilters = array (
- 1 => array (IMG_FILTER_NEGATE, 0),
- 2 => array (IMG_FILTER_GRAYSCALE, 0),
- 3 => array (IMG_FILTER_BRIGHTNESS, 1),
- 4 => array (IMG_FILTER_CONTRAST, 1),
- 5 => array (IMG_FILTER_COLORIZE, 4),
- 6 => array (IMG_FILTER_EDGEDETECT, 0),
- 7 => array (IMG_FILTER_EMBOSS, 0),
- 8 => array (IMG_FILTER_GAUSSIAN_BLUR, 0),
- 9 => array (IMG_FILTER_SELECTIVE_BLUR, 0),
- 10 => array (IMG_FILTER_MEAN_REMOVAL, 0),
- 11 => array (IMG_FILTER_SMOOTH, 0),
- );
- }
-
- // get standard input properties
- $new_width = (int) abs ($this->param('w', 0));
- $new_height = (int) abs ($this->param('h', 0));
- $zoom_crop = (int) $this->param('zc', DEFAULT_ZC);
- $quality = (int) abs ($this->param('q', DEFAULT_Q));
- $align = $this->cropTop ? 't' : $this->param('a', 'c');
- $filters = $this->param('f', DEFAULT_F);
- $sharpen = (bool) $this->param('s', DEFAULT_S);
- $canvas_color = $this->param('cc', DEFAULT_CC);
- $canvas_trans = (bool) $this->param('ct', '1');
-
- // set default width and height if neither are set already
- if ($new_width == 0 && $new_height == 0) {
- $new_width = (int) DEFAULT_WIDTH;
- $new_height = (int) DEFAULT_HEIGHT;
- }
-
- // ensure size limits can not be abused
- $new_width = min ($new_width, MAX_WIDTH);
- $new_height = min ($new_height, MAX_HEIGHT);
-
- // set memory limit to be able to have enough space to resize larger images
- $this->setMemoryLimit();
-
- // open the existing image
- $image = $this->openImage ($mimeType, $localImage);
- if ($image === false) {
- return $this->error('Unable to open image.');
- }
-
- // Get original width and height
- $width = imagesx ($image);
- $height = imagesy ($image);
- $origin_x = 0;
- $origin_y = 0;
-
- // generate new w/h if not provided
- if ($new_width && !$new_height) {
- $new_height = floor ($height * ($new_width / $width));
- } else if ($new_height && !$new_width) {
- $new_width = floor ($width * ($new_height / $height));
- }
-
- // scale down and add borders
- if ($zoom_crop == 3) {
-
- $final_height = $height * ($new_width / $width);
-
- if ($final_height > $new_height) {
- $new_width = $width * ($new_height / $height);
- } else {
- $new_height = $final_height;
- }
-
- }
-
- // create a new true color image
- $canvas = imagecreatetruecolor ($new_width, $new_height);
- imagealphablending ($canvas, false);
-
- if (strlen($canvas_color) == 3) { //if is 3-char notation, edit string into 6-char notation
- $canvas_color = str_repeat(substr($canvas_color, 0, 1), 2) . str_repeat(substr($canvas_color, 1, 1), 2) . str_repeat(substr($canvas_color, 2, 1), 2);
- } else if (strlen($canvas_color) != 6) {
- $canvas_color = DEFAULT_CC; // on error return default canvas color
- }
-
- $canvas_color_R = hexdec (substr ($canvas_color, 0, 2));
- $canvas_color_G = hexdec (substr ($canvas_color, 2, 2));
- $canvas_color_B = hexdec (substr ($canvas_color, 4, 2));
-
- // Create a new transparent color for image
- // If is a png and PNG_IS_TRANSPARENT is false then remove the alpha transparency
- // (and if is set a canvas color show it in the background)
- if(preg_match('/^image\/png$/i', $mimeType) && !PNG_IS_TRANSPARENT && $canvas_trans){
- $color = imagecolorallocatealpha ($canvas, $canvas_color_R, $canvas_color_G, $canvas_color_B, 127);
- }else{
- $color = imagecolorallocatealpha ($canvas, $canvas_color_R, $canvas_color_G, $canvas_color_B, 0);
- }
-
-
- // Completely fill the background of the new image with allocated color.
- imagefill ($canvas, 0, 0, $color);
-
- // scale down and add borders
- if ($zoom_crop == 2) {
-
- $final_height = $height * ($new_width / $width);
-
- if ($final_height > $new_height) {
-
- $origin_x = $new_width / 2;
- $new_width = $width * ($new_height / $height);
- $origin_x = round ($origin_x - ($new_width / 2));
-
- } else {
-
- $origin_y = $new_height / 2;
- $new_height = $final_height;
- $origin_y = round ($origin_y - ($new_height / 2));
-
- }
-
- }
-
- // Restore transparency blending
- imagesavealpha ($canvas, true);
-
- if ($zoom_crop > 0) {
-
- $src_x = $src_y = 0;
- $src_w = $width;
- $src_h = $height;
-
- $cmp_x = $width / $new_width;
- $cmp_y = $height / $new_height;
-
- // calculate x or y coordinate and width or height of source
- if ($cmp_x > $cmp_y) {
-
- $src_w = round ($width / $cmp_x * $cmp_y);
- $src_x = round (($width - ($width / $cmp_x * $cmp_y)) / 2);
-
- } else if ($cmp_y > $cmp_x) {
-
- $src_h = round ($height / $cmp_y * $cmp_x);
- $src_y = round (($height - ($height / $cmp_y * $cmp_x)) / 2);
-
- }
-
- // positional cropping!
- if ($align) {
- if (strpos ($align, 't') !== false) {
- $src_y = 0;
- }
- if (strpos ($align, 'b') !== false) {
- $src_y = $height - $src_h;
- }
- if (strpos ($align, 'l') !== false) {
- $src_x = 0;
- }
- if (strpos ($align, 'r') !== false) {
- $src_x = $width - $src_w;
- }
- }
-
- imagecopyresampled ($canvas, $image, $origin_x, $origin_y, $src_x, $src_y, $new_width, $new_height, $src_w, $src_h);
-
- } else {
-
- // copy and resize part of an image with resampling
- imagecopyresampled ($canvas, $image, 0, 0, 0, 0, $new_width, $new_height, $width, $height);
-
- }
-
- if ($filters != '' && function_exists ('imagefilter') && defined ('IMG_FILTER_NEGATE')) {
- // apply filters to image
- $filterList = explode ('|', $filters);
- foreach ($filterList as $fl) {
-
- $filterSettings = explode (',', $fl);
- if (isset ($imageFilters[$filterSettings[0]])) {
-
- for ($i = 0; $i < 4; $i ++) {
- if (!isset ($filterSettings[$i])) {
- $filterSettings[$i] = null;
- } else {
- $filterSettings[$i] = (int) $filterSettings[$i];
- }
- }
-
- switch ($imageFilters[$filterSettings[0]][1]) {
-
- case 1:
-
- imagefilter ($canvas, $imageFilters[$filterSettings[0]][0], $filterSettings[1]);
- break;
-
- case 2:
-
- imagefilter ($canvas, $imageFilters[$filterSettings[0]][0], $filterSettings[1], $filterSettings[2]);
- break;
-
- case 3:
-
- imagefilter ($canvas, $imageFilters[$filterSettings[0]][0], $filterSettings[1], $filterSettings[2], $filterSettings[3]);
- break;
-
- case 4:
-
- imagefilter ($canvas, $imageFilters[$filterSettings[0]][0], $filterSettings[1], $filterSettings[2], $filterSettings[3], $filterSettings[4]);
- break;
-
- default:
-
- imagefilter ($canvas, $imageFilters[$filterSettings[0]][0]);
- break;
-
- }
- }
- }
- }
-
- // sharpen image
- if ($sharpen && function_exists ('imageconvolution')) {
-
- $sharpenMatrix = array (
- array (-1,-1,-1),
- array (-1,16,-1),
- array (-1,-1,-1),
- );
-
- $divisor = 8;
- $offset = 0;
-
- imageconvolution ($canvas, $sharpenMatrix, $divisor, $offset);
-
- }
- //Straight from Wordpress core code. Reduces filesize by up to 70% for PNG's
- if ( (IMAGETYPE_PNG == $origType || IMAGETYPE_GIF == $origType) && function_exists('imageistruecolor') && !imageistruecolor( $image ) && imagecolortransparent( $image ) > 0 ){
- imagetruecolortopalette( $canvas, false, imagecolorstotal( $image ) );
- }
-
- $imgType = "";
- $tempfile = tempnam($this->cacheDirectory, 'timthumb_tmpimg_');
- if(preg_match('/^image\/(?:jpg|jpeg)$/i', $mimeType)){
- $imgType = 'jpg';
- imagejpeg($canvas, $tempfile, $quality);
- } else if(preg_match('/^image\/png$/i', $mimeType)){
- $imgType = 'png';
- imagepng($canvas, $tempfile, floor($quality * 0.09));
- } else if(preg_match('/^image\/gif$/i', $mimeType)){
- $imgType = 'gif';
- imagegif($canvas, $tempfile);
- } else {
- return $this->sanityFail("Could not match mime type after verifying it previously.");
- }
-
- if($imgType == 'png' && OPTIPNG_ENABLED && OPTIPNG_PATH && @is_file(OPTIPNG_PATH)){
- $exec = OPTIPNG_PATH;
- $this->debug(3, "optipng'ing $tempfile");
- $presize = filesize($tempfile);
- $out = `$exec -o1 $tempfile`; //you can use up to -o7 but it really slows things down
- clearstatcache();
- $aftersize = filesize($tempfile);
- $sizeDrop = $presize - $aftersize;
- if($sizeDrop > 0){
- $this->debug(1, "optipng reduced size by $sizeDrop");
- } else if($sizeDrop < 0){
- $this->debug(1, "optipng increased size! Difference was: $sizeDrop");
- } else {
- $this->debug(1, "optipng did not change image size.");
- }
- } else if($imgType == 'png' && PNGCRUSH_ENABLED && PNGCRUSH_PATH && @is_file(PNGCRUSH_PATH)){
- $exec = PNGCRUSH_PATH;
- $tempfile2 = tempnam($this->cacheDirectory, 'timthumb_tmpimg_');
- $this->debug(3, "pngcrush'ing $tempfile to $tempfile2");
- $out = `$exec $tempfile $tempfile2`;
- $todel = "";
- if(is_file($tempfile2)){
- $sizeDrop = filesize($tempfile) - filesize($tempfile2);
- if($sizeDrop > 0){
- $this->debug(1, "pngcrush was succesful and gave a $sizeDrop byte size reduction");
- $todel = $tempfile;
- $tempfile = $tempfile2;
- } else {
- $this->debug(1, "pngcrush did not reduce file size. Difference was $sizeDrop bytes.");
- $todel = $tempfile2;
- }
- } else {
- $this->debug(3, "pngcrush failed with output: $out");
- $todel = $tempfile2;
- }
- @unlink($todel);
- }
-
- $this->debug(3, "Rewriting image with security header.");
- $tempfile4 = tempnam($this->cacheDirectory, 'timthumb_tmpimg_');
- $context = stream_context_create ();
- $fp = fopen($tempfile,'r',0,$context);
- file_put_contents($tempfile4, $this->filePrependSecurityBlock . $imgType . ' ?' . '>'); //6 extra bytes, first 3 being image type
- file_put_contents($tempfile4, $fp, FILE_APPEND);
- fclose($fp);
- @unlink($tempfile);
- $this->debug(3, "Locking and replacing cache file.");
- $lockFile = $this->cachefile . '.lock';
- $fh = fopen($lockFile, 'w');
- if(! $fh){
- return $this->error("Could not open the lockfile for writing an image.");
- }
- if(flock($fh, LOCK_EX)){
- @unlink($this->cachefile); //rename generally overwrites, but doing this in case of platform specific quirks. File might not exist yet.
- rename($tempfile4, $this->cachefile);
- flock($fh, LOCK_UN);
- fclose($fh);
- @unlink($lockFile);
- } else {
- fclose($fh);
- @unlink($lockFile);
- @unlink($tempfile4);
- return $this->error("Could not get a lock for writing.");
- }
- $this->debug(3, "Done image replace with security header. Cleaning up and running cleanCache()");
- imagedestroy($canvas);
- imagedestroy($image);
- return true;
- }
- protected function calcDocRoot(){
- $docRoot = @$_SERVER['DOCUMENT_ROOT'];
- if (defined('LOCAL_FILE_BASE_DIRECTORY')) {
- $docRoot = LOCAL_FILE_BASE_DIRECTORY;
- }
- if(!isset($docRoot)){
- $this->debug(3, "DOCUMENT_ROOT is not set. This is probably windows. Starting search 1.");
- if(isset($_SERVER['SCRIPT_FILENAME'])){
- $docRoot = str_replace( '\\', '/', substr($_SERVER['SCRIPT_FILENAME'], 0, 0-strlen($_SERVER['PHP_SELF'])));
- $this->debug(3, "Generated docRoot using SCRIPT_FILENAME and PHP_SELF as: $docRoot");
- }
- }
- if(!isset($docRoot)){
- $this->debug(3, "DOCUMENT_ROOT still is not set. Starting search 2.");
- if(isset($_SERVER['PATH_TRANSLATED'])){
- $docRoot = str_replace( '\\', '/', substr(str_replace('\\\\', '\\', $_SERVER['PATH_TRANSLATED']), 0, 0-strlen($_SERVER['PHP_SELF'])));
- $this->debug(3, "Generated docRoot using PATH_TRANSLATED and PHP_SELF as: $docRoot");
- }
- }
- if($docRoot && $_SERVER['DOCUMENT_ROOT'] != '/'){ $docRoot = preg_replace('/\/$/', '', $docRoot); }
- $this->debug(3, "Doc root is: " . $docRoot);
- $this->docRoot = $docRoot;
-
- }
- protected function getLocalImagePath($src){
- $src = ltrim($src, '/'); //strip off the leading '/'
- if(! $this->docRoot){
- $this->debug(3, "We have no document root set, so as a last resort, lets check if the image is in the current dir and serve that.");
- //We don't support serving images outside the current dir if we don't have a doc root for security reasons.
- $file = preg_replace('/^.*?([^\/\\\\]+)$/', '$1', $src); //strip off any path info and just leave the filename.
- if(is_file($file)){
- return $this->realpath($file);
- }
- return $this->error("Could not find your website document root and the file specified doesn't exist in timthumbs directory. We don't support serving files outside timthumb's directory without a document root for security reasons.");
- } else if ( ! is_dir( $this->docRoot ) ) {
- $this->error("Server path does not exist. Ensure variable \$_SERVER['DOCUMENT_ROOT'] is set correctly");
- }
-
- //Do not go past this point without docRoot set
-
- //Try src under docRoot
- if(file_exists ($this->docRoot . '/' . $src)) {
- $this->debug(3, "Found file as " . $this->docRoot . '/' . $src);
- $real = $this->realpath($this->docRoot . '/' . $src);
- if(stripos($real, $this->docRoot) === 0){
- return $real;
- } else {
- $this->debug(1, "Security block: The file specified occurs outside the document root.");
- //allow search to continue
- }
- }
- //Check absolute paths and then verify the real path is under doc root
- $absolute = $this->realpath('/' . $src);
- if($absolute && file_exists($absolute)){ //realpath does file_exists check, so can probably skip the exists check here
- $this->debug(3, "Found absolute path: $absolute");
- if(! $this->docRoot){ $this->sanityFail("docRoot not set when checking absolute path."); }
- if(stripos($absolute, $this->docRoot) === 0){
- return $absolute;
- } else {
- $this->debug(1, "Security block: The file specified occurs outside the document root.");
- //and continue search
- }
- }
-
- $base = $this->docRoot;
-
- // account for Windows directory structure
- if (strstr($_SERVER['SCRIPT_FILENAME'],':')) {
- $sub_directories = explode('\\', str_replace($this->docRoot, '', $_SERVER['SCRIPT_FILENAME']));
- } else {
- $sub_directories = explode('/', str_replace($this->docRoot, '', $_SERVER['SCRIPT_FILENAME']));
- }
-
- foreach ($sub_directories as $sub){
- $base .= $sub . '/';
- $this->debug(3, "Trying file as: " . $base . $src);
- if(file_exists($base . $src)){
- $this->debug(3, "Found file as: " . $base . $src);
- $real = $this->realpath($base . $src);
- if(stripos($real, $this->realpath($this->docRoot)) === 0){
- return $real;
- } else {
- $this->debug(1, "Security block: The file specified occurs outside the document root.");
- //And continue search
- }
- }
- }
- return false;
- }
- protected function realpath($path){
- //try to remove any relative paths
- $remove_relatives = '/\w+\/\.\.\//';
- while(preg_match($remove_relatives,$path)){
- $path = preg_replace($remove_relatives, '', $path);
- }
- //if any remain use PHP realpath to strip them out, otherwise return $path
- //if using realpath, any symlinks will also be resolved
- return preg_match('#^\.\./|/\.\./#', $path) ? realpath($path) : $path;
- }
- protected function toDelete($name){
- $this->debug(3, "Scheduling file $name to delete on destruct.");
- $this->toDeletes[] = $name;
- }
- protected function serveWebshot(){
- $this->debug(3, "Starting serveWebshot");
- $instr = "Please follow the instructions at http://code.google.com/p/timthumb/ to set your server up for taking website screenshots.";
- if(! is_file(WEBSHOT_CUTYCAPT)){
- return $this->error("CutyCapt is not installed. $instr");
- }
- if(! is_file(WEBSHOT_XVFB)){
- return $this->Error("Xvfb is not installed. $instr");
- }
- $cuty = WEBSHOT_CUTYCAPT;
- $xv = WEBSHOT_XVFB;
- $screenX = WEBSHOT_SCREEN_X;
- $screenY = WEBSHOT_SCREEN_Y;
- $colDepth = WEBSHOT_COLOR_DEPTH;
- $format = WEBSHOT_IMAGE_FORMAT;
- $timeout = WEBSHOT_TIMEOUT * 1000;
- $ua = WEBSHOT_USER_AGENT;
- $jsOn = WEBSHOT_JAVASCRIPT_ON ? 'on' : 'off';
- $javaOn = WEBSHOT_JAVA_ON ? 'on' : 'off';
- $pluginsOn = WEBSHOT_PLUGINS_ON ? 'on' : 'off';
- $proxy = WEBSHOT_PROXY ? ' --http-proxy=' . WEBSHOT_PROXY : '';
- $tempfile = tempnam($this->cacheDirectory, 'timthumb_webshot');
- $url = $this->src;
- if(! preg_match('/^https?:\/\/[a-zA-Z0-9\.\-]+/i', $url)){
- return $this->error("Invalid URL supplied.");
- }
- $url = preg_replace('/[^A-Za-z0-9\-\.\_:\/\?\&\+\;\=]+/', '', $url); //RFC 3986 plus ()$ chars to prevent exploit below. Plus the following are also removed: @*!~#[]',
- // 2014 update by Mark Maunder: This exploit: http://cxsecurity.com/issue/WLB-2014060134
- // uses the $(command) shell execution syntax to execute arbitrary shell commands as the web server user.
- // So we're now filtering out the characters: '$', '(' and ')' in the above regex to avoid this.
- // We are also filtering out chars rarely used in URLs but legal accoring to the URL RFC which might be exploitable. These include: @*!~#[]',
- // We're doing this because we're passing this URL to the shell and need to make very sure it's not going to execute arbitrary commands.
- if(WEBSHOT_XVFB_RUNNING){
- putenv('DISPLAY=:100.0');
- $command = "$cuty $proxy --max-wait=$timeout --user-agent=\"$ua\" --javascript=$jsOn --java=$javaOn --plugins=$pluginsOn --js-can-open-windows=off --url=\"$url\" --out-format=$format --out=$tempfile";
- } else {
- $command = "$xv --server-args=\"-screen 0, {$screenX}x{$screenY}x{$colDepth}\" $cuty $proxy --max-wait=$timeout --user-agent=\"$ua\" --javascript=$jsOn --java=$javaOn --plugins=$pluginsOn --js-can-open-windows=off --url=\"$url\" --out-format=$format --out=$tempfile";
- }
- $this->debug(3, "Executing command: $command");
- $out = `$command`;
- $this->debug(3, "Received output: $out");
- if(! is_file($tempfile)){
- $this->set404();
- return $this->error("The command to create a thumbnail failed.");
- }
- $this->cropTop = true;
- if($this->processImageAndWriteToCache($tempfile)){
- $this->debug(3, "Image processed succesfully. Serving from cache");
- return $this->serveCacheFile();
- } else {
- return false;
- }
- }
- protected function serveExternalImage(){
- if(! preg_match('/^https?:\/\/[a-zA-Z0-9\-\.]+/i', $this->src)){
- $this->error("Invalid URL supplied.");
- return false;
- }
- $tempfile = tempnam($this->cacheDirectory, 'timthumb');
- $this->debug(3, "Fetching external image into temporary file $tempfile");
- $this->toDelete($tempfile);
- #fetch file here
- if(! $this->getURL($this->src, $tempfile)){
- @unlink($this->cachefile);
- touch($this->cachefile);
- $this->debug(3, "Error fetching URL: " . $this->lastURLError);
- $this->error("Error reading the URL you specified from remote host." . $this->lastURLError);
- return false;
- }
-
- $mimeType = $this->getMimeType($tempfile);
- if(! preg_match("/^image\/(?:jpg|jpeg|gif|png)$/i", $mimeType)){
- $this->debug(3, "Remote file has invalid mime type: $mimeType");
- @unlink($this->cachefile);
- touch($this->cachefile);
- $this->error("The remote file is not a valid image. Mimetype = '" . $mimeType . "'" . $tempfile);
- return false;
- }
- if($this->processImageAndWriteToCache($tempfile)){
- $this->debug(3, "Image processed succesfully. Serving from cache");
- return $this->serveCacheFile();
- } else {
- return false;
- }
- }
- public static function curlWrite($h, $d){
- fwrite(self::$curlFH, $d);
- self::$curlDataWritten += strlen($d);
- if(self::$curlDataWritten > MAX_FILE_SIZE){
- return 0;
- } else {
- return strlen($d);
- }
- }
- protected function serveCacheFile(){
- $this->debug(3, "Serving {$this->cachefile}");
- if(! is_file($this->cachefile)){
- $this->error("serveCacheFile called in timthumb but we couldn't find the cached file.");
- return false;
- }
- $fp = fopen($this->cachefile, 'rb');
- if(! $fp){ return $this->error("Could not open cachefile."); }
- fseek($fp, strlen($this->filePrependSecurityBlock), SEEK_SET);
- $imgType = fread($fp, 3);
- fseek($fp, 3, SEEK_CUR);
- if(ftell($fp) != strlen($this->filePrependSecurityBlock) + 6){
- @unlink($this->cachefile);
- return $this->error("The cached image file seems to be corrupt.");
- }
- $imageDataSize = filesize($this->cachefile) - (strlen($this->filePrependSecurityBlock) + 6);
- $this->sendImageHeaders($imgType, $imageDataSize);
- $bytesSent = @fpassthru($fp);
- fclose($fp);
- if($bytesSent > 0){
- return true;
- }
- $content = file_get_contents ($this->cachefile);
- if ($content != FALSE) {
- $content = substr($content, strlen($this->filePrependSecurityBlock) + 6);
- echo $content;
- $this->debug(3, "Served using file_get_contents and echo");
- return true;
- } else {
- $this->error("Cache file could not be loaded.");
- return false;
- }
- }
- protected function sendImageHeaders($mimeType, $dataSize){
- if(! preg_match('/^image\//i', $mimeType)){
- $mimeType = 'image/' . $mimeType;
- }
- if(strtolower($mimeType) == 'image/jpg'){
- $mimeType = 'image/jpeg';
- }
- $gmdate_expires = gmdate ('D, d M Y H:i:s', strtotime ('now +10 days')) . ' GMT';
- $gmdate_modified = gmdate ('D, d M Y H:i:s') . ' GMT';
- // send content headers then display image
- header ('Content-Type: ' . $mimeType);
- header ('Accept-Ranges: none'); //Changed this because we don't accept range requests
- header ('Last-Modified: ' . $gmdate_modified);
- header ('Content-Length: ' . $dataSize);
- if(BROWSER_CACHE_DISABLE){
- $this->debug(3, "Browser cache is disabled so setting non-caching headers.");
- header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
- header("Pragma: no-cache");
- header('Expires: ' . gmdate ('D, d M Y H:i:s', time()));
- } else {
- $this->debug(3, "Browser caching is enabled");
- header('Cache-Control: max-age=' . BROWSER_CACHE_MAX_AGE . ', must-revalidate');
- header('Expires: ' . $gmdate_expires);
- }
- return true;
- }
- protected function securityChecks(){
- }
- protected function param($property, $default = ''){
- if (isset ($_GET[$property])) {
- return $_GET[$property];
- } else {
- return $default;
- }
- }
- protected function openImage($mimeType, $src){
- switch ($mimeType) {
- case 'image/jpeg':
- $image = imagecreatefromjpeg ($src);
- break;
-
- case 'image/png':
- $image = imagecreatefrompng ($src);
- imagealphablending( $image, true );
- imagesavealpha( $image, true );
- break;
-
- case 'image/gif':
- $image = imagecreatefromgif ($src);
- break;
-
- default:
- $this->error("Unrecognised mimeType");
- }
-
- return $image;
- }
- protected function getIP(){
- $rem = @$_SERVER["REMOTE_ADDR"];
- $ff = @$_SERVER["HTTP_X_FORWARDED_FOR"];
- $ci = @$_SERVER["HTTP_CLIENT_IP"];
- if(preg_match('/^(?:192\.168|172\.16|10\.|127\.)/', $rem)){
- if($ff){ return $ff; }
- if($ci){ return $ci; }
- return $rem;
- } else {
- if($rem){ return $rem; }
- if($ff){ return $ff; }
- if($ci){ return $ci; }
- return "UNKNOWN";
- }
- }
- protected function debug($level, $msg){
- if(DEBUG_ON && $level <= DEBUG_LEVEL){
- $execTime = sprintf('%.6f', microtime(true) - $this->startTime);
- $tick = sprintf('%.6f', 0);
- if($this->lastBenchTime > 0){
- $tick = sprintf('%.6f', microtime(true) - $this->lastBenchTime);
- }
- $this->lastBenchTime = microtime(true);
- error_log("TimThumb Debug line " . __LINE__ . " [$execTime : $tick]: $msg");
- }
- }
- protected function sanityFail($msg){
- return $this->error("There is a problem in the timthumb code. Message: Please report this error at <a href='http://code.google.com/p/timthumb/issues/list'>timthumb's bug tracking page</a>: $msg");
- }
- protected function getMimeType($file){
- $info = getimagesize($file);
- if(is_array($info) && $info['mime']){
- return $info['mime'];
- }
- return '';
- }
- protected function setMemoryLimit(){
- $inimem = ini_get('memory_limit');
- $inibytes = timthumb::returnBytes($inimem);
- $ourbytes = timthumb::returnBytes(MEMORY_LIMIT);
- if($inibytes < $ourbytes){
- ini_set ('memory_limit', MEMORY_LIMIT);
- $this->debug(3, "Increased memory from $inimem to " . MEMORY_LIMIT);
- } else {
- $this->debug(3, "Not adjusting memory size because the current setting is " . $inimem . " and our size of " . MEMORY_LIMIT . " is smaller.");
- }
- }
- protected static function returnBytes($size_str){
- switch (substr ($size_str, -1))
- {
- case 'M': case 'm': return (int)$size_str * 1048576;
- case 'K': case 'k': return (int)$size_str * 1024;
- case 'G': case 'g': return (int)$size_str * 1073741824;
- default: return $size_str;
- }
- }
-
- protected function getURL($url, $tempfile){
- $this->lastURLError = false;
- $url = preg_replace('/ /', '%20', $url);
- if(function_exists('curl_init')){
- $this->debug(3, "Curl is installed so using it to fetch URL.");
- self::$curlFH = fopen($tempfile, 'w');
- if(! self::$curlFH){
- $this->error("Could not open $tempfile for writing.");
- return false;
- }
- self::$curlDataWritten = 0;
- $this->debug(3, "Fetching url with curl: $url");
- $curl = curl_init($url);
- curl_setopt ($curl, CURLOPT_TIMEOUT, CURL_TIMEOUT);
- curl_setopt ($curl, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/534.30 (KHTML, like Gecko) Chrome/12.0.742.122 Safari/534.30");
- curl_setopt ($curl, CURLOPT_RETURNTRANSFER, TRUE);
- curl_setopt ($curl, CURLOPT_HEADER, 0);
- curl_setopt ($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
- curl_setopt ($curl, CURLOPT_WRITEFUNCTION, 'timthumb::curlWrite');
- @curl_setopt ($curl, CURLOPT_FOLLOWLOCATION, true);
- @curl_setopt ($curl, CURLOPT_MAXREDIRS, 10);
-
- $curlResult = curl_exec($curl);
- fclose(self::$curlFH);
- $httpStatus = curl_getinfo($curl, CURLINFO_HTTP_CODE);
- if($httpStatus == 404){
- $this->set404();
- }
- if($httpStatus == 302){
- $this->error("External Image is Redirecting. Try alternate image url");
- return false;
- }
- if($curlResult){
- curl_close($curl);
- return true;
- } else {
- $this->lastURLError = curl_error($curl);
- curl_close($curl);
- return false;
- }
- } else {
- $img = @file_get_contents ($url);
- if($img === false){
- $err = error_get_last();
- if(is_array($err) && $err['message']){
- $this->lastURLError = $err['message'];
- } else {
- $this->lastURLError = $err;
- }
- if(preg_match('/404/', $this->lastURLError)){
- $this->set404();
- }
-
- return false;
- }
- if(! file_put_contents($tempfile, $img)){
- $this->error("Could not write to $tempfile.");
- return false;
- }
- return true;
- }
-
- }
- protected function serveImg($file){
- $s = getimagesize($file);
- if(! ($s && $s['mime'])){
- return false;
- }
- header ('Content-Type: ' . $s['mime']);
- header ('Content-Length: ' . filesize($file) );
- header ('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
- header ("Pragma: no-cache");
- $bytes = @readfile($file);
- if($bytes > 0){
- return true;
- }
- $content = @file_get_contents ($file);
- if ($content != FALSE){
- echo $content;
- return true;
- }
- return false;
-
- }
- protected function set404(){
- $this->is404 = true;
- }
- protected function is404(){
- return $this->is404;
- }
-} \ No newline at end of file
diff --git a/libs/Utils.php b/libs/Utils.php
deleted file mode 100644
index 397448c..0000000
--- a/libs/Utils.php
+++ /dev/null
@@ -1,281 +0,0 @@
-<?php
-if (!defined('__TYPECHO_ROOT_DIR__')) exit;
-
-/**
- * Utils.php
- * 辅助工具
- *
- * Author: Eltrac(BigCoke233)
- * License: MIT
- */
-
-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);
- }
-
- /**
- * 判断插件是否可用(存在且已激活)
- */
- 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;
- }
-
- /**
- * 判定内容是否过时
- *
- * @return array
- */
- public static function isOutdated($archive)
- {
- date_default_timezone_set("Asia/Shanghai");
- $created = round((time()- $archive->created) / 3600 / 24);
- $updated = round((time()- $archive->modified) / 3600 / 24);
- return array("is" => $created > 90,
- "created" => $created,
- "updated" => $updated);
- }
-
- /**
- * 编辑界面添加内容
- */
- public static function addButton(){
- echo '<link rel="stylesheet" href="/usr/themes/Miracles/assets/css/setting.miracles.css" />';
- echo '<link rel="stylesheet" href="/usr/themes/Miracles/assets/css/owo.min.css" />';
- echo '<script src="/usr/themes/Miracles/assets/js/OwO.min.js"></script>';
- echo '<script src="/usr/themes/Miracles/assets/js/editor.js"></script>';
- echo '<style>#custom-field textarea{width:100%}
- .OwO span{background:none!important;width:unset!important;height:unset!important}
- .OwO .OwO-logo{
- z-index: unset!important;
- }
- .OwO .OwO-body .OwO-items{
- -webkit-overflow-scrolling: touch;
- overflow-x: hidden;
- }
- .OwO .OwO-body .OwO-items-image .OwO-item{
- max-width:-moz-calc(20% - 10px);
- max-width:-webkit-calc(20% - 10px);
- max-width:calc(20% - 10px)
- }
- #wmd-owo-button:hover{
- background:transparent!important}
- @media screen and (max-width:760px){
- .OwO .OwO-body .OwO-items-image .OwO-item{
- max-width:-moz-calc(25% - 10px);
- max-width:-webkit-calc(25% - 10px);
- max-width:calc(25% - 10px)
- }
- }</style>';
- }
-
- /**
- * 自动生成引用
- */
- public static function addRequires($files,$type,$cdn,$custom) {
- if ($cdn=='1'){
- $path = 'https://cdn.jsdelivr.net/gh/BigCoke233/miracles@'.themeVersion()."/assets/";
- }
- elseif ($cdn=='2'){
- $path = 'https://raw.githack.com/BigCoke233/miracles/master/assets/';
- }
- elseif ($cdn=='4'){
- $path = 'https://rawcdn.githack.com/BigCoke233/miracles/master/assets/';
- }
- elseif ($cdn=='5'){
- $path = 'https://cdn.9jojo.cn/Miracles/'.themeVersion().'/';
- }
- elseif ($cdn=='3'){
- $path = $custom;
- }else{
- $path = Helper::options()->themeUrl("","Miracles/assets");
- }
- foreach ($files as $file) {
- if ($type == "js"){
- echo "<script src=".$path. $type."/".$file.".".$type."></script>";
- }
- elseif ($type == "css"){
- echo "<link rel=\"stylesheet\" href=".$path. $type."/".$file.".".$type." />";
- }
- }
- }
-
- /**
- * 自动生成懒加载图片 url
- */
- public static function addLoadingImages($cdn, $loading_image, $type){
- if ($type=='normal'):
- $loading = $loading_image;
- elseif($type=='link'):
- $loading = 'avatar';
- elseif($type=='owo'):
- $loading = 'owo';
- endif;
-
- if ($cdn=='1' || $cdn=='6'){
- $path = 'https://cdn.jsdelivr.net/gh/BigCoke233/miracles@'.themeVersion()."/images/loading/".$loading.'.gif';
- }
- elseif ($cdn=='2'){
- $path = 'https://raw.githack.com/BigCoke233/miracles/master/images/loading/'.$loading.'.gif';
- }
- elseif ($cdn=='4'){
- $path = 'https://rawcdn.githack.com/BigCoke233/miracles/master/images/loading/'.$loading.'.gif';
- }
- elseif ($cdn=='5'){
- //9jojo CDN 并未提供图片缓存 则换用 jsDelivr
- $path = 'https://cdn.jsdelivr.net/gh/BigCoke233/miracles@'.themeVersion()."/images/loading/".$loading.'.gif';
- }
- elseif ($cdn=='3'){
- $path = $custom;
- }else{
- $path = Helper::options()->themeUrl("","Miracles/images/loading").$loading.'.gif';
- }
- return $path;
- }
-
- /**
- * 缩略图
- */
- public static function postBanner($post){
- if($post->fields->banner && $post->fields->banner=!''):
- $banner = $post->fields->banner;
- else:
- if($GLOBALS['miraclesOptions_randomBanner']==''){
- $banner = '/usr/themes/Miracles/images/postbg/';
- $banner .= srand(mb_strlen($post->title));
- $banner .= mt_rand(1,15).'.jpg';
- }
- else{
- $banner_url = explode(',', $GLOBALS['miraclesOptions_randomBanner']);
- $banner = $banner_url[mt_rand(0,count($banner_url)-1)];
- }
- endif;
- //使用 TimThumb 剪裁
- if($GLOBALS['miraclesIfTimThumb']=='on') {
- if($GLOBALS['miraclesIfTimThumbSize']=='regular'){
- $banner_size = '&h=336&w=564';
- }
- elseif($GLOBALS['miraclesIfTimThumbSize']=='big'){
- $banner_size = '&h=420&w=705';
- }
- elseif($GLOBALS['miraclesIfTimThumbSize']=='large'){
- $banner_size = '&h=504&w=846';
- }
- elseif($GLOBALS['miraclesIfTimThumbSize']=='huge'){
- $banner_size = '&h=560&w=940';
- }
- else{
- //避免有憨憨打错单词,当成 big 来算
- $banner_size = '&h=420&w=705';
- }
- $banner_url = '/usr/themes/Miracles/libs/TimThumb.php';
- $banner = $banner_url.'?src='.$banner.$banner_size;
- }
- //不知道为什么会有奇怪的空格,所以这里用暴力的方法去掉
- $banner = trim($banner);
-
- echo $banner;
- }
-
- /**
- * 压缩 HTML
- * thanks https://www.jiangxu.site/concerning-how-to-typecho-integrated-html-compression.html
- */
- public static function compressHtml($html_source) {
- $chunks = preg_split('/(<!--<nocompress>-->.*?<!--<\/nocompress>-->|<nocompress>.*?<\/nocompress>|<pre.*?\/pre>|<textarea.*?\/textarea>|<script.*?\/script>)/msi', $html_source, -1, PREG_SPLIT_DELIM_CAPTURE);
- $compress = '';
- foreach ($chunks as $c) {
- if (strtolower(substr($c, 0, 19)) == '<!--<nocompress>-->') {
- $c = substr($c, 19, strlen($c) - 19 - 20);
- $compress .= $c;
- continue;
- } else if (strtolower(substr($c, 0, 12)) == '<nocompress>') {
- $c = substr($c, 12, strlen($c) - 12 - 13);
- $compress .= $c;
- continue;
- } else if (strtolower(substr($c, 0, 4)) == '<pre' || strtolower(substr($c, 0, 9)) == '<textarea') {
- $compress .= $c;
- continue;
- } else if (strtolower(substr($c, 0, 7)) == '<script' && strpos($c, '//') != false && (strpos($c, "\r") !== false || strpos($c, "\n") !== false)) {
- $tmps = preg_split('/(\r|\n)/ms', $c, -1, PREG_SPLIT_NO_EMPTY);
- $c = '';
- foreach ($tmps as $tmp) {
- if (strpos($tmp, '//') !== false) {
- if (substr(trim($tmp), 0, 2) == '//') {
- continue;
- }
- $chars = preg_split('//', $tmp, -1, PREG_SPLIT_NO_EMPTY);
- $is_quot = $is_apos = false;
- foreach ($chars as $key => $char) {
- if ($char == '"' && $chars[$key - 1] != '\\' && !$is_apos) {
- $is_quot = !$is_quot;
- } else if ($char == '\'' && $chars[$key - 1] != '\\' && !$is_quot) {
- $is_apos = !$is_apos;
- } else if ($char == '/' && $chars[$key + 1] == '/' && !$is_quot && !$is_apos) {
- $tmp = substr($tmp, 0, $key);
- break;
- }
- }
- }
- $c .= $tmp;
- }
- }
- $c = preg_replace('/[\\n\\r\\t]+/', ' ', $c);
- $c = preg_replace('/\\s{2,}/', ' ', $c);
- $c = preg_replace('/>\\s</', '> <', $c);
- $c = preg_replace('/\\/\\*.*?\\*\\//i', '', $c);
- $c = preg_replace('/<!--[^!]*-->/', '', $c);
- $compress .= $c;
- }
- return $compress;
- }
-} \ No newline at end of file
diff --git a/libs/lang/en-us.php b/libs/lang/en-us.php
deleted file mode 100644
index e908ff4..0000000
--- a/libs/lang/en-us.php
+++ /dev/null
@@ -1,82 +0,0 @@
-<?php
-$GLOBALS['langInfo'] = array(
- "name" => "English",
- "author" => "Eltrac",
- "last_update" => "2020\/5\/3"
-);
-$GLOBALS['postTexts'] = array(
- "read_more" => "Read More",
- "sort_title" => "Category: %s",
- "post_time" => "Published on %s",
- "post_views" => "Viewd by %s people",
- "post_anchor" => "Paragraph Link",
- "post_share" => "Share by: ",
- "post_tag" => "None.",
- "post_timeAlert_1" => "This articles is published %s days ago and ",
- "post_timeAlert_2" => "last updated %s days ago, some information may be out of date."
-);
-$GLOBALS['commentFormTexts'] = array(
- "nameInput" => "Name*",
- "emailInput" => "Email*",
- "urlInput" => "http(s):\/\/",
- "submit" => "Comment",
- "submitLoading" => "Posting..."
-);
-$GLOBALS['commentListTexts'] = array(
- "byAuthor" => "Author",
- "commentNum" => "There're %s comments",
- "commentNumNone" => "Not any comments",
- "commentHidden" => "The author has hidden the comment list, you won't see your comment, either.",
- "commentClosed" => "The author has turned the comment function off.",
- "commentWaiting" => "Your comment is awaiting moderation!",
- "commentStatus" => "Hello, ",
- "commentLogout" => "Sign out"
-);
-$GLOBALS['footerTexts'] = array(
- "startTime" => "The site has built for",
- "startTimeDay" => " days ",
- "startTimeHour" => "h ",
- "startTimeMin" => "min ",
- "startTimeSec" => "s ",
- "startTimeYear" => " years "
-);
-$GLOBALS['headerTexts'] = array(
- "loginAlready" => "You've already loged in",
- "loginAlreadyInfo" => "But still nice to see you, %s~",
- "loginAdminEntrance" => "Enter the Dashboard",
- "loginTitle" => "Login",
- "loginUsername" => "Username",
- "loginPassword" => "Password",
- "loginSubmit" => "login",
- "navTitle" => "Navigation",
- "drawerHome" => "Home"
-);
-$GLOBALS['archivePageTexts'] = array(
- "archiveTagTitle" => "Tags",
- "archivePostTitle" => "Posts",
- "archiveCategoryTitle" => "Category",
- "archiveTimeYear" => "",
- "archiveYearTotal" => "%s articles in total",
- "archiveStart" => "Everything started on %s"
-);
-$GLOBALS['archivesTitles'] = array(
- 'category' => _t('Posts with category %s'),
- 'search' => _t('Posts with keyword %s'),
- 'tag' => _t('Posts with tag %s'),
- 'author' => _t('Posts by %s')
-);
-$GLOBALS['aboutPageTexts'] = array(
- "aboutShareGithub" => "GitHub",
- "aboutShareQQ" => "QQ",
- "aboutShareB" => "Bilibili",
- "aboutShareEmail" => "E-mail"
-);
-$GLOBALS['sayingPageTexts'] = array(
- "sayingPlaceholder" => "Anything interesting happening?",
- "sayingSubmit" => "Publish"
-);
-$GLOBALS['otherTexts'] = array(
- "copyrightAlertTitle" => "Copyright",
- "copyrightAlert" => "The content of the article is original unless otherwise stated. If you need to reproduce this article, remember to link to the original document (%s).The reproduction of any content is not allowed for modification, interpretation or commercial use, please respect the copyright.",
- "goTop" => "Go Top"
-); \ No newline at end of file
diff --git a/libs/lang/moe.php b/libs/lang/moe.php
deleted file mode 100644
index fbbc5a2..0000000
--- a/libs/lang/moe.php
+++ /dev/null
@@ -1,93 +0,0 @@
-<?php
-//语言包信息
-$GLOBALS['langInfo'] = array(
- "name" => "萌语",
- "author" => "Eltrac",
- "last_update" => "2020\/5\/3"
-);
-//文章
-$GLOBALS['postTexts'] = array(
- "read_more" => "戳进去康",
- "sort_title" => "垃圾分类:这是 %s 垃圾",
- "post_time" => "在 %s 的时候粗生的",
- "post_views" => "被偷窥 %s 次惹",
- "post_anchor" => "戳我!戳我!",
- "post_share" => "种草给:",
- "post_tag" => "这个人好懒哦,连标签都不写的",
- "post_timeAlert_1" => "这篇文是在 %s 天前水的,",
- "post_timeAlert_2" => "憨憨作者 %s 天前改了下,估计不能看了。"
-);
-//评论表单
-$GLOBALS['commentFormTexts'] = array(
- "nameInput" => "你叫啥名啊*",
- "emailInput" => "你的邮箱在哪哇*",
- "urlInput" => "http(s):\/\/",
- "submit" => "发粗去",
- "submitLoading" => "在发了在发了"
-);
-//评论列表
-$GLOBALS['commentListTexts'] = array(
- "byAuthor" => "傻子",
- "commentNum" => "%s 条咸鱼躺在这",
- "commentNumNone" => "连一条咸鱼都没有",
- "commentHidden" => "评论列表被博主吃了!你看不到评论了!",
- "commentClosed" => "评论功能被博主吃了!你不能评论了!",
- "commentWaiting" => "博主正在检查你有没有 ghs",
- "commentStatus" => "你素 ",
- "commentLogout" => "我不做人了!"
-);
-//页脚
-$GLOBALS['footerTexts'] = array(
- "startTime" => "苟延残喘了",
- "startTimeDay" => " 天 ",
- "startTimeHour" => " 小时 ",
- "startTimeMin" => " 分 ",
- "startTimeSec" => " 秒 ",
- "startTimeYear" => " 年 "
-);
-//页眉
-$GLOBALS['headerTexts'] = array(
- "loginAlready" => "登陆了,快爪巴",
- "loginAlreadyInfo" => "你素 %s!奶思吐蜜特由",
- "loginAdminEntrance" => "去后宫",
- "loginTitle" => "快点进来",
- "loginUsername" => "你哒名字",
- "loginPassword" => "密码!我不会看的 qwq",
- "loginSubmit" => "爪巴进去",
- "navTitle" => "要去哪里",
- "drawerHome" => "回家"
-);
-//归档页面
-$GLOBALS['archivePageTexts'] = array(
- "archiveTagTitle" => "博主贴的标签",
- "archiveCategoryTitle" => "乱分的类",
- "archivePostTitle" => "博主写的水文",
- "archiveTimeYear" => "年的水",
- "archiveYearTotal" => "这年水了 %s 篇文",
- "archiveStart" => "从 %s 开始水文"
-);
-//检索
-$GLOBALS['archivesTitles'] = array(
- 'category' => _t('分类 %s 下的水文'),
- 'search' => _t('搜 %s 粗来的水文'),
- 'tag' => _t('标签 %s 下的水文'),
- 'author' => _t('%s 这个憨憨水的文章')
-);
-//关于页面
-$GLOBALS['aboutPageTexts'] = array(
- "aboutShareGithub" => "GayHub",
- "aboutShareQQ" => "疼讯扣扣",
- "aboutShareB" => "某破站",
- "aboutShareEmail" => "是邮箱呢!"
-);
-//说说页面
-$GLOBALS['sayingPageTexts'] = array(
- "sayingPlaceholder" => "嘤嘤嘤 QAQ",
- "sayingSubmit" => "发粗去"
-);
-//其他
-$GLOBALS['otherTexts'] = array(
- "copyrightAlertTitle" => "水文也有版权!",
- "copyrightAlert" => "文章内容若未经过特别声明均为原创内容,转载需要注明原文作者和本文的链接:%s。原文中的任何内容不允许转载者进行修改、演绎以及一些商业用途,不尊重版权的憨憨会被大灰狼次掉。",
- "goTop" => "爬到上面"
-); \ No newline at end of file
diff --git a/libs/lang/zh-cn.php b/libs/lang/zh-cn.php
deleted file mode 100644
index c4d4220..0000000
--- a/libs/lang/zh-cn.php
+++ /dev/null
@@ -1,92 +0,0 @@
-<?php
-//语言包信息
-$GLOBALS['langInfo'] = array(
- "name" => "简体中文",
- "author" => "Eltrac",
- "last_update" => "2020\/7\/14"
-);
-//文章
-$GLOBALS['postTexts'] = array(
- "read_more" => "阅读全文",
- "sort_title" => "文章分类:%s",
- "post_time" => "该文章发布于 %s",
- "post_views" => "该文章被浏览 %s 次",
- "post_anchor" => "章节链接",
- "post_share" => "分享至:",
- "post_tag" => "这人还没有写标签哦~",
- "post_timeAlert_1" => "本文编写于 %s 天前,",
- "post_timeAlert_2" => "最后修改于 %s 天前,其中某些信息可能已经过时。"
-);
-//评论表单
-$GLOBALS['commentFormTexts'] = array(
- "nameInput" => "称呼*",
- "emailInput" => "邮箱*",
- "urlInput" => "http(s):\/\/",
- "submit" => "评论",
- "submitLoading" => "提交中..."
-);
-//评论列表
-$GLOBALS['commentListTexts'] = array(
- "byAuthor" => "博主",
- "commentNum" => "已有 %s 条评论",
- "commentNumNone" => "暂无评论",
- "commentHidden" => "博主已关闭本页面的评论显示,您评论后将不会看到您的评论内容",
- "commentClosed" => "博主已关闭本页面的评论功能",
- "commentWaiting" => "您的评论正在等待审核!",
- "commentStatus" => "登陆身份:",
- "commentLogout" => "登出"
-);
-//页脚
-$GLOBALS['footerTexts'] = array(
- "startTime" => "记录已延续了",
- "startTimeDay" => " 天 ",
- "startTimeHour" => " 小时 ",
- "startTimeMin" => " 分 ",
- "startTimeSec" => " 秒 ",
- "startTimeYear" => " 年 "
-);
-//页眉
-$GLOBALS['headerTexts'] = array(
- "loginAlready" => "你已经登陆了",
- "loginAlreadyInfo" => "不过康纳很乐意再次见到 %s 呢~",
- "loginAdminEntrance" => "进入后台",
- "loginTitle" => "登录后台",
- "loginUsername" => "请输入用户名",
- "loginPassword" => "请输入密码",
- "loginSubmit" => "登录",
- "navTitle" => "页面导航",
- "drawerHome" => "首页"
-);
-//归档页面
-$GLOBALS['archivePageTexts'] = array(
- "archiveTagTitle" => "文章标签",
- "archivePostTitle" => "文章归档",
- "archiveCategoryTitle" => "文章分类",
- "archiveTimeYear" => "年",
- "archiveYearTotal" => "共 %s 篇文章",
- "archiveStart" => "一切开始于 %s"
-);
-//检索
-$GLOBALS['archivesTitles'] = array(
- 'category' => _t('分类 %s 下的文章'),
- 'search' => _t('包含关键字 %s 的文章'),
- 'tag' => _t('标签 %s 下的文章'),
- 'author' => _t('%s 发布的文章')
-);
-//关于页面
-$GLOBALS['aboutPageTexts'] = array(
- "aboutShareGithub" => "GitHub",
- "aboutShareQQ" => "QQ",
- "aboutShareB" => "哔哩哔哩",
- "aboutShareEmail" => "电子邮件"
-);
-//说说页面
-$GLOBALS['sayingPageTexts'] = array(
- "sayingPlaceholder" => "有什么有趣的事情吗?",
- "sayingSubmit" => "发表新鲜事"
-);
-//其他
-$GLOBALS['otherTexts'] = array(
- "copyrightAlert" => "文章内容若未经过特别声明均为原创内容,转载需要注明原文作者和本文的链接:%s。原文中的任何内容不允许转载者进行修改、演绎以及一些商业用途,请尊重版权。",
- "goTop" => "返回顶部"
-); \ No newline at end of file
diff --git a/libs/lang/zh-tw.php b/libs/lang/zh-tw.php
deleted file mode 100644
index f23580c..0000000
--- a/libs/lang/zh-tw.php
+++ /dev/null
@@ -1,93 +0,0 @@
-<?php
-//語言包信息
-$GLOBALS['langInfo'] = array(
- "name" => "簡體中文",
- "author" => "Eltrac",
- "last_update" => "2020\/5\/3"
-);
-//文章
-$GLOBALS['postTexts'] = array(
- "read_more" => "閱讀全文",
- "sort_title" => "文章分類:%s",
- "post_time" => "該文章發佈於 %s",
- "post_views" => "該文章被瀏覽 %s 次",
- "post_anchor" => "章節鏈接",
- "post_share" => "分享至:",
- "post_tag" => "這人還沒有寫標籤哦~",
- "post_timeAlert_1" => "本文編寫於 %s 天前,",
- "post_timeAlert_2" => "最後修改於 %s 天前,其中某些信息可能已經過時。"
-);
-//評論表單
-$GLOBALS['commentFormTexts'] = array(
- "nameInput" => "稱呼 *",
- "emailInput" => "郵箱 *",
- "urlInput" => "http(s):\/\/",
- "submit" => "評論",
- "submitLoading" => "提交中..."
-);
-//評論列表
-$GLOBALS['commentListTexts'] = array(
- "byAuthor" => "博主",
- "commentNum" => "已有 %s 條評論",
- "commentNumNone" => "暫無評論",
- "commentHidden" => "博主已關閉本頁面的評論顯示,您評論後將不會看到您的評論內容",
- "commentClosed" => "博主已關閉本頁面的評論功能",
- "commentWaiting" => "您的評論正在等待審核!",
- "commentStatus" => "登陸身份:",
- "commentLogout" => "登出"
-);
-//頁腳
-$GLOBALS['footerTexts'] = array(
- "startTime" => "記錄已延續了",
- "startTimeDay" => " 天 ",
- "startTimeHour" => " 小時 ",
- "startTimeMin" => " 分 ",
- "startTimeSec" => " 秒 ",
- "startTimeYear" => " 年 "
-);
-//頁眉
-$GLOBALS['headerTexts'] = array(
- "loginAlready" => "你已經登陸了",
- "loginAlreadyInfo" => "不過康納很樂意再次見到 %s 呢~",
- "loginAdminEntrance" => "進入後台",
- "loginTitle" => "登錄後台",
- "loginUsername" => "請輸入用戶名",
- "loginPassword" => "請輸入密碼",
- "loginSubmit" => "登錄",
- "navTitle" => "頁面導航",
- "drawerHome" => "首頁"
-);
-//歸檔頁面
-$GLOBALS['archivePageTexts'] = array(
- "archiveTagTitle" => "文章標籤",
- "archivePostTitle" => "文章歸檔",
- "archiveCategoryTitle" => "文章分類",
- "archiveTimeYear" => "年",
- "archiveYearTotal" => "共 %s 篇文章",
- "archiveStart" => "壹切開始於 %s"
-);
-//检索
-$GLOBALS['archivesTitles'] = array(
- 'category' => _t('分類 %s 下的文章'),
- 'search' => _t('包含關鍵字 %s 的文章'),
- 'tag' => _t('標簽 %s 下的文章'),
- 'author' => _t('%s 發布的文章')
-);
-//關於頁面
-$GLOBALS['aboutPageTexts'] = array(
- "aboutShareGithub" => "GitHub",
- "aboutShareQQ" => "QQ",
- "aboutShareB" => "Bilibili",
- "aboutShareEmail" => "E-mail"
-);
-//說說頁面
-$GLOBALS['sayingPageTexts'] = array(
- "sayingPlaceholder" => "Anything interesting happening?",
- "sayingSubmit" => "發表新鮮事"
-);
-//其他
-$GLOBALS['otherTexts'] = array(
- "copyrightAlertTitle" => "版權",
- "copyrightAlert" => "文章內容若未經過特別聲明均為原創內容,轉載需要註明原文作者和本文的鏈接:%s。原文中的任何內容不允許轉載者進行修改、演繹以及壹些商業用途,請尊重版權。",
- "goTop" => "返回頂部"
-); \ No newline at end of file