You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

391 lines
18 KiB

4 years ago
3 years ago
4 years ago
  1. <?php
  2. function themeConfig($form) {
  3. echo '<style>
  4. .typecho-page-title h2 {
  5. font-weight: 600;
  6. color: #737373;
  7. }
  8. .typecho-page-title h2:before {
  9. content: "#";
  10. margin-right: 6px;
  11. color: #ff6d6d;
  12. font-size: 20px;
  13. font-weight: 600;
  14. }
  15. .themeConfig h3 {
  16. color: #737373;
  17. font-size: 20px;
  18. }
  19. .themeConfig h3:before {
  20. content: "[";
  21. margin-right: 5px;
  22. color: #ff6d6d;
  23. font-size: 25px;
  24. }
  25. .themeConfig h3:after {
  26. content: "]";
  27. margin-left: 5px;
  28. color: #ff6d6d;
  29. font-size: 25px;
  30. }
  31. .info{
  32. border: 1px solid #ffadad;
  33. padding: 20px;
  34. margin: -15px 10px 25px 0;
  35. background: #ffffff;
  36. border-radius: 5px;
  37. color: #ff6d6d;
  38. }
  39. </style>';
  40. echo '<span class="themeConfig"><h3>博客信息</h3></span>';
  41. //博客信息
  42. $logo = new Typecho_Widget_Helper_Form_Element_Text('logo', NULL,'images/akina.png', _t('网站logo地址'), _t('默认值images/akina.png,图片位置/usr/themes/Akina/images/akina.png'));
  43. $form->addInput($logo);
  44. $profile = new Typecho_Widget_Helper_Form_Element_Text('profile', NULL,'images/akinadeaava.jpg', _t('博主头像地址'), _t('默认值images/akinadeaava.jpg,图片位置/usr/themes/Akina/images/akinadeaava.jpg'));
  45. $form->addInput($profile);
  46. $wedo = new Typecho_Widget_Helper_Form_Element_Text('wedo', NULL,'images/donate/wedo.png', _t('微信收款码'), _t('默认值images/donate/wedo.png,图片位置/usr/themes/Akina/images/donate/wedo.png'));
  47. $form->addInput($wedo);
  48. $alido = new Typecho_Widget_Helper_Form_Element_Text('alido', NULL,'images/donate/alido.png', _t('支付宝收款码'), _t('默认值images/donate/alido.png,图片位置/usr/themes/Akina/images/donate/alido.png'));
  49. $form->addInput($alido);
  50. $sub = new Typecho_Widget_Helper_Form_Element_Text('sub', NULL,'个人博客', _t('网站副标题'), _t('默认内容"个人博客"'));
  51. $form->addInput($sub);
  52. $headerinfo = new Typecho_Widget_Helper_Form_Element_Text('headerinfo', NULL,'Carpe Diem and Do what I like', _t('头部内容'), _t('首页头部介绍'));
  53. $form->addInput($headerinfo);
  54. $NOTICE = new Typecho_Widget_Helper_Form_Element_Text('NOTICE', NULL,'我很荣幸的启用了Akina主题', _t('公告内容'), _t('首页公告内容'));
  55. $form->addInput($NOTICE);
  56. $ICP = new Typecho_Widget_Helper_Form_Element_Text('ICP', NULL,'Carpe Diem and Do what I like', _t('ICP备案号'), _t('备案号(默认内容"Carpe Diem and Do what I like")'));
  57. $form->addInput($ICP);
  58. $gongan = new Typecho_Widget_Helper_Form_Element_Text('gongan', NULL,'', _t('公安联网备案'), _t('格式“X公安备案xxxxxxxxxxxxxx号”(没有不填即可)'));
  59. $form->addInput($gongan);
  60. //个人信息
  61. //新浪
  62. $SINA = new Typecho_Widget_Helper_Form_Element_Text('SINA', NULL,'https://weibo.com/', _t('<br><span class="themeConfig"><h3>个人信息</h3></span><div class="info">不填写相关信息时可以隐藏该信息和图标</div>新浪微博地址'), _t('默认新浪微博首页(请规范填写,需https://,http://或者//)'));
  63. $form->addInput($SINA);
  64. //微信
  65. $Wechat = new Typecho_Widget_Helper_Form_Element_Text('Wechat', NULL,'', _t('微信号'), _t('首页个人信息'));
  66. $form->addInput($Wechat);
  67. //QQ
  68. $QQnum = new Typecho_Widget_Helper_Form_Element_Text('QQnum', NULL,'', _t('QQ信息'), _t('首页个人信息'));
  69. $form->addInput($QQnum);
  70. //酷安
  71. $coolapk = new Typecho_Widget_Helper_Form_Element_Text('coolapk', NULL,'', _t('酷安ID'), _t('填写酷安用户名'));
  72. $form->addInput($coolapk);
  73. $coolapkLink = new Typecho_Widget_Helper_Form_Element_Text('coolapkLink', NULL,'', _t(' '), _t('填写酷安用户链接,APP-我-点头像-右上角分享-复制链接'));
  74. $form->addInput($coolapkLink);
  75. //QQ空间
  76. $Qzone = new Typecho_Widget_Helper_Form_Element_Text('Qzone', NULL,'', _t('QQ空间信息'), _t('首页个人QQ空间信息:https://user.qzone.qq.com/QQ号码'));
  77. $form->addInput($Qzone);
  78. //Github
  79. $Github = new Typecho_Widget_Helper_Form_Element_Text('Github', NULL,'https://github.com/', _t('Github地址'), _t('Github主页地址(请规范填写,需https://,http://或者//)'));
  80. $form->addInput($Github);
  81. //哔哩哔哩
  82. $Bilibili = new Typecho_Widget_Helper_Form_Element_Text('Bilibili', NULL,'https://www.bilibili.com/', _t('Bilibili地址'), _t('Bilibili主页地址(请规范填写,需https://,http://或者//)'));
  83. $form->addInput($Bilibili);
  84. //网易云音乐
  85. $Music = new Typecho_Widget_Helper_Form_Element_Text('Music', NULL,'https://music.163.com/', _t('网易云音乐用户ID'), _t('登陆网页版网易云音乐,点击个人主页。https://music.163.com/#/user/home?id=这里是ID'));
  86. $form->addInput($Music);
  87. //文章推荐
  88. $sticky = new Typecho_Widget_Helper_Form_Element_Text('sticky', NULL,NULL, _t('<br><span class="themeConfig"><h3>文章推荐</h3></span>文章置顶'), _t('填写文章cid,按照输入顺序显示(请以半角逗号,或空格分隔)'));
  89. $form->addInput($sticky);
  90. $featureCids = new Typecho_Widget_Helper_Form_Element_Text('featureCids', NULL,NULL, _t('聚焦内容'), _t('填写文章cid,按照输入顺序只显示前三个(请以半角逗号,或空格分隔)'));
  91. $form->addInput($featureCids);
  92. //广告设置
  93. $adPostImg = new Typecho_Widget_Helper_Form_Element_Text('adPostImg', NULL,'', _t('<br><span class="themeConfig"><h3>广告设置</h3></span><div class="info">不填写相关信息时可以隐藏该广告展示</div>文章页广告'), _t('填写广告图片链接'));
  94. $form->addInput($adPostImg);
  95. $adPostkLink = new Typecho_Widget_Helper_Form_Element_Text('adPostkLink', NULL,'', _t(' '), _t('填写文章页广告超链接'));
  96. $form->addInput($adPostkLink);
  97. //加速设置
  98. $DNS = new Typecho_Widget_Helper_Form_Element_Text('DNS', NULL,'https://cdn.zhebk.cn', _t('<br><span class="themeConfig"><h3>加速设置</h3></span><div class="info">劣质CDN甚至会拖慢网站的速度,图标异常请自行解决跨域问题。CDN付费用户注意,该操作会让你的钱包遭受不可逆的降维打击。</div>DNS预解析加速'), _t('比如填写引用图片的域名(请规范填写,需https://,http://或者//)'));
  99. $form->addInput($DNS);
  100. $CDNURL = new Typecho_Widget_Helper_Form_Element_Text('CDNURL', NULL,NULL, _t('CDN镜像加速'), _t('填写CDN域名(请规范填写,需https://,http://或者//,末尾不加/)'));
  101. $form->addInput($CDNURL);
  102. //外观设置
  103. $headimg = new Typecho_Widget_Helper_Form_Element_Text('headimg', NULL,'images/headerbg.jpg', _t('<br><span class="themeConfig"><h3>外观设置</h3></span>首页头部图'), _t('默认值images/headerbg.jpg,图片位置/usr/themes/Akina/images/headerbg.jpg'));
  104. $form->addInput($headimg);
  105. $menu = new Typecho_Widget_Helper_Form_Element_Checkbox('menu',
  106. array(
  107. 'show' => _t('一直显示菜单'),
  108. 'indexbg' => _t('一直显示首页大图'),
  109. 'feature' => _t('一直显示聚焦内容'),
  110. 'page' => _t('使用ajax加载文章'),
  111. 'xl' => _t('下拉自动加载文章'),
  112. 'dark' => _t('开启夜间模式(跟随系统)'),
  113. ),
  114. array('page'), _t('其他设置'));
  115. $form->addInput($menu->multiMode());
  116. $postDoc = new Typecho_Widget_Helper_Form_Element_Radio('postDoc', array(
  117. 'leftDoc' => _t('左侧显示'),
  118. 'rightDoc' => _t('右侧显示'),
  119. 'none' => _t('不显示')
  120. ), 'none', _t('开启文章目录'));
  121. $form->addInput($postDoc);
  122. $cssCode = new Typecho_Widget_Helper_Form_Element_Textarea('cssCode', null, null, _t('自定义 CSS'), _t('可以方便的自定义博客样式,避免修改源码影响主题模板迭代。(请编写完整的style标签)'));
  123. $form->addInput($cssCode);
  124. $jsCode = new Typecho_Widget_Helper_Form_Element_Textarea('jsCode', null, null, _t('自定义 JS'), _t('可以方便的添加js代码,统计代码可以填写到这里。(请编写完整的script标签)'));
  125. $form->addInput($jsCode);
  126. }
  127. //判断本地、cdn和自定义资源加载逻辑
  128. function authorProfile($src,$theurl){
  129. if($src){
  130. if(substr($src,0,1)=="i"){
  131. $src = $theurl . $src;
  132. }
  133. }
  134. return $src;
  135. }
  136. //阅读次数统计
  137. function Postviews($archive) {
  138. $db = Typecho_Db::get();
  139. $cid = $archive->cid;
  140. if (!array_key_exists('views', $db->fetchRow($db->select()->from('table.contents')))) {
  141. $db->query('ALTER TABLE `'.$db->getPrefix().'contents` ADD `views` INT(10) DEFAULT 0;');
  142. }
  143. $exist = $db->fetchRow($db->select('views')->from('table.contents')->where('cid = ?', $cid))['views'];
  144. if ($archive->is('single')) {
  145. $cookie = Typecho_Cookie::get('contents_views');
  146. $cookie = $cookie ? explode(',', $cookie) : array();
  147. if (!in_array($cid, $cookie)) {
  148. $db->query($db->update('table.contents')
  149. ->rows(array('views' => (int)$exist+1))
  150. ->where('cid = ?', $cid));
  151. $exist = (int)$exist+1;
  152. array_push($cookie, $cid);
  153. $cookie = implode(',', $cookie);
  154. Typecho_Cookie::set('contents_views', $cookie);
  155. }
  156. }
  157. return $exist;
  158. }
  159. // 缩略图设置
  160. function themeFields($layout){
  161. $radioPostImg = new Typecho_Widget_Helper_Form_Element_Radio('radioPostImg', array(
  162. 'custom' => _t('自定义'),
  163. 'random' => _t('随机图'),
  164. 'none' => _t('不显示')
  165. ), 'none', _t('开启文章/页面缩略图'));
  166. $layout->addItem($radioPostImg);
  167. $thumbnail = new Typecho_Widget_Helper_Form_Element_Text('thumbnail', null, null, _t('文章/页面缩略图Url'), _t('需要带上http(s)://'));
  168. $icon = new Typecho_Widget_Helper_Form_Element_Text('icon', null, null, _t('文章/页面首页图标Url'), _t('需要带上http(s)://'));
  169. $dtMode = new Typecho_Widget_Helper_Form_Element_Radio('dtMode', array(true => _t('开启'), false => _t('关闭')), false, _t('文章动态模式'), _t('该文章在列表展示方式为动态模式'));
  170. $layout->addItem($thumbnail);
  171. $layout->addItem($icon);
  172. $layout->addItem($dtMode);
  173. }
  174. /**
  175. * 从数据库查询上/下篇文章内容信息
  176. * 返回内容包括文章缩略、标题、链接
  177. *
  178. * @param bool $mode 查询上或下篇
  179. * @param mixed $archive
  180. *
  181. * @return array|bool
  182. */
  183. // 相关代码感谢 https://github.com/Siphils/Typecho-Theme-Aria/blob/master/lib/Contents.php
  184. function getNextPrev($mode, $archive){
  185. $options = Helper::options();
  186. $db = Typecho_Db::get();
  187. //数据准备
  188. $where = null;
  189. $sorted = null;
  190. $name = 'thumbnail';
  191. $thumbnail = 'str_value';
  192. //$mode为true查询上文,false查询下文
  193. if ($mode) {
  194. $where = 'table.contents.created < ?';
  195. $sorted = Typecho_Db::SORT_DESC;
  196. } else {
  197. $where = 'table.contents.created > ?';
  198. $sorted = Typecho_Db::SORT_ASC;
  199. }
  200. $query = $db->select()->from('table.contents')
  201. ->where($where, $archive->created)
  202. ->where('table.contents.status = ?', 'publish')
  203. ->where('table.contents.type = ?', $archive->type)
  204. ->where('table.contents.password IS NULL')
  205. ->order('table.contents.created', $sorted)
  206. ->limit(1);
  207. $content = $db->fetchRow($query);
  208. $result = null;
  209. if ($content) {
  210. $content = $archive->filter($content);
  211. $title = $content['title'];
  212. $link = $content['permalink'];
  213. $query = $db->select()->from('table.fields')
  214. ->where('table.fields.cid = ?', $content['cid'])
  215. ->where('table.fields.name = ?', $name)
  216. ->limit(1);
  217. $content = $db->fetchRow($query);
  218. if ($content) {
  219. $img = $content[$thumbnail] ? $content[$thumbnail] : '/usr/themes/Akina/images/random/deu' . mt_rand(1,7). '.jpg';
  220. } else {
  221. $img = '/usr/themes/Akina/images/random/deu' . mt_rand(1,7). '.jpg';
  222. }
  223. $result = array('img' => $img, 'title' => $title, 'link' => $link);
  224. } else {
  225. $result = false;
  226. }
  227. return $result;
  228. }
  229. //输出相邻文章链接,标题,缩略图
  230. function theNextPrev($widget){
  231. $html = '';
  232. $prevResult = getNextPrev(true, $widget);
  233. $nextResult = getNextPrev(false, $widget);
  234. if (!$prevResult && !$nextResult) {
  235. //第一篇文章,什么也不需要输出
  236. $html .= '';
  237. } else if (!$nextResult) {
  238. $html .= '<div class="post-nepre half next" style="width:100%;"><a href="' . $prevResult["link"] . '" rel="next"><div class="background" style="background-image:url(' . $prevResult["img"] . ');"></div><span class="label">Next Post</span><div class="info"><h3>' . $prevResult["title"] . '</h3><hr></div></a></div>';
  239. } else if (!$prevResult) {
  240. $html .= '<div class="post-nepre half previous"style="width:100%;"><a href="' . $nextResult["link"] . '" rel="prev"><div class="background" style="background-image:url( '. $nextResult["img"] . ');"></div><span class="label">Previous Post</span><div class="info"><h3>' . $nextResult["title"] . '</h3><hr></div></a></div>';
  241. } else {
  242. $html .= '<div class="post-nepre half previous"><a href="' . $nextResult["link"] . '" rel="prev"><div class="background" style="background-image:url('. $nextResult["img"] .');"></div><span class="label">Previous Post</span><div class="info"><h3>' . $nextResult["title"] . '</h3><hr></div></a></div>';
  243. $html .= '<div class="post-nepre half next"><a href="' . $prevResult["link"] . '" rel="next"><div class="background" style="background-image:url('. $prevResult["img"] . ');"></div><span class="label">Next Post</span><div class="info"><h3>' . $prevResult["title"] . '</h3><hr></div></a></div>';
  244. }
  245. echo $html;
  246. }
  247. //修改后台设置适应模板
  248. function themeInit($archive){
  249. Helper::options()->commentsPageBreak = true; //启用分页
  250. Helper::options()->commentsPageDisplay = 'first'; //在列出时将第一页作为默认显示
  251. Helper::options()->commentsOrder = 'DESC'; //将较新的的评论显示在前面
  252. Helper::options()->commentsHTMLTagAllowed = '<img src="">'; //评论允许img标签
  253. //文章目录
  254. if ($archive->is('single')) {
  255. $archive->content = createCatalog($archive->content);
  256. }
  257. }
  258. //评论添加回复@标记
  259. function get_commentReply_at($coid)
  260. {
  261. $db = Typecho_Db::get();
  262. $prow = $db->fetchRow($db->select('parent')->from('table.comments')
  263. ->where('coid = ? AND status = ?', $coid, 'approved'));
  264. $parent = $prow['parent'];
  265. if ($parent != "0") {
  266. $arow = $db->fetchRow($db->select('author')->from('table.comments')
  267. ->where('coid = ? AND status = ?', $parent, 'approved'));
  268. $author = $arow['author'];
  269. $href = '<a href="#" rel="nofollow" class="cute atreply">@' . $author . '</a> : ';
  270. echo $href;
  271. }
  272. }
  273. //公安联网备案,获取备案号
  274. function gonganbeian($str){
  275. $str = trim($str);
  276. $result = '';
  277. for($i=0;$i<strlen($str);$i++){
  278. if(is_numeric($str[$i])){
  279. $result.=$str[$i];
  280. }
  281. }
  282. if(empty($result)){
  283. return '';
  284. }else{
  285. return $result;
  286. }
  287. }
  288. //文章目录
  289. //来源 https://www.offodd.com/76.html
  290. //为文章标题添加锚点
  291. function createCatalog($obj) {
  292. global $catalog;
  293. global $catalog_count;
  294. $catalog = array();
  295. $catalog_count = 0;
  296. $obj = preg_replace_callback('/<h([1-3])(.*?)>(.*?)<\/h\1>/i', function($obj) {
  297. global $catalog;
  298. global $catalog_count;
  299. $catalog_count ++;
  300. $catalog[] = array('text' => trim(strip_tags($obj[3])), 'depth' => $obj[1], 'count' => $catalog_count);
  301. return '<h'.$obj[1].$obj[2].'><a name="cl-'.$catalog_count.'"></a>'.$obj[3].'</h'.$obj[1].'>';
  302. }, $obj);
  303. return $obj;
  304. }
  305. //输出文章目录容器
  306. function getCatalog() {
  307. global $catalog;
  308. $index = '';
  309. if ($catalog) {
  310. $index = '<ul>'."\n";
  311. $prev_depth = '';
  312. $to_depth = 0;
  313. foreach($catalog as $catalog_item) {
  314. $catalog_depth = $catalog_item['depth'];
  315. if ($prev_depth) {
  316. if ($catalog_depth == $prev_depth) {
  317. $index .= '</li>'."\n";
  318. } elseif ($catalog_depth > $prev_depth) {
  319. $to_depth++;
  320. $index .= '<ul>'."\n";
  321. } else {
  322. $to_depth2 = ($to_depth > ($prev_depth - $catalog_depth)) ? ($prev_depth - $catalog_depth) : $to_depth;
  323. if ($to_depth2) {
  324. for ($i=0; $i<$to_depth2; $i++) {
  325. $index .= '</li>'."\n".'</ul>'."\n";
  326. $to_depth--;
  327. }
  328. }
  329. $index .= '</li>';
  330. }
  331. }
  332. $index .= '<li><a href="#cl-'.$catalog_item['count'].'">'.$catalog_item['text'].'</a>';
  333. $prev_depth = $catalog_item['depth'];
  334. }
  335. for ($i=0; $i<=$to_depth; $i++) {
  336. $index .= '</li>'."\n".'</ul>'."\n";
  337. }
  338. $index = '<div id="toc-container">'."\n".'<div id="toc">'."\n".'<strong>文章目录</strong>'."\n".$index.'</div>'."\n".'</div>'."\n";
  339. }
  340. echo $index;
  341. }
  342. //随机文章
  343. function getRandomPosts($limit = 10){
  344. $db = Typecho_Db::get();
  345. $adapterName = $db->getAdapterName();//兼容非MySQL数据库
  346. if($adapterName == 'pgsql' || $adapterName == 'Pdo_Pgsql' || $adapterName == 'Pdo_SQLite' || $adapterName == 'SQLite'){
  347. $order_by = 'RANDOM()';
  348. }else{
  349. $order_by = 'RAND()';
  350. }
  351. $sql = $db->select()->from('table.contents')
  352. ->where('status = ?','publish')
  353. ->where('table.contents.created <= ?', time())
  354. ->where('type = ?', 'post')
  355. ->limit($limit)
  356. ->order($order_by);
  357. $result = $db->fetchAll($sql);
  358. if($result){
  359. foreach($result as $val){
  360. $val = Typecho_Widget::widget('Widget_Abstract_Contents')->push($val);
  361. $post_title = htmlspecialchars($val['title']);
  362. $permalink = $val['permalink'];
  363. echo '<li><a href="'.$permalink.'" title="'.$post_title.'" target="_blank">'.$post_title.'</a></li>';
  364. }
  365. }
  366. }
  367. ?>