0, 'duoshuo_api_hostname' => 'api.duoshuo.com', 'duoshuo_cron_sync_enabled' => 1, 'duoshuo_seo_enabled' => 1, 'duoshuo_postpone_print_scripts'=> 0, 'duoshuo_cc_fix' => 1, 'duoshuo_sync_pingback_and_trackback'=> 0, 'duoshuo_social_login_enabled' => 1, 'duoshuo_comments_wrapper_intro'=> '', 'duoshuo_comments_wrapper_outro'=> '', 'duoshuo_last_log_id' => 0, 'duoshuo_theme' => 'default', 'duoshuo_style_patch' => 1, ); protected function __construct(){ $this->shortName = $this->getOption('short_name'); $this->secret = $this->getOption('secret'); foreach (self::$_defaultOptions as $optionName => $value) if (get_option($optionName) === false) update_option($optionName, $value); $this->pluginDirUrl = plugin_dir_url(__FILE__); } /** * * @return Duoshuo_WordPress */ public static function getInstance(){ if (self::$_instance === null) self::$_instance = new self(); return self::$_instance; } public function timezone(){ return get_option('gmt_offset'); } public function getOption($key){ return get_option('duoshuo_' . $key); } public function updateOption($key, $value){ return update_option('duoshuo_' . $key, $value); } public function deleteOption($key){ return delete_option('duoshuo_' . $key); } public function updateUserMeta($userId, $metaKey, $metaValue){ return function_exists('update_user_meta') ? update_user_meta($userId, $metaKey, $metaValue) : update_usermeta($userId, $metaKey, $metaValue); } public function getUserMeta($userId, $metaKey, $single = false){ //get_user_meta 从3.0开始有效: get_usermeta($user->ID, $blog_prefix.'capabilities', true); return function_exists('get_user_meta') ? get_user_meta($userId, $metaKey, true) : get_usermeta($userId, $metaKey); } public function updateThreadMeta($threadId, $metaKey, $metaValue){ return update_post_meta($threadId, $metaKey, $metaValue); } public function threadKey($post){ return $post->post_status == 'inherit' ? ($post->post_parent ? $post->post_parent : null) : $post->ID; } public function topPost($post){ return $post->post_status == 'inherit' ? ($post->post_parent ? get_post($post->post_parent) : null) : $post; } public function get_blog_prefix(){ global $wpdb; return method_exists($wpdb,'get_blog_prefix') ? $wpdb->get_blog_prefix() : $wpdb->prefix; } public function connected(){ $connected_failed = get_option('duoshuo_connect_failed'); return $connected_failed ? (time() - $connected_failed > 1800) : true; } public function connectFailed(){ update_option('duoshuo_connect_failed', time()); } public function normalizeUrl($url){ if (strpos($url, '/') === 0){ $siteurl = get_option('siteurl'); if (strlen($siteurl) >=8 && (false !== $pos = strpos($siteurl, '/', 8))) $siteurl = substr($siteurl, 0, $pos); return $siteurl . $url; } else{ return $url; } } public function allowedHtml($tags, $context = ''){ if (!isset($tags['img'])) $tags['img'] = array(); $tags['img']['src'] = true; return $tags; } public function setJwtCookie($logged_in_cookie, $expire, $expiration, $user_id, $scheme){ $jwt = $this->jwt($user_id); $secure = $scheme == 'secure_auth'; $secure_logged_in_cookie = apply_filters('secure_logged_in_cookie', false, $user_id, $secure); // $httponly = false //setcookie('duoshuo_token', $jwt, $expire, PLUGINS_COOKIE_PATH, COOKIE_DOMAIN, $secure, true); setcookie('duoshuo_token', $jwt, $expire, ADMIN_COOKIE_PATH, COOKIE_DOMAIN, $secure); setcookie('duoshuo_token', $jwt, $expire, COOKIEPATH, COOKIE_DOMAIN, $secure_logged_in_cookie); if ( COOKIEPATH != SITECOOKIEPATH ) setcookie('duoshuo_token', $jwt, $expire, SITECOOKIEPATH, COOKIE_DOMAIN, $secure_logged_in_cookie); $this->syncUserToRemote($user_id); } public function clearJwtCookie(){ // 3.5版本之前没有定义 YEAR_IN_SECONDS //setcookie( 'duoshuo_token', ' ', time() - 31536000, PLUGINS_COOKIE_PATH, COOKIE_DOMAIN ); setcookie( 'duoshuo_token', ' ', time() - 31536000, ADMIN_COOKIE_PATH, COOKIE_DOMAIN ); setcookie( 'duoshuo_token', ' ', time() - 31536000, COOKIEPATH, COOKIE_DOMAIN ); if ( COOKIEPATH != SITECOOKIEPATH ) setcookie( 'duoshuo_token', ' ', time() - 31536000, SITECOOKIEPATH, COOKIE_DOMAIN ); } public function oauthConnect(){ if (!$this->connected()) return ; if (!isset($_GET['code'])) return false; try{ $keys = array( 'code' => $_GET['code'], 'redirect_uri' => (is_ssl()?'https':'http').'://duoshuo.com/login-callback/', ); $token = $this->getClient()->getAccessToken('code', $keys); if ($token['code'] != 0) return false; $this->userLogin($token); } catch(Duoshuo_Exception $e){ $this->connectFailed(); } } public function userLogin($token){ global $wpdb, $error; nocache_headers(); if (isset($token['user_key'])){//登陆成功 $user = get_user_by('id', $token['user_key']); $this->updateUserMeta($user->ID, 'duoshuo_access_token', $token['access_token']); wp_clear_auth_cookie(); wp_set_auth_cookie($user->ID, true, is_ssl()); wp_set_current_user($user->ID); if (isset($_GET['redirect_to'])){ // wordpress 采用的是redirect_to字段 wp_redirect($_GET['redirect_to']); exit; } } else{ if (isset($_GET['redirect_to']) && $_GET['redirect_to'] !== admin_url()){// 如果是在内容页登录,无论如何都把用户带回内容页 wp_redirect($_GET['redirect_to']); exit; } else{ $client = new Duoshuo_Client($this->shortName, $this->secret, null, $token['access_token']); $response = $client->request('GET', 'users/profile', array('user_id'=> $token['user_id'])); if (get_option('users_can_register')){// 如果站点开启注册 // 要求用户输入帐号进行绑定 $query = array( 'action' => 'register', //'duoshuo_user_id' => $token['user_id'], 'duoshuo_access_token'=>$token['access_token'], ); $this->duoshuoUserId = $token['user_id']; $registerUrl = site_url( 'wp-login.php?' . http_build_query($query), 'login' ); $error = '' . '' . esc_html($response['response']['name']) . ',欢迎!
' . '请绑定已注册的本站帐号;
' . '如果你还没有本站帐号,请注册'; } else{// 如果站点未开启注册 //如果是从wp-login页面发起的请求,就不触发重定向 $error = '' . '' . esc_html($response['response']['name']) . ',欢迎!
' . '你还没有和本站的用户帐号绑定,
' . '如果你已经注册,请先登录之后绑定社交帐号'; } } } } public function bindUser($user_login, $user = null){ // 早期版本wp_login接口只有第一个参数 if (empty($user)){ $user = get_user_by('login', $user_login); } if (isset($_POST['duoshuo_user_id'])){ $query = array( 'master_user_id'=> $_POST['duoshuo_user_id'], 'jwt' => $this->jwt($user->ID), 'redirect_uri' => admin_url(), ); wp_redirect((is_ssl()?'https':'http').'://duoshuo.com/merge/?'. http_build_query($query, null, '&')); exit; } } public function userRegisterHook($userId){ if (!$this->connected()) return ; // WP_User $user = get_user_by('id', $userId); try{ if (isset($_POST['user_login']) && isset($_POST['duoshuo_access_token'])){ // 已登录多说帐号,且多说帐号并未与本站user_key绑定 $client = new Duoshuo_Client($this->shortName, $this->secret, null, $_POST['duoshuo_access_token']); $params = array( 'user' => $this->packageUser($user), ); $remoteResponse = $client->request('POST', 'sites/join', $params); // 不再需要记录duoshuo_user_id } else{ // 未登录多说帐号 $this->exportUsers(array($user)); } } catch(Duoshuo_Exception $e){ $this->connectFailed(); } } public function originalCommentsNotice(){ echo '
' . '

多说正在努力地为您的网站提供强大的社会化评论服务,WordPress原生评论数据现在仅用于备份;

' . '

多说会将每一条评论实时写回本地数据库,您在多说删除/审核了评论,也同样会同步到本地数据;

' . '

您在本页做的任何管理评论操作,都不会对多说评论框上的评论起作用,请访问评论管理后台进行评论管理。

' . '
'; } /** * * @return Duoshuo_Client */ public function getClient($userId = 0){ //如果不输入参数,就是游客 if ($userId !== null){ $accessToken = $this->getUserMeta($userId, 'duoshuo_access_token'); if (is_string($accessToken)) $client = new Duoshuo_Client($this->shortName, $this->secret, $this->jwt($userId), $accessToken); } if (!isset($client)) $client = new Duoshuo_Client($this->shortName, $this->secret, $this->jwt($userId)); $apiHostname = $this->getOption('api_hostname'); if ($apiHostname) $client->end_point = 'http://' . $apiHostname . '/'; return $client; } public function config(){ /*if ($_SERVER['REQUEST_METHOD'] == 'POST' && !($this->shortName && $this->secret)){ self::registerSite(); }*/ include dirname(__FILE__) . '/config.php'; } public function sync(){ include dirname(__FILE__) . '/sync.php'; } public function manage(){ include dirname(__FILE__) . '/manage.php'; } public function themes(){ include dirname(__FILE__) . '/themes.php'; } public function preferences(){ include dirname(__FILE__) . '/preferences.php'; } public function checkDependency($name){ global $wp_version; switch ($name){ case 'php': return array(PHP_VERSION, version_compare(PHP_VERSION, '5.3.0', '<') ? '建议升级php到5.3或以上' : true); case 'wordpress': return array($wp_version, version_compare($wp_version, '3.3.0', '<') ? '建议升级WordPress到3.3或以上' : true); case 'json': if (!extension_loaded('json')) return array('缺少json扩展', '安装并启用JSON扩展'); return array(true, true); case 'curl': if (!extension_loaded('curl')) return array('缺少curl扩展', '安装并启用curl扩展'); if (!function_exists('curl_init')) return array('curl_init()被禁用', '启用curl_init()函数'); if (!function_exists('curl_exec')) return array('curl_exec()被禁用', '启用curl_exec()函数'); return array(true, true); case 'fopen': if (!function_exists('fopen')) return array('fopen()被禁用', '启用fopen()函数'); if (!function_exists('ini_get')) return array('ini_get()被禁用', '启用ini_get()函数'); if (!ini_get('allow_url_fopen')) return array('allow_url_fopen被关闭', '在php.ini中设置allow_url_fopen = On'); return array(true, true); case 'fsockopen': if (!function_exists('fsockopen')) return array('fsockopen()被禁用', '启用fsockopen()函数'); return array(true, true); case 'hash_hmac': if (!function_exists('hash_hmac')) return array('hash_hmac()不存在', '升级php到5.3或以上'); return array(true, true); default: return array(true, true); } } public function settings(){ include dirname(__FILE__) . '/settings.php'; } public function statistics(){ include dirname(__FILE__) . '/statistics.php'; } public function profile(){ include dirname(__FILE__) . '/profile.php'; } public function reset(){ global $wpdb; //delete_option('duoshuo_short_name'); // 删除状态有关的值 delete_option('duoshuo_secret'); delete_option('duoshuo_synchronized'); delete_option('duoshuo_connect_failed'); delete_option('duoshuo_notice'); delete_option('duoshuo_sync_lock'); // 删除所有选项 foreach (self::$_defaultOptions as $optionName => $value) delete_option($optionName); // WP 2.9 以后支持这个函数 if (function_exists('delete_metadata')){ delete_metadata('user', 0, 'duoshuo_access_token', '', true); delete_metadata('user', 0, 'duoshuo_user_id', '', true); delete_metadata('post', 0, 'duoshuo_thread_id', '', true); delete_metadata('comment', 0, 'duoshuo_parent_id', '', true); delete_metadata('comment', 0, 'duoshuo_post_id', '', true); } //清空comment_agent字段 $wpdb->get_results($wpdb->prepare("update wp_comments set comment_agent='' where comment_agent LIKE '%%Duoshuo/%%'")); $redirect_url = add_query_arg('message', 'reset', admin_url('admin.php?page=duoshuo')); wp_redirect($redirect_url); exit; } /** * 关闭默认的评论,避免spammer */ public function commentsOpen($open, $post_id = null) { //if ($this->EMBED || get_post_meta($post_id, 'duoshuo_thread_id', true)) // return false; $script_name = array_pop( explode( '/', $_SERVER['PHP_SELF'] ) ); if (preg_match('/wp\-comments\-post\.php$/', $script_name) && get_post_meta($post_id, 'duoshuo_status', true) !== 'disabled') return false; return $open; } public function commentsTemplate($value){ global $wpdb, $post, $comments; $topPost = $this->topPost($post); if ($topPost === null) // 可能是inherit 但post_parent=0 return $value; if ( !( is_singular() && ( have_comments() || 'open' == $topPost->comment_status ) ) ) { return $value; } if (get_post_meta($topPost->ID, 'duoshuo_status', true) == 'disabled') return $value; /* if ( !dsq_is_installed() || !dsq_can_replace() ) { return $value; }*/ $threadId = get_post_meta($topPost->ID, 'duoshuo_thread_id', true); if (empty($threadId) && $this->connected()){ $this->syncUserToRemote($topPost->post_author); $this->syncPostToRemote($topPost->ID, $topPost); try{ $comments = $wpdb->get_results($wpdb->prepare("SELECT * FROM $wpdb->comments where comment_post_ID = %d AND comment_agent NOT LIKE '%%Duoshuo/%%' order by comment_ID asc", $topPost->ID)); $this->exportComments($comments); } catch(Duoshuo_Exception $e){ $this->connectFailed(); } } $this->EMBED = true; return dirname(__FILE__) . '/comments.php'; // return $value; } public function commentsPopupLinkAttributes($attribs){ global $post; $threadKey = $this->threadKey($post); if ($threadKey === null) // post_status = inherit, post_parent = 0 return $attribs; if (has_filter('comments_number', array($this, 'commentsText'))) remove_filter('comments_number', array($this, 'commentsText')); $attribs .= ' class="ds-thread-count" data-thread-key="' . $threadKey .'"'; return $attribs; } public function commentsText($comment_text, $number = null){ global $post; $threadKey = $this->threadKey($post); if ($threadKey === null) // post_status = inherit, post_parent = 0 return $comment_text; $attribs = 'class="ds-thread-count" data-thread-key="' . $threadKey .'"'; if (preg_match('/^<([a-z]+)( .*)?>(.*)<\/([a-z]+)>$/i', $comment_text, $matches) && $matches[1] == $matches[4]) return "<$matches[1] $attribs$matches[2]>$matches[3]"; else return "$comment_text"; } public function jwt($userId = null){ if ($userId === null) $user = wp_get_current_user(); elseif($userId != 0) $user = get_user_by( 'id', $userId); if (empty($user) || !$user->ID) return null; $token = array( 'short_name'=> $this->shortName, 'user_key' => $user->ID, 'name' => $user->display_name, ); return self::encodeJWT($token, $this->secret); } /** * @deprecated * @param string|int $userId * @return mixed */ public function userData($userId = null){ // null 代表当前登录用户,0代表游客 if ($userId === null) $current_user = wp_get_current_user(); elseif($userId != 0) $current_user = get_user_by( 'id', $userId); if (isset($current_user) && $current_user->ID) { $avatar_tag = get_avatar($current_user->ID); $avatar_data = array(); preg_match('/(src)=((\'|")[^(\'|")]*(\'|"))/i', $avatar_tag, $avatar_data); $avatar = htmlspecialchars_decode(str_replace(array('"', "'"), '', $avatar_data[2]), ENT_QUOTES); return array( 'id' => $current_user->ID, 'name' => $current_user->display_name, 'avatar' => $avatar, 'email' => $current_user->user_email, ); } else{ return array(); } } public function buildQuery($options = array()){ $query = array( 'short_name' => $this->shortName, 'sso' => array( 'login'=> site_url('wp-login.php', 'login') .'?action=duoshuo_login', 'logout'=> htmlspecialchars_decode(wp_logout_url(), ENT_QUOTES), ), ); if ($theme = $this->getOption('theme')) $query['theme'] = $theme; if ($this->getOption('style_patch')) $query['stylePatch'] = 'wordpress/' . str_replace(' ', '_', function_exists('wp_get_theme') ? wp_get_theme()->get('Name') : get_current_theme()); if (!empty($options)) $query['options'] = $options; return $query; } public function appendScripts(){ if ($this->_scriptsPrinted) return; $this->_scriptsPrinted = true; ?> _scriptsPrinted) return; $this->_scriptsPrinted = true; ?> duoshuoUserId)){ // 登录后发现没有本站帐号,输入帐号进行绑定 ?> 'duoshuo_login', 'redirect_to'=>urlencode(admin_url())), site_url('wp-login.php', 'login'));?>
printScripts();?> shortName = $_GET['short_name']; $this->secret = $_GET['secret']; ?> getOption('debug')); $progress = $this->getOption('synchronized'); if (!$progress || is_numeric($progress))// 之前已经完成了导出流程 $progress = 'user/0'; list($type, $offset) = explode('/', $progress); try{ switch($type){ case 'user': $limit = 30; // 不包括user_login, user_pass $columns = array('ID', 'user_nicename', 'user_email', 'user_url', 'user_registered', 'display_name'); $users = $wpdb->get_results( $wpdb->prepare("SELECT " . implode(',', $columns) . " FROM $wpdb->users order by ID asc limit %d,%d", $offset, $limit)); $count = $this->exportUsers($users); break; case 'post': $limit = 10; $columns = array('ID', 'post_author', 'post_date', 'post_date_gmt', 'post_content', 'post_title', 'post_excerpt', 'post_status', 'comment_status', 'ping_status', 'post_name', 'post_modified_gmt', 'guid', 'post_type', 'post_parent'); $posts = $wpdb->get_results( $wpdb->prepare("SELECT " . implode(',', $columns) . " FROM $wpdb->posts where post_type not in ('attachment', 'nav_menu_item', 'revision') and post_status not in ('auto-draft', 'draft', 'trash', 'inherit') order by ID asc limit %d,%d", $offset, $limit) );// 'inherit' 不再进行同步 $count = $this->exportPosts($posts); break; case 'comment': $limit = 50; $comments = $wpdb->get_results( $wpdb->prepare("SELECT * FROM $wpdb->comments where comment_agent NOT LIKE '%%Duoshuo/%%' order by comment_ID asc limit %d,%d", $offset, $limit)); $count = $this->exportComments($comments); break; default: } if ($count == $limit){ $progress = $type . '/' . ($offset + $limit); } elseif($type == 'user') $progress = 'post/0'; elseif($type == 'post') $progress = 'comment/0'; elseif($type == 'comment') $progress = time(); update_option('duoshuo_synchronized', $progress); $response = array( 'progress'=>$progress, 'code' => 0 ); $this->sendJsonResponse($response); } catch(Duoshuo_Exception $e){ $this->sendException($e); } } public function packageOptions(){ global $wp_version; $options = array( 'url' => get_option('home'), 'siteurl' => get_option('siteurl'), 'admin_email' => get_option('admin_email'), 'timezone' => get_option('timezone_string'), 'use_smilies' => get_option('use_smilies'), 'name' => html_entity_decode(get_option('blogname'), ENT_QUOTES, 'UTF-8'), 'description' => html_entity_decode(get_option('blogdescription'), ENT_QUOTES, 'UTF-8'), 'system_theme' => function_exists('wp_get_theme') ? wp_get_theme()->get('Name') : get_current_theme(),//'current_theme'=>'system_theme', 'system_version'=> $wp_version, 'plugin_version'=> self::VERSION, 'local_api_url' => $this->pluginDirUrl . 'api.php', 'oauth_proxy_url'=> $this->pluginDirUrl . 'oauth-proxy.php', ); $akismet_api_key = get_option('wordpress_api_key'); if ($akismet_api_key) $options['akismet_api_key'] = $akismet_api_key; return $options; } /** * 通知多说服务器更新站点信息 */ public function updateSite(){ if (!$this->connected()) return; $params = $this->packageOptions(); $user = wp_get_current_user(); try{ $response = $this->getClient($user->ID)->request('POST', 'sites/settings', $params); if (is_string($response)){ $this->errorMessages[] = $response; } elseif(isset($response['code']) && $response['code'] != 0){ $this->errorMessages[] = $response['errorMessage']; } } catch(Duoshuo_Exception $e){ $this->connectFailed(); } } /* public function updatedOption($option, $oldvalue = null, $newvalue = null){ $options = array('blogname', 'blogdescription', 'home', 'siteurl', 'admin_email', 'timezone_string', 'use_smilies', 'system_theme', 'akismet_api_key'); if (in_array($option, $options)) $this->needToUpdateSite = true; }*/ public function syncUserToRemote($userId){ if (!$this->connected()) return ; // WP_User $userData = get_user_by('id', $userId); try{ $this->exportUsers(array($userData)); } catch(Duoshuo_Exception $e){ $this->connectFailed(); } } /** * 同步这篇文章到所有社交网站 * @param string $postId */ public function syncPostToRemote($postId, $post = null){ if (!$this->connected()) return; if ($post == null) $post = get_post($postId); if (in_array($post->post_type, array('nav_menu_item', 'revision', 'attachment')) || in_array($post->post_status, array('inherit', 'auto-draft', 'draft', 'trash'))) //'inherit' 不再进行同步 return ; $params = $this->packageThread($post); if (isset($_POST['sync_to'])){ if ($_POST['sync_to'][0] == 'placeholder') unset($_POST['sync_to'][0]); $params['sync_to'] = implode(',', $_POST['sync_to']); } try{ $response = $this->getClient($post->post_author)->request('POST', 'threads/sync', $params); unset($_POST['sync_to']); //避免某些插件多次触发save_post if (is_array($response) && isset($response['code']) && $response['code'] == 0 && isset($response['response'])) update_post_meta($post->ID, 'duoshuo_thread_id', $response['response']['thread_id']); } catch(Duoshuo_Exception $e){ $this->connectFailed(); } } public function packageUser($user){ static $roleMap = array( 'administrator' => 'administrator', 'editor' => 'editor', 'author' => 'author', 'contributor' => 'user', 'subscriber' => 'user', ); if ($user instanceof WP_User){ // wordpress 3.3 $userData = $user->data; unset($userData->user_pass); unset($userData->user_login); $capabilities = $user->caps; } else{ $userData = $user; unset($userData->user_pass); unset($userData->user_login); $capabilities = $this->getUserMeta($user->ID, $this->get_blog_prefix().'capabilities', true); } $data = array( 'user_key' => $userData->ID, 'name' => $userData->display_name, 'email' => $userData->user_email, 'url' => $userData->user_url, 'created_at'=> $userData->user_registered, 'meta' => json_encode($userData), ); $avatar_data = array(); if (preg_match('/(src)=((\'|")[^(\'|")]*(\'|"))/i', get_avatar($userData->ID), $avatar_data)) $data['avatar_url'] = htmlspecialchars_decode(str_replace(array('"', "'"), '', $avatar_data[2]), ENT_QUOTES); foreach($roleMap as $wpRole => $role) if (isset($capabilities[$wpRole]) && $capabilities[$wpRole]){ $data['role'] = $role; break; } return $data; } public function packageThread($post){ $post->custom = get_post_custom($post->ID); $meta = clone ($post); unset($meta->post_title); unset($meta->post_content); unset($meta->post_excerpt); unset($meta->post_date_gmt); unset($meta->post_modified_gmt); unset($meta->post_name); unset($meta->post_status); unset($meta->comment_status); unset($meta->ping_status); unset($meta->guid); unset($meta->post_type); unset($meta->post_author); unset($meta->ID); $params = array( 'thread_key'=> $post->ID, 'author_key'=> $post->post_author, 'title' => html_entity_decode($post->post_title, ENT_QUOTES, 'UTF-8'), 'content' => $post->post_content, 'excerpt' => $post->post_excerpt, 'created_at'=> mysql2date('Y-m-d\TH:i:s+00:00', $post->post_date_gmt), 'updated_at'=> mysql2date('Y-m-d\TH:i:s+00:00', $post->post_modified_gmt), 'ip' => $_SERVER['REMOTE_ADDR'], 'url' => get_permalink($post), 'slug' => $post->post_name, 'status' => $post->post_status, 'comment_status'=> $post->comment_status, 'ping_status'=> $post->ping_status, 'guid' => $post->guid, 'type' => $post->post_type, 'meta' => json_encode($meta), 'source' => 'wordpress', ); if (!class_exists('nggLoader', false) || class_exists('nggRewrite', false)) $params['filtered_content'] = str_replace(']]>', ']]>', apply_filters('the_content', $post->post_content)); if (function_exists('get_post_thumbnail_id')){ // WordPress 2.9开始支持 $post_thumbnail_id = get_post_thumbnail_id( $post->ID ); if ( $post_thumbnail_id ) { $params['thumbnail'] = $this->normalizeUrl(wp_get_attachment_url($post_thumbnail_id)); //$image = wp_get_attachment_image_src( $post_thumbnail_id, $size, false); //list($src, $width, $height) = $image; //$meta = wp_get_attachment_metadata($id); //'large-feature' //'post-thumbnail' } } $args = array( 'post_parent' => $post->ID, 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => 'ASC', 'orderby' => 'menu_order ID' ); $images = array(); $children = get_children($args); if (is_array($children)) foreach($children as $attachment) $images[] = $this->normalizeUrl(wp_get_attachment_url($attachment->ID)); if (!empty($images)) $params['images'] = json_encode($images); /* $authorId = $this->getUserMeta($post->post_author, 'duoshuo_user_id', true); if (!empty($authorId)) $params['author_id'] = $authorId; $threadId = get_post_meta($post->ID, 'duoshuo_thread_id', true); if (!empty($threadId)) $params['thread_id'] = $threadId;*/ return $params; } public function packageComment($comment){ static $statusMap = array( '0' => 'pending', '1' => 'approved', 'trash' => 'deleted', 'spam' => 'spam', 'post-trashed'=>'thread-deleted', ); $meta = clone ($comment); unset($meta->comment_ID); unset($meta->comment_post_ID); unset($meta->comment_author); unset($meta->comment_author_email); unset($meta->comment_author_url); unset($meta->comment_author_IP); unset($meta->comment_date_gmt); unset($meta->comment_content); unset($meta->comment_karma); unset($meta->comment_approved); unset($meta->comment_agent); unset($meta->comment_type); unset($meta->comment_parent); unset($meta->user_id); $data = array( 'thread_key' => $comment->comment_post_ID, 'post_key' => $comment->comment_ID, 'author_key' => $comment->user_id, 'author_name' => htmlspecialchars_decode($comment->comment_author, ENT_QUOTES), 'author_email' => $comment->comment_author_email, 'author_url' => $comment->comment_author_url, 'created_at' => str_replace(' ', 'T', $comment->comment_date_gmt) . '+00:00', 'message' => $comment->comment_content, 'agent' => $comment->comment_agent, 'type' => $comment->comment_type, 'ip' => $comment->comment_author_IP, 'status' => $statusMap[$comment->comment_approved], 'parent_key' => $comment->comment_parent, // TODO 接收的地方要处理一下 'meta' => json_encode($meta), // comment_date, comment_karma ); //'source' => 'import', return $data; } public function exportOneComment($comment_ID){ $comment = get_comment($comment_ID); return $this->exportComments(array($comment)); } /** * 从服务器pull评论到本地 * * @param array $posts */ public function createPost($post){ global $wpdb; // 将img加到白名单中,仅对WordPress 3.5.0以后有效 if (!has_filter('wp_kses_allowed_html', array($this, 'allowedHtml'))) add_filter('wp_kses_allowed_html', array($this, 'allowedHtml')); static $approvedMap = array( 'pending' => '0', 'approved' => '1', 'deleted' => 'trash', 'spam' => 'spam', 'thread-deleted'=>'post-trashed', ); $post_id = isset($post['thread_key']) ? $post['thread_key'] : $wpdb->get_var("SELECT post_id FROM $wpdb->postmeta WHERE meta_key = 'duoshuo_thread_id' AND meta_value = $post[thread_id]"); if (!is_numeric($post_id)) // 找不到对应的文章 return array(); $data = array( 'comment_author' => trim(strip_tags($post['author_name'])), 'comment_author_email'=>$post['author_email'], 'comment_author_url'=> $post['author_url'], 'comment_author_IP' => $post['ip'], 'comment_date' => $this->rfc3339_to_mysql($post['created_at']), 'comment_date_gmt' => $this->rfc3339_to_mysql_gmt($post['created_at']), 'comment_content' => $post['message'], 'comment_approved' => $approvedMap[$post['status']], 'comment_agent' => 'Duoshuo/' . self::VERSION . ':' . $post['post_id'], 'comment_type' => $post['type'], 'comment_post_ID' => $post_id, //'comment_karma' ); if ($post['parent_id']){ $parent_id = $wpdb->get_var( "SELECT comment_ID FROM $wpdb->commentmeta WHERE meta_key = 'duoshuo_post_id' AND meta_value = '$post[parent_id]'"); if (isset($parent_id)) $data['comment_parent'] = $parent_id; } $author_id = isset($post['author_key']) ? $post['author_key'] : $wpdb->get_var( "SELECT user_id FROM $wpdb->usermeta WHERE meta_key = 'duoshuo_user_id' AND meta_value = $post[author_id]"); if (is_numeric($author_id)) $data['user_id'] = $author_id; if (isset($post['post_key'])){ $data['comment_ID'] = $post['post_key']; } elseif(isset($post['post_id'])){ $data['comment_ID'] = $wpdb->get_var( "SELECT comment_ID FROM $wpdb->commentmeta WHERE meta_key = 'duoshuo_post_id' AND meta_value = '$post[post_id]'"); } if(isset($data['comment_ID'])){ // wp_update_comment 中会做 wp_filter_comment wp_update_comment($data); } else{ $data = wp_filter_comment($data); $data['comment_ID'] = wp_insert_comment($data); } if ($post['parent_id']) update_comment_meta($data['comment_ID'], 'duoshuo_parent_id', $post['parent_id']); else delete_comment_meta($data['comment_ID'], 'duoshuo_parent_id'); update_comment_meta($data['comment_ID'], 'duoshuo_post_id', $post['post_id']); return array($post_id); } public function deleteForeverPost($postIdArray){ global $wpdb; $commentIdArray = $wpdb->get_col( "SELECT comment_ID FROM $wpdb->commentmeta WHERE meta_key = 'duoshuo_post_id' AND meta_value IN ('" . implode("', '", $postIdArray) . "')"); if (count($commentIdArray)){ $commentIdArray = $wpdb->get_col( "SELECT comment_ID FROM $wpdb->comments WHERE comment_ID IN ('" . implode("', '", $commentIdArray) . "')"); foreach ($commentIdArray as $commentId) wp_delete_comment($commentId, true); } return array(); } public function deletePost($postIdArray){ global $wpdb; $commentIdArray = $wpdb->get_col( "SELECT comment_ID FROM $wpdb->commentmeta WHERE meta_key = 'duoshuo_post_id' AND meta_value IN ('" . implode("', '", $postIdArray) . "')"); if (count($commentIdArray)){ $commentIdArray = $wpdb->get_col( "SELECT comment_ID FROM $wpdb->comments WHERE comment_ID IN ('" . implode("', '", $commentIdArray) . "')"); foreach ($commentIdArray as $commentId) wp_trash_comment($commentId); } return array(); } public function spamPost($postIdArray){ global $wpdb; $commentIdArray = $wpdb->get_col( "SELECT comment_ID FROM $wpdb->commentmeta WHERE meta_key = 'duoshuo_post_id' AND meta_value IN ('" . implode("', '", $postIdArray) . "')"); if (count($commentIdArray)){ $commentIdArray = $wpdb->get_col( "SELECT comment_ID FROM $wpdb->comments WHERE comment_ID IN ('" . implode("', '", $commentIdArray) . "')"); foreach($commentIdArray as $commentId) wp_spam_comment($commentId); } return array(); } public function approvePost($postIdArray){ global $wpdb; $commentIdArray = $wpdb->get_col( "SELECT comment_ID FROM $wpdb->commentmeta WHERE meta_key = 'duoshuo_post_id' AND meta_value IN ('" . implode("', '", $postIdArray) . "')"); if (count($commentIdArray)){ $commentIdArray = $wpdb->get_col( "SELECT comment_ID FROM $wpdb->comments WHERE comment_ID IN ('" . implode("', '", $commentIdArray) . "')"); foreach ($commentIdArray as $commentId) wp_set_comment_status($commentId, 'approve'); } return array(); } public function notices(){ foreach($this->errorMessages as $message) echo '

