diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..485dee6 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.idea diff --git a/Action.php b/Action.php index 0ae8a8a..03daa5a 100644 --- a/Action.php +++ b/Action.php @@ -1,157 +1,177 @@ db = Typecho_Db::get(); - } - /** - * 添加新的链接转换 - * - */ - public function add(){ - $key = $this->request->key; - $key = $key ? $key : Typecho_Common::randString(8); - $target = $this->request->target; - if($target === "" || $target === "http://"){ - $this->widget('Widget_Notice')->set(_t('请输入目标链接。'), NULL, 'error'); - } - //判断key是否被占用 - elseif($this->getTarget($key)){ - $this->widget('Widget_Notice')->set(_t('该key已被使用,请更换key值。'), NULL, 'error'); - } else { - $links=array( - 'key' => $key, - 'target' => $this->request->target, - 'count' => 0 - ); - $insertId = $this->db->query($this->db->insert('table.shortlinks')->rows($links)); - } - } - - /** - * 修改链接 - * - */ - - public function edit(){ - $target = $this->request->url; - $id = $this->request->id; - if(trim($target) == "" || $target == "http://"){ - Typecho_Response::throwJson('error'); - }else{ - if($id){ - $this->db->query($this->db->update('table.shortlinks')->rows(array('target' => $target)) - ->where('id = ?', $id)); - Typecho_Response::throwJson('success'); - } - } - } - /** - *删除链接转换 - * - * @param int $id - */ - public function del($id){ - $this->db->query($this->db->delete('table.shortlinks') - ->where('id = ?', $id)); - - } - /** - * 链接重定向 - * - */ - public function shortlink(){ - $key = $this->request->key; - $siteUrl = preg_replace("/https?:\/\//", "", Typecho_Widget::widget('Widget_Options')->siteUrl); - $pOption = Typecho_Widget::widget('Widget_Options')->Plugin('ShortLinks'); // 插件选项 - $requestString = str_replace("|","/",$key); // 特殊字符处理 - $referer = $this->request->getReferer(); - // 允许空 referer - if (empty($referer) && $pOption->null_referer === "1") - $referer = $siteUrl; - $referer_list = ShortLinks_Plugin::textareaToArr($pOption->referer_list); // 允许的referer列表 - $target = $this->getTarget($key); - // 设置nofollow属性 - $this->response->setHeader('X-Robots-Tag','noindex, nofollow'); - if($target){ - // 自定义短链 - // 增加统计 - $count = $this->db->fetchObject($this->db->select('count') - ->from('table.shortlinks') - ->where('key = ?', $key))->count; - $count = $count+1; - $this->db->query($this->db->update('table.shortlinks') - ->rows(array('count' => $count)) - ->where('key = ?', $key)); - } else if ($requestString === base64_encode(base64_decode($requestString))){ - // 自动转换链接处理 - $target = base64_decode($requestString); - $allow_redirect = false; // 默认不允许跳转 - // 检查 referer - $allow_redirect = ShortLinks_Plugin::checkDomain($referer, $referer_list); - if (strpos($referer,$siteUrl) !== false) { - $allow_redirect = true; - } - if (!$allow_redirect) { - // referer 非法跳转到首页 - $this->response->redirect($siteUrl,301); - exit(); - } - } else { - throw new Typecho_Widget_Exception(_t('您访问的网页不存在'), 404); - } - if ($pOption->go_page == 0) { - // 无跳转页面 - $this->response->redirect(htmlspecialchars_decode($target),301); - } else { - $html = str_replace(array('{{url}}', '{{delay}}'), array($target, $pOption->go_delay), file_get_contents(__DIR__ . '/go.html')); - _e($html); - exit(); - } - } - /** - * 获取目标链接 - * - * @param string $key - * @return void - */ - public function getTarget($key){ - $target = $this->db->fetchRow($this->db->select('target') - ->from('table.shortlinks') - ->where(' key = ?' , $key)); - if(isset($target['target'])){ - return $target['target']; - }else{ - return FALSE; - } - } - - /** - * 重设自定义链接 - */ - public function resetLink(){ - $link = $this->request->link; - Helper::removeRoute('go'); - Helper::addRoute('go', $link, 'ShortLinks_Action', 'shortlink'); - Typecho_Response::throwJson('success'); - } - public function action(){ - $this->widget('Widget_User')->pass('administrator'); - $this->on($this->request->is('add'))->add(); - $this->on($this->request->is('edit'))->edit(); - $this->on($this->request->is('del'))->del($this->request->del); - $this->on($this->request->is('resetLink'))->resetLink(); - $this->response->goBack(); - } + private $db; + + public function __construct($request, $response, $params = NULL) + { + parent::__construct($request, $response, $params); + $this->db = Typecho_Db::get(); + } + + /** + * 添加新的链接转换 + * + */ + public function add() + { + $key = $this->request->key; + $key = $key ? $key : Typecho_Common::randString(8); + $target = $this->request->target; + if ($target === "" || $target === "http://") { + $this->widget('Widget_Notice')->set(_t('请输入目标链接。'), NULL, 'error'); + } //判断key是否被占用 + elseif ($this->getTarget($key)) { + $this->widget('Widget_Notice')->set(_t('该key已被使用,请更换key值。'), NULL, 'error'); + } else { + $links = array( + 'key' => $key, + 'target' => $this->request->target, + 'count' => 0 + ); + $insertId = $this->db->query($this->db->insert('table.shortlinks')->rows($links)); + } + } + + /** + * 修改链接 + * + */ + + public function edit() + { + $target = $this->request->url; + $id = $this->request->id; + if (trim($target) == "" || $target == "http://") { + Typecho_Response::throwJson('error'); + } else { + if ($id) { + $this->db->query($this->db->update('table.shortlinks')->rows(array('target' => $target)) + ->where('id = ?', $id)); + Typecho_Response::throwJson('success'); + } + } + } + + /** + *删除链接转换 + * + * @param int $id + */ + public function del($id) + { + $this->db->query($this->db->delete('table.shortlinks') + ->where('id = ?', $id)); + + } + + /** + * 链接重定向 + * + */ + public function shortlink() + { + $key = $this->request->key; + $siteUrl = preg_replace("/https?:\/\//", "", Typecho_Widget::widget('Widget_Options')->siteUrl); + $pOption = Typecho_Widget::widget('Widget_Options')->Plugin('ShortLinks'); // 插件选项 + $requestString = str_replace("|", "/", $key); // 特殊字符处理 + $referer = $this->request->getReferer(); + // 允许空 referer + if (empty($referer) && $pOption->null_referer === "1") + $referer = $siteUrl; + $referer_list = ShortLinks_Plugin::textareaToArr($pOption->referer_list); // 允许的referer列表 + $target = $this->getTarget($key); + // 设置nofollow属性 + $this->response->setHeader('X-Robots-Tag', 'noindex, nofollow'); + if ($target) { + // 自定义短链 + // 增加统计 + $count = $this->db->fetchObject($this->db->select('count') + ->from('table.shortlinks') + ->where('key = ?', $key))->count; + $count = $count + 1; + $this->db->query($this->db->update('table.shortlinks') + ->rows(array('count' => $count)) + ->where('key = ?', $key)); + } else if ($requestString === base64_encode(base64_decode($requestString))) { + // 自动转换链接处理 + $target = base64_decode($requestString); + $allow_redirect = false; // 默认不允许跳转 + // 检查 referer + $allow_redirect = ShortLinks_Plugin::checkDomain($referer, $referer_list); + if (strpos($referer, $siteUrl) !== false) { + $allow_redirect = true; + } + if (!$allow_redirect) { + // referer 非法跳转到首页 + $this->response->redirect($siteUrl, 301); + exit(); + } + } else { + throw new Typecho_Widget_Exception(_t('您访问的网页不存在'), 404); + } + + if ($pOption->go_template === 'NULL') { + // 无跳转页面 + $this->response->redirect(htmlspecialchars_decode($target), 301); + } else { + $filename = __DIR__ . DIRECTORY_SEPARATOR . 'templates' . DIRECTORY_SEPARATOR . $pOption->go_template . '.html'; + if (PATH_SEPARATOR !== ':') + $filename = mb_convert_encoding($filename, 'GBK', "auto"); + $contents = file_get_contents($filename); + $html = str_replace(array('{{url}}', '{{delay}}'), array($target, $pOption->go_delay), + $contents); + _e($html); + exit(); + } + } + + /** + * 获取目标链接 + * + * @param string $key + * @return void + */ + public function getTarget($key) + { + $target = $this->db->fetchRow($this->db->select('target') + ->from('table.shortlinks') + ->where(' key = ?', $key)); + if (isset($target['target'])) { + return $target['target']; + } else { + return FALSE; + } + } + + /** + * 重设自定义链接 + */ + public function resetLink() + { + $link = $this->request->link; + Helper::removeRoute('go'); + Helper::addRoute('go', $link, 'ShortLinks_Action', 'shortlink'); + Typecho_Response::throwJson('success'); + } + + public function action() + { + $this->widget('Widget_User')->pass('administrator'); + $this->on($this->request->is('add'))->add(); + $this->on($this->request->is('edit'))->edit(); + $this->on($this->request->is('del'))->del($this->request->del); + $this->on($this->request->is('resetLink'))->resetLink(); + $this->response->goBack(); + } } + ?> \ No newline at end of file diff --git a/Plugin.php b/Plugin.php index 1440f9a..002f453 100644 --- a/Plugin.php +++ b/Plugin.php @@ -1,4 +1,5 @@ * 通过菜单“创建->短链接”设置
@@ -6,202 +7,224 @@ * * @package ShortLinks * @author Ryan - * @version 1.0.9 + * @version 1.1.0 a1 * @link http://blog.iplayloli.com/typecho-plugin-shortlinks.html */ - class ShortLinks_Plugin implements Typecho_Plugin_Interface - { - /** - * 激活插件方法,如果激活失败,直接抛出异常 - * - * @access public - * @return String - * @throws Typecho_Plugin_Exception - */ - public static function activate() - { - $db = Typecho_Db::get(); - $shortlinks = $db->getPrefix() . 'shortlinks'; - $adapter = $db->getAdapterName(); - if("Pdo_SQLite" === $adapter || "SQLite" === $adapter){ - $db->query(" CREATE TABLE IF NOT EXISTS ". $shortlinks ." ( +class ShortLinks_Plugin implements Typecho_Plugin_Interface +{ + /** + * 激活插件方法,如果激活失败,直接抛出异常 + * + * @access public + * @return String + * @throws Typecho_Plugin_Exception + */ + public static function activate() + { + $db = Typecho_Db::get(); + $shortlinks = $db->getPrefix() . 'shortlinks'; + $adapter = $db->getAdapterName(); + if ("Pdo_SQLite" === $adapter || "SQLite" === $adapter) { + $db->query(" CREATE TABLE IF NOT EXISTS " . $shortlinks . " ( id INTEGER PRIMARY KEY, key TEXT, target TEXT, count NUMERIC)"); - } - if("Pdo_Mysql" === $adapter || "Mysql" === $adapter){ - $db->query("CREATE TABLE IF NOT EXISTS ". $shortlinks ." ( + } + if ("Pdo_Mysql" === $adapter || "Mysql" === $adapter) { + $db->query("CREATE TABLE IF NOT EXISTS " . $shortlinks . " ( `id` int(8) NOT NULL AUTO_INCREMENT, `key` varchar(64) NOT NULL, `target` varchar(10000) NOT NULL, `count` int(8) DEFAULT '0', PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1"); - } - Helper::addAction('shortlinks', 'ShortLinks_Action'); - Helper::addRoute('go', '/go/[key]/', 'ShortLinks_Action', 'shortlink'); - Helper::addPanel(2, 'ShortLinks/panel.php', '短链接', '短链接管理', 'administrator'); - Typecho_Plugin::factory('Widget_Abstract_Contents')->contentEx = array('ShortLinks_Plugin','replace'); - Typecho_Plugin::factory('Widget_Abstract_Contents')->excerptEx = array('ShortLinks_Plugin','replace'); - Typecho_Plugin::factory('Widget_Abstract_Contents')->filter = array('ShortLinks_Plugin','replace'); - Typecho_Plugin::factory('Widget_Abstract_Comments')->filter = array('ShortLinks_Plugin','replace'); - Typecho_Plugin::factory('Widget_Archive')->singleHandle = array('ShortLinks_Plugin','replace'); - return('数据表 '.$shortlinks.' 创建成功, 插件已经成功激活!'); - } - /** - * 禁用插件方法,如果禁用失败,直接抛出异常 - * - * @static - * @access public - * @return String - * @throws Typecho_Plugin_Exception - */ - public static function deactivate() - { - Helper::removeRoute('go'); - Helper::removeAction('shortlinks'); - Helper::removePanel(2, 'ShortLinks/panel.php'); - return('短链接插件已被禁用,但是数据表并没有被删除'); - } - /** - * 获取插件配置面板 - * - * @access public - * @param Typecho_Widget_Helper_Form $form 配置面板 - * @return void - */ - public static function config(Typecho_Widget_Helper_Form $form) - { - $radio = new Typecho_Widget_Helper_Form_Element_Radio('convert' , array('1'=>_t('开启'),'0'=>_t('关闭')),'1',_t('外链转内链'),_t('开启后会帮你把外链转换成内链')); - $form->addInput($radio); - $radio = new Typecho_Widget_Helper_Form_Element_Radio('convert_comment_link' , array('1'=>_t('开启'),'0'=>_t('关闭')),'1',_t('转换评论者链接'),_t('开启后会帮你把评论者链接转换成内链')); - $form->addInput($radio); - $radio = new Typecho_Widget_Helper_Form_Element_Radio('go_page' , array('1'=>_t('开启'),'0'=>_t('关闭')),'1',_t('跳转页面开关'),_t('开启后会展示跳转页面')); - $form->addInput($radio); - $edit = new Typecho_Widget_Helper_Form_Element_Text('go_delay', NULL, _t('3'), _t('跳转延时'), _t('跳转页面停留时间')); - $form->addInput($edit); - $radio = new Typecho_Widget_Helper_Form_Element_Radio('target' , array('1'=>_t('开启'),'0'=>_t('关闭')),'1',_t('新窗口打开文章中的链接'),_t('开启后会帮你文章中的链接新增target属性')); - $form->addInput($radio); - $textarea = new Typecho_Widget_Helper_Form_Element_Textarea('convert_custom_field', NULL, NULL, _t('需要处理的自定义字段'), _t('在这里设置需要处理的自定义字段,一行一个(实验性功能)')); - $form->addInput($textarea); - $radio = new Typecho_Widget_Helper_Form_Element_Radio('null_referer' , array('1'=>_t('开启'),'0'=>_t('关闭')),'1',_t('空Referer开关'),_t('开启后会允许空Referer')); - $form->addInput($radio); - $referer_list = new Typecho_Widget_Helper_Form_Element_Textarea('referer_list', NULL, NULL, _t('referer 白名单'), _t('在这里设置 referer 白名单,一行一个')); - $form->addInput($referer_list); - $nonConvertList = new Typecho_Widget_Helper_Form_Element_Textarea('nonConvertList', NULL, _t("b0.upaiyun.com" . PHP_EOL ."glb.clouddn.com" . PHP_EOL ."qbox.me" . PHP_EOL ."qnssl.com"), _t('外链转换白名单'), _t('在这里设置外链转换白名单(评论者链接不生效)')); - $form->addInput($nonConvertList); - } - /** - * 个人用户的配置面板 - * - * @access public - * @param Typecho_Widget_Helper_Form $form - * @return void - */ - public static function personalConfig(Typecho_Widget_Helper_Form $form){} - /** - * 外链转内链 - * - * @access public - * @param $content - * @param $class - * @return $content - */ - public static function replace($text, $widget, $lastResult) { - $text = empty($lastResult) ? $text : $lastResult; - $pluginOption = Typecho_Widget::widget('Widget_Options')->Plugin('ShortLinks'); // 插件选项 - $siteUrl = Helper::options()->siteUrl; - $target = ($pluginOption->target) ? ' target="_blank" ' : ''; // 新窗口打开 - if($pluginOption->convert == 1) { - if (!is_string($text) && $text instanceof Widget_Archive) { - // 自定义字段处理 - $fieldsList = self::textareaToArr($pluginOption->convert_custom_field); - if ($fieldsList) { - foreach ($fieldsList as $field) { - if (isset($text->fields[$field])) { - @preg_match_all('//',$text->fields[$field], $matches); - if($matches){ - foreach($matches[2] as $link){ - $text->fields[$field] = str_replace("href=\"$link\"", "href=\"". self::convertLink($link) . "\"", $text->fields[$field]); - } - } - } - } - } - } - if (($widget instanceof Widget_Archive)||($widget instanceof Widget_Abstract_Comments)) { - $fields = unserialize($widget->fields); - if (is_array($fields)&&array_key_exists("noshort", $fields)) - return $text; - // 文章内容和评论内容处理 - @preg_match_all('//', $text, $matches); - if($matches){ - foreach($matches[2] as $link){ - $text= str_replace("href=\"$link\"", "href=\"". self::convertLink($link) . "\"" . $target, $text); - } - } - } - if ($pluginOption->convert_comment_link == 1 && $widget instanceof Widget_Abstract_Comments) { - // 评论者链接处理 - $url = $text['url']; - if(strpos($url,'://')!==false && strpos($url, rtrim($siteUrl, '/'))===false) { - $text['url'] = self::convertLink($url, false); - } - } - } - return $text; - } - /** - * 转换链接形式 - * - * @access public - * @param $link - * @return $string - */ - public static function convertLink($link, $check = true) { - $rewrite = (Helper::options()->rewrite) ? '' : 'index.php/'; // 伪静态处理 - $pluginOption = Typecho_Widget::widget('Widget_Options')->Plugin('ShortLinks'); // 插件选项 - $linkBase = ltrim(rtrim(Typecho_Router::get('go')['url'] , '/'), '/'); // 防止链接形式修改后不能用 - $siteUrl = Helper::options()->siteUrl; - $target = ($pluginOption->target) ? ' target="_blank" ' : ''; // 新窗口打开 - $nonConvertList = self::textareaToArr($pluginOption->nonConvertList); // 不转换列表 - if ($check) { - if (strpos($link, '://') !== false && strpos($link, rtrim($siteUrl, '/')) !== false) return $link; //本站链接不处理 - if (self::checkDomain($link, $nonConvertList)) return $link; // 不转换列表中的不处理 - if (preg_match('/\.(jpg|jepg|png|ico|bmp|gif|tiff)/i',$link)) return $link; // 图片不处理 - } - return $siteUrl . $rewrite. str_replace('[key]', str_replace("/","|",base64_encode(htmlspecialchars_decode($link))), $linkBase); - } - /** - * 检查域名是否在数组中存在 - * - * @access public - * @param $url $arr - * @param $class - * @return boolean - */ - public static function checkDomain($url, $arr) { - if ($arr === null) return false; - if (count($arr) === 0) return false; - foreach($arr as $a) { - if (strpos($url, $a) !== false) { - return true; - } - } - return false; - } - /** - * 一行一个文本框转数组 - * - * @access public - * @param $textarea - * @param $class - * @return $arr - */ - public static function textareaToArr($textarea) { - $str = str_replace(array("\r\n", "\r", "\n"), "|", $textarea); - if ($str == "") return null; - return explode("|", $str); - } - } + } + Helper::addAction('shortlinks', 'ShortLinks_Action'); + Helper::addRoute('go', '/go/[key]/', 'ShortLinks_Action', 'shortlink'); + Helper::addPanel(2, 'ShortLinks/panel.php', '短链接', '短链接管理', 'administrator'); + Typecho_Plugin::factory('Widget_Abstract_Contents')->contentEx = array('ShortLinks_Plugin', 'replace'); + Typecho_Plugin::factory('Widget_Abstract_Contents')->excerptEx = array('ShortLinks_Plugin', 'replace'); + Typecho_Plugin::factory('Widget_Abstract_Contents')->filter = array('ShortLinks_Plugin', 'replace'); + Typecho_Plugin::factory('Widget_Abstract_Comments')->filter = array('ShortLinks_Plugin', 'replace'); + Typecho_Plugin::factory('Widget_Archive')->singleHandle = array('ShortLinks_Plugin', 'replace'); + return ('数据表 ' . $shortlinks . ' 创建成功, 插件已经成功激活!'); + } + + /** + * 禁用插件方法,如果禁用失败,直接抛出异常 + * + * @static + * @access public + * @return String + * @throws Typecho_Plugin_Exception + */ + public static function deactivate() + { + Helper::removeRoute('go'); + Helper::removeAction('shortlinks'); + Helper::removePanel(2, 'ShortLinks/panel.php'); + return ('短链接插件已被禁用,但是数据表并没有被删除'); + } + + /** + * 获取插件配置面板 + * + * @access public + * @param Typecho_Widget_Helper_Form $form 配置面板 + * @return void + */ + public static function config(Typecho_Widget_Helper_Form $form) + { + $radio = new Typecho_Widget_Helper_Form_Element_Radio('convert', array('1' => _t('开启'), '0' => _t('关闭')), '1', _t('外链转内链'), _t('开启后会帮你把外链转换成内链')); + $form->addInput($radio); + $radio = new Typecho_Widget_Helper_Form_Element_Radio('convert_comment_link', array('1' => _t('开启'), '0' => _t('关闭')), '1', _t('转换评论者链接'), _t('开启后会帮你把评论者链接转换成内链')); + $form->addInput($radio); + $template_files = scandir(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'templates'); + $go_templates = array('NULL' => '不使用'); + foreach ($template_files as $item) { + if (PATH_SEPARATOR !== ':') + $item = mb_convert_encoding($item, "UTF-8", "GBK"); + $name = mb_split("\.", $item)[0]; + if (empty($name)) continue; + $go_templates[$name] = $name; + } + $edit = new Typecho_Widget_Helper_Form_Element_Select('go_template', $go_templates, '默认模板', _t('跳转页面模板')); + $form->addInput($edit); + $edit = new Typecho_Widget_Helper_Form_Element_Text('go_delay', NULL, _t('3'), _t('跳转延时'), _t('跳转页面停留时间')); + $form->addInput($edit); + $radio = new Typecho_Widget_Helper_Form_Element_Radio('target', array('1' => _t('开启'), '0' => _t('关闭')), '1', _t('新窗口打开文章中的链接'), _t('开启后会帮你文章中的链接新增target属性')); + $form->addInput($radio); + $textarea = new Typecho_Widget_Helper_Form_Element_Textarea('convert_custom_field', NULL, NULL, _t('需要处理的自定义字段'), _t('在这里设置需要处理的自定义字段,一行一个(实验性功能)')); + $form->addInput($textarea); + $radio = new Typecho_Widget_Helper_Form_Element_Radio('null_referer', array('1' => _t('开启'), '0' => _t('关闭')), '1', _t('空Referer开关'), _t('开启后会允许空Referer')); + $form->addInput($radio); + $referer_list = new Typecho_Widget_Helper_Form_Element_Textarea('referer_list', NULL, NULL, _t('referer 白名单'), _t('在这里设置 referer 白名单,一行一个')); + $form->addInput($referer_list); + $nonConvertList = new Typecho_Widget_Helper_Form_Element_Textarea('nonConvertList', NULL, _t("b0.upaiyun.com" . PHP_EOL . "glb.clouddn.com" . PHP_EOL . "qbox.me" . PHP_EOL . "qnssl.com"), _t('外链转换白名单'), _t('在这里设置外链转换白名单(评论者链接不生效)')); + $form->addInput($nonConvertList); + } + + /** + * 个人用户的配置面板 + * + * @access public + * @param Typecho_Widget_Helper_Form $form + * @return void + */ + public static function personalConfig(Typecho_Widget_Helper_Form $form) + { + } + + /** + * 外链转内链 + * + * @access public + * @param $content + * @param $class + * @return $content + */ + public static function replace($text, $widget, $lastResult) + { + $text = empty($lastResult) ? $text : $lastResult; + $pluginOption = Typecho_Widget::widget('Widget_Options')->Plugin('ShortLinks'); // 插件选项 + $siteUrl = Helper::options()->siteUrl; + $target = ($pluginOption->target) ? ' target="_blank" ' : ''; // 新窗口打开 + if ($pluginOption->convert == 1) { + if (!is_string($text) && $text instanceof Widget_Archive) { + // 自定义字段处理 + $fieldsList = self::textareaToArr($pluginOption->convert_custom_field); + if ($fieldsList) { + foreach ($fieldsList as $field) { + if (isset($text->fields[$field])) { + @preg_match_all('//', $text->fields[$field], $matches); + if ($matches) { + foreach ($matches[2] as $link) { + $text->fields[$field] = str_replace("href=\"$link\"", "href=\"" . self::convertLink($link) . "\"", $text->fields[$field]); + } + } + } + } + } + } + if (($widget instanceof Widget_Archive) || ($widget instanceof Widget_Abstract_Comments)) { + $fields = unserialize($widget->fields); + if (is_array($fields) && array_key_exists("noshort", $fields)) + return $text; + // 文章内容和评论内容处理 + @preg_match_all('//', $text, $matches); + if ($matches) { + foreach ($matches[2] as $link) { + $text = str_replace("href=\"$link\"", "href=\"" . self::convertLink($link) . "\"" . $target, $text); + } + } + } + if ($pluginOption->convert_comment_link == 1 && $widget instanceof Widget_Abstract_Comments) { + // 评论者链接处理 + $url = $text['url']; + if (strpos($url, '://') !== false && strpos($url, rtrim($siteUrl, '/')) === false) { + $text['url'] = self::convertLink($url, false); + } + } + } + return $text; + } + + /** + * 转换链接形式 + * + * @access public + * @param $link + * @return $string + */ + public static function convertLink($link, $check = true) + { + $rewrite = (Helper::options()->rewrite) ? '' : 'index.php/'; // 伪静态处理 + $pluginOption = Typecho_Widget::widget('Widget_Options')->Plugin('ShortLinks'); // 插件选项 + $linkBase = ltrim(rtrim(Typecho_Router::get('go')['url'], '/'), '/'); // 防止链接形式修改后不能用 + $siteUrl = Helper::options()->siteUrl; + $target = ($pluginOption->target) ? ' target="_blank" ' : ''; // 新窗口打开 + $nonConvertList = self::textareaToArr($pluginOption->nonConvertList); // 不转换列表 + if ($check) { + if (strpos($link, '://') !== false && strpos($link, rtrim($siteUrl, '/')) !== false) return $link; //本站链接不处理 + if (self::checkDomain($link, $nonConvertList)) return $link; // 不转换列表中的不处理 + if (preg_match('/\.(jpg|jepg|png|ico|bmp|gif|tiff)/i', $link)) return $link; // 图片不处理 + } + return $siteUrl . $rewrite . str_replace('[key]', str_replace("/", "|", base64_encode(htmlspecialchars_decode($link))), $linkBase); + } + + /** + * 检查域名是否在数组中存在 + * + * @access public + * @param $url $arr + * @param $class + * @return boolean + */ + public static function checkDomain($url, $arr) + { + if ($arr === null) return false; + if (count($arr) === 0) return false; + foreach ($arr as $a) { + if (strpos($url, $a) !== false) { + return true; + } + } + return false; + } + + /** + * 一行一个文本框转数组 + * + * @access public + * @param $textarea + * @param $class + * @return $arr + */ + public static function textareaToArr($textarea) + { + $str = str_replace(array("\r\n", "\r", "\n"), "|", $textarea); + if ($str == "") return null; + return explode("|", $str); + } +} diff --git a/README.md b/README.md index 2608f25..354121e 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ Typecho外链转内链插件,支持正文和评论者链接 2. 通过菜单“创建->短链接”设置; 3. 自定义短链功能来自[golinks](http://defe.me/prg/429.html "golinks"); 4. 支持 referer 白名单和外链转换白名单; -5. 支持跳转页面; +5. 支持跳转页面,可以自行制作模板放到templates目录下,插件设置里可选择,目前自带5个模板; 6. 支持自定义字段转换(实验性功能); 7. 支持关闭指定页面的链接转换功能。添加自定义字段`noshort`即可; @@ -22,5 +22,7 @@ Typecho外链转内链插件,支持正文和评论者链接 [DEFE](http://defe.me/prg/429.html "golinks") +[左岸](https://www.zrahh.com/archives/451.html "左岸") + ### 预览 暂时没有 diff --git a/panel.php b/panel.php index 45388f6..091fd12 100644 --- a/panel.php +++ b/panel.php @@ -3,82 +3,87 @@ include 'menu.php'; ?>
-
- -
-
-
-
    -
  • -
    -     KEY:     - 目标: - -
    -
  • - -
  • - - 自定义链接: - -
  • -
-
-
- - - - - - - - - - - - - - - - - - - page) ? $request->page : 1 ; ?> - fetchAll($db->select()->from('table.shortlinks')->page($page, 15)->order('table.shortlinks.id', Typecho_Db::SORT_DESC)); ?> - - - - - - - - - - -
- - - - index($rourl);?> - - 修改 - -
-
-
-
-
    - fetchObject($db->select(array('COUNT(id)' => 'num'))->from('table.shortlinks'))->num; ?> - -
  • - +
    + +
    +
    +
    +
      +
    • +
      +     KEY:     + 目标: + +
      +
    • -
    -
    -
    -
    -
    -
