Plugin Directory

Changeset 1826582


Ignore:
Timestamp:
02/22/2018 12:26:20 AM (8 years ago)
Author:
ryanv12
Message:

Preparing for 3.0.13 release

Location:
disqus-comment-system/trunk
Files:
3 added
3 deleted
7 edited

Legend:

Unmodified
Added
Removed
  • disqus-comment-system/trunk/README.txt

    r1819436 r1826582  
    44Requires at least: 4.4
    55Tested up to: 4.9.4
    6 Stable tag: 3.0.12
     6Stable tag: 3.0.13
    77Requires PHP: 5.4
    88
     
    123123== Changelog ==
    124124
     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
    125131= 3.0.12 =
    126132
  • disqus-comment-system/trunk/disqus.php

    r1819436 r1826582  
    1616 * Plugin URI:        https://disqus.com/
    1717 * Description:       Disqus helps publishers increase engagement and build loyal audiences. Supports syncing comments to your database for easy backup.
    18  * Version:           3.0.12
     18 * Version:           3.0.13
    1919 * Author:            Disqus
    2020 * Author URI:        https://disqus.com/
     
    2424 * Domain Path:       /languages
    2525 */
     26
     27$DISQUSVERSION = '3.0.13';
    2628
    2729// If this file is called directly, abort.
     
    6870 */
    6971function run_disqus() {
     72    global $DISQUSVERSION;
    7073
    71     $plugin = new Disqus( '3.0.12' );
     74    $plugin = new Disqus( $DISQUSVERSION );
    7275    $plugin->run();
    7376
  • disqus-comment-system/trunk/includes/class-disqus-api-service.php

    r1817585 r1826582  
    5757     * @param     string $endpoint    The Disqus API secret key.
    5858     * @param     array  $params      The params to be appended to the query.
    59      * @return    array               The response data array.
     59     * @return    mixed               The response data.
    6060     */
    6161    public function api_get( $endpoint, $params ) {
     
    8080        ) );
    8181
    82         $dsq_response_data = json_decode( $dsq_response['body'] );
    83 
    84         return $dsq_response_data;
     82        return $this->get_response_body( $dsq_response );
    8583    }
    8684
     
    9189     * @param     string $endpoint    The Disqus API secret key.
    9290     * @param     array  $params      The params to be added to the body.
    93      * @return    array               The response data array.
     91     * @return    mixed               The response data.
    9492     */
    9593    public function api_post( $endpoint, $params ) {
     
    106104        ) );
    107105
    108         $dsq_response_data = json_decode( $dsq_response['body'] );
     106        return $this->get_response_body( $dsq_response );
     107    }
    109108
    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;
    111129    }
    112130}
  • disqus-comment-system/trunk/public/class-disqus-public.php

    r1819436 r1826582  
    2323
    2424    /**
    25      * The ID of this plugin.
    26      *
    27      * @since    3.0
    28      * @access   private
    29      * @var      string $disqus    The ID of this plugin.
    30      */
    31     private $disqus;
    32 
    33     /**
    34      * The version of this plugin.
    35      *
    36      * @since    3.0
    37      * @access   private
    38      * @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.0
    46      * @access   private
    47      * @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.0
    55      * @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     /**
    6625     * Returns the Disqus identifier for a given post.
    6726     *
    6827     * @since     3.0
    69      * @access    private
    7028     * @param     WP_Post $post    The WordPress post to create the title for.
    7129     * @return    string           The formatted identifier to be passed to Disqus.
    7230     */
    73     private function dsq_identifier_for_post( $post ) {
     31    public static function dsq_identifier_for_post( $post ) {
    7432        return $post->ID . ' ' . $post->guid;
    7533    }
     
    7937     *
    8038     * @since     3.0
    81      * @access    private
    8239     * @param     WP_Post $post    The WordPress post to create the title for.
    8340     * @return    string           The cleaned title to be passed to Disqus.
    8441     */
    85     private function dsq_title_for_post( $post ) {
     42    public static function dsq_title_for_post( $post ) {
    8643        $title = get_the_title( $post );
    8744        $title = strip_tags( $title, '<b><u><i><h1><h2><h3><code><blockquote><br><hr>' );
     
    9350     *
    9451     * @since     3.0
    95      * @access    private
    9652     * @param     WP_User $user          The WordPress user to authenticate.
    9753     * @param     string  $secret_key    The Disqus API Secret Key.
    9854     * @return    array                  The signed payload to authenticate a user with Single Sign-On.
    9955     */
    100     private function remote_auth_s3_for_user( $user, $secret_key ) {
     56    public static function remote_auth_s3_for_user( $user, $secret_key ) {
    10157        $payload_user = array();
    10258        if ( $user->ID ) {
     
    12278     * @return    array            The embed configuration to localize the comments embed script with.
    12379     */
    124     private function embed_vars_for_post( $post ) {
     80    public static function embed_vars_for_post( $post ) {
     81        global $DISQUSVERSION;
     82
    12583        $embed_vars = array(
    12684            'disqusConfig' => array(
    127                 'integration' => 'wordpress ' . $this->version,
     85                'integration' => 'wordpress ' . $DISQUSVERSION,
    12886            ),
    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 ),
    13391            'postId' => $post->ID,
    13492        );
     
    149107            );
    150108            $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 );
    152110        }
    153111
    154112        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;
    155154    }
    156155
     
    229228        global $post;
    230229
    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 );
    234233
    235234            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  
    1313
    1414<div id="disqus_thread"></div>
     15<?php
     16if ( 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  
    354354
    355355    /**
    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.
    386357     *
    387358     * @since     3.0
    388      * @param     array $new_settings    Any options to be updated.
    389      * @access    private
    390      * @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.0
    421      * @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.0
    432      * @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.0
    475      * @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.0
    520      * @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.0
    554      * @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.0
    584      * @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.0
    629      * @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.0
    642      * @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 present
    699         // 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.0
    743      * @access    private
    744      * @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.0
    754      * @access    private
    755      * @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->version
    811             )
    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->ID
    855             )
    856         );
    857 
    858         $item->appendChild(
    859             $xml->createElement(
    860                 'wp:post_date_gmt',
    861                 $post->post_date_gmt
    862             )
    863         );
    864 
    865         $item->appendChild(
    866             $xml->createElement(
    867                 'wp:comment_status',
    868                 $post->comment_status
    869             )
    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_ID
    880                 )
    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_email
    892                 )
    893             );
    894 
    895             $wpcomment->appendChild(
    896                 $xml->createElement(
    897                     'wp:comment_author_url',
    898                     $c->comment_author_url
    899                 )
    900             );
    901 
    902             $wpcomment->appendChild(
    903                 $xml->createElement(
    904                     'wp:comment_author_IP',
    905                     $c->comment_author_IP
    906                 )
    907             );
    908 
    909             $wpcomment->appendChild(
    910                 $xml->createElement(
    911                     'wp:comment_date',
    912                     $c->comment_date
    913                 )
    914             );
    915 
    916             $wpcomment->appendChild(
    917                 $xml->createElement(
    918                     'wp:comment_date_gmt',
    919                     $c->comment_date_gmt
    920                 )
    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_approved
    932                 )
    933             );
    934 
    935             $wpcomment->appendChild(
    936                 $xml->createElement(
    937                     'wp:comment_type',
    938                     $c->comment_type
    939                 )
    940             );
    941 
    942             $wpcomment->appendChild(
    943                 $xml->createElement(
    944                     'wp:comment_parent',
    945                     $c->comment_parent
    946                 )
    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.0
    970      * @access    private
    971359     * @return    array    The REST schema.
    972360     */
    973     private function dsq_get_settings_schema() {
     361    public function dsq_get_settings_schema() {
    974362        return array(
    975363            // This tells the spec of JSON Schema we are using which is draft 4.
     
    1020408                    'readonly' => true,
    1021409                ),
     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                ),
    1022415            ),
    1023416        );
    1024417    }
     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    }
    10251029}
  • disqus-comment-system/trunk/uninstall.php

    r1817585 r1826582  
    2626delete_option( 'disqus_sync_token' );
    2727delete_option( 'disqus_last_sync_message' );
     28delete_option( 'disqus_render_js' );
    2829delete_option( 'disqus_manual_sync' ); // Legacy option.
Note: See TracChangeset for help on using the changeset viewer.