'.$message.'

'; $duoshuo_notice = $this->getOption('notice'); if (!empty($duoshuo_notice)){//系统推送的通知 echo '
'.$duoshuo_notice.'
'; } elseif ($duoshuo_notice === false){ update_option('duoshuo_notice', ''); } $messages = array( 'registered'=>'注册成功,请同步数据', 'reset' =>'已重置', ); if (isset($_GET['message']) && isset($messages[$_GET['message']])) echo '

'.$messages[$_GET['message']].'

'; } public function showException($e){ echo '

' . $e->getMessage() . '

'; } public function sendException($e){ $response = array( 'code' => $e->getCode(), 'errorMessage'=>$e->getMessage(), ); echo json_encode($response); exit; } public function sendJsonResponse($response){ if (!headers_sent()) { nocache_headers(); header('Content-type: application/json; charset=UTF-8'); } echo json_encode($response); exit; } //发布文章时候的同步设置 public function syncOptions(){ global $post; switch($post->post_status){ case 'auto-draft': case 'inherit': case 'draft': case 'trash': break; case 'publish': break; default: } $query = array( 'callback' => 'getSyncOptionsCallback', //'require' => 'site,visitor,serverTime', 'jwt' => $this->jwt(), ); if ($post->ID) $query['thread_key'] = $post->ID; $jsonpUrl = (is_ssl()?'https':'http').'://' . $this->shortName . '.duoshuo.com/api/users/syncOptions.jsonp?' . http_build_query($query, null, '&'); ?>
getOption('debug')); try{ $response = array( 'count' => $this->syncLog(), 'code' => 0 ); $this->sendJsonResponse($response); } catch(Duoshuo_Exception $e){ if ($e->getCode() == Duoshuo_Exception::REQUEST_TIMED_OUT){ $this->connectFailed(); $this->updateOption('sync_lock', 0); } $this->sendException($e); } } public function actionsFilter($actions){ /** * TODO $actions['ds-comments'] = '管理评论'; */ return $actions; } public function pluginActionLinks($links, $file) { if (empty($this->shortName) || empty($this->secret)) // 如果已经设置好了站点信息,就不显示安装 || !is_numeric($this->getOption('synchronized')) array_unshift($links, ''.__('Install').''); else array_unshift($links, ''.__('Settings').''); return $links; } public function dashboardWidget(){ if ( !$widget_options = get_option( 'dashboard_widget_options' ) ) $widget_options = array(); if ( !isset($widget_options['dashboard_duoshuo']) ) $widget_options['dashboard_duoshuo'] = array(); $widgets = get_option( 'dashboard_widget_options' ); $total_items = isset( $widgets['dashboard_duoshuo'] ) && isset( $widgets['dashboard_duoshuo']['items'] ) ? absint( $widgets['dashboard_duoshuo']['items'] ) : 5; echo ''; $this->printScripts(); } /** * The recent comments dashboard widget control. * * @since 3.0.0 */ public function dashboardWidgetControl() { if ( !$widget_options = get_option( 'dashboard_widget_options' ) ) $widget_options = array(); if ( !isset($widget_options['dashboard_duoshuo']) ) $widget_options['dashboard_duoshuo'] = array(); if ( 'POST' == $_SERVER['REQUEST_METHOD'] && isset($_POST['widget-duoshuo']) ) { $number = absint( $_POST['widget-duoshuo']['items'] ); $widget_options['dashboard_duoshuo']['items'] = $number; update_option( 'dashboard_widget_options', $widget_options ); } $number = isset( $widget_options['dashboard_duoshuo']['items'] ) ? (int) $widget_options['dashboard_duoshuo']['items'] : ''; echo '

'; echo '

'; } public function registerSettings(){ register_setting('duoshuo', 'duoshuo_short_name'); register_setting('duoshuo', 'duoshuo_secret'); foreach (self::$_defaultOptions as $optionName => $value) register_setting('duoshuo', $optionName); } public function updateLocalOptions(){ foreach (self::$_defaultOptions as $optionName => $value) if (isset($_POST[$optionName])) update_option($optionName, stripslashes($_POST[$optionName])); //stripslashes($_POST['duoshuo_comments_wrapper_intro']) //stripslashes($_POST['duoshuo_comments_wrapper_outro']) } }