PageRenderTime 51ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 1ms

/var/Helper.php

https://gitlab.com/wuhang2003/typecho
PHP | 442 lines | 236 code | 56 blank | 150 comment | 29 complexity | 218e938da966d46b56f2ae710f35f684 MD5 | raw file
  1. <?php
  2. /**
  3. * 插件帮手将默认出现在所有的typecho发行版中.
  4. * 因此你可以放心使用它的功能, 以方便你的插件安装在用户的系统里.
  5. *
  6. * @package Helper
  7. * @author qining
  8. * @version 1.0.0
  9. * @link http://typecho.org
  10. */
  11. class Helper
  12. {
  13. /**
  14. * 获取Widget_Options对象
  15. *
  16. * @access public
  17. * @return Widget_Options
  18. */
  19. public static function options()
  20. {
  21. return Typecho_Widget::widget('Widget_Options');
  22. }
  23. /**
  24. * 获取Widget_Security对象
  25. *
  26. * @return Widget_Security
  27. */
  28. public static function security()
  29. {
  30. return Typecho_Widget::widget('Widget_Security');
  31. }
  32. /**
  33. * 强行删除某个插件
  34. *
  35. * @access public
  36. * @param string $pluginName 插件名称
  37. * @return void
  38. */
  39. public static function removePlugin($pluginName)
  40. {
  41. try {
  42. /** 获取插件入口 */
  43. list($pluginFileName, $className) = Typecho_Plugin::portal($pluginName, __TYPECHO_ROOT_DIR__ . '/' . __TYPECHO_PLUGIN_DIR__);
  44. /** 获取已启用插件 */
  45. $plugins = Typecho_Plugin::export();
  46. $activatedPlugins = $plugins['activated'];
  47. /** 载入插件 */
  48. require_once $pluginFileName;
  49. /** 判断实例化是否成功 */
  50. if (!isset($activatedPlugins[$pluginName]) || !class_exists($className)
  51. || !method_exists($className, 'deactivate')) {
  52. throw new Typecho_Widget_Exception(_t('无法禁用插件'), 500);
  53. }
  54. $result = call_user_func(array($className, 'deactivate'));
  55. } catch (Exception $e) {
  56. //nothing to do
  57. }
  58. $db = Typecho_Db::get();
  59. try {
  60. Typecho_Plugin::deactivate($pluginName);
  61. $db->query($db->update('table.options')
  62. ->rows(array('value' => serialize(Typecho_Plugin::export())))
  63. ->where('name = ?', 'plugins'));
  64. } catch (Typecho_Plugin_Exception $e) {
  65. //nothing to do
  66. }
  67. $db->query($db->delete('table.options')->where('name = ?', 'plugin:' . $pluginName));
  68. }
  69. /**
  70. * 导入语言项
  71. *
  72. * @access public
  73. * @param string $domain
  74. * @return void
  75. */
  76. public static function lang($domain)
  77. {
  78. $currentLang = Typecho_I18n::getLang();
  79. if ($currentLang) {
  80. $currentLang = basename($currentLang);
  81. $fileName = dirname(__FILE__) . '/' . $domain . '/lang/' . $currentLang;
  82. if (file_exists($fileName)) {
  83. Typecho_I18n::addLang($fileName);
  84. }
  85. }
  86. }
  87. /**
  88. * 增加路由
  89. *
  90. * @access public
  91. * @param string $name 路由名称
  92. * @param string $url 路由路径
  93. * @param string $widget 组件名称
  94. * @param string $action 组件动作
  95. * @param string $after 在某个路由后面
  96. * @return integer
  97. */
  98. public static function addRoute($name, $url, $widget, $action = NULL, $after = NULL)
  99. {
  100. $routingTable = self::options()->routingTable;
  101. if (isset($routingTable[0])) {
  102. unset($routingTable[0]);
  103. }
  104. $pos = 0;
  105. foreach ($routingTable as $key => $val) {
  106. $pos ++;
  107. if ($key == $after) {
  108. break;
  109. }
  110. }
  111. $pre = array_slice($routingTable, 0, $pos);
  112. $next = array_slice($routingTable, $pos);
  113. $routingTable = array_merge($pre, array($name => array(
  114. 'url' => $url,
  115. 'widget' => $widget,
  116. 'action' => $action
  117. )), $next);
  118. self::options()->routingTable = $routingTable;
  119. $db = Typecho_Db::get();
  120. return Typecho_Widget::widget('Widget_Abstract_Options')->update(array('value' => serialize($routingTable))
  121. , $db->sql()->where('name = ?', 'routingTable'));
  122. }
  123. /**
  124. * 移除路由
  125. *
  126. * @access public
  127. * @param string $name 路由名称
  128. * @return integer
  129. */
  130. public static function removeRoute($name)
  131. {
  132. $routingTable = self::options()->routingTable;
  133. if (isset($routingTable[0])) {
  134. unset($routingTable[0]);
  135. }
  136. unset($routingTable[$name]);
  137. self::options()->routingTable = $routingTable;
  138. $db = Typecho_Db::get();
  139. return Typecho_Widget::widget('Widget_Abstract_Options')->update(array('value' => serialize($routingTable))
  140. , $db->sql()->where('name = ?', 'routingTable'));
  141. }
  142. /**
  143. * 增加action扩展
  144. *
  145. * @access public
  146. * @param string $actionName 需要扩展的action名称
  147. * @param string $widgetName 需要扩展的widget名称
  148. * @return integer
  149. */
  150. public static function addAction($actionName, $widgetName)
  151. {
  152. $actionTable = unserialize(self::options()->actionTable);
  153. $actionTable = empty($actionTable) ? array() : $actionTable;
  154. $actionTable[$actionName] = $widgetName;
  155. $db = Typecho_Db::get();
  156. return Typecho_Widget::widget('Widget_Abstract_Options')->update(array('value' => (self::options()->actionTable = serialize($actionTable)))
  157. , $db->sql()->where('name = ?', 'actionTable'));
  158. }
  159. /**
  160. * 删除action扩展
  161. *
  162. * @access public
  163. * @param string $actionName
  164. * @return Typecho_Widget
  165. */
  166. public static function removeAction($actionName)
  167. {
  168. $actionTable = unserialize(self::options()->actionTable);
  169. $actionTable = empty($actionTable) ? array() : $actionTable;
  170. if (isset($actionTable[$actionName])) {
  171. unset($actionTable[$actionName]);
  172. reset($actionTable);
  173. }
  174. $db = Typecho_Db::get();
  175. return Typecho_Widget::widget('Widget_Abstract_Options')->update(array('value' => (self::options()->actionTable = serialize($actionTable)))
  176. , $db->sql()->where('name = ?', 'actionTable'));
  177. }
  178. /**
  179. * 增加一个菜单
  180. *
  181. * @access public
  182. * @param string $menuName 菜单名
  183. * @return integer
  184. */
  185. public static function addMenu($menuName)
  186. {
  187. $panelTable = unserialize(self::options()->panelTable);
  188. $panelTable['parent'] = empty($panelTable['parent']) ? array() : $panelTable['parent'];
  189. $panelTable['parent'][] = $menuName;
  190. $db = Typecho_Db::get();
  191. Typecho_Widget::widget('Widget_Abstract_Options')->update(array('value' => (self::options()->panelTable = serialize($panelTable)))
  192. , $db->sql()->where('name = ?', 'panelTable'));
  193. end($panelTable['parent']);
  194. return key($panelTable['parent']) + 10;
  195. }
  196. /**
  197. * 移除一个菜单
  198. *
  199. * @access public
  200. * @param string $menuName 菜单名
  201. * @return integer
  202. */
  203. public static function removeMenu($menuName)
  204. {
  205. $panelTable = unserialize(self::options()->panelTable);
  206. $panelTable['parent'] = empty($panelTable['parent']) ? array() : $panelTable['parent'];
  207. if (false !== ($index = array_search($menuName, $panelTable['parent']))) {
  208. unset($panelTable['parent'][$index]);
  209. }
  210. $db = Typecho_Db::get();
  211. Typecho_Widget::widget('Widget_Abstract_Options')->update(array('value' => (self::options()->panelTable = serialize($panelTable)))
  212. , $db->sql()->where('name = ?', 'panelTable'));
  213. return $index + 10;
  214. }
  215. /**
  216. * 增加一个面板
  217. *
  218. * @access public
  219. * @param integer $index 菜单索引
  220. * @param string $fileName 文件名称
  221. * @param string $title 面板标题
  222. * @param string $subTitle 面板副标题
  223. * @param string $level 进入权限
  224. * @param boolean $hidden 是否隐藏
  225. * @param string $addLink 新增项目链接, 会显示在页面标题之后
  226. * @return integer
  227. */
  228. public static function addPanel($index, $fileName, $title, $subTitle, $level, $hidden = false, $addLink = '')
  229. {
  230. $panelTable = unserialize(self::options()->panelTable);
  231. $panelTable['child'] = empty($panelTable['child']) ? array() : $panelTable['child'];
  232. $panelTable['child'][$index] = empty($panelTable['child'][$index]) ? array() : $panelTable['child'][$index];
  233. $fileName = urlencode(trim($fileName, '/'));
  234. $panelTable['child'][$index][] = array($title, $subTitle, 'extending.php?panel=' . $fileName, $level, $hidden, $addLink);
  235. $panelTable['file'] = empty($panelTable['file']) ? array() : $panelTable['file'];
  236. $panelTable['file'][] = $fileName;
  237. $panelTable['file'] = array_unique($panelTable['file']);
  238. $db = Typecho_Db::get();
  239. Typecho_Widget::widget('Widget_Abstract_Options')->update(array('value' => (self::options()->panelTable = serialize($panelTable)))
  240. , $db->sql()->where('name = ?', 'panelTable'));
  241. end($panelTable['child'][$index]);
  242. return key($panelTable['child'][$index]);
  243. }
  244. /**
  245. * 移除一个面板
  246. *
  247. * @access public
  248. * @param integer $index 菜单索引
  249. * @param string $fileName 文件名称
  250. * @return integer
  251. */
  252. public static function removePanel($index, $fileName)
  253. {
  254. $panelTable = unserialize(self::options()->panelTable);
  255. $panelTable['child'] = empty($panelTable['child']) ? array() : $panelTable['child'];
  256. $panelTable['child'][$index] = empty($panelTable['child'][$index]) ? array() : $panelTable['child'][$index];
  257. $panelTable['file'] = empty($panelTable['file']) ? array() : $panelTable['file'];
  258. $fileName = urlencode(trim($fileName, '/'));
  259. if (false !== ($key = array_search($fileName, $panelTable['file']))) {
  260. unset($panelTable['file'][$key]);
  261. }
  262. $return = 0;
  263. foreach ($panelTable['child'][$index] as $key => $val) {
  264. if ($val[2] == 'extending.php?panel=' . $fileName) {
  265. unset($panelTable['child'][$index][$key]);
  266. $return = $key;
  267. }
  268. }
  269. $db = Typecho_Db::get();
  270. Typecho_Widget::widget('Widget_Abstract_Options')->update(array('value' => (self::options()->panelTable = serialize($panelTable)))
  271. , $db->sql()->where('name = ?', 'panelTable'));
  272. return $return;
  273. }
  274. /**
  275. * 获取面板url
  276. *
  277. * @access public
  278. * @param string $fileName
  279. * @return string
  280. */
  281. public static function url($fileName)
  282. {
  283. return Typecho_Common::url('extending.php?panel=' . (trim($fileName, '/')), self::options()->adminUrl);
  284. }
  285. /**
  286. * 手动配置插件变量
  287. *
  288. * @access public
  289. * @static
  290. * @param mixed $pluginName 插件名称
  291. * @param array $settings 变量键值对
  292. * @param bool $isPersonal. (default: false) 是否为私人变量
  293. * @return void
  294. */
  295. public static function configPlugin($pluginName, array $settings, $isPersonal = false)
  296. {
  297. if (empty($settings)) {
  298. return;
  299. }
  300. Widget_Plugins_Edit::configPlugin($pluginName, $settings, $isPersonal);
  301. }
  302. /**
  303. * 评论回复按钮
  304. *
  305. * @access public
  306. * @param string $theId 评论元素id
  307. * @param integer $coid 评论id
  308. * @param string $word 按钮文字
  309. * @param string $formId 表单id
  310. * @param integer $style 样式类型
  311. * @return void
  312. */
  313. public static function replyLink($theId, $coid, $word = 'Reply', $formId = 'respond', $style = 2)
  314. {
  315. if (self::options()->commentsThreaded) {
  316. echo '<a href="#' . $formId . '" rel="nofollow" onclick="return typechoAddCommentReply(\'' .
  317. $theId . '\', ' . $coid . ', \'' . $formId . '\', ' . $style . ');">' . $word . '</a>';
  318. }
  319. }
  320. /**
  321. * 评论取消按钮
  322. *
  323. * @access public
  324. * @param string $word 按钮文字
  325. * @param string $formId 表单id
  326. * @return void
  327. */
  328. public static function cancleCommentReplyLink($word = 'Cancle', $formId = 'respond')
  329. {
  330. if (self::options()->commentsThreaded) {
  331. echo '<a href="#' . $formId . '" rel="nofollow" onclick="return typechoCancleCommentReply(\'' .
  332. $formId . '\');">' . $word . '</a>';
  333. }
  334. }
  335. /**
  336. * 评论回复js脚本
  337. *
  338. * @access public
  339. * @return void
  340. */
  341. public static function threadedCommentsScript()
  342. {
  343. if (self::options()->commentsThreaded) {
  344. echo
  345. <<<EOF
  346. <script type="text/javascript">
  347. var typechoAddCommentReply = function (cid, coid, cfid, style) {
  348. var _ce = document.getElementById(cid), _cp = _ce.parentNode;
  349. var _cf = document.getElementById(cfid);
  350. var _pi = document.getElementById('comment-parent');
  351. if (null == _pi) {
  352. _pi = document.createElement('input');
  353. _pi.setAttribute('type', 'hidden');
  354. _pi.setAttribute('name', 'parent');
  355. _pi.setAttribute('id', 'comment-parent');
  356. var _form = 'form' == _cf.tagName ? _cf : _cf.getElementsByTagName('form')[0];
  357. _form.appendChild(_pi);
  358. }
  359. _pi.setAttribute('value', coid);
  360. if (null == document.getElementById('comment-form-place-holder')) {
  361. var _cfh = document.createElement('div');
  362. _cfh.setAttribute('id', 'comment-form-place-holder');
  363. _cf.parentNode.insertBefore(_cfh, _cf);
  364. }
  365. 1 == style ? (null == _ce.nextSibling ? _cp.appendChild(_cf)
  366. : _cp.insertBefore(_cf, _ce.nextSibling)) : _ce.appendChild(_cf);
  367. return false;
  368. };
  369. var typechoCancleCommentReply = function (cfid) {
  370. var _cf = document.getElementById(cfid),
  371. _cfh = document.getElementById('comment-form-place-holder');
  372. var _pi = document.getElementById('comment-parent');
  373. if (null != _pi) {
  374. _pi.parentNode.removeChild(_pi);
  375. }
  376. if (null == _cfh) {
  377. return true;
  378. }
  379. _cfh.parentNode.insertBefore(_cf, _cfh);
  380. return false;
  381. };
  382. </script>
  383. EOF;
  384. }
  385. }
  386. }