Disqus Comment System - Version 2.41

Version Description

Download this release

Release Info

Developer Disqus
Plugin Icon Disqus Comment System
Version 2.41
Comparing to
See all releases

Code changes from version 2.33.8752 to 2.41

comments-legacy.php DELETED
@@ -1,13 +0,0 @@
1
- <?php
2
- $permalink = get_permalink();
3
- $title = get_the_title();
4
- $excerpt = get_the_excerpt();
5
- ?>
6
- <div id="disqus_thread"></div>
7
- <script type="text/javascript">
8
- var disqus_url = '<?php echo $permalink; ?> ';
9
- var disqus_title = '<?php echo $title; ?>';
10
- var disqus_message = '<?php echo $excerpt; ?>';
11
- </script>
12
- <script type="text/javascript" src="<?php echo DISQUS_URL; ?>/forums/<?php echo get_option('disqus_forum_url'); ?>/embed.js"></script>
13
- <noscript>Please enable JavaScript to view the <a href="<?php echo 'http://disqus.com/?ref_noscript=' . get_option('disqus_forum_url') ?>">comments powered by Disqus.</a></noscript>
 
 
 
 
 
 
 
 
 
 
 
 
 
comments.php CHANGED
@@ -3,37 +3,76 @@
3
  ?>
4
 
5
  <div id="disqus_thread">
6
- <div id="dsq-content">
7
- <ul id="dsq-comments">
8
- <?php foreach ( $dsq_response['posts'] as $comment ) : ?>
9
- <li id="dsq-comment-<?php echo $comment['id']; ?>">
10
- <div id="dsq-comment-header-<?php echo $comment['id']; ?>" class="dsq-comment-header">
11
- <cite id="dsq-cite-<?php echo $comment['id']; ?>">
12
- <?php if($comment['user']['url']) : ?>
13
- <a id="dsq-author-user-<?php echo $comment['id']; ?>" href="<?php echo $comment['user']['url']; ?>" target="_blank" rel="nofollow"><?php echo $comment['user']['display_name']; ?></a>
14
- <?php else : ?>
15
- <span id="dsq-author-user-<?php echo $comment['id']; ?>"><?php echo $comment['user']['display_name']; ?></span>
16
- <?php endif; ?>
17
- </cite>
18
- </div>
19
- <div id="dsq-comment-body-<?php echo $comment['id']; ?>" class="dsq-comment-body">
20
- <div id="dsq-comment-message-<?php echo $comment['id']; ?>" class="dsq-comment-message"><?php echo $comment['message']; ?></div>
21
- </div>
22
- </li>
23
- <?php endforeach; ?>
24
- </ul>
25
- </div>
 
 
 
 
 
 
 
 
 
26
  </div>
27
 
28
  <a href="http://disqus.com" class="dsq-brlink">blog comments powered by <span class="logo-disqus">Disqus</span></a>
29
 
30
- <script type="text/javascript" charset="utf-8">
31
  var disqus_url = '<?php echo get_permalink(); ?> ';
 
32
  var disqus_container_id = 'disqus_thread';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33
  var facebookXdReceiverPath = '<?php echo DSQ_PLUGIN_URL . '/xd_receiver.htm' ?>';
34
  </script>
35
 