+
  • + + 自定义链接: + +
  • + +
    +
    + + + + + + + + + + + + + + + + + + + page) ? $request->page : 1; ?> + fetchAll($db->select()->from('table.shortlinks')->page($page, 15)->order('table.shortlinks.id', Typecho_Db::SORT_DESC)); ?> + + + + + + + + + + +
    + + + + index($rourl); ?> + + 修改 + +
    +
    +
    +
    +
      + fetchObject($db->select(array('COUNT(id)' => 'num'))->from('table.shortlinks'))->num; ?> + +
    • +
    • + + +
    +
    +
    +
    +
    +
    diff --git "a/templates/\346\250\241\346\235\277 (1).html" "b/templates/\346\250\241\346\235\277 (1).html" new file mode 100644 index 0000000..b55d639 --- /dev/null +++ "b/templates/\346\250\241\346\235\277 (1).html" @@ -0,0 +1,23 @@ + + + + + + + + +页面加载中,请稍候... + + + +
    + +
    + + \ No newline at end of file diff --git "a/templates/\346\250\241\346\235\277 (2).html" "b/templates/\346\250\241\346\235\277 (2).html" new file mode 100644 index 0000000..b11a08b --- /dev/null +++ "b/templates/\346\250\241\346\235\277 (2).html" @@ -0,0 +1,45 @@ + + + + + + + + +页面加载中,请稍候... + + + +
    +
    + L +
    +
    + O +
    +
    + A +
    +
    + D +
    +
    + I +
    +
    + N +
    +
    + G +
    +
    +
    +
    +
    +
    +
    +
    + + \ No newline at end of file diff --git "a/templates/\346\250\241\346\235\277 (3).html" "b/templates/\346\250\241\346\235\277 (3).html" new file mode 100644 index 0000000..f762f16 --- /dev/null +++ "b/templates/\346\250\241\346\235\277 (3).html" @@ -0,0 +1,37 @@ + + + + + + + + +页面加载中,请稍候... + + + +
    + + LOADING + + + + + + + + + + + + + +
    + + \ No newline at end of file diff --git "a/templates/\346\250\241\346\235\277 (4).html" "b/templates/\346\250\241\346\235\277 (4).html" new file mode 100644 index 0000000..8215480 --- /dev/null +++ "b/templates/\346\250\241\346\235\277 (4).html" @@ -0,0 +1,32 @@ + + + + + + + + +页面加载中,请稍候... + + + + + + +
    + +
    + + + + +
    +
    + + + \ No newline at end of file diff --git a/go.html "b/templates/\351\273\230\350\256\244\346\250\241\346\235\277.html" similarity index 100% rename from go.html rename to "templates/\351\273\230\350\256\244\346\250\241\346\235\277.html"