PageRenderTime 1157ms CodeModel.GetById 41ms RepoModel.GetById 5ms app.codeStats 0ms

/Abstract.php

https://github.com/wp-plugins/duoshuo
PHP | 249 lines | 173 code | 49 blank | 27 comment | 22 complexity | 15e87c1669ca9ac288e908e2d8365c49 MD5 | raw file
  1. <?php
  2. class Duoshuo_Abstract {
  3. const DOMAIN = 'duoshuo.com';
  4. const STATIC_DOMAIN = 'static.duoshuo.com';
  5. const VERSION = '1.1';
  6. /**
  7. *
  8. * @var string
  9. */
  10. public $shortName;
  11. /**
  12. *
  13. * @var string
  14. */
  15. public $secret;
  16. /**
  17. * 默认的获取Client的函数,可以被派生
  18. * @param string|int $userId
  19. * @return Duoshuo_Client
  20. */
  21. public function getClient($userId = 0){
  22. return new Duoshuo_Client($this->shortName, $this->secret);
  23. }
  24. public function syncLog(){
  25. $this->updateOption('sync_lock', time());
  26. $last_log_id = $this->getOption('last_log_id');
  27. if (!$last_log_id)
  28. $last_log_id = 0;
  29. $limit = 20;
  30. $params = array(
  31. 'limit' => $limit,
  32. 'order' => 'asc',
  33. );
  34. $client = $this->getClient();
  35. $posts = array();
  36. $affectedThreads = array();
  37. //do{
  38. $params['since_id'] = $last_log_id;
  39. $response = $client->request('GET', 'log/list', $params);
  40. if (is_string($response))
  41. throw new Duoshuo_Exception($response, Duoshuo_Exception::INTERNAL_SERVER_ERROR);
  42. if (!isset($response['response']))
  43. throw new Duoshuo_Exception($response['message'], $response['code']);
  44. foreach($response['response'] as $log){
  45. switch($log['action']){
  46. case 'create':
  47. $affected = $this->createPost($log['meta']);
  48. break;
  49. case 'approve':
  50. $affected = $this->approvePost($log['meta']);
  51. break;
  52. case 'spam':
  53. $affected = $this->spamPost($log['meta']);
  54. break;
  55. case 'delete':
  56. $affected = $this->deletePost($log['meta']);
  57. break;
  58. case 'delete-forever':
  59. $affected = $this->deleteForeverPost($log['meta']);
  60. break;
  61. case 'update'://现在并没有update操作的逻辑
  62. default:
  63. $affected = array();
  64. }
  65. //合并
  66. if (is_array($affected))
  67. $affectedThreads = array_merge($affectedThreads, $affected);
  68. if (strlen($log['log_id']) > strlen($last_log_id) || strcmp($log['log_id'], $last_log_id) > 0)
  69. $last_log_id = $log['log_id'];
  70. }
  71. $this->updateOption('last_log_id', $last_log_id);
  72. //} while (count($response['response']) == $limit);//如果返回和最大请求条数一致,则再取一次
  73. $this->updateOption('sync_lock', 0);
  74. //更新静态文件
  75. if ($this->getOption('sync_to_local') && $this->plugin->getOption('seo_enabled'))
  76. $this->refreshThreads(array_unique($affectedThreads));
  77. return count($response['response']);
  78. }
  79. function rfc3339_to_mysql($string){
  80. if (method_exists('DateTime', 'createFromFormat')){ // php 5.3.0
  81. return DateTime::createFromFormat(DateTime::RFC3339, $string)->format('Y-m-d H:i:s');
  82. }
  83. else{
  84. $timestamp = strtotime($string);
  85. return gmdate('Y-m-d H:i:s', $timestamp + $this->timezone() * 3600);
  86. }
  87. }
  88. function rfc3339_to_mysql_gmt($string){
  89. if (method_exists('DateTime', 'createFromFormat')){ // php 5.3.0
  90. return DateTime::createFromFormat(DateTime::RFC3339, $string)->setTimezone(new DateTimeZone('UTC'))->format('Y-m-d H:i:s');
  91. }
  92. else{
  93. $timestamp = strtotime($string);
  94. return gmdate('Y-m-d H:i:s', $timestamp);
  95. }
  96. }
  97. static function encodeJWT($payload, $key){
  98. $header = array('typ' => 'JWT', 'alg' => 'HS256');
  99. $segments = array(
  100. str_replace('=', '', strtr(base64_encode(json_encode($header)), '+/', '-_')),
  101. str_replace('=', '', strtr(base64_encode(json_encode($payload)), '+/', '-_')),
  102. );
  103. $signing_input = implode('.', $segments);
  104. $signature = self::hmacsha256($signing_input, $key);
  105. $segments[] = str_replace('=', '', strtr(base64_encode($signature), '+/', '-_'));
  106. return implode('.', $segments);
  107. }
  108. // from: http://www.php.net/manual/en/function.sha1.php#39492
  109. // Calculate HMAC-SHA1 according to RFC2104
  110. // http://www.ietf.org/rfc/rfc2104.txt
  111. static function hmacsha1($data, $key) {
  112. if (function_exists('hash_hmac'))
  113. return hash_hmac('sha1', $data, $key, true);
  114. $blocksize=64;
  115. if (strlen($key)>$blocksize)
  116. $key=pack('H*', sha1($key));
  117. $key=str_pad($key,$blocksize,chr(0x00));
  118. $ipad=str_repeat(chr(0x36),$blocksize);
  119. $opad=str_repeat(chr(0x5c),$blocksize);
  120. $hmac = pack(
  121. 'H*',sha1(
  122. ($key^$opad).pack(
  123. 'H*',sha1(
  124. ($key^$ipad).$data
  125. )
  126. )
  127. )
  128. );
  129. return $hmac;
  130. }
  131. /**
  132. * from: http://www.php.net/manual/en/function.sha1.php#39492
  133. * Calculate HMAC-SHA1 according to RFC2104
  134. * http://www.ietf.org/rfc/rfc2104.txt
  135. * Used in OAuth1 and remoteAuth
  136. */
  137. static function hmacsha256($data, $key) {
  138. if (function_exists('hash_hmac'))
  139. return hash_hmac('sha256', $data, $key, true);
  140. if (!class_exists('nanoSha2', false))
  141. require 'nanoSha2.php';
  142. $nanoSha2 = new nanoSha2();
  143. $blocksize=64;
  144. if (strlen($key)>$blocksize)
  145. $key=pack('H*', $nanoSha2->hash($key, true));
  146. $key=str_pad($key,$blocksize,chr(0x00));
  147. $ipad=str_repeat(chr(0x36),$blocksize);
  148. $opad=str_repeat(chr(0x5c),$blocksize);
  149. $hmac = pack(
  150. 'H*',$nanoSha2->hash(
  151. ($key^$opad).pack(
  152. 'H*', $nanoSha2->hash(($key^$ipad).$data, true)
  153. ),
  154. true
  155. )
  156. );
  157. return $hmac;
  158. }
  159. function exportUsers($users){
  160. if (count($users) === 0)
  161. return 0;
  162. $params = array('users'=>array());
  163. foreach($users as $user)
  164. $params['users'][] = $this->packageUser($user);
  165. $remoteResponse = $this->getClient()->request('POST', 'users/import', $params);
  166. // @deprecated 不再需要记录duoshuo_user_id
  167. if (is_array($remoteResponse) && isset($remoteResponse['response'])){
  168. foreach($remoteResponse['response'] as $userId => $duoshuoUserId)
  169. $this->updateUserMeta($userId, 'duoshuo_user_id', $duoshuoUserId);
  170. }
  171. return count($users);
  172. }
  173. function exportPosts($threads){
  174. if (count($threads) === 0)
  175. return 0;
  176. $params = array(
  177. 'threads' => array(),
  178. );
  179. foreach($threads as $index => $thread){
  180. $params['threads'][] = $this->packageThread($thread);
  181. }
  182. $remoteResponse = $this->getClient()->request('POST','threads/import', $params);
  183. if (is_array($remoteResponse) && isset($remoteResponse['response'])){
  184. foreach($remoteResponse['response'] as $threadId => $duoshuoThreadId)
  185. $this->updateThreadMeta($threadId, 'duoshuo_thread_id', $duoshuoThreadId);
  186. }
  187. return count($threads);
  188. }
  189. function exportComments($comments){
  190. if (count($comments) === 0)
  191. return 0;
  192. $params = array(
  193. 'posts' => array()
  194. );
  195. foreach($comments as $comment)
  196. $params['posts'][] = $this->packageComment($comment);
  197. $remoteResponse = $this->getClient()->request('POST', 'posts/import', $params);
  198. return count($comments);
  199. }
  200. }