36
- <script type="text/javascript" charset="utf-8">
37
  var DsqLocal = {
38
  'trackbacks': [
39
  <?php
@@ -60,12 +99,11 @@
60
  };
61
  </script>
62
 
63
- <script type="text/javascript" charset="utf-8">
64
  (function() {
65
- var dsq = document.createElement('script');
66
- dsq.type = 'text/javascript';
67
  dsq.async = true;
68
- dsq.src = "http://<?php echo strtolower(get_option('disqus_forum_url')); ?>.<?php echo DISQUS_DOMAIN; ?>/disqus.js?v=2.0&slug=<?php echo $dsq_response['thread_slug']; ?>&pname=wordpress&pver=<?php echo $dsq_version; ?>";
69
  (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
70
  })();
71
  </script>
3
  ?>
4
 
5
  <div id="disqus_thread">
6
+ <?php
7
+ if (is_file(TEMPLATEPATH . '/comments.php')) {
8
+ include(TEMPLATEPATH . '/comments.php');
9
+ }
10
+ else {
11
+ ?>
12
+ <div id="dsq-content">
13
+ <ul id="dsq-comments">
14
+ <?php foreach ($comments as $comment) : ?>
15
+ <li id="dsq-comment-<?php echo comment_ID(); ?>">
16
+ <div id="dsq-comment-header-<?php echo comment_ID(); ?>" class="dsq-comment-header">
17
+ <cite id="dsq-cite-<?php echo comment_ID(); ?>">
18
+ <?php if(comment_author_url()) : ?>
19
+ <a id="dsq-author-user-<?php echo comment_ID(); ?>" href="<?php echo comment_author_url(); ?>" target="_blank" rel="nofollow"><?php echo comment_author(); ?></a>
20
+ <?php else : ?>
21
+ <span id="dsq-author-user-<?php echo comment_ID(); ?>"><?php echo comment_author(); ?></span>
22
+ <?php endif; ?>
23
+ </cite>
24
+ </div>
25
+ <div id="dsq-comment-body-<?php echo comment_ID(); ?>" class="dsq-comment-body">
26
+ <div id="dsq-comment-message-<?php echo comment_ID(); ?>" class="dsq-comment-message"><?php comment_text(); ?></div>
27
+ </div>
28
+ </li>
29
+ <?php endforeach; ?>
30
+ </ul>
31
+ </div>
32
+ <?
33
+ }
34
+ ?>
35
  </div>
36
 
37
  <a href="http://disqus.com" class="dsq-brlink">blog comments powered by <span class="logo-disqus">Disqus</span></a>
38
 
39
+ <script type="text/javascript">
40
  var disqus_url = '<?php echo get_permalink(); ?> ';
41
+ var disqus_identifier = '<?php echo dsq_identifier_for_post($post); ?>';
42
  var disqus_container_id = 'disqus_thread';
43
+ var disqus_domain = '<?php echo DISQUS_DOMAIN; ?>';
44
+ var disqus_shortname = '<?php echo strtolower(get_option('disqus_forum_url')); ?>';
45
+ var disqus_title = <?php echo json_encode(dsq_title_for_post($post)); ?>;
46
+ <?php if (false && get_option('disqus_developer')): ?>
47
+ var disqus_developer = 1;
48
+ <?php endif; ?>
49
+ var disqus_config = function () {
50
+ var config = this; // Access to the config object
51
+
52
+ /*
53
+ All currently supported events:
54
+ * preData — fires just before we request for initial data
55
+ * preInit - fires after we get initial data but before we load any dependencies
56
+ * onInit - fires when all dependencies are resolved but before dtpl template is rendered
57
+ * afterRender - fires when template is rendered but before we show it
58
+ * onReady - everything is done
59
+ */
60
+
61
+ config.callbacks.preData.push(function() {
62
+ // clear out the container (its filled for SEO/legacy purposes)
63
+ document.getElementById(disqus_container_id).innerHTML = '';
64
+ })
65
+ config.callbacks.onReady.push(function() {
66
+ // sync comments in the background so we don't block the page
67
+ var req = new XMLHttpRequest();
68
+ req.open('GET', '?cf_action=sync_comments&post_id=<?php echo $post->ID; ?>', true);
69
+ req.send(null);
70
+ });
71
+ };
72
  var facebookXdReceiverPath = '<?php echo DSQ_PLUGIN_URL . '/xd_receiver.htm' ?>';
73
  </script>
74
 
75
+ <script type="text/javascript">
76
  var DsqLocal = {
77
  'trackbacks': [
78
  <?php
99
  };
100
  </script>
101
 
102
+ <script type="text/javascript">
103
  (function() {
104
+ var dsq = document.createElement('script'); dsq.type = 'text/javascript';
 
105
  dsq.async = true;
106
+ dsq.src = 'http://' + disqus_shortname + '.' + disqus_domain + '/embed.js?pname=wordpress&pver=<?php echo $dsq_version; ?>';
107
  (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
108
  })();
109
  </script>
disqus.php CHANGED
@@ -4,18 +4,19 @@ Plugin Name: Disqus Comment System
4
  Plugin URI: http://disqus.com/
5
  Description: The Disqus comment system replaces your WordPress comment system with your comments hosted and powered by Disqus. Head over to the Comments admin page to set up your DISQUS Comment System.
6
  Author: Disqus <team@disqus.com>
7
- Version: 2.33.8752
8
  Author URI: http://disqus.com/
9
  */
10
 
11
- require_once('lib/api.php');
12
 
13
- define('DISQUS_URL', 'http://disqus.com');
14
- define('DISQUS_API_URL', DISQUS_URL);
15
  define('DISQUS_DOMAIN', 'disqus.com');
16
- define('DISQUS_IMPORTER_URL', 'http://import.disqus.net');
17
- define('DISQUS_MEDIA_URL', 'http://media.disqus.com');
18
  define('DISQUS_RSS_PATH', '/latest.rss');
 
19
 
20
  function dsq_plugin_basename($file) {
21
  $file = dirname($file);
@@ -48,7 +49,7 @@ define('DSQ_PLUGIN_URL', WP_CONTENT_URL . '/plugins/' . dsq_plugin_basename(__FI
48
  * @global string $dsq_version
49
  * @since 1.0
50
  */
51
- $dsq_version = '2.33';
52
  $mt_dsq_version = '2.01';
53
  /**
54
  * Response from Disqus get_thread API call for comments template.
@@ -77,7 +78,7 @@ $dsq_cc_script_embedded = false;
77
  * @global string $dsq_api
78
  * @since 1.0
79
  */
80
- $dsq_api = new DisqusAPI(get_option('disqus_forum_url'), get_option('disqus_api_key'));
81
  /**
82
  * DISQUS is_feed check.
83
  *
@@ -106,10 +107,6 @@ $DSQ_QUERY_POST_IDS = array();
106
  * Helper functions.
107
  */
108
 
109
- function dsq_legacy_mode() {
110
- return get_option('disqus_forum_url') && !get_option('disqus_api_key');
111
- }
112
-
113
  function dsq_is_installed() {
114
  return get_option('disqus_forum_url') && get_option('disqus_api_key');
115
  }
@@ -168,7 +165,8 @@ function dsq_sync_comments($post, $comments) {
168
 
169
  // Get last_comment_date id for $post with Disqus metadata
170
  // (This is the date that is stored in the Disqus DB.)
171
- $last_comment_date = $wpdb->get_var('SELECT max(comment_date) FROM ' . $wpdb->prefix . 'comments WHERE comment_post_ID=' . intval($post->ID) . " AND comment_agent LIKE 'Disqus/%';");
 
172
  if ( $last_comment_date ) {
173
  $last_comment_date = strtotime($last_comment_date);
174
  }
@@ -178,26 +176,36 @@ function dsq_sync_comments($post, $comments) {
178
  }
179
 
180
  foreach ( $comments as $comment ) {
181
- if ( $comment['imported'] ) {
 
182
  continue;
183
- } else if ( $comment['date'] <= $last_comment_date ) {
184
  // If comment date of comment is <= last_comment_date, skip comment.
185
  continue;
186
  } else {
187
  // Else, insert_comment
188
  $commentdata = array(
189
  'comment_post_ID' => $post->ID,
190
- 'comment_author' => $comment['user']['display_name'],
191
- 'comment_author_email' => $comment['user']['email'],
192
- 'comment_author_url' => $comment['user']['url'],
193
- 'comment_author_IP' => $comment['user']['ip_address'],
194
- 'comment_date' => date('Y-m-d H:i:s', $comment['date']),
195
- 'comment_date_gmt' => date('Y-m-d H:i:s', $comment['date_gmt']),
196
- 'comment_content' => $comment['message'],
197
  'comment_approved' => 1,
198
- 'comment_agent' => 'Disqus/1.0:' . intval($comment['id']),
199
  'comment_type' => '',
200
  );
 
 
 
 
 
 
 
 
 
 
 
 
 
201
  wp_insert_comment($commentdata);
202
  }
203
  }
@@ -205,12 +213,15 @@ function dsq_sync_comments($post, $comments) {
205
  if( isset($_POST['dsq_api_key']) && $_POST['dsq_api_key'] == get_option('disqus_api_key') ) {
206
  if( isset($_GET['dsq_sync_action']) && isset($_GET['dsq_sync_comment_id']) ) {
207
  $comment_parts = explode('=', $_GET['dsq_sync_comment_id']);
208
- if( 'wp_id' == $comment_parts[0] ) {
209
- $comment_id = intval($comment_parts[1]);
210
- } else {
211
- $comment_id = $wpdb->get_var('SELECT comment_ID FROM ' . $wpdb->prefix . 'comments WHERE comment_post_ID=' . intval($post->ID) . " AND comment_agent LIKE 'Disqus/1.0:" . intval($comment_parts[1]) . "'");
212
- }
213
 
 
 
 
 
 
 
 
 
214
  switch( $_GET['dsq_sync_action'] ) {
215
  case 'mark_spam':
216
  wp_set_comment_status($comment_id, 'spam');
@@ -230,37 +241,52 @@ function dsq_sync_comments($post, $comments) {
230
  }
231
 
232
  function dsq_request_handler() {
 
 
 
 
233
  if (!empty($_GET['cf_action'])) {
234
  switch ($_GET['cf_action']) {
 
 
 
 
 
 
 
 
 
 
235
  case 'export_comments':
236
- if (current_user_can('manage_options')) {
237
- // handle vars
238
  $post_id = intval($_GET['post_id']);
239
  $limit = 2;
240
  global $wpdb, $dsq_api;
241
- $posts = $wpdb->get_results("
242
  SELECT *
243
  FROM $wpdb->posts
244
  WHERE post_type != 'revision'
245
  AND post_status = 'publish'
246
  AND comment_count > 0
247
- AND ID > $post_id
248
  ORDER BY ID ASC
249
  LIMIT $limit
250
- ");
251
  $first_post_id = $posts[0]->ID;
252
  $last_post_id = $posts[(count($posts) - 1)]->ID;
253
- $max_post_id = $wpdb->get_var("
254
  SELECT MAX(ID)
255
  FROM $wpdb->posts
256
  WHERE post_type != 'revision'
257
  AND post_status = 'publish'
258
  AND comment_count > 0
259
- AND ID > $post_id
260
- ");
261
- if ($last_post_id == $max_post_id) {
 
262
  $status = 'complete';
263
- $msg = 'All comments sent to Disqus!';
264
  }
265
  else {
266
  $status = 'partial';
@@ -275,27 +301,65 @@ function dsq_request_handler() {
275
  if (count($posts)) {
276
  include_once(dirname(__FILE__) . '/export.php');
277
  $wxr = dsq_export_wp($posts);
278
- $import_id = $dsq_api->import_wordpress_comments($wxr);
279
- if ($import_id < 0) {
280
  $result = 'fail';
281
  $msg = '<p class="status dsq-export-fail">Sorry, something unexpected happened with the export. Please <a href="#" id="dsq_export_retry">try again</a></p><p>If your API key has changed, you may need to reinstall Disqus (deactivate the plugin and then reactivate it). If you are still having issues, refer to the <a href="http://disqus.com/help/wordpress" onclick="window.open(this.href); return false">WordPress help page</a>.</p>';
282
  }
283
  else {
 
 
 
 
284
  $result = 'success';
285
  }
286
  }
287
  // send AJAX response
288
- $response = compact('result', 'status', 'last_post_id', 'msg');
289
  header('Content-type: text/javascript');
290
  echo cf_json_encode($response);
291
  die();
292
  }
293
- break;
294
  }
295
  }
296
  }
 
297
  add_action('init', 'dsq_request_handler');
298
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
299
  /**
300
  * Compatibility
301
  */
@@ -426,16 +490,14 @@ function esc_attr( $text ) {
426
  */
427
 
428
  function dsq_get_style() {
429
- echo "<link rel=\"stylesheet\" href=\"" . DISQUS_API_URL ."/stylesheets/" . strtolower(get_option('disqus_forum_url')) . "/disqus.css?v=2.0\" type=\"text/css\" media=\"screen\" />";
430
  }
431
 
432
  add_action('wp_head','dsq_get_style');
433
 
434
  function dsq_comments_template($value) {
435
- global $dsq_response;
436
- global $dsq_sort;
437
- global $dsq_api;
438
  global $post;
 
439
 
440
  if ( !( is_singular() && ( have_comments() || 'open' == $post->comment_status ) ) ) {
441
  return;
@@ -445,31 +507,9 @@ function dsq_comments_template($value) {
445
  return $value;
446
  }
447
 
448
- if ( dsq_legacy_mode() ) {
449
- return dirname(__FILE__) . '/comments-legacy.php';
450
- }
451
-
452
- $permalink = get_permalink();
453
- $title = get_the_title();
454
- $excerpt = get_the_excerpt();
455
-
456
- $dsq_sort = get_option('disqus_sort');
457
- if ( is_numeric($_COOKIE['disqus_sort']) ) {
458
- $dsq_sort = $_COOKIE['disqus_sort'];
459
- }
460
-
461
- if ( is_numeric($_GET['dsq_sort']) ) {
462
- setcookie('disqus_sort', $_GET['dsq_sort']);
463
- $dsq_sort = $_GET['dsq_sort'];
464
- }
465
-
466
- // Call "get_thread" API method.
467
- $dsq_response = $dsq_api->get_thread($post, $permalink, $title, $excerpt);
468
- if( $dsq_response < 0 ) {
469
- return false;
470
  }
471
- // Sync comments with database.
472
- dsq_sync_comments($post, $dsq_response['posts']);
473
 
474
  // TODO: If a disqus-comments.php is found in the current template's
475
  // path, use that instead of the default bundled comments.php
@@ -483,7 +523,7 @@ function dsq_comments_number($comment_text) {
483
  global $post;
484
 
485
  if ( dsq_can_replace() ) {
486
- return '<span class="dsq-postid-'.$post->ID.'">View Comments</span>';
487
  } else {
488
  return $comment_text;
489
  }
@@ -627,17 +667,18 @@ dsq_fire_export = function() {
627
  dsq_export_comments = function() {
628
  var $ = jQuery;
629
  var status = $('#dsq_export .status');
630
- var post_id = status.attr('rel') || 0;
631
  $.get(
632
  '<?php echo admin_url('index.php'); ?>',
633
  {
634
  cf_action: 'export_comments',
635
- post_id: post_id
 
636
  },
637
  function(response) {
638
  switch (response.result) {
639
  case 'success':
640
- status.html(response.msg).attr('rel', response.last_post_id);
641
  switch (response.status) {
642
  case 'partial':
643
  dsq_export_comments();
@@ -672,11 +713,24 @@ function dsq_warning() {
672
  dsq_manage_dialog('You must <a href="edit-comments.php?page=disqus">configure the plugin</a> to enable Disqus Comments.', true);
673
  }
674
 
675
- if ( dsq_legacy_mode() && $_GET['page'] == 'disqus' ) {
676
  dsq_manage_dialog('Disqus Comments has not yet been configured. (<a href="edit-comments.php?page=disqus">Click here to configure</a>)');
677
  }
678
  }
679
 
 
 
 
 
 
 
 
 
 
 
 
 
 
680
  // catch original query
681
  function dsq_parse_query($query) {
682
  add_action('the_posts', 'dsq_add_request_post_ids', 999);
@@ -725,25 +779,36 @@ function dsq_loop_end($query) {
725
  }
726
  add_action('loop_end', 'dsq_loop_end');
727
 
728
- function dsq_js_comment_count_url() {
729
- return 'http://'.strtolower(get_option('disqus_forum_url')).'.'.DISQUS_DOMAIN.'/get_num_replies_from_wpid.js?v=2.2&amp;t=span';
730
- }
731
 
732
  function dsq_output_loop_comment_js($post_ids = null) {
 
 
 
733
  if (count($post_ids)) {
734
- $post_id_str = '';
735
- $i = 0;
736
- foreach ($post_ids as $post_id) {
737
- $post_id_str .= '&amp;wpid'.$i.'='.$post_id;
738
- $i++;
739
- }
740
  ?>
741
  <script type="text/javascript">
742
  // <![CDATA[
743
- (function() {
744
- document.write('<script charset="utf-8" type="text/javascript" src="<?php echo dsq_js_comment_count_url().$post_id_str; ?>"><' + '/script>');
745
-
746
- })();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
747
  //]]>
748
  </script>
749
  <?php
@@ -755,17 +820,24 @@ function dsq_output_footer_comment_js() {
755
  ?>
756
  <script type="text/javascript">
757
  // <![CDATA[
758
- (function() {
 
 
759
  var nodes = document.getElementsByTagName('span');
760
- var query = '&';
761
- for (var i = 0; i < nodes.length; i++) {
762
  if (nodes[i].className.indexOf('dsq-postid') != -1) {
763
- query += 'wpid' + i + '=' + encodeURIComponent(nodes[i].className.replace('dsq-postid-', '')) + '&';
 
 
 
 
764
  }
765
  }
766
- document.write('<script charset="utf-8" type="text/javascript" src="<?php echo dsq_js_comment_count_url(); ?>' + query + '"><' + '/script>');
767
-
768
- })();
 
 
769
  //]]>
770
  </script>
771
  <?php
@@ -791,30 +863,8 @@ add_action('pre_post_update', 'dsq_prev_permalink');
791
  function dsq_check_permalink($post_id) {
792
  global $dsq_prev_permalinks;
793
  if (!empty($dsq_prev_permalinks['post_'.$post_id]) && $dsq_prev_permalinks['post_'.$post_id] != get_permalink($post_id)) {
794
- // API request to get old DSQ ID - get_thread_by_url
795
  $post = get_post($post_id);
796
- global $dsq_api;
797
- $thread = $dsq_api->get_thread(
798
- $post,
799
- $dsq_prev_permalinks['post_'.$post_id],
800
- get_the_title($post_id),
801
- get_the_excerpt($post_id)
802
- );
803
- // API request to update DSQ ID to new permalink - update_thread
804
- if (is_array($thread) && !empty($thread['thread_id'])) {
805
- $http = new WP_Http;
806
- $response = $http->request(
807
- DISQUS_API_URL . '/api/update_thread/',
808
- array(
809
- 'method' => 'POST',
810
- 'body' => array(
811
- 'thread_id' => $thread['thread_id'],
812
- 'url' => get_permalink($post_id),
813
- 'forum_api_key' => $dsq_api->forum_api_key,
814
- )
815
- )
816
- );
817
- }
818
  }
819
  }
820
  add_action('edit_post', 'dsq_check_permalink');
@@ -973,5 +1023,18 @@ function dsq_hmacsha1($data, $key) {
973
  return bin2hex($hmac);
974
  }
975
 
 
 
 
 
 
 
 
 
 
 
 
 
 
976
 
977
  ?>
4
  Plugin URI: http://disqus.com/
5
  Description: The Disqus comment system replaces your WordPress comment system with your comments hosted and powered by Disqus. Head over to the Comments admin page to set up your DISQUS Comment System.
6
  Author: Disqus <team@disqus.com>
7
+ Version: 2.41
8
  Author URI: http://disqus.com/
9
  */
10
 
11
+ require_once('lib/wpapi.php');
12
 
13
+ define('DISQUS_URL', 'http://disqus.com/');
14
+ define('DISQUS_API_URL', DISQUS_URL . 'api/');
15
  define('DISQUS_DOMAIN', 'disqus.com');
16
+ define('DISQUS_IMPORTER_URL', 'http://import.disqus.net/');
17
+ define('DISQUS_MEDIA_URL', 'http://disqus.com/media/');
18
  define('DISQUS_RSS_PATH', '/latest.rss');
19
+ define('DISQUS_CAN_EXPORT', is_file(dirname(__FILE__) . '/export.php'));
20
 
21
  function dsq_plugin_basename($file) {
22
  $file = dirname($file);
49
  * @global string $dsq_version
50
  * @since 1.0
51
  */
52
+ $dsq_version = '2.41';
53
  $mt_dsq_version = '2.01';
54
  /**
55
  * Response from Disqus get_thread API call for comments template.
78
  * @global string $dsq_api
79
  * @since 1.0
80
  */
81
+ $dsq_api = new DisqusWordPressAPI(get_option('disqus_forum_url'), get_option('disqus_api_key'));
82
  /**
83
  * DISQUS is_feed check.
84
  *
107
  * Helper functions.
108
  */
109
 
 
 
 
 
110
  function dsq_is_installed() {
111
  return get_option('disqus_forum_url') && get_option('disqus_api_key');
112
  }
165
 
166
  // Get last_comment_date id for $post with Disqus metadata
167
  // (This is the date that is stored in the Disqus DB.)
168
+ $last_comment_date = $wpdb->get_var($wpdb->prepare('SELECT max(comment_date) FROM ' . $wpdb->comments . ' WHERE comment_post_ID = %d AND comment_agent LIKE \'Disqus/%%\'', $post->ID));
169
+
170
  if ( $last_comment_date ) {
171
  $last_comment_date = strtotime($last_comment_date);
172
  }
176
  }
177
 
178
  foreach ( $comments as $comment ) {
179
+ $ts = strtotime($comment->created_at);
180
+ if ( $comment->imported ) {
181
  continue;
182
+ } else if ( $ts <= $last_comment_date ) {
183
  // If comment date of comment is <= last_comment_date, skip comment.
184
  continue;
185
  } else {
186
  // Else, insert_comment
187
  $commentdata = array(
188
  'comment_post_ID' => $post->ID,
189
+ 'comment_date' => $comment->created_at,
190
+ 'comment_date_gmt' => $comment->created_at,
191
+ 'comment_content' => $comment->message,
 
 
 
 
192
  'comment_approved' => 1,
193
+ 'comment_agent' => 'Disqus/1.0:' . intval($comment->id),
194
  'comment_type' => '',
195
  );
196
+ if ($comment->is_anonymous) {
197
+ $commentdata['comment_author'] = $comment->anonymous_author->name;
198
+ $commentdata['comment_author_email'] = $comment->anonymous_author->email;
199
+ $commentdata['comment_author_url'] = $comment->anonymous_author->url;
200
+ $commentdata['comment_author_IP'] = $comment->anonymous_author->ip_address;
201
+ }
202
+ else {
203
+ $commentdata['comment_author'] = $comment->author->display_name;
204
+ $commentdata['comment_author_email'] = $comment->author->email;
205
+ $commentdata['comment_author_url'] = $comment->author->url;
206
+ $commentdata['comment_author_IP'] = $comment->author->ip_address;
207
+ }
208
+
209
  wp_insert_comment($commentdata);
210
  }
211
  }
213
  if( isset($_POST['dsq_api_key']) && $_POST['dsq_api_key'] == get_option('disqus_api_key') ) {
214
  if( isset($_GET['dsq_sync_action']) && isset($_GET['dsq_sync_comment_id']) ) {
215
  $comment_parts = explode('=', $_GET['dsq_sync_comment_id']);
 
 
 
 
 
216
 
217
+ if (!($comment_id = intval($comment_parts[1])) > 0) {
218
+ return;
219
+ }
220
+
221
+ if( 'wp_id' != $comment_parts[0] ) {
222
+ $comment_id = $wpdb->get_var($wpdb->prepare('SELECT comment_ID FROM ' . $wpdb->comments . ' WHERE comment_post_ID = %d AND comment_agent LIKE %s', intval($post->ID), 'Disqus/1.0:' . $comment_id));
223
+ }
224
+
225
  switch( $_GET['dsq_sync_action'] ) {
226
  case 'mark_spam':
227
  wp_set_comment_status($comment_id, 'spam');
241
  }
242
 
243
  function dsq_request_handler() {
244
+ global $dsq_response;
245
+ global $dsq_api;
246
+ global $post;
247
+
248
  if (!empty($_GET['cf_action'])) {
249
  switch ($_GET['cf_action']) {
250
+ case 'sync_comments':
251
+ if( !( $post_id = $_GET['post_id'] ) ) {
252
+ header("HTTP/1.0 400 Bad Request");
253
+ die();
254
+ }
255
+ // schedule the event for 30 seconds from now in case they
256
+ // happen to make a quick post
257
+ wp_schedule_single_event(time(), 'dsq_sync_post', array($post_id));
258
+ die('OK');
259
+ break;
260
  case 'export_comments':
261
+ if (current_user_can('manage_options') && DISQUS_CAN_EXPORT) {
262
+ $timestamp = intval($_GET['timestamp']);
263
  $post_id = intval($_GET['post_id']);
264
  $limit = 2;
265
  global $wpdb, $dsq_api;
266
+ $posts = $wpdb->get_results($wpdb->prepare("
267
  SELECT *
268
  FROM $wpdb->posts
269
  WHERE post_type != 'revision'
270
  AND post_status = 'publish'
271
  AND comment_count > 0
272
+ AND ID > %d
273
  ORDER BY ID ASC
274
  LIMIT $limit
275
+ ", $post_id));
276
  $first_post_id = $posts[0]->ID;
277
  $last_post_id = $posts[(count($posts) - 1)]->ID;
278
+ $max_post_id = $wpdb->get_var($wpdb->prepare("
279
  SELECT MAX(ID)
280
  FROM $wpdb->posts
281
  WHERE post_type != 'revision'
282
  AND post_status = 'publish'
283
  AND comment_count > 0
284
+ AND ID > %d
285
+ ", $post_id));
286
+ $eof = (int)($last_post_id == $max_post_id);
287
+ if ($eof) {
288
  $status = 'complete';
289
+ $msg = 'Your comments have been sent to Disqus and queued for import!<br/><a href="'.DISQUS_IMPORTER_URL.'" target="_blank">See the status of your import at Disqus</a>';
290
  }
291
  else {
292
  $status = 'partial';
301
  if (count($posts)) {
302
  include_once(dirname(__FILE__) . '/export.php');
303
  $wxr = dsq_export_wp($posts);
304
+ $response = $dsq_api->import_wordpress_comments($wxr, $timestamp, $eof);
305
+ if (!($response['group_id'] > 0)) {
306
  $result = 'fail';
307
  $msg = '<p class="status dsq-export-fail">Sorry, something unexpected happened with the export. Please <a href="#" id="dsq_export_retry">try again</a></p><p>If your API key has changed, you may need to reinstall Disqus (deactivate the plugin and then reactivate it). If you are still having issues, refer to the <a href="http://disqus.com/help/wordpress" onclick="window.open(this.href); return false">WordPress help page</a>.</p>';
308
  }
309
  else {
310
+ if ($eof) {
311
+ $msg = 'Your comments have been sent to Disqus and queued for import!<br/><a href="'.$response['link'].'" target="_blank">See the status of your import at Disqus</a>';
312
+
313
+ }
314
  $result = 'success';
315
  }
316
  }
317
  // send AJAX response
318
+ $response = compact('result', 'timestamp', 'status', 'last_post_id', 'msg', 'eof');
319
  header('Content-type: text/javascript');
320
  echo cf_json_encode($response);
321
  die();
322
  }
323
+ break;
324
  }
325
  }
326
  }
327
+
328
  add_action('init', 'dsq_request_handler');
329
 
330
+ function dsq_sync_post($post_id) {
331
+ global $dsq_api;
332
+
333
+ $post = get_post($post_id);
334
+
335
+ // Call update_thread to ensure our permalink is up to date
336
+ dsq_update_permalink($post);
337
+
338
+ // Pull comments from API
339
+ $dsq_response = $dsq_api->get_thread($post);
340
+ if( $dsq_response < 0 ) {
341
+ // header("HTTP/1.0 500 Internal Server Error");
342
+ echo 'There was an error when attempting to sync comments';
343
+ return;
344
+ }
345
+ // Sync comments with database.
346
+ dsq_sync_comments($post, $dsq_response);
347
+ }
348
+
349
+ add_action('dsq_sync_post', 'dsq_sync_post');
350
+
351
+ function dsq_update_permalink($post) {
352
+ global $dsq_api;
353
+
354
+ $response = $dsq_api->api->update_thread(null, array(
355
+ 'thread_identifier' => dsq_identifier_for_post($post),
356
+ 'title' => dsq_title_for_post($post),
357
+ 'url' => dsq_link_for_post($post)
358
+ ));
359
+
360
+ return $response;
361
+ }
362
+
363
  /**
364
  * Compatibility
365
  */
490
  */
491
 
492
  function dsq_get_style() {
493
+ echo "<link rel=\"stylesheet\" href=\"" . DISQUS_URL ."stylesheets/" . strtolower(get_option('disqus_forum_url')) . "/disqus.css?v=2.0\" type=\"text/css\" media=\"screen\" />";
494
  }
495
 
496
  add_action('wp_head','dsq_get_style');
497
 
498
  function dsq_comments_template($value) {
 
 
 
499
  global $post;
500
+ global $comments;
501
 
502
  if ( !( is_singular() && ( have_comments() || 'open' == $post->comment_status ) ) ) {
503
  return;
507
  return $value;
508
  }
509
 
510
+ if ( !dsq_is_installed() ) {
511
+ return $value;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
512
  }
 
 
513
 
514
  // TODO: If a disqus-comments.php is found in the current template's
515
  // path, use that instead of the default bundled comments.php
523
  global $post;
524
 
525
  if ( dsq_can_replace() ) {
526
+ return '<span class="dsq-postid" rel="'.htmlspecialchars(dsq_identifier_for_post($post)).'">View Comments</span>';
527
  } else {
528
  return $comment_text;
529
  }
667
  dsq_export_comments = function() {
668
  var $ = jQuery;
669
  var status = $('#dsq_export .status');
670
+ var export_info = (status.attr('rel') || '0|' + (new Date().getTime()/1000)).split('|');
671
  $.get(
672
  '<?php echo admin_url('index.php'); ?>',
673
  {
674
  cf_action: 'export_comments',
675
+ post_id: export_info[0],
676
+ timestamp: export_info[1]
677
  },
678
  function(response) {
679
  switch (response.result) {
680
  case 'success':
681
+ status.html(response.msg).attr('rel', response.last_post_id + '|' + response.timestamp);
682
  switch (response.status) {
683
  case 'partial':
684
  dsq_export_comments();
713
  dsq_manage_dialog('You must <a href="edit-comments.php?page=disqus">configure the plugin</a> to enable Disqus Comments.', true);
714
  }
715
 
716
+ if ( !dsq_is_installed() && $_GET['page'] == 'disqus' ) {
717
  dsq_manage_dialog('Disqus Comments has not yet been configured. (<a href="edit-comments.php?page=disqus">Click here to configure</a>)');
718
  }
719
  }
720
 
721
+ /**
722
+ * Wrapper for built-in __() which pulls all text from
723
+ * the disqus domain and supports variable interpolation.
724
+ */
725
+ function dsq_i($text, $params=null) {
726
+ if (!is_array($params))
727
+ {
728
+ $params = func_get_args();
729
+ $params = array_slice($params, 1);
730
+ }
731
+ return vsprintf(__($text, 'disqus'), $params);
732
+ }
733
+
734
  // catch original query
735
  function dsq_parse_query($query) {
736
  add_action('the_posts', 'dsq_add_request_post_ids', 999);
779
  }
780
  add_action('loop_end', 'dsq_loop_end');
781
 
782
+ // if someone has a better hack, let me know
783
+ // prevents duplicate calls to count.js
784
+ $_HAS_COUNTS = false;
785
 
786
  function dsq_output_loop_comment_js($post_ids = null) {
787
+ global $_HAS_COUNTS;
788
+ if ($_HAS_COUNTS) return;
789
+ $_HAS_COUNTS = true;
790
  if (count($post_ids)) {
 
 
 
 
 
 
791
  ?>
792
  <script type="text/javascript">
793
  // <![CDATA[
794
+ var disqus_shortname = '<?php echo strtolower(get_option('disqus_forum_url')); ?>';
795
+ var disqus_domain = '<?php echo DISQUS_DOMAIN; ?>';
796
+ (function () {
797
+ var nodes = document.getElementsByTagName('span');
798
+ for (var i = 0, url; i < nodes.length; i++) {
799
+ if (nodes[i].className.indexOf('dsq-postid') != -1) {
800
+ nodes[i].parentNode.setAttribute('data-disqus-identifier', nodes[i].getAttribute('rel'));
801
+ url = nodes[i].parentNode.href.split('#', 1);
802
+ if (url.length == 1) url = url[0];
803
+ else url = url[1]
804
+ nodes[i].parentNode.href = url + '#disqus_thread';
805
+ }
806
+ }
807
+ var s = document.createElement('script'); s.async = true;
808
+ s.type = 'text/javascript';
809
+ s.src = 'http://' + disqus_domain + '/forums/' + disqus_shortname + '/count.js';
810
+ (document.getElementsByTagName('HEAD')[0] || document.getElementsByTagName('BODY')[0]).appendChild(s);
811
+ }());
812
  //]]>
813
  </script>
814
  <?php
820
  ?>
821
  <script type="text/javascript">
822
  // <![CDATA[
823
+ var disqus_shortname = '<?php echo strtolower(get_option('disqus_forum_url')); ?>';
824
+ var disqus_domain = '<?php echo DISQUS_DOMAIN; ?>';
825
+ (function () {
826
  var nodes = document.getElementsByTagName('span');
827
+ for (var i = 0, url; i < nodes.length; i++) {
 
828
  if (nodes[i].className.indexOf('dsq-postid') != -1) {
829
+ nodes[i].parentNode.setAttribute('data-disqus-identifier', nodes[i].getAttribute('rel'));
830
+ url = nodes[i].parentNode.href.split('#', 1);
831
+ if (url.length == 1) url = url[0];
832
+ else url = url[1]
833
+ nodes[i].parentNode.href = url + '#disqus_thread';
834
  }
835
  }
836
+ var s = document.createElement('script'); s.async = true;
837
+ s.type = 'text/javascript';
838
+ s.src = 'http://' + disqus_domain + '/forums/' + disqus_shortname + '/count.js';
839
+ (document.getElementsByTagName('HEAD')[0] || document.getElementsByTagName('BODY')[0]).appendChild(s);
840
+ }());
841
  //]]>
842
  </script>
843
  <?php
863
  function dsq_check_permalink($post_id) {
864
  global $dsq_prev_permalinks;
865
  if (!empty($dsq_prev_permalinks['post_'.$post_id]) && $dsq_prev_permalinks['post_'.$post_id] != get_permalink($post_id)) {
 
866
  $post = get_post($post_id);
867
+ dsq_update_permalink($post);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
868
  }
869
  }
870
  add_action('edit_post', 'dsq_check_permalink');
1023
  return bin2hex($hmac);
1024
  }
1025
 
1026
+ function dsq_identifier_for_post($post) {
1027
+ return $post->ID . ' ' . $post->guid;
1028
+ }
1029
+
1030
+ function dsq_title_for_post($post) {
1031
+ $title = get_the_title($post);
1032
+ $title = strip_tags($title, DISQUS_ALLOWED_HTML);
1033
+ return $title;
1034
+ }
1035
+
1036
+ function dsq_link_for_post($post) {
1037
+ return get_permalink($post);
1038
+ }
1039
 
1040
  ?>
lib/api.php DELETED
@@ -1,149 +0,0 @@
1
- <?php
2
- /**
3
- * Implementation of the Disqus v2 API.
4
- *
5
- * @author Disqus <team@disqus.com>
6
- * @copyright 2007-2008 Big Head Labs
7
- * @link http://disqus.com/
8
- * @package Disqus
9
- * @subpackage lib
10
- * @version 2.0
11
- */
12
-
13
- require_once('url.php');
14
- require_once(ABSPATH.WPINC.'/http.php');
15
-
16
- /** @#+
17
- * Constants
18
- */
19
- /**
20
- * Base URL for Disqus.
21
- */
22
- define('ALLOWED_HTML', '<b><u><i><h1><h2><h3><code><blockquote><br><hr>');
23
-
24
- /**
25
- * Helper methods for all of the Disqus v2 API methods.
26
- *
27
- * @package Disqus
28
- * @author DISQUS.com <team@disqus.com>
29
- * @copyright 2007-2008 Big Head Labs
30
- * @version 2.0
31
- */
32
- class DisqusAPI {
33
- var $short_name;
34
- var $forum_api_key;
35
-
36
- function DisqusAPI($short_name=NULL, $forum_api_key=NULL) {
37
- $this->short_name = $short_name;
38
- $this->forum_api_key = $forum_api_key;
39
- }
40
-
41
- function get_forum_list($username, $password) {
42
- $credentials = base64_encode($username . ':' . $password);
43
- $response = dsq_urlopen(DISQUS_API_URL . '/api/v2/get_forum_list/', array(
44
- 'credentials' => $credentials,
45
- 'response_type' => 'php'
46
- ));
47
- $data = unserialize($response['data']);
48
- if(!$data || $data['stat'] == 'fail') {
49
- if($data['err']['code'] == 'bad-credentials') {
50
- return -2;
51
- } else {
52
- return -1;
53
- }
54
- }
55
- return $data['forums'];
56
- }
57
-
58
- function get_forum_api_key($username, $password, $short_name) {
59
- $credentials = base64_encode($username . ':' . $password);
60
- $response = dsq_urlopen(DISQUS_API_URL . '/api/v2/get_forum_api_key/', array(
61
- 'credentials' => $credentials,
62
- 'short_name' => $short_name,
63
- 'response_type' => 'php'
64
- ));
65
- $data = unserialize($response['data']);
66
- if(!$data || $data['stat'] == 'fail') {
67
- if($data['err']['code'] == 'bad-credentials') {
68
- return -2;
69
- } else {
70
- return -1;
71
- }
72
- }
73
-
74
- return $data['forum_api_key'];
75
- }
76
-
77
- function get_thread($post, $permalink, $title, $excerpt) {
78
- $title = strip_tags($title, ALLOWED_HTML);
79
- $title = urlencode($title);
80
-
81
- $excerpt = strip_tags($excerpt, ALLOWED_HTML);
82
- $excerpt = urlencode($excerpt);
83
- $excerpt = substr($excerpt, 0, 300);
84
-
85
- $thread_meta = $post->ID . ' ' . $post->guid;
86
-
87
- $response = @dsq_urlopen(DISQUS_API_URL . '/api/v2/get_thread/', array(
88
- 'short_name' => $this->short_name,
89
- 'thread_url' => $permalink,
90
- 'thread_meta' => $thread_meta,
91
- 'response_type' => 'php',
92
- 'title' => $title,
93
- 'message' => $excerpt,
94
- 'api_key' => $this->forum_api_key,
95
- 'source' => 'DsqWordPress20',
96
- 'state_closed' => ($post->comment_status == 'closed') ? '1' : '0'
97
- ));
98
-
99
- $data = unserialize($response['data']);
100
- if(!$data || $data['stat'] == 'fail') {
101
- if($data['err']['code'] == 'bad-key') {
102
- return -2;
103
- } else {
104
- return -1;
105
- }
106
- }
107
-
108
- return $data;
109
- }
110
-
111
- function import_wordpress_comments($wxr) {
112
- $http = new WP_Http();
113
- $response = $http->request(
114
- DISQUS_IMPORTER_URL . '/api/import-wordpress-comments/',
115
- array(
116
- 'method' => 'POST',
117
- 'body' => array(
118
- 'forum_url' => $this->short_name,
119
- 'forum_api_key' => $this->forum_api_key,
120
- 'response_type' => 'php',
121
- 'wxr' => $wxr,
122
- )
123
- )
124
- );
125
- $data = unserialize($response['body']);
126
- if (!$data || $data['stat'] == 'fail') {
127
- return -1;
128
- }
129
- return $data['import_id'];
130
- }
131
-
132
- function get_import_status($import_id) {
133
- $response = @dsq_urlopen(DISQUS_IMPORTER_URL . '/api/get-import-status/', array(
134
- 'forum_url' => $this->short_name,
135
- 'forum_api_key' => $this->forum_api_key,
136
- 'import_id' => $import_id,
137
- 'response_type' => 'php'
138
- ));
139
-
140
- $data = unserialize($response['data']);
141
- if(!$data || $data['stat'] == 'fail') {
142
- return -1;
143
- }
144
- return $data;
145
- }
146
-
147
- }
148
-
149
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/api/disqus/disqus.php ADDED
@@ -0,0 +1,429 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Implementation of the Disqus v1.1 API.
4
+ *
5
+ * http://groups.google.com/group/disqus-dev/web/api-1-1
6
+ *
7
+ * @author Disqus <team@disqus.com>
8
+ * @copyright 2007-2010 Big Head Labs
9
+ * @link http://disqus.com/
10
+ * @package Disqus
11
+ * @version 1.1
12
+ */
13
+
14
+ require_once('url.php');
15
+
16
+ /** @#+
17
+ * Constants
18
+ */
19
+ /**
20
+ * Base URL for Disqus.
21
+ */
22
+
23
+ define('DISQUS_TYPE_SPAM', 'spam');
24
+ define('DISQUS_TYPE_DELETED', 'killed');
25
+ define('DISQUS_TYPE_KILLED', DISQUS_TYPE_DELETED);
26
+ define('DISQUS_TYPE_NEW', 'new');
27
+
28
+ define('DISQUS_STATE_APPROVED', 'approved');
29
+ define('DISQUS_STATE_UNAPPROVED', 'unapproved');
30
+ define('DISQUS_STATE_SPAM', 'spam');
31
+ define('DISQUS_STATE_DELETED', 'killed');
32
+ define('DISQUS_STATE_KILLED', DISQUS_STATE_DELETED);
33
+
34
+ define('DISQUS_ACTION_SPAM', 'spam');
35
+ define('DISQUS_ACTION_APPROVE', 'approve');
36
+ define('DISQUS_ACTION_DELETE', 'delete');
37
+ define('DISQUS_ACTION_KILL', 'kill');
38
+
39
+ if (!extension_loaded('json')) {
40
+ require_once('json.php');
41
+ function dsq_json_decode($data) {
42
+ $json = new JSON;
43
+ return $json->unserialize($data);
44
+ }
45
+ } else {
46
+ function dsq_json_decode($data) {
47
+ return json_decode($data);
48
+ }
49
+ }
50
+
51
+ /**
52
+ * Helper methods for all of the Disqus 1.1 API methods.
53
+ *
54
+ * @package Disqus
55
+ * @author DISQUS.com <team@disqus.com>
56
+ * @copyright 2007-2010 Big Head Labs
57
+ * @version 1.1
58
+ */
59
+ class DisqusAPI {
60
+ var $user_api_key;
61
+ var $forum_api_key;
62
+ var $api_url = 'http://www.disqus.com/api/';
63
+ var $api_version = '1.1';
64
+
65
+ /**
66
+ * Creates a new interface to the Disqus API.
67
+ *
68
+ * @param $user_api_key
69
+ * (optional) The User API key to use.
70
+ * @param $forum_api_key
71
+ * (optional) The Forum API key to use.
72
+ * @param $api_url
73
+ * (optional) The prefix URL to use when calling the Disqus API.
74
+ */
75
+ function DisqusAPI($user_api_key, $forum_api_key, $api_url='http://www.disqus.com/api/') {
76
+ $this->user_api_key = $user_api_key;
77
+ $this->forum_api_key = $forum_api_key;
78
+ $this->api_url = $api_url;
79
+ $this->last_error = null;
80
+ }
81
+
82
+ /**
83
+ * Makes a call to a Disqus API method.
84
+ *
85
+ * @return
86
+ * The Disqus object.
87
+ * @param $method
88
+ * The Disqus API method to call.
89
+ * @param $args
90
+ * An associative array of arguments to be passed.
91
+ * @param $post
92
+ * TRUE or FALSE, depending on whether we're making a POST call.
93
+ */
94
+ function call($method, $args=array(), $post=false) {
95
+ $url = $this->api_url . $method . '/';
96
+
97
+ if (!isset($args['user_api_key'])) {
98
+ $args['user_api_key'] = $this->user_api_key;
99
+ }
100
+ if (!isset($args['forum_api_key'])) {
101
+ $args['forum_api_key'] = $this->forum_api_key;
102
+ }
103
+ if (!isset($args['api_version'])) {
104
+ $args['api_version'] = $this->api_version;
105
+ }
106
+
107
+ foreach ($args as $key=>$value) {
108
+ // XXX: Disqus is lacking some exception handling and we sometimes
109
+ // end up with 500s when passing invalid values
110
+ if (empty($value)) unset($args[$key]);
111
+ }
112
+
113
+ if (!$post) {
114
+ $url .= '?' . dsq_get_query_string($args);
115
+ $args = null;
116
+ }
117
+
118
+ $response = dsq_urlopen($url, $args);
119
+
120
+ $data = dsq_json_decode($response['data']);
121
+
122
+ if(!$data || !$data->succeeded) {
123
+ $this->last_error = $data->message;
124
+ return false;
125
+ }
126
+
127
+ if ($response['code'] != 200) {
128
+ $this->last_error = 'Unknown error';
129
+ return false;
130
+ }
131
+
132
+ return $data->message;
133
+ }
134
+
135
+ /**
136
+ * Retrieve the last error message recorded.
137
+ *
138
+ * @return
139
+ * The last recorded error from the API
140
+ */
141
+ function get_last_error() {
142
+ if (empty($this->last_error)) return;
143
+ return $this->last_error;
144
+ }
145
+
146
+ /**
147
+ * Validate API key and get username.
148
+ *
149
+ * @return
150
+ * Username matching the API key
151
+ */
152
+ function get_user_name() {
153
+ return $this->call('get_user_name', array(), true);
154
+ }
155
+
156
+ /**
157
+ * Returns an array of hashes representing all forums the user owns.
158
+ *
159
+ * @return
160
+ * An array of hashes representing all forums the user owns.
161
+ */
162
+ function get_forum_list() {
163
+ return $this->call('get_forum_list');
164
+ }
165
+
166
+ /**
167
+ * Get a forum API key for a specific forum.
168
+ *
169
+ * @param $forum_id
170
+ * the unique id of the forum
171
+ * @return
172
+ * A string which is the Forum Key for the given forum.
173
+ */
174
+ function get_forum_api_key($forum_id) {
175
+ $params = array(
176
+ 'forum_id' => $forum_id,
177
+ );
178
+
179
+ return $this->call('get_forum_api_key', $params);
180
+ }
181
+
182
+ /**
183
+ * Get a list of comments on a website.
184
+ *
185
+ * Both filter and exclude are multivalue arguments with comma as a divider.
186
+ * That makes is possible to use combined requests. For example, if you want
187
+ * to get all deleted spam messages, your filter argument should contain
188
+ * 'spam,killed' string.
189
+ *
190
+ * @param $forum_id
191
+ * The forum ID.
192
+ * @param $params
193
+ * - limit: Number of entries that should be included in the response. Default is 25.
194
+ * - start: Starting point for the query. Default is 0.
195
+ * - filter: Type of entries that should be returned.
196
+ * - exclude: Type of entries that should be excluded from the response.
197
+ * @return
198
+ * Returns posts from a forum specified by id.
199
+ */
200
+ function get_forum_posts($forum_id, $params=array()) {
201
+ $params['forum_id'] = $forum_id;
202
+
203
+ return $this->call('get_forum_posts', $params);
204
+ }
205
+
206
+ /**
207
+ * Count a number of comments in articles.
208
+ *
209
+ * @param $thread_ids
210
+ * an array of thread IDs belonging to the given forum.
211
+ * @return
212
+ * A hash having thread_ids as keys and 2-element arrays as values.
213
+ */
214
+ function get_num_posts($thread_ids) {
215
+ $params = array(
216
+ 'thread_ids' => is_array($thread_ids) ? implode(',', $thread_ids) : $thread_ids,
217
+ );
218
+
219
+ return $this->call('get_num_posts', $params);
220
+ }
221
+
222
+ /**
223
+ * Returns a list of categories that were created for a website (forum) provided.
224
+ *
225
+ * @param $forum_id
226
+ * the unique of the forum
227
+ * @return
228
+ * A hash containing category_id, title, forum_id, and is_default.
229
+ */
230
+ function get_categories_list($forum_id) {
231
+ $params = array(
232
+ 'forum_id' => $forum_id,
233
+ );
234
+
235
+ return $this->call('get_categories_list', $params);
236
+ }
237
+
238
+ /**
239
+ * Get a list of threads on a website.
240
+ *
241
+ * @param $forum_id
242
+ * the unique id of the forum.
243
+ * @param $params
244
+ * - limit: Number of entries that should be included in the response. Default is 25.
245
+ * - start: Starting point for the query. Default is 0.
246
+ * - category_id: Filter entries by category
247
+ * @return
248
+ * An array of hashes representing all threads belonging to the given forum.
249
+ */
250
+ function get_thread_list($forum_id, $params=array()) {
251
+ $params['forum_id'] = $forum_id;
252
+
253
+ return $this->call('get_thread_list', $params);
254
+ }
255
+
256
+ /**
257
+ * Get a list of threads with new comments.
258
+ *
259
+ * @param $forum_id
260
+ * The Forum ID.
261
+ * @param $since
262
+ * Start date for new posts. Format: 2009-03-30T15:41, Timezone: UTC.
263
+ * @return
264
+ * An array of hashes representing all threads with new comments since offset.
265
+ */
266
+ function get_updated_threads($forum_id, $since) {
267
+ $params = array(
268
+ 'forum_id' => $forum_id,
269
+ 'since' => is_string($since) ? $string : strftime('%Y-%m-%dT%H:%M', $since),
270
+ );
271
+
272
+ return $this->call('get_updated_threads', $params);
273
+ }
274
+
275
+ /**
276
+ * Get a list of comments in a thread.
277
+ *
278
+ * Both filter and exclude are multivalue arguments with comma as a divider.
279
+ * That makes is possible to use combined requests. For example, if you want
280
+ * to get all deleted spam messages, your filter argument should contain
281
+ * 'spam,killed' string. Note that values are joined by AND statement so
282
+ * 'spam,new' will return all messages that are new and marked as spam. It
283
+ * will not return messages that are new and not spam or that are spam but
284
+ * not new (i.e. has already been moderated).
285
+ *
286
+ * @param $thread_id
287
+ * The ID of a thread belonging to the given forum
288
+ * @param $params
289
+ * - limit: Number of entries that should be included in the response. Default is 25.
290
+ * - start: Starting point for the query. Default is 0.
291
+ * - filter: Type of entries that should be returned (new, spam or killed).
292
+ * - exclude: Type of entries that should be excluded from the response (new, spam or killed).
293
+ * @return
294
+ * An array of hashes representing representing all posts belonging to the
295
+ * given forum.
296
+ */
297
+ function get_thread_posts($thread_id, $params=array()) {
298
+ $params['thread_id'] = $thread_id;
299
+
300
+ return $this->call('get_thread_posts', $params);
301
+ }
302
+
303
+ /**
304
+ * Get or create thread by identifier.
305
+ *
306
+ * This method tries to find a thread by its identifier and title. If there is
307
+ * no such thread, the method creates it. In either case, the output value is
308
+ * a thread object.
309
+ *
310
+ * @param $identifier
311
+ * Unique value (per forum) for a thread that is used to keep be able to get
312
+ * data even if permalink is changed.
313
+ * @param $title
314
+ * The title of the thread to possibly be created.
315
+ * @param $params
316
+ * - category_id: Filter entries by category
317
+ * - create_on_fail: if thread does not exist, the method will create it
318
+ * @return
319
+ * Returns a hash with two keys:
320
+ * - thread: a hash representing the thread corresponding to the identifier.
321
+ * - created: indicates whether the thread was created as a result of this
322
+ * method call. If created, it will have the specified title.
323
+ */
324
+ function thread_by_identifier($identifier, $title, $params=array()) {
325
+ $params['identifier'] = $identifier;
326
+ $params['title'] = $title;
327
+
328
+ return $this->call('POST', 'thread_by_identifier', $params);
329
+ }
330
+
331
+ /**
332
+ * Get thread by URL.
333
+ *
334
+ * Finds a thread by its URL. Output value is a thread object.
335
+ *
336
+ * @param $url
337
+ * the URL to check for an associated thread
338
+ * @param $partner_api_key
339
+ * (optional) The Partner API key.
340
+ * @return
341
+ * A thread object, otherwise NULL.
342
+ */
343
+ function get_thread_by_url($url, $partner_api_key=null) {
344
+ $params = array(
345
+ 'url' => $url,
346
+ 'partner_api_key' => $partner_api_key,
347
+ );
348
+
349
+ return $this->call('get_thread_by_url', $params);
350
+ }
351
+
352
+ /**
353
+ * Updates thread.
354
+ *
355
+ * Updates thread, specified by id and forum API key, with values described in
356
+ * the optional arguments.
357
+ *
358
+ * @param $thread_id
359
+ * the ID of a thread belonging to the given forum
360
+ * @param $params
361
+ * - title: the title of the thread
362
+ * - slug: the per-forum-unique string used for identifying this thread in
363
+ * disqus.com URL’s relating to this thread. Composed of
364
+ * underscore-separated alphanumeric strings.
365
+ * - url: the URL this thread is on, if known.
366
+ * - allow_comments: whether this thread is open to new comments
367
+ * @return
368
+ * Returns an empty success message.
369
+ */
370
+ function update_thread($thread_id, $params=array()) {
371
+ $params['thread_id'] = $thread_id;
372
+
373
+ return $this->call('update_thread', $params, true);
374
+ }
375
+
376
+ /**
377
+ * Creates a new post.
378
+ *
379
+ * Creates a comment to the thread specified by id.
380
+ *
381
+ * @param $thread_id
382
+ * the thread to post to
383
+ * @param $message
384
+ * the content of the post
385
+ * @param $author_name
386
+ * the post creator’s name
387
+ * @param $author_email
388
+ * the post creator’s email address
389
+ * @param $params
390
+ * - partner_api_key
391
+ * - created_at: Format: 2009-03-30T15:41, Timezone: UTC
392
+ * - ip_address: the author’s IP address
393
+ * - author_url: the author's homepage
394
+ * - parent_post: the id of the parent post
395
+ * - state: Comment's state, must be one of the following: approved,
396
+ * unapproved, spam, killed
397
+ * @return
398
+ * Returns modified version.
399
+ */
400
+ function create_post($thread_id, $message, $author_name, $author_email, $params=array()) {
401
+ $params['thread_id'] = $thread_id;
402
+ $params['message'] = $message;
403
+ $params['author_name'] = $author_name;
404
+ $params['author_email'] = $author_email;
405
+
406
+ return $this->call('create_post', $params, true);
407
+ }
408
+
409
+ /**
410
+ * Delete a comment or mark it as spam (or not spam).
411
+ *
412
+ * @param $post_id
413
+ * The Post ID.
414
+ * @param $action
415
+ * Name of action to be performed. Value can be 'spam', 'approve' or 'kill'.
416
+ * @return
417
+ * Returns modified version.
418
+ */
419
+ function moderate_post($post_id, $action) {
420
+ $params = array(
421
+ 'post_id' => $post_id,
422
+ 'action' => $action,
423
+ );
424
+
425
+ return $this->call('moderate_post', $params, true);
426
+ }
427
+ }
428
+
429
+ ?>
lib/api/disqus/json.php ADDED
@@ -0,0 +1,377 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ ***************************************************************************
4
+ * Copyright (C) 2007 by Cesar D. Rodas *
5
+ * crodas@phpy.org *
6
+ * *
7
+ * Permission is hereby granted, free of charge, to any person obtaining *
8
+ * a copy of this software and associated documentation files (the *
9
+ * "Software"), to deal in the Software without restriction, including *
10
+ * without limitation the rights to use, copy, modify, merge, publish, *
11
+ * distribute, sublicense, and/or sell copies of the Software, and to *
12
+ * permit persons to whom the Software is furnished to do so, subject to *
13
+ * the following conditions: *
14
+ * *
15
+ * The above copyright notice and this permission notice shall be *
16
+ * included in all copies or substantial portions of the Software. *
17
+ * *
18
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, *
19
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF *
20
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*
21
+ * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR *
22
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, *
23
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR *
24
+ * OTHER DEALINGS IN THE SOFTWARE. *
25
+ ***************************************************************************
26
+ */
27
+
28
+ /**
29
+ * Serialize and Unserialize PHP Objects and array
30
+ * into JSON notation.
31
+ *
32
+ * @category Javascript
33
+ * @package JSON
34
+ * @author Cesar D. Rodas <crodas@phpy.org>
35
+ * @copyright 2007 Cesar D. Rodas
36
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
37
+ * @version 1.0
38
+ * @link http://cesars.users.phpclasses.org/json
39
+ */
40
+
41
+ define('IN_NOWHERE',0);
42
+ define('IN_STRING',1);
43
+ define('IN_OBJECT',2);
44
+ define('IN_ATOMIC',3);
45
+ define('IN_ASSIGN',4);
46
+ define('IN_ENDSTMT',5);
47
+ define('IN_ARRAY',6);
48
+
49
+ /**
50
+ * JSON
51
+ *
52
+ * This class serilize an PHP OBJECT or an ARRAY into JSON
53
+ * notation. Also convert a JSON text into a PHP OBJECT or
54
+ * array.
55
+ *
56
+ * @category Javascript
57
+ * @package JSON
58
+ * @author Cesar D. Rodas <crodas@phpy.org>
59
+ * @copyright 2007 Cesar D. Rodas
60
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
61
+ * @version 1.0
62
+ * @link http://cesars.users.phpclasses.org/json
63
+ */
64
+ class JSON
65
+ {
66
+ /**
67
+ * Was parsed with an error?
68
+ *
69
+ * var bool
70
+ * @access private
71
+ */
72
+ var $error;
73
+
74
+ function Json() {
75
+ $this->error = false;
76
+ }
77
+
78
+ /**
79
+ * Serialize
80
+ *
81
+ * Serialize a PHP OBJECT or an ARRAY into
82
+ * JSON notation.
83
+ *
84
+ * param mixed $obj Object or array to serialize
85
+ * return string JSON.
86
+ */
87
+ function serialize($obj) {
88
+ if ( is_object($obj) ) {
89
+ $e = get_object_vars($obj);
90
+ /* bug reported by Ben Rowe */
91
+ /* Adding default empty array if the */
92
+ /* object doesn't have any property */
93
+ $properties = array();
94
+ foreach ($e as $k => $v) {
95
+ $properties[] = $this->_serialize( $k,$v );
96
+ }
97
+ return "{".implode(",",$properties)."}";
98
+ } else if ( is_array($obj) ) {
99
+ return $this->_serialize('',$obj);
100
+ }
101
+ }
102
+
103
+ /**
104
+ * UnSerialize
105
+ *
106
+ * Transform an JSON text into a PHP object
107
+ * and return it.
108
+ * @access public
109
+ * @param string $text JSON text
110
+ * @return mixed PHP Object, array or false.
111
+ */
112
+ function unserialize( $text ) {
113
+ $this->error = false;
114
+
115
+ return !$this->error ? $this->_unserialize($text) : false;
116
+ }
117
+
118
+ /**
119
+ * UnSerialize
120
+ *
121
+ * Transform an JSON text into a PHP object
122
+ * and return it.
123
+ * @access private
124
+ * @param string $text JSON text
125
+ * @return mixed PHP Object, array or false.
126
+ */
127
+ function _unserialize($text) {
128
+ $ret = new stdClass;
129
+
130
+ while ( $f = $this->getNextToken($text,$i,$type) ) {
131
+ switch ( $type ) {
132
+ case IN_ARRAY:
133
+ $tmp = $this->_unserializeArray($text);
134
+ $ret = $tmp[0];
135
+ break;
136
+ case IN_OBJECT:
137
+ $g=0;
138
+ do {
139
+ $varName = $this->getNextToken($f,$g,$xType);
140
+ if ( $xType != IN_STRING ) {
141
+ return false; /* error parsing */
142
+ }
143
+ $this->getNextToken($f,$g,$xType);
144
+ if ( $xType != IN_ASSIGN) return false;
145
+ $value = $this->getNextToken($f,$g,$xType);
146
+
147
+ if ( $xType == IN_OBJECT) {
148
+ $ret->$varName = $this->unserialize( "{".$value."}" );
149
+ $g--;
150
+ } else if ($xType == IN_ARRAY) {
151
+ $ret->$varName = $this->_unserializeArray( $value);
152
+ $g--;
153
+ } else
154
+ $ret->$varName = $value;
155
+
156
+ $this->getNextToken($f,$g,$xType);
157
+ } while ( $xType == IN_ENDSTMT);
158
+ break;
159
+ default:
160
+ $this->error = true;
161
+ break 2;
162
+ }
163
+ }
164
+ return $ret;
165
+ }
166
+
167
+ /**
168
+ * JSON Array Parser
169
+ *
170
+ * This method transform an json-array into a PHP
171
+ * array
172
+ * @access private
173
+ * @param string $text String to parse
174
+ * @return Array PHP Array
175
+ */
176
+ function _unserializeArray($text) {
177
+ $r = array();
178
+ do {
179
+ $f = $this->getNextToken($text,$i,$type);
180
+ switch ( $type ) {
181
+ case IN_STRING:
182
+ case IN_ATOMIC:
183
+ $r[] = $f;
184
+ break;
185
+ case IN_OBJECT:
186
+ $r[] = $this->unserialize("{".$f."}");
187
+ $i--;
188
+ break;
189
+ case IN_ARRAY:
190
+ $r[] = $this->_unserializeArray($f);
191
+ $i--;
192
+ break;
193
+
194
+ }
195
+ $this->getNextToken($text,$i,$type);
196
+ } while ( $type == IN_ENDSTMT);
197
+
198
+ return $r;
199
+ }
200
+
201
+ /**
202
+ * Tokenizer
203
+ *
204
+ * Return to the Parser the next valid token and the type
205
+ * of the token. If the tokenizer fails it returns false.
206
+ *
207
+ * @access private
208
+ * @param string $e Text to extract token
209
+ * @param integer $i Start position to search next token
210
+ * @param integer $state Variable to get the token type
211
+ * @return string|bool Token in string or false on error.
212
+ */
213
+ function getNextToken($e, &$i, &$state) {
214
+ $state = IN_NOWHERE;
215
+ $end = -1;
216
+ $start = -1;
217
+ while ( $i < strlen($e) && $end == -1 ) {
218
+ switch( $e[$i] ) {
219
+ /* objects */
220
+ case "{":
221
+ case "[":
222
+ $_tag = $e[$i];
223
+ $_endtag = $_tag == "{" ? "}" : "]";
224
+ if ( $state == IN_NOWHERE ) {
225
+ $start = $i+1;
226
+ switch ($state) {
227
+ case IN_NOWHERE:
228
+ $aux = 1; /* for loop objects */
229
+ $state = $_tag == "{" ? IN_OBJECT : IN_ARRAY;
230
+ break;
231
+ default:
232
+ break 2; /* exit from switch and while */
233
+ }
234
+ while ( ++$i && $i < strlen($e) && $aux != 0 ) {
235
+ switch( $e[$i] ) {
236
+ case $_tag:
237
+ $aux++;
238
+ break;
239
+ case $_endtag:
240
+ $aux--;
241
+ break;
242
+ }
243
+ }
244
+ $end = $i-1;
245
+ }
246
+ break;
247
+
248
+ case '"':
249
+ case "'":
250
+ $state = IN_STRING;
251
+ $buf = "";
252
+ while ( ++$i && $i < strlen($e) && $e[$i] != '"' ) {
253
+ if ( $e[$i] == "\\")
254
+ $i++;
255
+ $buf .= $e[$i];
256
+ }
257
+ $i++;
258
+ return eval('return "'.str_replace('"','\"',$buf).'";');
259
+ break;
260
+ case ":":
261
+ $state = IN_ASSIGN;
262
+ $end = 1;
263
+ break;
264
+ case "n":
265
+ if ( substr($e,$i,4) == "null" ) {
266
+ $i=$i+4;
267
+ $state = IN_ATOMIC;
268
+ return NULL;
269
+ }
270
+ else break 2; /* exit from switch and while */
271
+ case "t":
272
+ if ( substr($e,$i,4) == "true") {
273
+ $state = IN_ATOMIC;
274
+ $i=$i+4;
275
+ return true;
276
+ }else break 2; /* exit from switch and while */
277
+ break;
278
+ case "f":
279
+ if ( substr($e,$i,4) == "false") {
280
+ $state = IN_ATOMIC;
281
+ $i=$i+4;
282
+ return false;
283
+ }
284
+ else break 2; /* exit from switch and while */
285
+ break;
286
+ case ",":
287
+ $state = IN_ENDSTMT;
288
+ $end = 1;
289
+ break;
290
+ case " ":
291
+ case "\t":
292
+ case "\r":
293
+ case "\n":
294
+ break;
295
+ case "+":
296
+ case "-":
297
+ case 0:
298
+ case 1:
299
+ case 2:
300
+ case 3:
301
+ case 4:
302
+ case 5:
303
+ case 6:
304
+ case 7:
305
+ case 8:
306
+ case 9:
307
+ case '.':
308
+ $state = IN_ATOMIC;
309
+ $start = (int)$i;
310
+ if ( $e[$i] == "-" || $e[$i] == "+")
311
+ $i++;
312
+ for ( ; $i < strlen($e) && (is_numeric($e[$i]) || $e[$i] == "." || strtolower($e[$i]) == "e") ;$i++){
313
+ $n = $i+1 < strlen($e) ? $e[$i+1] : "";
314
+ $a = strtolower($e[$i]);
315
+ if ( $a == "e" && ($n == "+" || $n == "-"))
316
+ $i++;
317
+ else if ( $a == "e")
318
+ $this->error=true;
319
+ }
320
+
321
+ $end = $i;
322
+ break 2; /* break while too */
323
+ default:
324
+ $this->error = true;
325
+
326
+ }
327
+ $i++;
328
+ }
329
+
330
+ return $start == -1 || $end == -1 ? false : substr($e, $start, $end - $start);
331
+ }
332
+
333
+ /**
334
+ * Internal Serializer
335
+ *
336
+ * @param string $key Variable name
337
+ * @param mixed $value Value of the variable
338
+ * @access private
339
+ * @return string Serialized variable
340
+ */
341
+ function _serialize ( $key = '', &$value ) {
342
+ $r = '';
343
+ if ( $key != '')$r .= "\"${key}\" : ";
344
+ if ( is_numeric($value) ) {
345
+ $r .= ''.$value.'';
346
+ } else if ( is_string($value) ) {
347
+ $r .= '"'.$this->toString($value).'"';
348
+ } else if ( is_object($value) ) {
349
+ $r .= $this->serialize($value);
350
+ } else if ( is_null($value) ) {
351
+ $r .= "null";
352
+ } else if ( is_bool($value) ) {
353
+ $r .= $value ? "true":"false";
354
+ } else if ( is_array($value) ) {
355
+ foreach($value as $k => $v)
356
+ $f[] = $this->_serialize('',$v);
357
+ $r .= "[".implode(",",$f)."]";
358
+ unset($f);
359
+ }
360
+ return $r;
361
+ }
362
+
363
+ /**
364
+ * Convert String variables
365
+ *
366
+ * @param string $e Variable with an string value
367
+ * @access private
368
+ * @return string Serialized variable
369
+ */
370
+ function toString($e) {
371
+ $rep = array("\\","\r","\n","\t","'",'"');
372
+ $val = array("\\\\",'\r','\n','\t','\'','\"');
373
+ $e = str_replace($rep, $val, $e);
374
+ return $e;
375
+ }
376
+ }
377
+ ?>
lib/{url.php → api/disqus/url.php} RENAMED
@@ -1,5 +1,6 @@
1
  <?php
2
  define('USER_AGENT', 'Disqus-WPPlugin/2.0-dev');
 
3
 
4
  function dsq_get_query_string($postdata) {
5
  $postdata_str = '';
@@ -56,10 +57,11 @@ function _dsq_curl_urlopen($url, $postdata, &$response, $file_name, $file_field)
56
  $postdata_str = dsq_get_query_string($postdata);
57
 
58
  $c_options = array(
59
- CURLOPT_USERAGENT => USER_AGENT,
60
- CURLOPT_RETURNTRANSFER => true,
61
- CURLOPT_POST => ($postdata_str ? 1 : 0),
62
- CURLOPT_HTTPHEADER => array('Expect:')
 
63
  );
64
  if($postdata) {
65
  $c_options[CURLOPT_POSTFIELDS] = $postdata_str;
@@ -108,7 +110,7 @@ function _dsq_fsockopen_urlopen($url, $postdata, &$response, $file_name, $file_f
108
  $host = $url_pieces['host'] . ':' . $url_pieces['port'];
109
  }
110
 
111
- $fp = @fsockopen($url_pieces['host'], $url_pieces['port']);
112
  if(!$fp) { return false; }
113
  $req .= ($postdata_str ? 'POST' : 'GET') . ' ' . $url_pieces['path'] . " HTTP/1.1\r\n";
114
  $req .= 'Host: ' . $host . "\r\n";
@@ -169,19 +171,22 @@ function _dsq_fopen_urlopen($url, $postdata, &$response, $file_name, $file_field
169
  $header = dsq_get_http_headers_for_request($boundary, $content, $file_name, $file_field);
170
 
171
  $params = array('http' => array(
172
- 'method' => 'POST',
173
- 'header' => $header,
174
- 'content' => $content,
 
175
  ));
176
  } else {
177
  if($postdata) {
178
  $params = array('http' => array(
179
- 'method' => 'POST',
180
- 'header' => 'Content-Type: application/x-www-form-urlencoded',
181
- 'content' => dsq_get_query_string($postdata)
 
182
  ));
183
  }
184
  }
 
185
 
186
  ini_set('user_agent', USER_AGENT);
187
  $ctx = stream_context_create($params);
1
  <?php
2
  define('USER_AGENT', 'Disqus-WPPlugin/2.0-dev');
3
+ define('SOCKET_TIMEOUT', 10);
4
 
5
  function dsq_get_query_string($postdata) {
6
  $postdata_str = '';
57
  $postdata_str = dsq_get_query_string($postdata);
58
 
59
  $c_options = array(
60
+ CURLOPT_USERAGENT => USER_AGENT,
61
+ CURLOPT_RETURNTRANSFER => true,
62
+ CURLOPT_POST => ($postdata_str ? 1 : 0),
63
+ CURLOPT_HTTPHEADER => array('Expect:'),
64
+ CURLOPT_TIMEOUT => SOCKET_TIMEOUT
65
  );
66
  if($postdata) {
67
  $c_options[CURLOPT_POSTFIELDS] = $postdata_str;
110
  $host = $url_pieces['host'] . ':' . $url_pieces['port'];
111
  }
112
 
113
+ $fp = @fsockopen($url_pieces['host'], $url_pieces['port'], $errno, $errstr, SOCKET_TIMEOUT);
114
  if(!$fp) { return false; }
115
  $req .= ($postdata_str ? 'POST' : 'GET') . ' ' . $url_pieces['path'] . " HTTP/1.1\r\n";
116
  $req .= 'Host: ' . $host . "\r\n";
171
  $header = dsq_get_http_headers_for_request($boundary, $content, $file_name, $file_field);
172
 
173
  $params = array('http' => array(
174
+ 'method' => 'POST',
175
+ 'header' => $header,
176
+ 'content' => $content,
177
+ 'timeout' => SOCKET_TIMEOUT
178
  ));
179
  } else {
180
  if($postdata) {
181
  $params = array('http' => array(
182
+ 'method' => 'POST',
183
+ 'header' => 'Content-Type: application/x-www-form-urlencoded',
184
+ 'content' => dsq_get_query_string($postdata),
185
+ 'timeout' => SOCKET_TIMEOUT
186
  ));
187
  }
188
  }
189
+
190
 
191
  ini_set('user_agent', USER_AGENT);
192
  $ctx = stream_context_create($params);
lib/api/tests.php ADDED
@@ -0,0 +1,166 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ date_default_timezone_set('America/Los_Angeles');
4
+
5
+ define('DISQUS_API_URL', 'http://dev.disqus.org:8000/api/');
6
+
7
+ require_once('PHPUnit/Framework.php');
8
+ require_once('disqus.php');
9
+ require_once('json.php');
10
+
11
+ define('USER_API_KEY', $_SERVER['argv'][count($_SERVER['argv'])-1]);
12
+
13
+ if (strlen(USER_API_KEY) != 64) {
14
+ die('Syntax: phpunit tests.php <user_api_key>');
15
+ }
16
+
17
+ class DisqusAPITest extends PHPUnit_Framework_TestCase {
18
+ public function test_get_user_name() {
19
+ $dsq = new DisqusAPI(USER_API_KEY, null, DISQUS_API_URL);
20
+ $response = $dsq->get_user_name();
21
+
22
+ $this->assertTrue($response !== false);
23
+ }
24
+
25
+ public function test_get_forum_list() {
26
+ $dsq = new DisqusAPI(USER_API_KEY, null, DISQUS_API_URL);
27
+ $response = $dsq->get_forum_list();
28
+
29
+ $this->assertTrue($response !== false);
30
+ }
31
+
32
+ /**
33
+ * @depends test_get_forum_list
34
+ */
35
+ public function test_get_forum_api_key() {
36
+ $dsq = new DisqusAPI(USER_API_KEY, null, DISQUS_API_URL);
37
+
38
+ $response = $dsq->get_forum_list();
39
+ $forum_id = $response[0]->id;
40
+
41
+ $response = $dsq->get_forum_api_key($forum_id);
42
+
43
+ $this->assertTrue($response !== false);
44
+ }
45
+
46
+ /**
47
+ * @depends test_get_forum_list
48
+ */
49
+ public function test_get_forum_posts() {
50
+ $dsq = new DisqusAPI(USER_API_KEY, null, DISQUS_API_URL);
51
+
52
+ $response = $dsq->get_forum_list();
53
+ $this->assertTrue($response !== false);
54
+
55
+ $forum_id = $response[0]->id;
56
+
57
+ $response = $dsq->get_forum_posts($forum_id);
58
+ $this->assertTrue($response !== false);
59
+ }
60
+
61
+ /**
62
+ * @depends test_get_forum_posts
63
+ */
64
+ public function test_get_num_posts() {
65
+ $dsq = new DisqusAPI(USER_API_KEY, null, DISQUS_API_URL);
66
+
67
+ $response = $dsq->get_forum_list();
68
+ $this->assertTrue($response !== false);
69
+
70
+ $forum_id = $response[0]->id;
71
+
72
+ $response = $dsq->get_forum_posts($forum_id);
73
+ $this->assertTrue($response !== false);
74
+
75
+ $thread_id = $response[0]->thread->id;
76
+
77
+ $response = $dsq->get_num_posts(array($thread_id));
78
+ $this->assertTrue($response !== false);
79
+ }
80
+
81
+ /**
82
+ * @depends test_get_forum_list
83
+ */
84
+ public function test_get_categories_list() {
85
+ $dsq = new DisqusAPI(USER_API_KEY, null, DISQUS_API_URL);
86
+
87
+ $response = $dsq->get_forum_list();
88
+ $this->assertTrue($response !== false);
89
+
90
+ $forum_id = $response[0]->id;
91
+
92
+ $response = $dsq->get_categories_list($forum_id);
93
+ $this->assertTrue($response !== false);
94
+ }
95
+
96
+ /**
97
+ * @depends test_get_forum_list
98
+ */
99
+ public function test_get_thread_list() {
100
+ $dsq = new DisqusAPI(USER_API_KEY, null, DISQUS_API_URL);
101
+
102
+ $response = $dsq->get_forum_list();
103
+ $this->assertTrue($response !== false);
104
+
105
+ $forum_id = $response[0]->id;
106
+
107
+ $response = $dsq->get_thread_list($forum_id);
108
+ $this->assertTrue($response !== false);
109
+ }
110
+
111
+ /**
112
+ * @depends test_get_forum_list
113
+ */
114
+ public function test_get_updated_threads() {
115
+ $dsq = new DisqusAPI(USER_API_KEY, null, DISQUS_API_URL);
116
+
117
+ $response = $dsq->get_forum_list();
118
+ $this->assertTrue($response !== false);
119
+
120
+ $forum_id = $response[0]->id;
121
+
122
+ $response = $dsq->get_updated_threads($forum_id, time());
123
+ $this->assertTrue($response !== false);
124
+ }
125
+
126
+ /**
127
+ * @depends test_get_forum_posts
128
+ */
129
+ public function test_get_thread_posts() {
130
+ $dsq = new DisqusAPI(USER_API_KEY, null, DISQUS_API_URL);
131
+
132
+ $response = $dsq->get_forum_list();
133
+ $this->assertTrue($response !== false);
134
+
135
+ $forum_id = $response[0]->id;
136
+
137
+ $response = $dsq->get_forum_posts($forum_id);
138
+ $this->assertTrue($response !== false);
139
+
140
+ $thread_id = $response[0]->thread->id;
141
+
142
+ $response = $dsq->get_thread_posts($thread_id);
143
+ $this->assertTrue($response !== false);
144
+ }
145
+
146
+ public function test_json() {
147
+ $subjects = array(
148
+ "[1, 2, 3]",
149
+ "{foo: 'bar'}",
150
+ "{foo: 'bar', 1: true, 2: false, 3: nil, 4: [1, 2, 3]}",
151
+ // "'hello'",
152
+ // "true",
153
+ // "false",
154
+ // "nil",
155
+ // "1",
156
+ );
157
+
158
+ foreach ($subjects as $v) {
159
+ $json = new JSON;
160
+
161
+ $this->assertEquals($json->unserialize($v), json_decode($v));
162
+ }
163
+ }
164
+ }
165
+
166
+ ?>
lib/wpapi.php ADDED
@@ -0,0 +1,115 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Implementation of the Disqus API designed for WordPress.
4
+ *
5
+ * @author Disqus <team@disqus.com>
6
+ * @copyright 2007-2010 Big Head Labs
7
+ * @link http://disqus.com/
8
+ * @package Disqus
9
+ * @subpackage DisqusWordPressAPI
10
+ * @version 2.0
11
+ */
12
+
13
+ require_once(ABSPATH.WPINC.'/http.php');
14
+ require_once('api/disqus/disqus.php');
15
+ /** @#+
16
+ * Constants
17
+ */
18
+ /**
19
+ * Base URL for Disqus.
20
+ */
21
+ define('DISQUS_ALLOWED_HTML', '<b><u><i><h1><h2><h3><code><blockquote><br><hr>');
22
+
23
+ /**
24
+ * Helper methods for all of the Disqus v2 API methods.
25
+ *
26
+ * @package Disqus
27
+ * @subpackage DisqusWordPressAPI
28
+ * @author DISQUS.com <team@disqus.com>
29
+ * @copyright 2007-2008 Big Head Labs
30
+ * @version 1.0
31
+ */
32
+ class DisqusWordPressAPI {
33
+ var $short_name;
34
+ var $forum_api_key;
35
+
36
+ function DisqusWordPressAPI($short_name=null, $forum_api_key=null, $user_api_key=null) {
37
+ $this->short_name = $short_name;
38
+ $this->forum_api_key = $forum_api_key;
39
+ $this->user_api_key = $user_api_key;
40
+ $this->api = new DisqusAPI($user_api_key, $forum_api_key, DISQUS_API_URL);
41
+ }
42
+
43
+ function get_last_error() {
44
+ return $this->api->get_last_error();
45
+ }
46
+
47
+ function get_user_api_key($username, $password) {
48
+ $response = $this->api->call('get_user_api_key', array(
49
+ 'username' => $username,
50
+ 'password' => $password,
51
+ ), true);
52
+ return $response;
53
+ }
54
+
55
+ function get_forum_list($user_api_key) {
56
+ $this->api->user_api_key = $user_api_key;
57
+ return $this->api->get_forum_list();
58
+ }
59
+
60
+ function get_forum_api_key($user_api_key, $id) {
61
+ $this->api->user_api_key = $user_api_key;
62
+ return $this->api->get_forum_api_key($id);
63
+ }
64
+
65
+ function get_thread_info($post) {
66
+ $identifier = dsq_identifier_for_post($post);
67
+
68
+ $title = dsq_title_for_post($post);
69
+
70
+ $response = $this->api->thread_by_identifier(array(
71
+ 'identifier' => $identifier,
72
+ 'title' => $title,
73
+ ));
74
+ return $response->thread;
75
+ }
76
+
77
+ function get_thread($post) {
78
+ $identifier = dsq_identifier_for_post($post);
79
+
80
+ $response = $this->api->get_thread_posts(null, array(
81
+ 'thread_identifier' => $identifier,
82
+ 'filter' => 'approved',
83
+ ));
84
+ return $response;
85
+ }
86
+
87
+ function import_wordpress_comments($wxr, $timestamp, $eof=true) {
88
+ $http = new WP_Http();
89
+ $response = $http->request(
90
+ DISQUS_IMPORTER_URL . 'api/import-wordpress-comments/',
91
+ array(
92
+ 'method' => 'POST',
93
+ 'body' => array(
94
+ 'forum_url' => $this->short_name,
95
+ 'forum_api_key' => $this->forum_api_key,
96
+ 'response_type' => 'php',
97
+ 'wxr' => $wxr,
98
+ 'timestamp' => $timestamp,
99
+ 'eof' => (int)$eof
100
+ )
101
+ )
102
+ );
103
+ if ($response->errors) {
104
+ return -1;
105
+ }
106
+ $data = unserialize($response['body']);
107
+ if (!$data || $data['stat'] == 'fail') {
108
+ return -1;
109
+ }
110
+
111
+ return $data;
112
+ }
113
+ }
114
+
115
+ ?>
manage.php CHANGED
@@ -1,6 +1,8 @@
1
  <?php
2
  global $dsq_version, $dsq_api;
3
 
 
 
4
  if ( !current_user_can('manage_options') ) {
5
  die();
6
  }
@@ -19,7 +21,7 @@ if ( !function_exists('wp_nonce_field') ) {
19
  }
20
 
21
  // Handle export function.
22
- if( isset($_POST['export']) ) {
23
  require_once(dirname(__FILE__) . '/export.php');
24
  dsq_export_wp();
25
  }
@@ -28,27 +30,28 @@ if( isset($_POST['export']) ) {
28
  if ( isset($_POST['uninstall']) ) {
29
  update_option('disqus_forum_url', '');
30
  update_option('disqus_api_key', '');
 
31
  update_option('disqus_partner_key', '');
32
  }
33
 
34
  // Clean-up POST parameters.
35
- foreach ( array('dsq_forum_url', 'dsq_username') as $key ) {
36
  if ( isset($_POST[$key]) ) { $_POST[$key] = strip_tags($_POST[$key]); }
37
  }
38
 
39
  // Handle installation process.
40
- if ( isset($_POST['dsq_forum_url']) && isset($_POST['dsq_username']) && isset($_POST['dsq_password']) ) {
41
- $api_key = $dsq_api->get_forum_api_key($_POST['dsq_username'], $_POST['dsq_password'], $_POST['dsq_forum_url']);
42
- update_option('disqus_forum_url', $_POST['dsq_forum_url']);
43
-
44
- if ( is_numeric($api_key) && $api_key < 0 ) {
45
  update_option('disqus_replace', 'replace');
46
- dsq_manage_dialog('There was an error completing the installation of Disqus. If you are still having issues, refer to the <a href="http://disqus.com/help/wordpress">WordPress help page</a>.', true);
47
  } else {
48
  update_option('disqus_api_key', $api_key);
49
  update_option('disqus_replace', 'all');
50
  }
51
-
52
  if (!empty($_POST['disqus_partner_key'])) {
53
  $partner_key = trim(stripslashes($_POST['disqus_partner_key']));
54
  if (!empty($partner_key)) {
@@ -65,25 +68,32 @@ if ( isset($_POST['disqus_forum_url']) && isset($_POST['disqus_replace']) ) {
65
  }
66
  update_option('disqus_forum_url', $disqus_forum_url);
67
  update_option('disqus_partner_key', trim(stripslashes($_POST['disqus_partner_key'])));
 
 
68
  update_option('disqus_replace', $_POST['disqus_replace']);
69
  update_option('disqus_cc_fix', isset($_POST['disqus_cc_fix']));
70
  dsq_manage_dialog('Your settings have been changed.');
71
  }
72
 
 
 
73
  // Get installation step process (or 0 if we're already installed).
74
  $step = @intval($_GET['step']);
75
- $step = ($step > 0 && isset($_POST['dsq_username'])) ? $step : 1;
76
- $step = (dsq_is_installed()) ? 0 : $step;
 
77
 
78
  if ( 2 == $step && isset($_POST['dsq_username']) && isset($_POST['dsq_password']) ) {
79
- $dsq_sites = $dsq_api->get_forum_list($_POST['dsq_username'], $_POST['dsq_password']);
 
 
 
 
 
 
80
  if ( $dsq_sites < 0 ) {
81
  $step = 1;
82
- if ( -2 == $dsq_sites ) {
83
- dsq_manage_dialog('Invalid password.', true);
84
- } else {
85
- dsq_manage_dialog('Unexpected error.', true);
86
- }
87
  }
88
  }
89
 
@@ -91,7 +101,7 @@ if ( 2 == $step && isset($_POST['dsq_username']) && isset($_POST['dsq_password']
91
  <div class="wrap" id="dsq-wrap">
92
  <ul id="dsq-tabs">
93
  <li class="selected" id="dsq-tab-main" rel="dsq-main"><?php echo (dsq_is_installed() ? 'Manage' : 'Install'); ?></li>
94
- <li id="dsq-tab-advanced" rel="dsq-advanced">Advanced Options</li>
95
  </ul>
96
 
97
  <div id="dsq-main" class="dsq-content">
@@ -100,32 +110,31 @@ switch ( $step ) {
100
  case 2:
101
  ?>
102
  <div id="dsq-step-2" class="dsq-main">
103
- <h2>Install Disqus Comments</h2>
104
 
105
  <form method="POST" action="?page=disqus">
106
  <?php wp_nonce_field('dsq-install-2'); ?>
107
  <table class="form-table">
108
  <tr>
109
- <th scope="row" valign="top">Select a website</th>
110
  <td>
111
  <?php
112
  foreach ( $dsq_sites as $counter => $dsq_site ):
113
  ?>
114
- <input name="dsq_forum_url" type="radio" id="dsq-site-<?php echo $counter; ?>" value="<?php echo $dsq_site['short_name']; ?>" />
115
- <label for="dsq-site-<?php echo $counter; ?>"><strong><?php echo $dsq_site['name']; ?></strong> (<u><?php echo $dsq_site['short_name']; ?>.disqus.com</u>)</label>
116
  <br />
117
  <?php
118
  endforeach;
119
  ?>
120
  <hr />
121
- <a href="http://disqus.com/comments/register/">Or register a new one on the Disqus website</a>.
122
  </td>
123
  </tr>
124
  </table>
125
 
126
  <p class="submit" style="text-align: left">
127
- <input type="hidden" name="dsq_username" value="<?php echo $_POST['dsq_username']; ?>">
128
- <input type="hidden" name="dsq_password" value="<?php echo str_replace('"', '&quot;', $_POST['dsq_password']); ?>">
129
  <input name="submit" type="submit" value="Next &raquo;" />
130
  </p>
131
  </form>
@@ -135,23 +144,23 @@ endforeach;
135
  case 1:
136
  ?>
137
  <div id="dsq-step-1" class="dsq-main">
138
- <h2>Install Disqus Comments</h2>
139
 
140
- <form method="POST" action="?page=disqus&step=2">
141
  <?php wp_nonce_field('dsq-install-1'); ?>
142
  <table class="form-table">
143
  <tr>
144
- <th scope="row" valign="top">Username</th>
145
  <td>
146
  <input id="dsq-username" name="dsq_username" tabindex="1" type="text" />
147
- <a href="http://disqus.com/profile/">(don't have a Disqus Profile yet?)</a>
148
  </td>
149
  </tr>
150
  <tr>
151
- <th scope="row" valign="top">Password</th>
152
  <td>
153
  <input type="password" id="dsq-password" name="dsq_password" tabindex="2">
154
- <a href="http://disqus.com/forgot/">(forgot your password?)</a>
155
  </td>
156
  </tr>
157
  </table>
@@ -166,10 +175,11 @@ case 1:
166
  <?php
167
  break;
168
  case 0:
 
169
  ?>
170
  <div class="dsq-main">
171
- <h2>Comments</h2>
172
- <iframe src="<?php echo DISQUS_API_URL; ?>/comments/moderate/<?php echo get_option('disqus_forum_url'); ?>/?template=wordpress" style="width: 100%; height: 800px"></iframe>
173
  </div>
174
  <?php } ?>
175
  </div>
@@ -178,64 +188,71 @@ case 0:
178
  $dsq_replace = get_option('disqus_replace');
179
  $dsq_forum_url = strtolower(get_option('disqus_forum_url'));
180
  $dsq_api_key = get_option('disqus_api_key');
 
181
  $dsq_partner_key = get_option('disqus_partner_key');
182
  $dsq_cc_fix = get_option('disqus_cc_fix');
183
  ?>
184
  <!-- Advanced options -->
185
  <div id="dsq-advanced" class="dsq-content dsq-advanced" style="display:none;">
186
- <h2>Advanced Options</h2>
187
- Version: <?php echo esc_html($dsq_version); ?>
188
  <form method="POST">
189
  <?php wp_nonce_field('dsq-advanced'); ?>
190
  <table class="form-table">
191
  <tr>
192
- <th scope="row" valign="top">Disqus short name</th>
193
  <td>
194
  <input name="disqus_forum_url" value="<?php echo esc_attr($dsq_forum_url); ?>" tabindex="1" type="text" />
195
  <br />
196
- This is the unique identifier for your website on Disqus Comments.
197
  </td>
198
  </tr>
199
 
200
  <tr>
201
- <th scope="row" valign="top">Disqus API Key</th>
202
  <td>
203
  <input type="text" name="disqus_api_key" value="<?php echo esc_attr($dsq_api_key); ?>" tabindex="2">
204
  <br />
205
- This is set for you when going through the installation steps.
206
  </td>
207
  </tr>
208
 
209
  <tr>
210
- <th scope="row" valign="top">Disqus Partner Key</th>
 
 
 
 
 
 
 
 
 
211
  <td>
212
  <input type="text" name="disqus_partner_key" value="<?php echo esc_attr($dsq_partner_key); ?>" tabindex="2">
213
  <br />
214
- Advanced: Used for single sign-on (SSO) integration. (<a href="http://disqus.com/help/sso" onclick="window.open(this.href); return false">more info on SSO</a>)
215
  </td>
216
  </tr>
217
 
218
  <tr>
219
- <th scope="row" valign="top">Use Disqus Comments on</th>
220
  <td>
221
  <select name="disqus_replace" tabindex="3" class="disqus-replace">
222
- <?php if ( dsq_legacy_mode() ) : ?>
223
- <option value="empty" <?php if('empty'==$dsq_replace){echo 'selected';}?>>Only future blog posts and existing posts without WordPress comments.</option>
224
- <?php endif ; ?>
225
- <option value="all" <?php if('all'==$dsq_replace){echo 'selected';}?>>On all existing and future blog posts.</option>
226
- <option value="closed" <?php if('closed'==$dsq_replace){echo 'selected';}?>>Only on blog posts with closed comments.</option>
227
  </select>
228
  <br />
229
- NOTE: Your WordPress comments will never be lost.
230
  </td>
231
  </tr>
232
 
233
  <tr>
234
- <th scope="row" valign="top">Comment Counts</th>
235
  <td>
236
  <input type="checkbox" id="disqus_comment_count" name="disqus_cc_fix" <?php if($dsq_cc_fix){echo 'checked="checked"';}?> >
237
- <label for="disqus_comment_count">Output JavaScript in footer</label>
238
- <br />NOTE: Check this if you have problems with the comment count displays including: not showing on permalinks, broken featured image carousels, or longer-than-usual homepage load times (<a href="http://disqus.com/help/wordpress" onclick="window.open(this.href); return false">more info</a>).
239
  </td>
240
  </tr>
241
 
@@ -247,26 +264,44 @@ case 0:
247
  </form>
248
 
249
  <table class="form-table">
 
250
  <tr>
251
- <th scope="row" valign="top">Export comments to Disqus</th>
252
  <td>
253
  <div id="dsq_export">
254
- <p class="status"><a href="#" class="button">Export Comments</a> This will sync your WordPress comments with Disqus</p>
255
  </div>
256
  </td>
257
  </tr>
258
-
259
  <tr>
260
- <th scope="row" valign="top">Uninstall Disqus Comments</th>
261
  <td>
262
  <form action="?page=disqus" method="POST">
263
  <?php wp_nonce_field('dsq-uninstall'); ?>
264
- <input type="submit" value="Uninstall" name="uninstall" onclick="return confirm('Are you sure you want to uninstall Disqus?')" class="button" />
265
  </form>
266
  </td>
267
  </tr>
268
 
269
  </table>
270
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
271
  </div>
272
  </div>
1
  <?php
2
  global $dsq_version, $dsq_api;
3
 
4
+ require(ABSPATH . 'wp-includes/version.php');
5
+
6
  if ( !current_user_can('manage_options') ) {
7
  die();
8
  }
21
  }
22
 
23
  // Handle export function.
24
+ if( isset($_POST['export']) and DISQUS_CAN_EXPORT ) {
25
  require_once(dirname(__FILE__) . '/export.php');
26
  dsq_export_wp();
27
  }
30
  if ( isset($_POST['uninstall']) ) {
31
  update_option('disqus_forum_url', '');
32
  update_option('disqus_api_key', '');
33
+ update_option('disqus_user_api_key', '');
34
  update_option('disqus_partner_key', '');
35
  }
36
 
37
  // Clean-up POST parameters.
38
+ foreach ( array('dsq_forum', 'dsq_username', 'dsq_user_api_key') as $key ) {
39
  if ( isset($_POST[$key]) ) { $_POST[$key] = strip_tags($_POST[$key]); }
40
  }
41
 
42
  // Handle installation process.
43
+ if ( isset($_POST['dsq_forum']) && isset($_POST['dsq_user_api_key']) ) {
44
+ list($dsq_forum_id, $dsq_forum_url) = explode(':', $_POST['dsq_forum']);
45
+ update_option('disqus_forum_url', $dsq_forum_url);
46
+ $api_key = $dsq_api->get_forum_api_key($_POST['dsq_user_api_key'], $dsq_forum_id);
47
+ if ( !$api_key || $api_key < 0 ) {
48
  update_option('disqus_replace', 'replace');
49
+ dsq_manage_dialog(dsq_i('There was an error completing the installation of Disqus. If you are still having issues, refer to the <a href="http://disqus.com/help/wordpress">WordPress help page</a>.'), true);
50
  } else {
51
  update_option('disqus_api_key', $api_key);
52
  update_option('disqus_replace', 'all');
53
  }
54
+
55
  if (!empty($_POST['disqus_partner_key'])) {
56
  $partner_key = trim(stripslashes($_POST['disqus_partner_key']));
57
  if (!empty($partner_key)) {
68
  }
69
  update_option('disqus_forum_url', $disqus_forum_url);
70
  update_option('disqus_partner_key', trim(stripslashes($_POST['disqus_partner_key'])));
71
+ update_option('disqus_api_key', trim(stripslashes($_POST['disqus_api_key'])));
72
+ update_option('disqus_user_api_key', trim(stripslashes($_POST['disqus_user_api_key'])));
73
  update_option('disqus_replace', $_POST['disqus_replace']);
74
  update_option('disqus_cc_fix', isset($_POST['disqus_cc_fix']));
75
  dsq_manage_dialog('Your settings have been changed.');
76
  }
77
 
78
+ $dsq_user_api_key = isset($_POST['dsq_user_api_key']) ? $_POST['dsq_user_api_key'] : null;
79
+
80
  // Get installation step process (or 0 if we're already installed).
81
  $step = @intval($_GET['step']);
82
+ if ($step > 1 && $dsq_user_api_key) $step = 1;
83
+ elseif ($step > 1 && !isset($_POST['dsq_username'])) $step = 1;
84
+ $step = (dsq_is_installed()) ? 0 : ($step ? $step : 1);
85
 
86
  if ( 2 == $step && isset($_POST['dsq_username']) && isset($_POST['dsq_password']) ) {
87
+ $dsq_user_api_key = $dsq_api->get_user_api_key($_POST['dsq_username'], $_POST['dsq_password']);
88
+ if ( !$dsq_user_api_key ) {
89
+ $step = 1;
90
+ dsq_manage_dialog($dsq_api->get_last_error(), true);
91
+ }
92
+
93
+ $dsq_sites = $dsq_api->get_forum_list($dsq_user_api_key);
94
  if ( $dsq_sites < 0 ) {
95
  $step = 1;
96
+ dsq_manage_dialog($dsq_api->get_last_error(), true);
 
 
 
 
97
  }
98
  }
99
 
101
  <div class="wrap" id="dsq-wrap">
102
  <ul id="dsq-tabs">
103
  <li class="selected" id="dsq-tab-main" rel="dsq-main"><?php echo (dsq_is_installed() ? 'Manage' : 'Install'); ?></li>
104
+ <li id="dsq-tab-advanced" rel="dsq-advanced"><?php echo dsq_i('Advanced Options'); ?></li>
105
  </ul>
106
 
107
  <div id="dsq-main" class="dsq-content">
110
  case 2:
111
  ?>
112
  <div id="dsq-step-2" class="dsq-main">
113
+ <h2><?php echo dsq_i('Install Disqus Comments'); ?></h2>
114
 
115
  <form method="POST" action="?page=disqus">
116
  <?php wp_nonce_field('dsq-install-2'); ?>
117
  <table class="form-table">
118
  <tr>
119
+ <th scope="row" valign="top"><?php echo dsq_i('Select a website'); ?></th>
120
  <td>
121
  <?php
122
  foreach ( $dsq_sites as $counter => $dsq_site ):
123
  ?>
124
+ <input name="dsq_forum" type="radio" id="dsq-site-<?php echo $counter; ?>" value="<?php echo $dsq_site->id; ?>:<?php echo $dsq_site->shortname; ?>" />
125
+ <label for="dsq-site-<?php echo $counter; ?>"><strong><?php echo htmlspecialchars($dsq_site->name); ?></strong> (<u><?php echo $dsq_site->shortname; ?>.disqus.com</u>)</label>
126
  <br />
127
  <?php
128
  endforeach;
129
  ?>
130
  <hr />
131
+ <a href="http://disqus.com/comments/register/"><?php echo dsq_i('Or register a new one on the Disqus website.'); ?></a>
132
  </td>
133
  </tr>
134
  </table>
135
 
136
  <p class="submit" style="text-align: left">
137
+ <input type="hidden" name="dsq_user_api_key" value="<?php echo htmlspecialchars($dsq_user_api_key); ?>"/>
 
138
  <input name="submit" type="submit" value="Next &raquo;" />
139
  </p>
140
  </form>
144
  case 1:
145
  ?>
146
  <div id="dsq-step-1" class="dsq-main">
147
+ <h2><?php echo dsq_i('Install Disqus Comments'); ?></h2>
148
 
149
+ <form method="POST" action="?page=disqus&amp;step=2">
150
  <?php wp_nonce_field('dsq-install-1'); ?>
151
  <table class="form-table">
152
  <tr>
153
+ <th scope="row" valign="top"><?php echo dsq_i('Username'); ?></th>
154
  <td>
155
  <input id="dsq-username" name="dsq_username" tabindex="1" type="text" />
156
+ <a href="http://disqus.com/profile/"><?php echo dsq_i('(don\'t have a Disqus Profile yet?)'); ?></a>
157
  </td>
158
  </tr>
159
  <tr>
160
+ <th scope="row" valign="top"><?php echo dsq_i('Password'); ?></th>
161
  <td>
162
  <input type="password" id="dsq-password" name="dsq_password" tabindex="2">
163
+ <a href="http://disqus.com/forgot/"><?php echo dsq_i('(forgot your password?)'); ?></a>
164
  </td>
165
  </tr>
166
  </table>
175
  <?php
176
  break;
177
  case 0:
178
+ $url = get_option('disqus_forum_url');
179
  ?>
180
  <div class="dsq-main">
181
+ <h2><?php echo dsq_i('Comments'); ?></h2>
182
+ <iframe src="<?php echo DISQUS_URL; ?>comments/moderate/<?php if ($url) echo $url . '/'; ?>?template=wordpress" style="width: 100%; height: 800px"></iframe>
183
  </div>
184
  <?php } ?>
185
  </div>
188
  $dsq_replace = get_option('disqus_replace');
189
  $dsq_forum_url = strtolower(get_option('disqus_forum_url'));
190
  $dsq_api_key = get_option('disqus_api_key');
191
+ $dsq_user_api_key = get_option('dsq_user_api_key');
192
  $dsq_partner_key = get_option('disqus_partner_key');
193
  $dsq_cc_fix = get_option('disqus_cc_fix');
194
  ?>
195
  <!-- Advanced options -->
196
  <div id="dsq-advanced" class="dsq-content dsq-advanced" style="display:none;">
197
+ <h2><?php echo dsq_i('Advanced Options'); ?></h2>
198
+ <?php echo dsq_i('Version: %s', esc_html($dsq_version)); ?>
199
  <form method="POST">
200
  <?php wp_nonce_field('dsq-advanced'); ?>
201
  <table class="form-table">
202
  <tr>
203
+ <th scope="row" valign="top"><?php echo dsq_i('Disqus short name'); ?></th>
204
  <td>
205
  <input name="disqus_forum_url" value="<?php echo esc_attr($dsq_forum_url); ?>" tabindex="1" type="text" />
206
  <br />
207
+ <?php echo dsq_i('This is the unique identifier for your website on Disqus Comments.'); ?>
208
  </td>
209
  </tr>
210
 
211
  <tr>
212
+ <th scope="row" valign="top"><?php echo dsq_i('Disqus API Key'); ?></th>
213
  <td>
214
  <input type="text" name="disqus_api_key" value="<?php echo esc_attr($dsq_api_key); ?>" tabindex="2">
215
  <br />
216
+ <?php echo dsq_i('This is set for you when going through the installation steps.'); ?>
217
  </td>
218
  </tr>
219
 
220
  <tr>
221
+ <th scope="row" valign="top"><?php echo dsq_i('Disqus User API Key'); ?></th>
222
+ <td>
223
+ <input type="text" name="disqus_user_api_key" value="<?php echo esc_attr($dsq_user_api_key); ?>" tabindex="2">
224
+ <br />
225
+ <?php echo dsq_i('This is set for you when going through the installation steps.'); ?>
226
+ </td>
227
+ </tr>
228
+
229
+ <tr>
230
+ <th scope="row" valign="top"><?php echo dsq_i('Disqus Partner Key'); ?></th>
231
  <td>
232
  <input type="text" name="disqus_partner_key" value="<?php echo esc_attr($dsq_partner_key); ?>" tabindex="2">
233
  <br />
234
+ <?php echo dsq_i('Advanced: Used for single sign-on (SSO) integration. (<a href="%s" onclick="window.open(this.href); return false">more info on SSO</a>)', 'http://disqus.com/help/sso'); ?>
235
  </td>
236
  </tr>
237
 
238
  <tr>
239
+ <th scope="row" valign="top"><?php echo dsq_i('Use Disqus Comments on'); ?></th>
240
  <td>
241
  <select name="disqus_replace" tabindex="3" class="disqus-replace">
242
+ <option value="all" <?php if('all'==$dsq_replace){echo 'selected';}?>><?php echo dsq_i('On all existing and future blog posts.'); ?></option>
243
+ <option value="closed" <?php if('closed'==$dsq_replace){echo 'selected';}?>><?php echo dsq_i('Only on blog posts with closed comments.'); ?></option>
 
 
 
244
  </select>
245
  <br />
246
+ <?php echo dsq_i('NOTE: Your WordPress comments will never be lost.'); ?>
247
  </td>
248
  </tr>
249
 
250
  <tr>
251
+ <th scope="row" valign="top"><?php echo dsq_i('Comment Counts'); ?></th>
252
  <td>
253
  <input type="checkbox" id="disqus_comment_count" name="disqus_cc_fix" <?php if($dsq_cc_fix){echo 'checked="checked"';}?> >
254
+ <label for="disqus_comment_count"<?php echo dsq_i('>Output JavaScript in footer'); ?></label>
255
+ <br /><?php echo dsq_i('NOTE: Check this if you have problems with the comment count displays including: not showing on permalinks, broken featured image carousels, or longer-than-usual homepage load times (<a href="%s" onclick="window.open(this.href); return false">more info</a>).', 'http://disqus.com/help/wordpress'); ?>
256
  </td>
257
  </tr>
258
 
264
  </form>
265
 
266
  <table class="form-table">
267
+ <?php if (DISQUS_CAN_EXPORT): ?>
268
  <tr>
269
+ <th scope="row" valign="top"><?php echo dsq_i('Export comments to Disqus'); ?></th>
270
  <td>
271
  <div id="dsq_export">
272
+ <p class="status"><a href="#" class="button"><?php echo dsq_i('Export Comments'); ?></a> <?php echo dsq_i('This will sync your WordPress comments with Disqus'); ?></p>
273
  </div>
274
  </td>
275
  </tr>
276
+ <?php endif; ?>
277
  <tr>
278
+ <th scope="row" valign="top"><?php echo dsq_i('Uninstall Disqus Comments'); ?></th>
279
  <td>
280
  <form action="?page=disqus" method="POST">
281
  <?php wp_nonce_field('dsq-uninstall'); ?>
282
+ <input type="submit" value="Uninstall" name="uninstall" onclick="return confirm('<?php echo dsq_i('Are you sure you want to uninstall Disqus?'); ?>')" class="button" />
283
  </form>
284
  </td>
285
  </tr>
286
 
287
  </table>
288
+ <br/>
289
+ <h3><?php echo dsq_i('Debug Information'); ?></h3>
290
+ <p><?php echo dsq_i('Having problems with the plugin? <a href="%s">Drop us a line</a> and include the following details and we\'ll do what we can.', 'mailto:help+wp@disqus.com'); ?></p>
291
+ <textarea style="width:90%; height:200px;">URL: <?php echo get_option('siteurl'); ?>
292
+ Version: <?php echo $wp_version; ?>
293
+
294
+ Plugin Version: <?php echo $dsq_version; ?>
295
+ Forum Shortname: <?php echo get_option('disqus_forum_url'); ?>
296
+
297
+ Active Theme: <?php $theme = get_theme(get_current_theme()); echo $theme['Name'].' '.$theme['Version']; ?>
298
+
299
+ Plugins:
300
+
301
+ <?php
302
+ foreach (get_plugins() as $plugin) {
303
+ echo $plugin['Name'].' '.$plugin['Version']."\n";
304
+ }
305
+ ?></textarea><br/>
306
  </div>
307
  </div>
readme.txt CHANGED
@@ -2,8 +2,8 @@
2
  Contributors: disqus, alexkingorg, crowdfavorite
3
  Tags: comments, threaded, email, notification, spam, avatars, community, profile, widget
4
  Requires at least: 2.8
5
- Tested up to: 2.9.2
6
- Stable tag: 2.33.8752
7
 
8
  The Disqus comment system replaces your WordPress comment system with your comments hosted and powered by Disqus.
9
 
@@ -43,7 +43,7 @@ The Disqus for WordPress plugin seamlessly integrates using the Disqus API and b
43
  of WordPress
44
 
45
  * Maintain the directory structure of the archive (all extracted files
46
- should exist in 'wp-content/plugins/disqus-comment-system/'
47
 
48
  2. From your blog administration, click on Comments to change settings
49
  (WordPress 2.0 users can find the settings under Options > Disqus.)
@@ -54,12 +54,31 @@ Go to [http://disqus.com/help/wordpress](http://disqus.com/help/wordpress)
54
 
55
  == Upgrading ==
56
 
57
- 1. Replace the old plugin with the new plugin (the plugin must stay in
58
- the disqus directory).
59
 
60
- 2. Your blog will be in legacy mode until you complete the configuration.
61
- This just means that it is using JavaScript to pull the comments instead
62
- of the API.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
63
 
64
  == Support ==
65
 
2
  Contributors: disqus, alexkingorg, crowdfavorite
3
  Tags: comments, threaded, email, notification, spam, avatars, community, profile, widget
4
  Requires at least: 2.8
5
+ Tested up to: 3.0
6
+ Stable tag: 2.41
7
 
8
  The Disqus comment system replaces your WordPress comment system with your comments hosted and powered by Disqus.
9
 
43
  of WordPress
44
 
45
  * Maintain the directory structure of the archive (all extracted files
46
+ should exist in 'wp-content/plugins/disqus/'
47
 
48
  2. From your blog administration, click on Comments to change settings
49
  (WordPress 2.0 users can find the settings under Options > Disqus.)
54
 
55
  == Upgrading ==
56
 
57
+ (If you were using legacy mode you will need to re-install the plugin completely)
 
58
 
59
+ Replace the old plugin with the new plugin (the plugin must stay in
60
+ the disqus directory). If the old plugin directory was 'disqus-comment-system'
61
+ you should remove it, and the new plugin should be stored in 'disqus'.
62
+
63
+ == Changes ==
64
+
65
+ 2.41
66
+
67
+ * Correct a bug with double urlencoding titles.
68
+
69
+ 2.40
70
+
71
+ * Comments are now synced with Disqus as a delayed asynchronous cron event.
72
+ * Comment count code has been updated to use the new widget. (Comment counts
73
+ must be linked to get tracked within "the loop" now).
74
+ * API bindings have been migrated to the generic 1.1 Disqus API.
75
+ * Pages will now properly update their permalink with Disqus when it changes. This is
76
+ done within the sync event above.
77
+ * There is now a Debug Information pane under Advanced to assist with support requests.
78
+ * When Disqus is unreachable it will fallback to the theme's built-in comment display.
79
+ * Legacy mode is no longer available.
80
+ * The plugin management interface can now be localized.
81
+ * The plugin is now valid HTML5.
82
 
83
  == Support ==
84