From 52ab9c1909f39c8854e8235cddd351ef72505e91 Mon Sep 17 00:00:00 2001 From: BigCoke233 Date: Thu, 30 Jul 2020 23:49:46 +0800 Subject: =?UTF-8?q?:fire:=20Del:=20=E7=A7=BB=E9=99=A4=E6=97=A7=E7=89=88?= =?UTF-8?q?=E6=9C=AC=E6=89=80=E6=9C=89=E6=96=87=E4=BB=B6=EF=BC=8C=E5=87=86?= =?UTF-8?q?=E5=A4=87=202.0=20=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- libs/Comments.php | 51 -- libs/Contents.php | 448 ----------------- libs/Language.php | 41 -- libs/Options.php | 213 --------- libs/TableContents.php | 0 libs/TimThumb.php | 1251 ------------------------------------------------ libs/Utils.php | 281 ----------- libs/lang/en-us.php | 82 ---- libs/lang/moe.php | 93 ---- libs/lang/zh-cn.php | 92 ---- libs/lang/zh-tw.php | 93 ---- 11 files changed, 2645 deletions(-) delete mode 100644 libs/Comments.php delete mode 100644 libs/Contents.php delete mode 100644 libs/Language.php delete mode 100755 libs/Options.php delete mode 100644 libs/TableContents.php delete mode 100644 libs/TimThumb.php delete mode 100644 libs/Utils.php delete mode 100644 libs/lang/en-us.php delete mode 100644 libs/lang/moe.php delete mode 100644 libs/lang/zh-cn.php delete mode 100644 libs/lang/zh-tw.php (limited to 'libs') 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 @@ --->'; - echo ''; - echo ''; - } - - /** - * 获取上级评论人 - */ - 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 = '@'.$author.'';; - }else if($status=='waiting'){ - $href = '评论审核中···'; - } - } - 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 @@ -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('//','',$text); - //owo - $text = Contents::parseEmo($text); - //Links - $text = Contents::parseLink($text); - //toc - $text = preg_replace('/{:toc:}/s', '
'.Contents::tableOfContents($text).'
', $text); - } - return $text; - } - - /** - * 解析图片 - */ - static public function parseImages($text){ - //FancyBox & 图题 - $text = preg_replace('//s','
${4}
',$text); - - return $text; - } - - /** - * 解析 Text-Color - */ - static public function parseTextColor($text){ - $text = preg_replace('/\&\{(.*?)\|(.*?)\|(.*?)\}/s','${1}',$text); - return $text; - } - - /** - * 解析 Ruby - */ - static public function parseRuby($text){ - $reg = '/\{\{(.*?):(.*?)\}\}/s'; - $rp = '${1}(${2})'; - $text = preg_replace($reg,$rp,$text); - - return $text; - } - - /** - * 解析 Tip - */ - static public function parseTip($text){ - //Tip without var - $text = preg_replace('/\[tip\](.*?)\[\/tip\]/s','
${1}
',$text); - //Tip - $text = preg_replace('/\[tip type="(.*?)"\](.*?)\[\/tip\]/s','
${2}
',$text); - //Tip Group - $text = preg_replace('/\[tip\-group\](.*?)\[\/tip\-group\]/s','
${1}
',$text); - - return $text; - } - - /** - * 解析 Notice - */ - static public function parseNotice($text){ - $text = preg_replace('/\[notice\](.*?)\[\/notice\]/s','
${1}
',$text); - return $text; - } - - /** - * 图片加阴影 - */ - static public function parsePicShadow($text){ - $text = preg_replace('/\[shadow\](.*?)\[\/shadow\]/s','
${1}
',$text); - return $text; - } - - /** - * 解析友链 - */ - static public function parseLink($text) - { - //解析友链盒子 - $reg = '/\[links\](.*?)\[\/links\]/s'; - $rp = ''; - $text = preg_replace($reg, $rp, $text); - //解析友链项目 - $reg = '/\[(.*?)\]\{(.*?)\}\((.*?)\)\+\((.*?)\)/s'; - $rp = ''; - $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], '
对不起, 您的主机不支持 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 .= ''; - } - $text = str_replace($matches[0][$j], '', $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 ''; - } - - /** - * 阿鲁表情回调函数 - * - * @return string - */ - private static function parseAruBiaoqingCallback($match) - { - return ''; - } - - /** - * 推特表情回调函数 - * - * @return string - */ - private static function parseTweBiaoqingCallback($match) - { - return ''; - } - - /** - * 解析代码块 - */ - static public function parseCode($text) { - $text = preg_replace('/
/s','
',$text);
-		return $text;
-	}
-	
-	/**
-	 * 解析键盘按键
-	 */
-    static public function parseKbd($text) {
-		$text = preg_replace('/\[\[(.*?)\]\]/s','${1}',$text);
-		return $text;
-    }
-    
-    /**
-	 * 解析 
- */ - static public function parseDetails($text) { - $text = preg_replace('/\[details sum="(.*?)"\](.*?)\[\/details\]/s','
${1}${2}
',$text); - return $text; - } - - /* == 文章目录 == */ - - /** - * 解析章节链接 - */ - static public function parseHeadings($text){ - $reg='/\(.*?)\<\/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 ''.$matchs[3].''; - } - - /** - * 文章目录 - */ - public static function tableOfContents($html) { - $pattern = '/(.*?)<\/h\1>/'; - preg_match_all($pattern, $html, $matches, PREG_SET_ORDER); - $output = ""; - foreach ($matches as $item) { - $output .= ' -
  • - ' . $item[3] . ' -
  • '; - } - return (!empty($output)) ? - "
      " . $output . "
    " : - ""; - } - - /* == 其他内容 == */ - - /** - * 解析自定义导航栏 - */ - 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 ''. $title .''; - } - elseif($type=="mobile") { - echo ''; - } - elseif($type=="drawer") { - echo ''. $title .''; - } - } - } - - 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 ''; - else: echo ''; - endif; - } - elseif($type=="mobile"){ - if(!$action): echo ''; - else: echo ''; - 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 @@ -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 @@ -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 ' - - - - '; - echo '
    -

    Miracles 主题设置面板

    -

    欢迎使用 Miracles 主题,目前版本是:'. $ver .',正在获取最新版本号......
    - 作者博客:Eltrac\'s | - 帮助文档:WIKI | - 问题反馈:issues

    -
    -    -    - -
    '; - if(isset($_POST['type'])){ - //备份数据提示 - if($_POST["type"]=="备份模板设置数据"){ - if($db->fetchRow($db->select()->from ('table.options')->where ('name = ?', 'theme:'.$name.'bf'))){ - echo '
    备份已更新,请等待自动刷新!如果等不到请点击'; - ?>这里
    - 备份完成,请等待自动刷新!如果等不到请点击'; - ?> 这里
    - fetchRow($db->select()->from ('table.options')->where ('name = ?', 'theme:'.$name.'bf'))){ - echo '
    检测到模板备份数据,恢复完成,请等待自动刷新!如果等不到请点击'; - ?> 这里
    - - 没有模板备份数据,恢复不了哦!'; - } - } - //删除数据提示 - if($_POST["type"]=="删除备份数据"){ - if($db->fetchRow($db->select()->from ('table.options')->where ('name = ?', 'theme:'.$name.'bf'))){ - echo '
    删除成功,请等待自动刷新,如果等不到请点击'; - ?> - 这里
    - - 备份已经被删除了'; - ?>'; - - - /** - * 设置项 - */ - //Info - $bannerTitle = new Typecho_Widget_Helper_Form_Element_Text('bannerTitle', NULL, NULL, _t('

    站点信息 Information

    站点名称'), _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
    ')); - $form->addInput($favicon); - - //nav - $navStyle = new Typecho_Widget_Helper_Form_Element_Select('navStyle',array('0'=>'顶部导航栏','1'=>'左侧抽屉栏'),'0','

    导航栏 Nav

    类型','选择导航栏的类型(若选择左侧抽屉蓝,则下一条设置失效)'); - $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
    ')); - $form->addInput($customNavIcon); - - //index-banner - $bannerUrl = new Typecho_Widget_Helper_Form_Element_Text('bannerUrl', NULL, NULL, _t('

    首页大图 Banner

    图片 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"
    ')); - $form->addInput($bannerHeight); - - //pjax - $pjax = new Typecho_Widget_Helper_Form_Element_Select('pjax',array( - '0'=>'关闭', - '1'=>'开启' - ),'1','

    Pjax 预加载

    是否开启','Pjax 预加载功能的开关'); - $form->addInput($pjax); - $pjax_complete = new Typecho_Widget_Helper_Form_Element_Textarea('pjax_complete', NULL, NULL, _t('Pjax 回调函数'), _t('Pjax 跳转页面后执行的事件,写入 js 代码,一般将 Pjax 重载(回调)函数写在这里。
    ')); - $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','

    优化

    CDN 加速加载静态资源(Beta)', - '开启后静态资源文件通过选择的 CDN 进行调用,加快网页加载速度。如果选择自定义则需要填写下一个设置项。
    * 如果你使用开发版,请不要选择 jsDelivr/9jojo 作为 CDN
    * GitHack 是实时更新的,如果你不是随时更新开发版,最好不要选用
    * GitHack CDN 速度较慢,国内不建议使用,就是拿来凑数的
    在这里感谢小太为 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)','自动分割网页中的中英文,在全角字符和半角字符之间加上空格,也会修复一些标点符号的错误(.=>。),可能会有误判或是有人不喜欢,所以在这里加个按钮
    '); - $form->addInput($pangu); - - //custom style - $grayTheme = new Typecho_Widget_Helper_Form_Element_Select('grayTheme',array( - '0'=>'关闭', - '1'=>'开启' - ),'0','

    个性化

    哀悼模式','打开后网站变为黑白'); - $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('如果开启了建站时间将会输出在其之后,反之会输出在站点信息之后。在此写上你想展示的颜文字,多个颜文字用"&&"分割,每次刷新更换。如不想开启请留空。
    ')); - $form->addInput($AnimeFace); - - //developer - $headerEcho = new Typecho_Widget_Helper_Form_Element_Textarea('headerEcho', NULL, NULL, _t('

    开发者设置

    自定义头部信息'), _t('填写 html 代码,将输出在 <head> 标签中,可以在这里写上统计代码')); - $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 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 @@ - /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 = "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 = '
      '; - foreach($this->errors as $err){ - $html .= '
    • ' . htmlentities($err) . '
    • '; - } - $html .= '
    '; - echo '

    A TimThumb error has occured

    The following error(s) occured:
    ' . $html . '
    '; - echo '
    Query String : ' . htmlentities( $_SERVER['QUERY_STRING'], ENT_QUOTES ); - echo '
    TimThumb version : ' . VERSION . '
    '; - } - 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 timthumb's bug tracking page: $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 @@ -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 ''; - echo ''; - echo ''; - echo ''; - echo ''; - } - - /** - * 自动生成引用 - */ - 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 ""; - } - elseif ($type == "css"){ - echo ""; - } - } - } - - /** - * 自动生成懒加载图片 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>|||)/msi', $html_source, -1, PREG_SPLIT_DELIM_CAPTURE); - $compress = ''; - foreach ($chunks as $c) { - if (strtolower(substr($c, 0, 19)) == '') { - $c = substr($c, 19, strlen($c) - 19 - 20); - $compress .= $c; - continue; - } else if (strtolower(substr($c, 0, 12)) == '') { - $c = substr($c, 12, strlen($c) - 12 - 13); - $compress .= $c; - continue; - } else if (strtolower(substr($c, 0, 4)) == ' $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 @@ - "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 @@ - "萌语", - "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 @@ - "简体中文", - "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 @@ - "簡體中文", - "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 -- cgit v1.2.3