Ajax.php 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. <?php
  2. namespace Widget;
  3. use Typecho\Http\Client;
  4. use Typecho\Widget\Exception;
  5. use Widget\Base\Options as BaseOptions;
  6. if (!defined('__TYPECHO_ROOT_DIR__')) {
  7. exit;
  8. }
  9. /**
  10. * 异步调用组件
  11. *
  12. * @author qining
  13. * @category typecho
  14. * @package Widget
  15. */
  16. class Ajax extends BaseOptions implements ActionInterface
  17. {
  18. /**
  19. * 针对rewrite验证的请求返回
  20. *
  21. * @access public
  22. * @return void
  23. */
  24. public function remoteCallback()
  25. {
  26. if ($this->options->generator == $this->request->getAgent()) {
  27. echo 'OK';
  28. }
  29. }
  30. /**
  31. * 获取最新版本
  32. *
  33. * @throws Exception|\Typecho\Db\Exception
  34. */
  35. public function checkVersion()
  36. {
  37. $this->user->pass('editor');
  38. $client = Client::get();
  39. if ($client) {
  40. $client->setHeader('User-Agent', $this->options->generator)
  41. ->setTimeout(10);
  42. $result = ['available' => 0];
  43. try {
  44. $client->send('https://typecho.org/version.json');
  45. /** 匹配内容体 */
  46. $response = $client->getResponseBody();
  47. $json = json_decode($response, true);
  48. if (!empty($json)) {
  49. $version = $this->options->version;
  50. if (
  51. isset($json['release'])
  52. && preg_match("/^[0-9\.]+$/", $json['release'])
  53. && version_compare($json['release'], $version, '>')
  54. ) {
  55. $result = [
  56. 'available' => 1,
  57. 'latest' => $json['release'],
  58. 'current' => $version,
  59. 'link' => 'https://typecho.org/download'
  60. ];
  61. }
  62. }
  63. } catch (\Exception $e) {
  64. // do nothing
  65. }
  66. $this->response->throwJson($result);
  67. }
  68. throw new Exception(_t('禁止访问'), 403);
  69. }
  70. /**
  71. * 远程请求代理
  72. *
  73. * @throws Exception
  74. * @throws Client\Exception|\Typecho\Db\Exception
  75. */
  76. public function feed()
  77. {
  78. $this->user->pass('subscriber');
  79. $client = Client::get();
  80. if ($client) {
  81. $client->setHeader('User-Agent', $this->options->generator)
  82. ->setTimeout(10)
  83. ->send('https://typecho.org/feed/');
  84. /** 匹配内容体 */
  85. $response = $client->getResponseBody();
  86. preg_match_all(
  87. "/<item>\s*<title>([^>]*)<\/title>\s*<link>([^>]*)<\/link>\s*<guid>[^>]*<\/guid>\s*<pubDate>([^>]*)<\/pubDate>/is",
  88. $response,
  89. $matches
  90. );
  91. $data = [];
  92. if ($matches) {
  93. foreach ($matches[0] as $key => $val) {
  94. $data[] = [
  95. 'title' => $matches[1][$key],
  96. 'link' => $matches[2][$key],
  97. 'date' => date('n.j', strtotime($matches[3][$key]))
  98. ];
  99. if ($key > 8) {
  100. break;
  101. }
  102. }
  103. }
  104. $this->response->throwJson($data);
  105. }
  106. throw new Exception(_t('禁止访问'), 403);
  107. }
  108. /**
  109. * 自定义编辑器大小
  110. *
  111. * @throws \Typecho\Db\Exception|Exception
  112. */
  113. public function editorResize()
  114. {
  115. $this->user->pass('contributor');
  116. if (
  117. $this->db->fetchObject($this->db->select(['COUNT(*)' => 'num'])
  118. ->from('table.options')->where('name = ? AND user = ?', 'editorSize', $this->user->uid))->num > 0
  119. ) {
  120. parent::update(
  121. ['value' => $this->request->size],
  122. $this->db->sql()->where('name = ? AND user = ?', 'editorSize', $this->user->uid)
  123. );
  124. } else {
  125. parent::insert([
  126. 'name' => 'editorSize',
  127. 'value' => $this->request->size,
  128. 'user' => $this->user->uid
  129. ]);
  130. }
  131. }
  132. /**
  133. * 异步请求入口
  134. *
  135. * @access public
  136. * @return void
  137. */
  138. public function action()
  139. {
  140. if (!$this->request->isAjax()) {
  141. $this->response->goBack();
  142. }
  143. $this->on($this->request->is('do=remoteCallback'))->remoteCallback();
  144. $this->on($this->request->is('do=feed'))->feed();
  145. $this->on($this->request->is('do=checkVersion'))->checkVersion();
  146. $this->on($this->request->is('do=editorResize'))->editorResize();
  147. }
  148. }