Changeset 1826582
- Timestamp:
- 02/22/2018 12:26:20 AM (8 years ago)
- Location:
- disqus-comment-system/trunk
- Files:
-
- 3 added
- 3 deleted
- 7 edited
-
README.txt (modified) (2 diffs)
-
admin/bundles/js/en.disqus-admin.bundle.3.0.12.js (deleted)
-
admin/bundles/js/en.disqus-admin.bundle.3.0.12.js.map (deleted)
-
admin/bundles/js/en.disqus-admin.bundle.3.0.12.min.js (deleted)
-
admin/bundles/js/en.disqus-admin.bundle.3.0.13.js (added)
-
admin/bundles/js/en.disqus-admin.bundle.3.0.13.js.map (added)
-
admin/bundles/js/en.disqus-admin.bundle.3.0.13.min.js (added)
-
disqus.php (modified) (3 diffs)
-
includes/class-disqus-api-service.php (modified) (4 diffs)
-
public/class-disqus-public.php (modified) (6 diffs)
-
public/partials/disqus-public-display.php (modified) (1 diff)
-
rest-api/class-disqus-rest-api.php (modified) (2 diffs)
-
uninstall.php (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
disqus-comment-system/trunk/README.txt
r1819436 r1826582 4 4 Requires at least: 4.4 5 5 Tested up to: 4.9.4 6 Stable tag: 3.0.1 26 Stable tag: 3.0.13 7 7 Requires PHP: 5.4 8 8 … … 123 123 == Changelog == 124 124 125 = 3.0.13 = 126 127 * Added a new option for rendering comments javascript directly into page markup 128 * Fixed warning that stated "cannot access private method Disqus_Rest_Api::dsq_get_settings_schema()" 129 * A few small copy changes in plugin's admin UI 130 125 131 = 3.0.12 = 126 132 -
disqus-comment-system/trunk/disqus.php
r1819436 r1826582 16 16 * Plugin URI: https://disqus.com/ 17 17 * Description: Disqus helps publishers increase engagement and build loyal audiences. Supports syncing comments to your database for easy backup. 18 * Version: 3.0.1 218 * Version: 3.0.13 19 19 * Author: Disqus 20 20 * Author URI: https://disqus.com/ … … 24 24 * Domain Path: /languages 25 25 */ 26 27 $DISQUSVERSION = '3.0.13'; 26 28 27 29 // If this file is called directly, abort. … … 68 70 */ 69 71 function run_disqus() { 72 global $DISQUSVERSION; 70 73 71 $plugin = new Disqus( '3.0.12');74 $plugin = new Disqus( $DISQUSVERSION ); 72 75 $plugin->run(); 73 76 -
disqus-comment-system/trunk/includes/class-disqus-api-service.php
r1817585 r1826582 57 57 * @param string $endpoint The Disqus API secret key. 58 58 * @param array $params The params to be appended to the query. 59 * @return array The response data array.59 * @return mixed The response data. 60 60 */ 61 61 public function api_get( $endpoint, $params ) { … … 80 80 ) ); 81 81 82 $dsq_response_data = json_decode( $dsq_response['body'] ); 83 84 return $dsq_response_data; 82 return $this->get_response_body( $dsq_response ); 85 83 } 86 84 … … 91 89 * @param string $endpoint The Disqus API secret key. 92 90 * @param array $params The params to be added to the body. 93 * @return array The response data array.91 * @return mixed The response data. 94 92 */ 95 93 public function api_post( $endpoint, $params ) { … … 106 104 ) ); 107 105 108 $dsq_response_data = json_decode( $dsq_response['body'] ); 106 return $this->get_response_body( $dsq_response ); 107 } 109 108 110 return $dsq_response_data; 109 /** 110 * Checks the type of response and returns and object variable with the Disqus response. 111 * 112 * @since 3.0 113 * @param WP_Error|array $response The remote response. 114 * @return mixed The response body in Disqus API format. 115 */ 116 private function get_response_body( $response ) { 117 if ( is_wp_error( $response ) ) { 118 // The WP_Error class has no way of getting the response body, so we have to 119 // emulate the Disqus API error format for downstream compatibility. 120 $error_message = $response->get_error_message(); 121 $response = new StdClass(); 122 $response->code = 2; 123 $response->response = $error_message; 124 } else { 125 $response = json_decode( $response['body'] ); 126 } 127 128 return $response; 111 129 } 112 130 } -
disqus-comment-system/trunk/public/class-disqus-public.php
r1819436 r1826582 23 23 24 24 /** 25 * The ID of this plugin.26 *27 * @since 3.028 * @access private29 * @var string $disqus The ID of this plugin.30 */31 private $disqus;32 33 /**34 * The version of this plugin.35 *36 * @since 3.037 * @access private38 * @var string $version The current version of this plugin.39 */40 private $version;41 42 /**43 * The unique Disqus forum shortname.44 *45 * @since 3.046 * @access private47 * @var string $shortname The unique Disqus forum shortname.48 */49 private $shortname;50 51 /**52 * Initialize the class and set its properties.53 *54 * @since 3.055 * @param string $disqus The name of the plugin.56 * @param string $version The version of this plugin.57 * @param string $shortname The configured Disqus shortname.58 */59 public function __construct( $disqus, $version, $shortname ) {60 $this->disqus = $disqus;61 $this->version = $version;62 $this->shortname = $shortname;63 }64 65 /**66 25 * Returns the Disqus identifier for a given post. 67 26 * 68 27 * @since 3.0 69 * @access private70 28 * @param WP_Post $post The WordPress post to create the title for. 71 29 * @return string The formatted identifier to be passed to Disqus. 72 30 */ 73 p rivatefunction dsq_identifier_for_post( $post ) {31 public static function dsq_identifier_for_post( $post ) { 74 32 return $post->ID . ' ' . $post->guid; 75 33 } … … 79 37 * 80 38 * @since 3.0 81 * @access private82 39 * @param WP_Post $post The WordPress post to create the title for. 83 40 * @return string The cleaned title to be passed to Disqus. 84 41 */ 85 p rivatefunction dsq_title_for_post( $post ) {42 public static function dsq_title_for_post( $post ) { 86 43 $title = get_the_title( $post ); 87 44 $title = strip_tags( $title, '<b><u><i><h1><h2><h3><code><blockquote><br><hr>' ); … … 93 50 * 94 51 * @since 3.0 95 * @access private96 52 * @param WP_User $user The WordPress user to authenticate. 97 53 * @param string $secret_key The Disqus API Secret Key. 98 54 * @return array The signed payload to authenticate a user with Single Sign-On. 99 55 */ 100 p rivatefunction remote_auth_s3_for_user( $user, $secret_key ) {56 public static function remote_auth_s3_for_user( $user, $secret_key ) { 101 57 $payload_user = array(); 102 58 if ( $user->ID ) { … … 122 78 * @return array The embed configuration to localize the comments embed script with. 123 79 */ 124 private function embed_vars_for_post( $post ) { 80 public static function embed_vars_for_post( $post ) { 81 global $DISQUSVERSION; 82 125 83 $embed_vars = array( 126 84 'disqusConfig' => array( 127 'integration' => 'wordpress ' . $ this->version,85 'integration' => 'wordpress ' . $DISQUSVERSION, 128 86 ), 129 'disqusIdentifier' => $this->dsq_identifier_for_post( $post ),130 'disqusShortname' => $this->shortname,131 'disqusTitle' => $this->dsq_title_for_post( $post ),132 'disqusUrl' => get_permalink( ),87 'disqusIdentifier' => Disqus_Public::dsq_identifier_for_post( $post ), 88 'disqusShortname' => get_option( 'disqus_forum_url' ), 89 'disqusTitle' => Disqus_Public::dsq_title_for_post( $post ), 90 'disqusUrl' => get_permalink( $post ), 133 91 'postId' => $post->ID, 134 92 ); … … 149 107 ); 150 108 $embed_vars['disqusConfig']['api_key'] = $public_key; 151 $embed_vars['disqusConfig']['remote_auth_s3'] = $this->remote_auth_s3_for_user( $user, $secret_key );109 $embed_vars['disqusConfig']['remote_auth_s3'] = Disqus_Public::remote_auth_s3_for_user( $user, $secret_key ); 152 110 } 153 111 154 112 return $embed_vars; 113 } 114 115 /** 116 * The ID of this plugin. 117 * 118 * @since 3.0 119 * @access private 120 * @var string $disqus The ID of this plugin. 121 */ 122 private $disqus; 123 124 /** 125 * The version of this plugin. 126 * 127 * @since 3.0 128 * @access private 129 * @var string $version The current version of this plugin. 130 */ 131 private $version; 132 133 /** 134 * The unique Disqus forum shortname. 135 * 136 * @since 3.0 137 * @access private 138 * @var string $shortname The unique Disqus forum shortname. 139 */ 140 private $shortname; 141 142 /** 143 * Initialize the class and set its properties. 144 * 145 * @since 3.0 146 * @param string $disqus The name of the plugin. 147 * @param string $version The version of this plugin. 148 * @param string $shortname The configured Disqus shortname. 149 */ 150 public function __construct( $disqus, $version, $shortname ) { 151 $this->disqus = $disqus; 152 $this->version = $version; 153 $this->shortname = $shortname; 155 154 } 156 155 … … 229 228 global $post; 230 229 231 if ( $this->dsq_embed_can_load_for_post( $post ) ) {232 233 $embed_vars = $this->embed_vars_for_post( $post );230 if ( $this->dsq_embed_can_load_for_post( $post ) && ! get_option( 'disqus_render_js' ) ) { 231 232 $embed_vars = Disqus_Public::embed_vars_for_post( $post ); 234 233 235 234 wp_enqueue_script( $this->disqus . '_embed', plugin_dir_url( __FILE__ ) . 'js/comment_embed.js', array(), $this->version, true ); -
disqus-comment-system/trunk/public/partials/disqus-public-display.php
r1817585 r1826582 13 13 14 14 <div id="disqus_thread"></div> 15 <?php 16 if ( get_option( 'disqus_render_js' ) ) { 17 global $post; 18 $embed_vars = Disqus_Public::embed_vars_for_post( $post ); 19 $js = file_get_contents( plugin_dir_path( dirname( dirname( __FILE__ ) ) ) . 'public/js/comment_embed.js' ); 20 ?> 21 <script> 22 var embedVars = <?php echo json_encode( $embed_vars ); ?>; 23 <?php echo $js; ?> 24 </script> 25 <?php 26 } 27 ?> -
disqus-comment-system/trunk/rest-api/class-disqus-rest-api.php
r1818662 r1826582 354 354 355 355 /** 356 * Checks a comment state to determine if it's valid for syncing. 357 * 358 * @since 3.0.11 359 * @param array $comment The WordPress comment instance. 360 * @return boolean Whether the comment is valid for syncing. 361 */ 362 private function is_pingback_or_disqus_comment( $comment ) { 363 return empty( $comment->comment_type ) && strpos( $comment->comment_agent, 'Disqus' ) === false; 364 } 365 366 /** 367 * Parses and returns body content for either form-url-encoded or json data. 368 * 369 * @since 3.0 370 * @param WP_REST_Request $request The request object. 371 * @return array Array of parsed request data. 372 */ 373 private function get_request_data( WP_REST_Request $request ) { 374 $content_type = $request->get_content_type(); 375 376 switch ( $content_type['value'] ) { 377 case 'application/json': 378 return $request->get_json_params(); 379 default: 380 return $request->get_body_params(); 381 } 382 } 383 384 /** 385 * Fetches all available plugin options and updates any values if passed, and returns updated array. 356 * Returns the schema for the Disqus admin settings REST endpoint. 386 357 * 387 358 * @since 3.0 388 * @param array $new_settings Any options to be updated.389 * @access private390 * @return array The current settings array.391 */392 private function get_or_update_settings( $new_settings = null ) {393 $settings = array();394 $schema = $this->dsq_get_settings_schema();395 $should_update = is_array( $new_settings );396 397 // Loops through properties in our schema to check the value and update if needed.398 foreach ( $schema['properties'] as $key => $schema_value ) {399 $should_update_param = $should_update && isset( $new_settings[ $key ] ) && false === $schema_value['readonly'];400 if ( $should_update_param ) {401 update_option( $key, $new_settings[ $key ] );402 }403 $settings[ $key ] = get_option( $key, null );404 405 // Escape only values that have been set, otherwise esc_attr() will change null to an empty string.406 if ( null !== $settings[ $key ] ) {407 $settings[ $key ] = esc_attr( $settings[ $key ] );408 }409 }410 411 // Add additional non-database options here.412 $settings['disqus_installed'] = trim( $settings['disqus_forum_url'] ) !== '';413 414 return $settings;415 }416 417 /**418 * Determines if subscription information matches information about this WordPress site.419 *420 * @since 3.0421 * @param object $subscription The Disqus webhook subscription array.422 * @return boolean Whether the subscription information belongs to this WordPress site.423 */424 private function validate_subscription( $subscription ) {425 return rest_url( Disqus_Rest_Api::REST_NAMESPACE . '/sync/webhook' ) === $subscription->url;426 }427 428 /**429 * Fetches and returns the syncing status from the Disqus servers.430 *431 * @since 3.0432 * @return array The syncing status array.433 * @throws Exception An exception if the Disqus API doesn't return with code 0 (status: 200).434 */435 private function get_sync_status() {436 $is_subscribed = false;437 $is_enabled = false;438 $current_subscription = null;439 $requires_update = false;440 441 if ( get_option( 'disqus_secret_key' ) && get_option( 'disqus_admin_access_token' ) ) {442 $api_data = $this->api_service->api_get( 'forums/webhooks/list', array(443 'forum' => get_option( 'disqus_forum_url' ),444 ));445 446 if ( 0 === $api_data->code ) {447 // Loop through each subscription, looking for the first match.448 foreach ( $api_data->response as $subscription ) {449 if ( $this->validate_subscription( $subscription ) ) {450 $current_subscription = $subscription;451 $is_enabled = $current_subscription->enableSending;452 $is_subscribed = true;453 $requires_update = get_option( 'disqus_sync_token' ) !== $current_subscription->secret;454 break;455 }456 }457 } else {458 throw new Exception( $api_data->response );459 }460 }461 462 return array(463 'subscribed' => $is_subscribed,464 'enabled' => $is_enabled,465 'requires_update' => $requires_update,466 'subscription' => $current_subscription,467 'last_message' => get_option( 'disqus_last_sync_message', '' ),468 );469 }470 471 /**472 * Enables automatic syncing from Disqus if disabled.473 *474 * @since 3.0475 * @return array The syncing status array.476 * @throws Exception An exception if the Disqus API doesn't return with code 0 (status: 200).477 */478 private function enable_sync() {479 $sync_status = $this->get_sync_status();480 $subscription = $sync_status['subscription'];481 $endpoint = null;482 $params = array(483 'url' => rest_url( Disqus_Rest_Api::REST_NAMESPACE . '/sync/webhook' ),484 'secret' => get_option( 'disqus_sync_token' ),485 'enableSending' => '1',486 );487 488 if ( ! $sync_status['subscribed'] ) {489 $endpoint = 'forums/webhooks/create';490 $params['forum'] = get_option( 'disqus_forum_url' );491 } elseif ( ! $sync_status['enabled'] || $sync_status['requires_update'] ) {492 $endpoint = 'forums/webhooks/update';493 $params['subscription'] = $subscription->id;494 }495 496 if ( null !== $endpoint ) {497 $api_data = $this->api_service->api_post( $endpoint, $params );498 499 if ( 0 === $api_data->code ) {500 $sync_status = array(501 'subscribed' => true,502 'enabled' => true,503 'requires_update' => false,504 'subscription' => $api_data->response,505 'last_message' => $sync_status['last_message'],506 );507 } else {508 $this->log_sync_message( 'Error enabling syncing: ' . $api_data->response );509 throw new Exception( $api_data->response );510 }511 }512 513 return $sync_status;514 }515 516 /**517 * Disables automatic syncing from Disqus if enabled.518 *519 * @since 3.0520 * @return array The syncing status array.521 * @throws Exception An exception if the Disqus API doesn't return with code 0 (status: 200).522 */523 private function disable_sync() {524 $sync_status = $this->get_sync_status();525 $subscription = $sync_status['subscription'];526 527 if ( $sync_status['enabled'] ) {528 $params = array(529 'subscription' => $subscription->id,530 'enableSending' => '0',531 );532 $api_data = $this->api_service->api_post( 'forums/webhooks/update', $params );533 534 if ( 0 === $api_data->code ) {535 $sync_status = array(536 'subscribed' => true,537 'enabled' => false,538 'requires_update' => false,539 'subscription' => $api_data->response,540 'last_message' => $sync_status['last_message'],541 );542 } else {543 throw new Exception( $api_data->response );544 }545 }546 547 return $sync_status;548 }549 550 /**551 * Creates a comment in the WordPress database given a Disqus post.552 *553 * @since 3.0554 * @param array $post The Disqus post object.555 * @return int The newly created comment ID.556 * @throws Exception An exception if comment can't be saved from post data.557 */558 private function create_comment_from_post( $post ) {559 $this->validate_disqus_post_data( $post );560 561 // Check to make sure we haven't synced this comment yet.562 $comment_query = new WP_Comment_Query( array(563 'meta_key' => 'dsq_post_id',564 'meta_value' => $post['id'],565 'number' => 1,566 ) );567 568 if ( ! empty( $comment_query->comments ) ) {569 $this->log_sync_message( 'Error syncing new comment "' . $post['id'] . '" from Disqus. Comment with this dsq_post_id already in the local database' );570 return 0;571 }572 573 $comment_data = $this->comment_data_from_post( $post );574 575 $new_comment_id = wp_insert_comment( $comment_data );576 577 return $new_comment_id;578 }579 580 /**581 * Updates a comment in the WordPress database given a Disqus post.582 *583 * @since 3.0584 * @param array $post The Disqus post object.585 * @return int The newly created comment ID.586 * @throws Exception An exception if comment can't be saved from post data.587 */588 private function update_comment_from_post( $post ) {589 $this->validate_disqus_post_data( $post );590 591 // Check to make sure we have synced this comment already.592 $comment_query = new WP_Comment_Query( array(593 'meta_key' => 'dsq_post_id',594 'meta_value' => $post['id'],595 'number' => 1,596 ) );597 598 $comments = $comment_query->comments;599 600 if ( empty( $comments ) ) {601 $this->log_sync_message( 'Error updating synced comment "' . $post['id'] . '" from Disqus. Comment with this dsq_post_id was not in the local database' );602 return 0;603 }604 605 foreach ( $comments as $comment ) {606 $updated_comment_id = $comment->comment_ID;607 }608 609 $comment_data = $this->comment_data_from_post( $post );610 $comment_data['comment_ID'] = $updated_comment_id;611 612 // Remove non-updating fields.613 unset( $comment_data['comment_meta'] );614 unset( $comment_data['comment_agent'] );615 unset( $comment_data['comment_parent'] );616 unset( $comment_data['comment_type'] );617 unset( $comment_data['comment_date_gmt'] );618 unset( $comment_data['comment_post_ID'] );619 620 $updated = wp_update_comment( $comment_data );621 622 return 1 === $updated ? $updated_comment_id : 0;623 }624 625 /**626 * Creates a comment in the WordPress database given a Disqus post.627 *628 * @since 3.0629 * @param array $post The Disqus post object.630 * @throws Exception An exception if comment is invalid.631 */632 private function validate_disqus_post_data( $post ) {633 if ( ! $post || get_option( 'disqus_forum_url' ) !== $post['forum'] ) {634 throw new Exception( 'The comment\'s forum does not match the installed forum. Was "' . $post['forum'] . '", expected "' . get_option( 'disqus_forum_url' ) . '"' );635 }636 }637 638 /**639 * Checks the state of a Disqus post (comment) and translates to the WordPress comment_approved format.640 *641 * @since 3.0642 * @param array $post The Disqus post object.643 * @return array The translated comment data to be inserted/updated.644 * @throws Exception An exception if comment can't be saved from post data.645 */646 private function comment_data_from_post( $post ) {647 $thread = $post['threadData'];648 $author = $post['author'];649 650 $wp_post_id = null;651 652 // Look up posts with the Disqus thread ID meta field.653 $post_query = new WP_Query( array(654 'meta_key' => 'dsq_thread_id',655 'meta_value' => $thread['id'],656 ) );657 658 if ( $post_query->have_posts() ) {659 $wp_post_id = $post_query->post->ID;660 wp_reset_postdata();661 }662 663 // If that doesn't exist, get the and update the matching post metadata.664 if ( null === $wp_post_id || false === $wp_post_id ) {665 $identifiers = $thread['identifiers'];666 $first_identifier = count( $identifiers ) > 0 ? $identifiers[0] : null;667 668 if ( null !== $first_identifier ) {669 $ident_parts = explode( ' ', $first_identifier, 2 );670 $wp_post_id = reset( $ident_parts );671 }672 673 // Keep the post's thread ID meta up to date.674 update_post_meta( $wp_post_id, 'dsq_thread_id', $thread['id'] );675 }676 677 if ( null === $wp_post_id || false == $wp_post_id ) {678 throw new Exception( 'No post found associated with the thread.' );679 }680 681 // Find the parent comment, if any.682 $parent = 0;683 if ( null !== $post['parent'] ) {684 $parent_comment_query = new WP_Comment_Query( array(685 'meta_key' => 'dsq_post_id',686 'meta_value' => (string) $post['parent'],687 'number' => 1,688 ) );689 $parent_comments = $parent_comment_query->comments;690 691 if ( empty( $parent_comments ) ) {692 throw new Exception( 'This comment\'s parent has not been synced yet.' );693 } else {694 $parent = $parent_comments[0]->comment_ID;695 }696 }697 698 // Email is a special permission for Disqus API applications and won't be present699 // if the user has not set the permission for their API application.700 $author_email = null;701 if ( isset( $author['email'] ) ) {702 $author_email = $author['email'];703 } elseif ( $author['isAnonymous'] ) {704 $author_email = 'anonymized-' . md5( $author['name'] ) . '@disqus.com';705 } else {706 $author_email = 'user-' . $author['id'] . '@disqus.com';707 }708 709 // Translate the comment approval state.710 $comment_approved = 1;711 if ( $post['isApproved'] && ! $post['isDeleted'] ) {712 $comment_approved = 1;713 } elseif ( $post['isDeleted'] ) {714 $comment_approved = 0; // Deleted is not a state in WordPress, so we'll keep them in pending.715 } elseif ( ! $post['isDeleted'] && ! $post['isSpam'] && ! $post['isApproved'] ) {716 $comment_approved = 0;717 } elseif ( $post['isSpam'] && ! $post['isApproved'] ) {718 $comment_approved = 'spam';719 }720 721 return array(722 'comment_post_ID' => (int) $wp_post_id,723 'comment_author' => $author['name'],724 'comment_author_email' => $author_email,725 'comment_author_IP' => $post['ipAddress'],726 'comment_author_url' => isset( $author['url'] ) ? $author['url'] : '',727 'comment_content' => $post['raw_message'],728 'comment_date_gmt' => $post['createdAt'],729 'comment_type' => '', // Leave blank for a regular comment.730 'comment_parent' => $parent,731 'comment_agent' => 'Disqus Sync Host',732 'comment_approved' => $comment_approved,733 'comment_meta' => array(734 'dsq_post_id' => $post['id'],735 ),736 );737 }738 739 /**740 * Stores the last sync log message with date/time appended.741 *742 * @since 3.0743 * @access private744 * @param string $message The base message to store.745 */746 private function log_sync_message( $message ) {747 update_option( 'disqus_last_sync_message', $message . ': ' . date( 'Y-m-d g:i a', time() ) );748 }749 750 /**751 * Outputs a list of comments to a WXR file for uploading to the Disqus importer.752 *753 * @since 3.0754 * @access private755 * @param WP_Post $post The post details the comments belong to.756 * @param array $comments The base message to store.757 * @return string The WXR document as a string.758 */759 private function generate_export_wxr( $post, $comments ) {760 761 $post_author = get_userdata( $post->post_author );762 763 $xml = new DOMDocument( '1.0', get_bloginfo( 'charset' ) );764 765 $rss = $xml->createElement( 'rss' );766 $rss->setAttribute( 'version', '2.0' );767 $rss->setAttributeNS(768 'http://www.w3.org/2000/xmlns/',769 'xmlns:excerpt',770 'http://wordpress.org/export/1.0/excerpt/'771 );772 $rss->setAttributeNS(773 'http://www.w3.org/2000/xmlns/',774 'xmlns:content',775 'http://purl.org/rss/1.0/modules/content/'776 );777 $rss->setAttributeNS(778 'http://www.w3.org/2000/xmlns/',779 'xmlns:dsq',780 'https://disqus.com/'781 );782 $rss->setAttributeNS(783 'http://www.w3.org/2000/xmlns/',784 'xmlns:wfw',785 'http://wellformedweb.org/CommentAPI/'786 );787 $rss->setAttributeNS(788 'http://www.w3.org/2000/xmlns/',789 'xmlns:dc',790 'http://purl.org/dc/elements/1.1/'791 );792 $rss->setAttributeNS(793 'http://www.w3.org/2000/xmlns/',794 'xmlns:wp',795 'http://wordpress.org/export/1.0/'796 );797 798 $channel = $xml->createElement( 'channel' );799 $channel->appendChild( $xml->createElement( 'title', get_bloginfo_rss( 'name' ) ) );800 $channel->appendChild( $xml->createElement( 'link', get_bloginfo_rss( 'url' ) ) );801 $channel->appendChild(802 $xml->createElement(803 'pubDate',804 mysql2date( 'D, d M Y H:i:s +0000', get_lastpostmodified( 'GMT' ), false )805 )806 );807 $channel->appendChild(808 $xml->createElement(809 'generator',810 'WordPress ' . get_bloginfo_rss( 'version' ) . '; Disqus ' . $this->version811 )812 );813 814 // Generate the item (the post).815 $item = $xml->createElement( 'item' );816 $item->appendChild(817 $xml->createElement( 'title', apply_filters( 'the_title_rss', $post->post_title ) )818 );819 $item->appendChild(820 $xml->createElement(821 'link',822 esc_url( apply_filters( 'the_permalink_rss', get_permalink( $post->ID ) ) )823 )824 );825 $item->appendChild(826 $xml->createElement(827 'pubDate',828 mysql2date( 'D, d M Y H:i:s +0000', get_post_time( 'Y-m-d H:i:s', true, $post ), false )829 )830 );831 832 $author_name_cdata = $xml->createCDATASection( $post_author->display_name );833 $author_name_element = $xml->createElement( 'dc:creator' );834 $author_name_element->appendChild( $author_name_cdata );835 $item->appendChild( $author_name_element );836 837 $guid = $xml->createElement( 'guid', $post->guid );838 $guid->setAttribute( 'isPermalink', 'false' );839 $item->appendChild( $guid );840 841 $post_content_cdata = $xml->createCDATASection( apply_filters( 'the_content_export', $post->post_content ) );842 $post_content_element = $xml->createElement( 'content:encoded' );843 $post_content_element->appendChild( $post_content_cdata );844 $item->appendChild( $post_content_element );845 846 $identifier_cdata = $xml->createCDATASection( $post->ID . ' ' . $post->guid );847 $identifier_element = $xml->createElement( 'dsq:thread_identifier' );848 $identifier_element->appendChild( $identifier_cdata );849 $item->appendChild( $identifier_element );850 851 $item->appendChild(852 $xml->createElement(853 'wp:post_id',854 $post->ID855 )856 );857 858 $item->appendChild(859 $xml->createElement(860 'wp:post_date_gmt',861 $post->post_date_gmt862 )863 );864 865 $item->appendChild(866 $xml->createElement(867 'wp:comment_status',868 $post->comment_status869 )870 );871 872 foreach ( $comments as $c ) {873 874 $wpcomment = $xml->createElement( 'wp:comment' );875 876 $wpcomment->appendChild(877 $xml->createElement(878 'wp:comment_id',879 $c->comment_ID880 )881 );882 883 $comment_author_name_cdata = $xml->createCDATASection( $c->comment_author );884 $comment_author_name_element = $xml->createElement( 'wp:comment_author' );885 $comment_author_name_element->appendChild( $comment_author_name_cdata );886 $wpcomment->appendChild( $comment_author_name_element );887 888 $wpcomment->appendChild(889 $xml->createElement(890 'wp:comment_author_email',891 $c->comment_author_email892 )893 );894 895 $wpcomment->appendChild(896 $xml->createElement(897 'wp:comment_author_url',898 $c->comment_author_url899 )900 );901 902 $wpcomment->appendChild(903 $xml->createElement(904 'wp:comment_author_IP',905 $c->comment_author_IP906 )907 );908 909 $wpcomment->appendChild(910 $xml->createElement(911 'wp:comment_date',912 $c->comment_date913 )914 );915 916 $wpcomment->appendChild(917 $xml->createElement(918 'wp:comment_date_gmt',919 $c->comment_date_gmt920 )921 );922 923 $comment_content_cdata = $xml->createCDATASection( $c->comment_content );924 $comment_content_element = $xml->createElement( 'wp:comment_content' );925 $comment_content_element->appendChild( $comment_content_cdata );926 $wpcomment->appendChild( $comment_content_element );927 928 $wpcomment->appendChild(929 $xml->createElement(930 'wp:comment_approved',931 $c->comment_approved932 )933 );934 935 $wpcomment->appendChild(936 $xml->createElement(937 'wp:comment_type',938 $c->comment_type939 )940 );941 942 $wpcomment->appendChild(943 $xml->createElement(944 'wp:comment_parent',945 $c->comment_parent946 )947 );948 949 $item->appendChild( $wpcomment );950 }951 952 // Append the post item to the channel.953 $channel->appendChild( $item );954 955 // Append the root channel to the RSS element.956 $rss->appendChild( $channel );957 958 // Finally append the root RSS element to the XML document.959 $xml->appendChild( $rss );960 961 $wxr = $xml->saveXML();962 963 return $wxr;964 }965 966 /**967 * Returns the schema for the Disqus admin settings REST endpoint.968 *969 * @since 3.0970 * @access private971 359 * @return array The REST schema. 972 360 */ 973 p rivatefunction dsq_get_settings_schema() {361 public function dsq_get_settings_schema() { 974 362 return array( 975 363 // This tells the spec of JSON Schema we are using which is draft 4. … … 1020 408 'readonly' => true, 1021 409 ), 410 'disqus_render_js' => array( 411 'description' => 'When true, the Disqus embed javascript is output directly into markup rather than being enqueued in a separate file.', 412 'type' => 'boolean', 413 'readonly' => false, 414 ), 1022 415 ), 1023 416 ); 1024 417 } 418 419 /** 420 * Checks a comment state to determine if it's valid for syncing. 421 * 422 * @since 3.0.11 423 * @param array $comment The WordPress comment instance. 424 * @return boolean Whether the comment is valid for syncing. 425 */ 426 private function is_pingback_or_disqus_comment( $comment ) { 427 return empty( $comment->comment_type ) && strpos( $comment->comment_agent, 'Disqus' ) === false; 428 } 429 430 /** 431 * Parses and returns body content for either form-url-encoded or json data. 432 * 433 * @since 3.0 434 * @param WP_REST_Request $request The request object. 435 * @return array Array of parsed request data. 436 */ 437 private function get_request_data( WP_REST_Request $request ) { 438 $content_type = $request->get_content_type(); 439 440 switch ( $content_type['value'] ) { 441 case 'application/json': 442 return $request->get_json_params(); 443 default: 444 return $request->get_body_params(); 445 } 446 } 447 448 /** 449 * Fetches all available plugin options and updates any values if passed, and returns updated array. 450 * 451 * @since 3.0 452 * @param array $new_settings Any options to be updated. 453 * @access private 454 * @return array The current settings array. 455 */ 456 private function get_or_update_settings( $new_settings = null ) { 457 $settings = array(); 458 $schema = $this->dsq_get_settings_schema(); 459 $should_update = is_array( $new_settings ); 460 461 // Loops through properties in our schema to check the value and update if needed. 462 foreach ( $schema['properties'] as $key => $schema_value ) { 463 $should_update_param = $should_update && isset( $new_settings[ $key ] ) && false === $schema_value['readonly']; 464 if ( $should_update_param ) { 465 update_option( $key, $new_settings[ $key ] ); 466 } 467 $settings[ $key ] = get_option( $key, null ); 468 469 // Escape only values that have been set, otherwise esc_attr() will change null to an empty string. 470 if ( null !== $settings[ $key ] ) { 471 $settings[ $key ] = esc_attr( $settings[ $key ] ); 472 } 473 } 474 475 // Add additional non-database options here. 476 $settings['disqus_installed'] = trim( $settings['disqus_forum_url'] ) !== ''; 477 478 return $settings; 479 } 480 481 /** 482 * Determines if subscription information matches information about this WordPress site. 483 * 484 * @since 3.0 485 * @param object $subscription The Disqus webhook subscription array. 486 * @return boolean Whether the subscription information belongs to this WordPress site. 487 */ 488 private function validate_subscription( $subscription ) { 489 return rest_url( Disqus_Rest_Api::REST_NAMESPACE . '/sync/webhook' ) === $subscription->url; 490 } 491 492 /** 493 * Fetches and returns the syncing status from the Disqus servers. 494 * 495 * @since 3.0 496 * @return array The syncing status array. 497 * @throws Exception An exception if the Disqus API doesn't return with code 0 (status: 200). 498 */ 499 private function get_sync_status() { 500 $is_subscribed = false; 501 $is_enabled = false; 502 $current_subscription = null; 503 $requires_update = false; 504 505 if ( get_option( 'disqus_secret_key' ) && get_option( 'disqus_admin_access_token' ) ) { 506 $api_data = $this->api_service->api_get( 'forums/webhooks/list', array( 507 'forum' => get_option( 'disqus_forum_url' ), 508 )); 509 510 if ( 0 === $api_data->code ) { 511 // Loop through each subscription, looking for the first match. 512 foreach ( $api_data->response as $subscription ) { 513 if ( $this->validate_subscription( $subscription ) ) { 514 $current_subscription = $subscription; 515 $is_enabled = $current_subscription->enableSending; 516 $is_subscribed = true; 517 $requires_update = get_option( 'disqus_sync_token' ) !== $current_subscription->secret; 518 break; 519 } 520 } 521 } else { 522 throw new Exception( $api_data->response ); 523 } 524 } 525 526 return array( 527 'subscribed' => $is_subscribed, 528 'enabled' => $is_enabled, 529 'requires_update' => $requires_update, 530 'subscription' => $current_subscription, 531 'last_message' => get_option( 'disqus_last_sync_message', '' ), 532 ); 533 } 534 535 /** 536 * Enables automatic syncing from Disqus if disabled. 537 * 538 * @since 3.0 539 * @return array The syncing status array. 540 * @throws Exception An exception if the Disqus API doesn't return with code 0 (status: 200). 541 */ 542 private function enable_sync() { 543 $sync_status = $this->get_sync_status(); 544 $subscription = $sync_status['subscription']; 545 $endpoint = null; 546 $params = array( 547 'url' => rest_url( Disqus_Rest_Api::REST_NAMESPACE . '/sync/webhook' ), 548 'secret' => get_option( 'disqus_sync_token' ), 549 'enableSending' => '1', 550 ); 551 552 if ( ! $sync_status['subscribed'] ) { 553 $endpoint = 'forums/webhooks/create'; 554 $params['forum'] = get_option( 'disqus_forum_url' ); 555 } elseif ( ! $sync_status['enabled'] || $sync_status['requires_update'] ) { 556 $endpoint = 'forums/webhooks/update'; 557 $params['subscription'] = $subscription->id; 558 } 559 560 if ( null !== $endpoint ) { 561 $api_data = $this->api_service->api_post( $endpoint, $params ); 562 563 if ( 0 === $api_data->code ) { 564 $sync_status = array( 565 'subscribed' => true, 566 'enabled' => true, 567 'requires_update' => false, 568 'subscription' => $api_data->response, 569 'last_message' => $sync_status['last_message'], 570 ); 571 } else { 572 $this->log_sync_message( 'Error enabling syncing: ' . $api_data->response ); 573 throw new Exception( $api_data->response ); 574 } 575 } 576 577 return $sync_status; 578 } 579 580 /** 581 * Disables automatic syncing from Disqus if enabled. 582 * 583 * @since 3.0 584 * @return array The syncing status array. 585 * @throws Exception An exception if the Disqus API doesn't return with code 0 (status: 200). 586 */ 587 private function disable_sync() { 588 $sync_status = $this->get_sync_status(); 589 $subscription = $sync_status['subscription']; 590 591 if ( $sync_status['enabled'] ) { 592 $params = array( 593 'subscription' => $subscription->id, 594 'enableSending' => '0', 595 ); 596 $api_data = $this->api_service->api_post( 'forums/webhooks/update', $params ); 597 598 if ( 0 === $api_data->code ) { 599 $sync_status = array( 600 'subscribed' => true, 601 'enabled' => false, 602 'requires_update' => false, 603 'subscription' => $api_data->response, 604 'last_message' => $sync_status['last_message'], 605 ); 606 } else { 607 throw new Exception( $api_data->response ); 608 } 609 } 610 611 return $sync_status; 612 } 613 614 /** 615 * Creates a comment in the WordPress database given a Disqus post. 616 * 617 * @since 3.0 618 * @param array $post The Disqus post object. 619 * @return int The newly created comment ID. 620 * @throws Exception An exception if comment can't be saved from post data. 621 */ 622 private function create_comment_from_post( $post ) { 623 $this->validate_disqus_post_data( $post ); 624 625 // Check to make sure we haven't synced this comment yet. 626 $comment_query = new WP_Comment_Query( array( 627 'meta_key' => 'dsq_post_id', 628 'meta_value' => $post['id'], 629 'number' => 1, 630 ) ); 631 632 if ( ! empty( $comment_query->comments ) ) { 633 $this->log_sync_message( 'Error syncing new comment "' . $post['id'] . '" from Disqus. Comment with this dsq_post_id already in the local database' ); 634 return 0; 635 } 636 637 $comment_data = $this->comment_data_from_post( $post ); 638 639 $new_comment_id = wp_insert_comment( $comment_data ); 640 641 return $new_comment_id; 642 } 643 644 /** 645 * Updates a comment in the WordPress database given a Disqus post. 646 * 647 * @since 3.0 648 * @param array $post The Disqus post object. 649 * @return int The newly created comment ID. 650 * @throws Exception An exception if comment can't be saved from post data. 651 */ 652 private function update_comment_from_post( $post ) { 653 $this->validate_disqus_post_data( $post ); 654 655 // Check to make sure we have synced this comment already. 656 $comment_query = new WP_Comment_Query( array( 657 'meta_key' => 'dsq_post_id', 658 'meta_value' => $post['id'], 659 'number' => 1, 660 ) ); 661 662 $comments = $comment_query->comments; 663 664 if ( empty( $comments ) ) { 665 $this->log_sync_message( 'Error updating synced comment "' . $post['id'] . '" from Disqus. Comment with this dsq_post_id was not in the local database' ); 666 return 0; 667 } 668 669 foreach ( $comments as $comment ) { 670 $updated_comment_id = $comment->comment_ID; 671 } 672 673 $comment_data = $this->comment_data_from_post( $post ); 674 $comment_data['comment_ID'] = $updated_comment_id; 675 676 // Remove non-updating fields. 677 unset( $comment_data['comment_meta'] ); 678 unset( $comment_data['comment_agent'] ); 679 unset( $comment_data['comment_parent'] ); 680 unset( $comment_data['comment_type'] ); 681 unset( $comment_data['comment_date_gmt'] ); 682 unset( $comment_data['comment_post_ID'] ); 683 684 $updated = wp_update_comment( $comment_data ); 685 686 return 1 === $updated ? $updated_comment_id : 0; 687 } 688 689 /** 690 * Creates a comment in the WordPress database given a Disqus post. 691 * 692 * @since 3.0 693 * @param array $post The Disqus post object. 694 * @throws Exception An exception if comment is invalid. 695 */ 696 private function validate_disqus_post_data( $post ) { 697 if ( ! $post || get_option( 'disqus_forum_url' ) !== $post['forum'] ) { 698 throw new Exception( 'The comment\'s forum does not match the installed forum. Was "' . $post['forum'] . '", expected "' . get_option( 'disqus_forum_url' ) . '"' ); 699 } 700 } 701 702 /** 703 * Checks the state of a Disqus post (comment) and translates to the WordPress comment_approved format. 704 * 705 * @since 3.0 706 * @param array $post The Disqus post object. 707 * @return array The translated comment data to be inserted/updated. 708 * @throws Exception An exception if comment can't be saved from post data. 709 */ 710 private function comment_data_from_post( $post ) { 711 $thread = $post['threadData']; 712 $author = $post['author']; 713 714 $wp_post_id = null; 715 716 // Look up posts with the Disqus thread ID meta field. 717 $post_query = new WP_Query( array( 718 'meta_key' => 'dsq_thread_id', 719 'meta_value' => $thread['id'], 720 ) ); 721 722 if ( $post_query->have_posts() ) { 723 $wp_post_id = $post_query->post->ID; 724 wp_reset_postdata(); 725 } 726 727 // If that doesn't exist, get the and update the matching post metadata. 728 if ( null === $wp_post_id || false === $wp_post_id ) { 729 $identifiers = $thread['identifiers']; 730 $first_identifier = count( $identifiers ) > 0 ? $identifiers[0] : null; 731 732 if ( null !== $first_identifier ) { 733 $ident_parts = explode( ' ', $first_identifier, 2 ); 734 $wp_post_id = reset( $ident_parts ); 735 } 736 737 // Keep the post's thread ID meta up to date. 738 update_post_meta( $wp_post_id, 'dsq_thread_id', $thread['id'] ); 739 } 740 741 if ( null === $wp_post_id || false == $wp_post_id ) { 742 throw new Exception( 'No post found associated with the thread.' ); 743 } 744 745 // Find the parent comment, if any. 746 $parent = 0; 747 if ( null !== $post['parent'] ) { 748 $parent_comment_query = new WP_Comment_Query( array( 749 'meta_key' => 'dsq_post_id', 750 'meta_value' => (string) $post['parent'], 751 'number' => 1, 752 ) ); 753 $parent_comments = $parent_comment_query->comments; 754 755 if ( empty( $parent_comments ) ) { 756 throw new Exception( 'This comment\'s parent has not been synced yet.' ); 757 } else { 758 $parent = $parent_comments[0]->comment_ID; 759 } 760 } 761 762 // Email is a special permission for Disqus API applications and won't be present 763 // if the user has not set the permission for their API application. 764 $author_email = null; 765 if ( isset( $author['email'] ) ) { 766 $author_email = $author['email']; 767 } elseif ( $author['isAnonymous'] ) { 768 $author_email = 'anonymized-' . md5( $author['name'] ) . '@disqus.com'; 769 } else { 770 $author_email = 'user-' . $author['id'] . '@disqus.com'; 771 } 772 773 // Translate the comment approval state. 774 $comment_approved = 1; 775 if ( $post['isApproved'] && ! $post['isDeleted'] ) { 776 $comment_approved = 1; 777 } elseif ( $post['isDeleted'] ) { 778 $comment_approved = 0; // Deleted is not a state in WordPress, so we'll keep them in pending. 779 } elseif ( ! $post['isDeleted'] && ! $post['isSpam'] && ! $post['isApproved'] ) { 780 $comment_approved = 0; 781 } elseif ( $post['isSpam'] && ! $post['isApproved'] ) { 782 $comment_approved = 'spam'; 783 } 784 785 return array( 786 'comment_post_ID' => (int) $wp_post_id, 787 'comment_author' => $author['name'], 788 'comment_author_email' => $author_email, 789 'comment_author_IP' => $post['ipAddress'], 790 'comment_author_url' => isset( $author['url'] ) ? $author['url'] : '', 791 'comment_content' => $post['raw_message'], 792 'comment_date_gmt' => $post['createdAt'], 793 'comment_type' => '', // Leave blank for a regular comment. 794 'comment_parent' => $parent, 795 'comment_agent' => 'Disqus Sync Host', 796 'comment_approved' => $comment_approved, 797 'comment_meta' => array( 798 'dsq_post_id' => $post['id'], 799 ), 800 ); 801 } 802 803 /** 804 * Stores the last sync log message with date/time appended. 805 * 806 * @since 3.0 807 * @access private 808 * @param string $message The base message to store. 809 */ 810 private function log_sync_message( $message ) { 811 update_option( 'disqus_last_sync_message', $message . ': ' . date( 'Y-m-d g:i a', time() ) ); 812 } 813 814 /** 815 * Outputs a list of comments to a WXR file for uploading to the Disqus importer. 816 * 817 * @since 3.0 818 * @access private 819 * @param WP_Post $post The post details the comments belong to. 820 * @param array $comments The base message to store. 821 * @return string The WXR document as a string. 822 */ 823 private function generate_export_wxr( $post, $comments ) { 824 825 $post_author = get_userdata( $post->post_author ); 826 827 $xml = new DOMDocument( '1.0', get_bloginfo( 'charset' ) ); 828 829 $rss = $xml->createElement( 'rss' ); 830 $rss->setAttribute( 'version', '2.0' ); 831 $rss->setAttributeNS( 832 'http://www.w3.org/2000/xmlns/', 833 'xmlns:excerpt', 834 'http://wordpress.org/export/1.0/excerpt/' 835 ); 836 $rss->setAttributeNS( 837 'http://www.w3.org/2000/xmlns/', 838 'xmlns:content', 839 'http://purl.org/rss/1.0/modules/content/' 840 ); 841 $rss->setAttributeNS( 842 'http://www.w3.org/2000/xmlns/', 843 'xmlns:dsq', 844 'https://disqus.com/' 845 ); 846 $rss->setAttributeNS( 847 'http://www.w3.org/2000/xmlns/', 848 'xmlns:wfw', 849 'http://wellformedweb.org/CommentAPI/' 850 ); 851 $rss->setAttributeNS( 852 'http://www.w3.org/2000/xmlns/', 853 'xmlns:dc', 854 'http://purl.org/dc/elements/1.1/' 855 ); 856 $rss->setAttributeNS( 857 'http://www.w3.org/2000/xmlns/', 858 'xmlns:wp', 859 'http://wordpress.org/export/1.0/' 860 ); 861 862 $channel = $xml->createElement( 'channel' ); 863 $channel->appendChild( $xml->createElement( 'title', get_bloginfo_rss( 'name' ) ) ); 864 $channel->appendChild( $xml->createElement( 'link', get_bloginfo_rss( 'url' ) ) ); 865 $channel->appendChild( 866 $xml->createElement( 867 'pubDate', 868 mysql2date( 'D, d M Y H:i:s +0000', get_lastpostmodified( 'GMT' ), false ) 869 ) 870 ); 871 $channel->appendChild( 872 $xml->createElement( 873 'generator', 874 'WordPress ' . get_bloginfo_rss( 'version' ) . '; Disqus ' . $this->version 875 ) 876 ); 877 878 // Generate the item (the post). 879 $item = $xml->createElement( 'item' ); 880 $item->appendChild( 881 $xml->createElement( 'title', apply_filters( 'the_title_rss', $post->post_title ) ) 882 ); 883 $item->appendChild( 884 $xml->createElement( 885 'link', 886 esc_url( apply_filters( 'the_permalink_rss', get_permalink( $post->ID ) ) ) 887 ) 888 ); 889 $item->appendChild( 890 $xml->createElement( 891 'pubDate', 892 mysql2date( 'D, d M Y H:i:s +0000', get_post_time( 'Y-m-d H:i:s', true, $post ), false ) 893 ) 894 ); 895 896 $author_name_cdata = $xml->createCDATASection( $post_author->display_name ); 897 $author_name_element = $xml->createElement( 'dc:creator' ); 898 $author_name_element->appendChild( $author_name_cdata ); 899 $item->appendChild( $author_name_element ); 900 901 $guid = $xml->createElement( 'guid', $post->guid ); 902 $guid->setAttribute( 'isPermalink', 'false' ); 903 $item->appendChild( $guid ); 904 905 $post_content_cdata = $xml->createCDATASection( apply_filters( 'the_content_export', $post->post_content ) ); 906 $post_content_element = $xml->createElement( 'content:encoded' ); 907 $post_content_element->appendChild( $post_content_cdata ); 908 $item->appendChild( $post_content_element ); 909 910 $identifier_cdata = $xml->createCDATASection( $post->ID . ' ' . $post->guid ); 911 $identifier_element = $xml->createElement( 'dsq:thread_identifier' ); 912 $identifier_element->appendChild( $identifier_cdata ); 913 $item->appendChild( $identifier_element ); 914 915 $item->appendChild( 916 $xml->createElement( 917 'wp:post_id', 918 $post->ID 919 ) 920 ); 921 922 $item->appendChild( 923 $xml->createElement( 924 'wp:post_date_gmt', 925 $post->post_date_gmt 926 ) 927 ); 928 929 $item->appendChild( 930 $xml->createElement( 931 'wp:comment_status', 932 $post->comment_status 933 ) 934 ); 935 936 foreach ( $comments as $c ) { 937 938 $wpcomment = $xml->createElement( 'wp:comment' ); 939 940 $wpcomment->appendChild( 941 $xml->createElement( 942 'wp:comment_id', 943 $c->comment_ID 944 ) 945 ); 946 947 $comment_author_name_cdata = $xml->createCDATASection( $c->comment_author ); 948 $comment_author_name_element = $xml->createElement( 'wp:comment_author' ); 949 $comment_author_name_element->appendChild( $comment_author_name_cdata ); 950 $wpcomment->appendChild( $comment_author_name_element ); 951 952 $wpcomment->appendChild( 953 $xml->createElement( 954 'wp:comment_author_email', 955 $c->comment_author_email 956 ) 957 ); 958 959 $wpcomment->appendChild( 960 $xml->createElement( 961 'wp:comment_author_url', 962 $c->comment_author_url 963 ) 964 ); 965 966 $wpcomment->appendChild( 967 $xml->createElement( 968 'wp:comment_author_IP', 969 $c->comment_author_IP 970 ) 971 ); 972 973 $wpcomment->appendChild( 974 $xml->createElement( 975 'wp:comment_date', 976 $c->comment_date 977 ) 978 ); 979 980 $wpcomment->appendChild( 981 $xml->createElement( 982 'wp:comment_date_gmt', 983 $c->comment_date_gmt 984 ) 985 ); 986 987 $comment_content_cdata = $xml->createCDATASection( $c->comment_content ); 988 $comment_content_element = $xml->createElement( 'wp:comment_content' ); 989 $comment_content_element->appendChild( $comment_content_cdata ); 990 $wpcomment->appendChild( $comment_content_element ); 991 992 $wpcomment->appendChild( 993 $xml->createElement( 994 'wp:comment_approved', 995 $c->comment_approved 996 ) 997 ); 998 999 $wpcomment->appendChild( 1000 $xml->createElement( 1001 'wp:comment_type', 1002 $c->comment_type 1003 ) 1004 ); 1005 1006 $wpcomment->appendChild( 1007 $xml->createElement( 1008 'wp:comment_parent', 1009 $c->comment_parent 1010 ) 1011 ); 1012 1013 $item->appendChild( $wpcomment ); 1014 } 1015 1016 // Append the post item to the channel. 1017 $channel->appendChild( $item ); 1018 1019 // Append the root channel to the RSS element. 1020 $rss->appendChild( $channel ); 1021 1022 // Finally append the root RSS element to the XML document. 1023 $xml->appendChild( $rss ); 1024 1025 $wxr = $xml->saveXML(); 1026 1027 return $wxr; 1028 } 1025 1029 } -
disqus-comment-system/trunk/uninstall.php
r1817585 r1826582 26 26 delete_option( 'disqus_sync_token' ); 27 27 delete_option( 'disqus_last_sync_message' ); 28 delete_option( 'disqus_render_js' ); 28 29 delete_option( 'disqus_manual_sync' ); // Legacy option.
Note: See TracChangeset
for help on using the changeset viewer.