PluginProbe
Disqus Conditional Load / 9.0.3
Disqus Conditional Load v9.0.3
trunk 1.0 10.0.1 10.0.3 10.0.4 10.0.5 10.0.6 10.0.7 10.0.8 10.1.0 10.1.1 10.1.2 10.1.3 10.1.4 10.1.5 10.1.6 10.1.7 10.1.8 10.1.9 10.2.0 10.2.1 10.2.2 10.2.3 10.2.4 11.0.0 All 68 releases
disqus-conditional-load / disqus-conditional-load.php

disqus-conditional-load.php in Disqus Conditional Load 9.0.3, at disqus-conditional-load.php

1,671 lines 57.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /*
3 Plugin Name: Disqus Conditional Load
4 Plugin URI: http://www.joelsays.com/plugins/disqus-conditional-load/
5 Description: Use Disqus commenting system with plenty of advanced featured like lazy load, woocommerce support, counts etc.
6 Author: Joel James
7 Version: 9.0.3
8 Author URI: http://www.joelsays.com/about-me/
9 Donate link: http://www.joelsays.com/donation/
10 */
11
12 /*.
13 require_module 'standard';
14 require_module 'pcre';
15 require_module 'mysql';
16 .*/
17
18 defined('ABSPATH') or die("Crap ! You can not access this directly.");
19
20 require_once(dirname(__FILE__) . '/lib/wp-api.php');
21 require_once(dirname(__FILE__) . '/includes/functions/js-functions.php');
22
23 if (defined('DISQUS_LOCAL')) { // DISQUS defines this for local development purposes
24 define('DISQUS_DOMAIN', 'dev.disqus.org:8000');
25 define('DISQUS_IMPORTER_URL', 'http://dev.disqus.org:8001/');
26 } else {
27 define('DISQUS_DOMAIN', 'disqus.com');
28 define('DISQUS_IMPORTER_URL', 'https://import.disqus.com/');
29 }
30 define('DISQUS_URL', 'http://' . DISQUS_DOMAIN . '/');
31 define('DISQUS_MEDIA_URL', 'http://' . DISQUS_DOMAIN . '/media/');
32 define('DISQUS_API_URL', 'http://' . DISQUS_DOMAIN . '/api/');
33 define('DISQUS_RSS_PATH', '/latest.rss');
34 define('DISQUS_CAN_EXPORT', is_file(dirname(__FILE__) . '/js-export.php'));
35 if (!defined('DISQUS_DEBUG')) {
36 define('DISQUS_DEBUG', false);
37 }
38 define('DISQUS_VERSION', '2.77');
39 define('DISQUS_SYNC_TIMEOUT', 30);
40
41 /**
42 * Returns an array of all option identifiers used by DISQUS.
43 * @return array[int]string
44 */
45 function dsq_options() {
46 return array(
47 '_disqus_sync_lock',
48 '_disqus_sync_post_ids',
49 # render disqus in the embed
50 'disqus_active',
51 'disqus_forum_url',
52 'disqus_api_key',
53 'disqus_user_api_key',
54 'disqus_replace',
55 'disqus_cc_fix',
56 # SSO features
57 'disqus_partner_key',
58 'disqus_public_key',
59 'disqus_secret_key',
60 'disqus_sso_button',
61 'disqus_sso_icon',
62 # disables automatic sync via cron
63 'disqus_manual_sync',
64 # disables server side rendering
65 'disqus_disable_ssr',
66 # the last sync comment id (from get_forum_posts)
67 'disqus_last_comment_id',
68 'disqus_version',
69 );
70 }
71
72 /**
73 * @param string $file
74 * @return string
75 */
76 function dsq_plugin_basename($file) {
77 $file = dirname($file);
78
79 // From WP2.5 wp-includes/plugin.php:plugin_basename()
80 $file = str_replace('\\','/',$file); // sanitize for Win32 installs
81 $file = preg_replace('|/+|','/', $file); // remove any duplicate slash
82 $file = preg_replace('|^.*/' . PLUGINDIR . '/|','',$file); // get relative path from plugins dir
83
84 if ( strstr($file, '/') === false ) {
85 return $file;
86 }
87
88 $pieces = explode('/', $file);
89 return !empty($pieces[count($pieces)-1]) ? $pieces[count($pieces)-1] : $pieces[count($pieces)-2];
90 }
91
92 if ( !defined('PLUGINDIR') ) {
93 define('PLUGINDIR', 'wp-content/plugins'); // Relative to ABSPATH. For back compat.
94 }
95
96 $mt_disqus_version = '2.01';
97 /**
98 * Response from Disqus get_thread API call for comments template.
99 *
100 * @global string $dsq_response
101 * @since 1.0
102 */
103 $dsq_response = '';
104 /**
105 * Disqus API instance.
106 *
107 * @global string $dsq_api
108 * @since 1.0
109 */
110 $dsq_api = new DisqusWordPressAPI(get_option('disqus_forum_url'), get_option('disqus_api_key'));
111
112 /**
113 * DISQUS currently unsupported dev toggle to output comments for this query.
114 *
115 * @global bool $DSQ_QUERY_COMMENTS
116 * @since ?
117 */
118 $DSQ_QUERY_COMMENTS = false;
119
120 /**
121 * DISQUS array to store post_ids from WP_Query for comment JS output.
122 *
123 * @global array $DSQ_QUERY_POST_IDS
124 * @since 2.2
125 */
126 $DSQ_QUERY_POST_IDS = array();
127
128 /**
129 * Helper functions.
130 */
131
132 /**
133 * Tests if required options are configured to display the Disqus embed.
134 * @return bool
135 */
136 function dsq_is_installed() {
137 return get_option('disqus_forum_url') && get_option('disqus_api_key');
138 }
139
140
141 /**
142 * @return bool
143 */
144 function dsq_can_replace() {
145 global $id, $post;
146
147 if (get_option('disqus_active') === '0'){ return false; }
148
149 $replace = get_option('disqus_replace');
150
151 if ( is_feed() ) { return false; }
152 if ( !isset($post) ) { return false; }
153 if ( 'draft' == $post->post_status ) { return false; }
154 if ( !get_option('disqus_forum_url') ) { return false; }
155 else if ( 'all' == $replace ) { return true; }
156
157 if ( !isset($post->comment_count) ) {
158 $num_comments = 0;
159 } else {
160 if ( 'empty' == $replace ) {
161 // Only get count of comments, not including pings.
162
163 // If there are comments, make sure there are comments (that are not track/pingbacks)
164 if ( $post->comment_count > 0 ) {
165 // Yuck, this causes a DB query for each post. This can be
166 // replaced with a lighter query, but this is still not optimal.
167 $comments = get_approved_comments($post->ID);
168 foreach ( $comments as $comment ) {
169 if ( $comment->comment_type != 'trackback' && $comment->comment_type != 'pingback' ) {
170 $num_comments++;
171 }
172 }
173 } else {
174 $num_comments = 0;
175 }
176 }
177 else {
178 $num_comments = $post->comment_count;
179 }
180 }
181
182 return ( ('empty' == $replace && 0 == $num_comments)
183 || ('closed' == $replace && 'closed' == $post->comment_status) );
184 }
185
186 function dsq_manage_dialog($message, $error = false) {
187 global $wp_version;
188
189 echo '<div '
190 . ( $error ? 'id="disqus_warning" ' : '')
191 . 'class="updated fade'
192 . ( (version_compare($wp_version, '2.5', '<') && $error) ? '-ff0000' : '' )
193 . '"><p><strong>'
194 . $message
195 . '</strong></p></div>';
196 }
197
198 function dsq_sync_comments($comments) {
199 global $wpdb;
200
201 // user MUST be logged out during this process
202 wp_set_current_user(0);
203
204 // we need the thread_ids so we can map them to posts
205 $thread_map = array();
206 foreach ( $comments as $comment ) {
207 $thread_map[$comment->thread->id] = null;
208 }
209 $thread_ids = "'" . implode("', '", array_keys($thread_map)) . "'";
210
211 $results = $wpdb->get_results( "SELECT post_id, meta_value FROM $wpdb->postmeta WHERE meta_key = 'dsq_thread_id' AND meta_value IN ({$thread_ids}) LIMIT 1");
212 foreach ( $results as $result ) {
213 $thread_map[$result->meta_value] = $result->post_id;
214 }
215 unset($result);
216
217 foreach ( $comments as $comment ) {
218 $ts = strtotime($comment->created_at);
219 if (!$thread_map[$comment->thread->id] && !empty($comment->thread->identifier)) {
220 // legacy threads dont already have their meta stored
221 foreach ( $comment->thread->identifier as $identifier ) {
222 // we know identifier starts with post_ID
223 if ($post_ID = (int)substr($identifier, 0, strpos($identifier, ' '))) {
224 $thread_map[$comment->thread->id] = $post_ID;
225 update_post_meta($post_ID, 'dsq_thread_id', $comment->thread->id);
226 if (DISQUS_DEBUG) {
227 echo "updated post {$post_ID}: dsq_thread_id set to {$comment->thread->id}\n";
228 }
229 }
230 }
231 unset($identifier);
232 }
233 if (!$thread_map[$comment->thread->id]) {
234 // shouldn't ever happen, but we can't be certain
235 if (DISQUS_DEBUG) {
236 if (!empty($comment->thread->identifier)) {
237 $idents = implode(', ', $comment->thread->identifier);
238 echo "skipped {$comment->id}: missing thread for identifiers ({$idents})\n";
239 } else {
240 echo "skipped {$comment->id}: missing thread (no identifier)\n";
241 }
242 }
243 continue;
244 }
245 $results = $wpdb->get_results($wpdb->prepare("SELECT comment_id FROM $wpdb->commentmeta WHERE meta_key = 'dsq_post_id' AND meta_value = %s LIMIT 1", $comment->id));
246 if (count($results)) {
247 // already exists
248 if (DISQUS_DEBUG) {
249 echo "skipped {$comment->id}: comment already exists\n";
250 }
251 if (count($results) > 1) {
252 // clean up duplicates -- fixes an issue where a race condition allowed comments to be synced multiple times
253 $results = array_slice($results, 1);
254 foreach ($results as $result) {
255 $wpdb->prepare("DELETE FROM $wpdb->commentmeta WHERE comment_id = %s LIMIT 1", $result);
256 }
257 }
258 continue;
259 }
260
261 $commentdata = false;
262
263 // first lets check by the id we have stored
264 if ($comment->meta) {
265 $meta = explode(';', $comment->meta);
266 foreach ($meta as $value) {
267 $value = explode('=', $value);
268 $meta[$value[0]] = $value[1];
269 }
270 unset($value);
271 if ($meta['wp_id']) {
272 $commentdata = $wpdb->get_row($wpdb->prepare( "SELECT comment_ID, comment_parent FROM $wpdb->comments WHERE comment_ID = %s LIMIT 1", $meta['wp_id']), ARRAY_A);
273 }
274 }
275
276 // skip comments that were imported but are missing meta information
277 if (!$commentdata && $comment->imported) {
278 if (DISQUS_DEBUG) {
279 echo "skipped {$comment->id}: comment not found and marked as imported\n";
280 }
281 continue;
282 }
283
284 // and follow up using legacy Disqus agent
285 if (!$commentdata) {
286 $commentdata = $wpdb->get_row($wpdb->prepare( "SELECT comment_ID, comment_parent FROM $wpdb->comments WHERE comment_agent = %s LIMIT 1", 'Disqus/1.0:'.$comment->id), ARRAY_A);
287 }
288 if (!$commentdata) {
289 // Comment doesnt exist yet, lets insert it
290 if ($comment->status == 'approved') {
291 $approved = 1;
292 } elseif ($comment->status == 'spam') {
293 $approved = 'spam';
294 } else {
295 $approved = 0;
296 }
297 $commentdata = array(
298 'comment_post_ID' => $thread_map[$comment->thread->id],
299 'comment_date' => date('Y-m-d\TH:i:s', strtotime($comment->created_at) + (get_option('gmt_offset') * 3600)),
300 'comment_date_gmt' => $comment->created_at,
301 'comment_content' => apply_filters('pre_comment_content', $comment->message),
302 'comment_approved' => $approved,
303 'comment_agent' => 'Disqus/1.1('.DISQUS_VERSION.'):'.intval($comment->id),
304 'comment_type' => '',
305 );
306 if ($comment->is_anonymous) {
307 $commentdata['comment_author'] = $comment->anonymous_author->name;
308 $commentdata['comment_author_email'] = $comment->anonymous_author->email;
309 $commentdata['comment_author_url'] = $comment->anonymous_author->url;
310 $commentdata['comment_author_IP'] = $comment->ip_address;
311 } else {
312 if (!empty($comment->author->display_name)) {
313 $commentdata['comment_author'] = $comment->author->display_name;
314 } else {
315 $commentdata['comment_author'] = $comment->author->username;
316 }
317 $commentdata['comment_author_email'] = $comment->author->email;
318 $commentdata['comment_author_url'] = $comment->author->url;
319 $commentdata['comment_author_IP'] = $comment->ip_address;
320 }
321 $commentdata = wp_filter_comment($commentdata);
322 if ($comment->parent_post) {
323 $parent_id = $wpdb->get_var($wpdb->prepare( "SELECT comment_id FROM $wpdb->commentmeta WHERE meta_key = 'dsq_post_id' AND meta_value = %s LIMIT 1", $comment->parent_post));
324 if ($parent_id) {
325 $commentdata['comment_parent'] = $parent_id;
326 }
327 }
328
329 // due to a race condition we need to test again for coment existance
330 if ($wpdb->get_row($wpdb->prepare( "SELECT comment_id FROM $wpdb->commentmeta WHERE meta_key = 'dsq_post_id' AND meta_value = %s LIMIT 1", $comment->id))) {
331 // already exists
332 if (DISQUS_DEBUG) {
333 echo "skipped {$comment->id}: comment already exists (second check)\n";
334 }
335 continue;
336 }
337
338 $commentdata['comment_ID'] = wp_insert_comment($commentdata);
339 if (DISQUS_DEBUG) {
340 echo "inserted {$comment->id}: id is {$commentdata[comment_ID]}\n";
341 }
342 }
343 if (!$commentdata['comment_parent'] && $comment->parent_post) {
344 $parent_id = $wpdb->get_var($wpdb->prepare( "SELECT comment_id FROM $wpdb->commentmeta WHERE meta_key = 'dsq_post_id' AND meta_value = %s LIMIT 1", $comment->parent_post));
345 if ($parent_id) {
346 $wpdb->query($wpdb->prepare( "UPDATE $wpdb->comments SET comment_parent = %s WHERE comment_id = %s", $parent_id, $commentdata['comment_ID']));
347 if (DISQUS_DEBUG) {
348 echo "updated {$comment->id}: comment_parent changed to {$parent_id}\n";
349 }
350
351 }
352 }
353 $comment_id = $commentdata['comment_ID'];
354 update_comment_meta($comment_id, 'dsq_parent_post_id', $comment->parent_post);
355 update_comment_meta($comment_id, 'dsq_post_id', $comment->id);
356 }
357 unset($comment);
358
359 if( isset($_POST['dsq_api_key']) && $_POST['dsq_api_key'] == get_option('disqus_api_key') ) {
360 if( isset($_GET['dsq_sync_action']) && isset($_GET['dsq_sync_comment_id']) ) {
361 $comment_parts = explode('=', $_GET['dsq_sync_comment_id']);
362
363 if (!($comment_id = intval($comment_parts[1])) > 0) {
364 return;
365 }
366
367 if( 'wp_id' != $comment_parts[0] ) {
368 $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));
369 }
370
371 switch( $_GET['dsq_sync_action'] ) {
372 case 'mark_spam':
373 wp_set_comment_status($comment_id, 'spam');
374 echo "<!-- dsq_sync: wp_set_comment_status($comment_id, 'spam') -->";
375 break;
376 case 'mark_approved':
377 wp_set_comment_status($comment_id, 'approve');
378 echo "<!-- dsq_sync: wp_set_comment_status($comment_id, 'approve') -->";
379 break;
380 case 'mark_killed':
381 wp_set_comment_status($comment_id, 'hold');
382 echo "<!-- dsq_sync: wp_set_comment_status($comment_id, 'hold') -->";
383 break;
384 }
385 }
386 }
387 }
388
389 function dsq_request_handler() {
390 global $dsq_response;
391 global $dsq_api;
392 global $post;
393 global $wpdb;
394
395 if (!empty($_GET['cf_action'])) {
396 switch ($_GET['cf_action']) {
397 case 'sync_comments':
398 if( !( $post_id = $_GET['post_id'] ) ) {
399 header("HTTP/1.0 400 Bad Request");
400 die();
401 }
402 // schedule the event for 5 minutes from now in case they
403 // happen to make a quick post
404 dsq_add_pending_post_id($post_id);
405
406 if (DISQUS_DEBUG) {
407 $response = dsq_sync_forum();
408 if (!$response) {
409 die('// error: '.$dsq_api->get_last_error());
410 } else {
411 list($last_comment_id, $comments) = $response;
412 die('// synced '.$comments.' comments');
413 }
414 } else {
415 $ts = time() + 300;
416 wp_schedule_single_event($ts, 'dsq_sync_forum');
417 die('// sync scheduled');
418 }
419 break;
420 case 'export_comments':
421 if (current_user_can('manage_options') && DISQUS_CAN_EXPORT) {
422 $timestamp = intval($_GET['timestamp']);
423 $post_id = intval($_GET['post_id']);
424 global $wpdb, $dsq_api;
425 $post = $wpdb->get_results($wpdb->prepare("
426 SELECT *
427 FROM $wpdb->posts
428 WHERE post_type != 'revision'
429 AND post_status = 'publish'
430 AND comment_count > 0
431 AND ID > %d
432 ORDER BY ID ASC
433 LIMIT 1
434 ", $post_id));
435 $post = $post[0];
436 $post_id = $post->ID;
437 $max_post_id = $wpdb->get_var($wpdb->prepare("
438 SELECT MAX(ID)
439 FROM $wpdb->posts
440 WHERE post_type != 'revision'
441 AND post_status = 'publish'
442 AND comment_count > 0
443 ", $post_id));
444 $eof = (int)($post_id == $max_post_id);
445 if ($eof) {
446 $status = 'complete';
447 $msg = dsq_i('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>');
448 }
449 else {
450 $status = 'partial';
451 $msg = dsq_i('Processed comments on post #%s&hellip;', $post_id);
452 }
453 $result = 'fail';
454 $response = null;
455 if ($post) {
456 require_once(dirname(__FILE__) . '/js-export.php');
457 $wxr = dsq_export_wp($post);
458 $response = $dsq_api->import_wordpress_comments($wxr, $timestamp, $eof);
459 if (!($response['group_id'] > 0)) {
460 $result = 'fail';
461 $msg = '<p class="status dsq-export-fail">'. dsq_i('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 Conditional Load(deactivate the plugin and then reactivate it). If you are still having issues, refer to the <a href="%s" onclick="window.open(this.href); return false">WordPress help page</a>.', 'http://disqus.com/help/wordpress'). '</p>';
462 $response = $dsq_api->get_last_error();
463 }
464 else {
465 if ($eof) {
466 $msg = dsq_i('Your comments have been sent to Disqus and queued for import!<br/><a href="%s" target="_blank">See the status of your import at Disqus</a>', $response['link']);
467
468 }
469 $result = 'success';
470 }
471 }
472 // send AJAX response
473 $response = compact('result', 'timestamp', 'status', 'post_id', 'msg', 'eof', 'response');
474 header('Content-type: text/javascript');
475 echo cf_json_encode($response);
476 die();
477 }
478 break;
479 case 'import_comments':
480 if (current_user_can('manage_options')) {
481 if (!isset($_GET['last_comment_id'])) $last_comment_id = false;
482 else $last_comment_id = $_GET['last_comment_id'];
483
484 if ($_GET['wipe'] == '1') {
485 $wpdb->query("DELETE FROM `".$wpdb->prefix."commentmeta` WHERE meta_key IN ('dsq_post_id', 'dsq_parent_post_id')");
486 $wpdb->query("DELETE FROM `".$wpdb->prefix."comments` WHERE comment_agent LIKE 'Disqus/%%'");
487 }
488
489 ob_start();
490 $response = dsq_sync_forum($last_comment_id, true);
491 $debug = ob_get_clean();
492 if (!$response) {
493 $status = 'error';
494 $result = 'fail';
495 $error = $dsq_api->get_last_error();
496 $msg = '<p class="status dsq-export-fail">'.dsq_i('There was an error downloading your comments from Disqus.').'<br/>'.htmlspecialchars($error).'</p>';
497 } else {
498 list($comments, $last_comment_id) = $response;
499 if (!$comments) {
500 $status = 'complete';
501 $msg = dsq_i('Your comments have been downloaded from Disqus and saved in your local database.');
502 } else {
503 $status = 'partial';
504 $msg = dsq_i('Import in progress (last post id: %s) &hellip;', $last_comment_id);
505 }
506 $result = 'success';
507 }
508 $debug = explode("\n", $debug);
509 $response = compact('result', 'status', 'comments', 'msg', 'last_comment_id', 'debug');
510 header('Content-type: text/javascript');
511 echo cf_json_encode($response);
512 die();
513 }
514 break;
515 }
516 }
517 }
518
519 add_action('init', 'dsq_request_handler');
520
521 /**
522 * @param string $option_name
523 */
524 function dsq_image_upload_handler($option_name) {
525 // If the upload field has a file in it
526 if(isset($_FILES[$option_name]) && ($_FILES[$option_name]['size'] > 0)) {
527 // Get the type of the uploaded file. This is returned as "type/extension"
528 $arr_file_type = wp_check_filetype(basename($_FILES[$option_name]['name']));
529 $uploaded_file_type = $arr_file_type['type'];
530 // Set an array containing a list of acceptable formats
531 $allowed_file_types = array('image/jpg','image/jpeg','image/gif','image/png','image/x-icon');
532 // If the uploaded file is the right format
533 if(in_array($uploaded_file_type, $allowed_file_types)) {
534 // Options array for the wp_handle_upload function. 'test_upload' => false
535 $upload_overrides = array( 'test_form' => false );
536 // Handle the upload using WP's wp_handle_upload function. Takes the posted file and an options array
537 $uploaded_file = wp_handle_upload($_FILES[$option_name], $upload_overrides);
538 // If the wp_handle_upload call returned a local path for the image
539 if(isset($uploaded_file['url'])) {
540 update_option($option_name, $uploaded_file['url']);
541 }
542 }
543 }
544 }
545
546 function dsq_add_pending_post_id($post_id) {
547 update_post_meta($post_id, 'dsq_needs_sync', '1', $unique=true);
548 }
549
550 function dsq_get_pending_post_ids() {
551 global $wpdb;
552
553 $results = $wpdb->get_results( "SELECT post_id FROM {$wpdb->postmeta} WHERE meta_key = 'dsq_needs_sync'");
554 $post_ids = array();
555 foreach ($results as $result) {
556 $post_ids[] = $result->post_id;
557 }
558 return $post_ids;
559 }
560
561 function dsq_clear_pending_post_ids($post_ids) {
562 global $wpdb;
563
564 $post_ids_query = "'" . implode("', '", $post_ids) . "'";
565 $wpdb->query("DELETE FROM {$wpdb->postmeta} WHERE meta_key = 'dsq_needs_sync' AND post_id IN ({$post_ids_query})");
566
567 update_meta_cache('dsq_needs_sync', $post_ids);
568 }
569
570
571 function dsq_sync_post($post_id) {
572 global $dsq_api, $wpdb;
573
574 $post = get_post($post_id);
575
576 // Call update_thread to ensure our permalink is up to date
577 dsq_update_permalink($post);
578 }
579
580 function dsq_sync_forum($last_comment_id=false, $force=false) {
581 global $dsq_api, $wpdb;
582
583 set_time_limit(DISQUS_SYNC_TIMEOUT);
584
585 if ($force) {
586 $sync_time = null;
587 } else {
588 $sync_time = (int)get_option('_disqus_sync_lock');
589 }
590
591 // lock expires after 1 hour
592 if ($sync_time && $sync_time > time() - 60*60) {
593 $dsq_api->api->last_error = 'Sync already in progress (lock found)';
594 return false;
595 } else {
596 update_option('_disqus_sync_lock', time());
597 }
598
599 // sync all pending posts
600 $post_ids = dsq_get_pending_post_ids();
601 dsq_clear_pending_post_ids($post_ids);
602
603 foreach ($post_ids as $post_id) {
604 dsq_sync_post($post_id);
605 }
606
607 if ($last_comment_id === false) {
608 $last_comment_id = get_option('disqus_last_comment_id');
609 if (!$last_comment_id) {
610 $last_comment_id = 0;
611 }
612 }
613 if ($last_comment_id) {
614 $last_comment_id++;
615 }
616
617 //$last_comment_id = 0;
618
619 // Pull comments from API
620 $dsq_response = $dsq_api->get_forum_posts($last_comment_id);
621 if( $dsq_response < 0 || $dsq_response === false ) {
622 return false;
623 }
624
625 // Sync comments with database.
626 dsq_sync_comments($dsq_response);
627 $total = 0;
628 if ($dsq_response) {
629 foreach ($dsq_response as $comment) {
630 $total += 1;
631 if ($comment->id > $last_comment_id) $last_comment_id = $comment->id;
632 }
633 if ($last_comment_id > get_option('disqus_last_comment_id')) {
634 update_option('disqus_last_comment_id', $last_comment_id);
635 }
636 }
637 unset($comment);
638 delete_option('_disqus_sync_lock');
639 return array($total, $last_comment_id);
640 }
641
642 add_action('dsq_sync_forum', 'dsq_sync_forum');
643
644 function dsq_update_permalink($post) {
645 global $dsq_api;
646
647 if (DISQUS_DEBUG) {
648 echo "updating post on disqus: {$post->ID}\n";
649 }
650
651 $response = $dsq_api->api->update_thread(null, array(
652 'thread_identifier' => dsq_identifier_for_post($post),
653 'title' => dsq_title_for_post($post),
654 'url' => dsq_link_for_post($post)
655 ));
656
657 update_post_meta($post->ID, 'dsq_thread_id', $response->id);
658
659 return $response;
660 }
661
662 /**
663 * Compatibility
664 */
665
666 if (!function_exists ( '_wp_specialchars' ) ) {
667 function _wp_specialchars( $string, $quote_style = ENT_NOQUOTES, $charset = false, $double_encode = false ) {
668 $string = (string) $string;
669
670 if ( 0 === strlen( $string ) ) {
671 return '';
672 }
673
674 // Don't bother if there are no specialchars - saves some processing
675 if ( !preg_match( '/[&<>"\']/', $string ) ) {
676 return $string;
677 }
678
679 // Account for the previous behaviour of the function when the $quote_style is not an accepted value
680 if ( empty( $quote_style ) ) {
681 $quote_style = ENT_NOQUOTES;
682 } elseif ( !in_array( $quote_style, array( 0, 2, 3, 'single', 'double' ), true ) ) {
683 $quote_style = ENT_QUOTES;
684 }
685
686 // Store the site charset as a static to avoid multiple calls to wp_load_alloptions()
687 if ( !$charset ) {
688 static $_charset;
689 if ( !isset( $_charset ) ) {
690 $alloptions = wp_load_alloptions();
691 $_charset = isset( $alloptions['blog_charset'] ) ? $alloptions['blog_charset'] : '';
692 }
693 $charset = $_charset;
694 }
695 if ( in_array( $charset, array( 'utf8', 'utf-8', 'UTF8' ) ) ) {
696 $charset = 'UTF-8';
697 }
698
699 $_quote_style = $quote_style;
700
701 if ( $quote_style === 'double' ) {
702 $quote_style = ENT_COMPAT;
703 $_quote_style = ENT_COMPAT;
704 } elseif ( $quote_style === 'single' ) {
705 $quote_style = ENT_NOQUOTES;
706 }
707
708 // Handle double encoding ourselves
709 if ( !$double_encode ) {
710 $string = wp_specialchars_decode( $string, $_quote_style );
711 $string = preg_replace( '/&(#?x?[0-9a-z]+);/i', '|wp_entity|$1|/wp_entity|', $string );
712 }
713
714 $string = @htmlspecialchars( $string, $quote_style, $charset );
715
716 // Handle double encoding ourselves
717 if ( !$double_encode ) {
718 $string = str_replace( array( '|wp_entity|', '|/wp_entity|' ), array( '&', ';' ), $string );
719 }
720
721 // Backwards compatibility
722 if ( 'single' === $_quote_style ) {
723 $string = str_replace( "'", '&#039;', $string );
724 }
725
726 return $string;
727 }
728 }
729
730 if (!function_exists ( 'wp_check_invalid_utf8' ) ) {
731 function wp_check_invalid_utf8( $string, $strip = false ) {
732 $string = (string) $string;
733
734 if ( 0 === strlen( $string ) ) {
735 return '';
736 }
737
738 // Store the site charset as a static to avoid multiple calls to get_option()
739 static $is_utf8;
740 if ( !isset( $is_utf8 ) ) {
741 $is_utf8 = in_array( get_option( 'blog_charset' ), array( 'utf8', 'utf-8', 'UTF8', 'UTF-8' ) );
742 }
743 if ( !$is_utf8 ) {
744 return $string;
745 }
746
747 // Check for support for utf8 in the installed PCRE library once and store the result in a static
748 static $utf8_pcre;
749 if ( !isset( $utf8_pcre ) ) {
750 $utf8_pcre = @preg_match( '/^./u', 'a' );
751 }
752 // We can't demand utf8 in the PCRE installation, so just return the string in those cases
753 if ( !$utf8_pcre ) {
754 return $string;
755 }
756
757 // preg_match fails when it encounters invalid UTF8 in $string
758 if ( 1 === @preg_match( '/^./us', $string ) ) {
759 return $string;
760 }
761
762 // Attempt to strip the bad chars if requested (not recommended)
763 if ( $strip && function_exists( 'iconv' ) ) {
764 return iconv( 'utf-8', 'utf-8', $string );
765 }
766
767 return '';
768 }
769 }
770
771 if (!function_exists ( 'esc_html' ) ) {
772 function esc_html( $text ) {
773 $safe_text = wp_check_invalid_utf8( $text );
774 $safe_text = _wp_specialchars( $safe_text, ENT_QUOTES );
775 return apply_filters( 'esc_html', $safe_text, $text );
776 }
777 }
778
779 if (!function_exists ( 'esc_attr' ) ) {
780 function esc_attr( $text ) {
781 $safe_text = wp_check_invalid_utf8( $text );
782 $safe_text = _wp_specialchars( $safe_text, ENT_QUOTES );
783 return apply_filters( 'attribute_escape', $safe_text, $text );
784 }
785 }
786
787 /**
788 * Filters/Actions
789 */
790
791 // ugly global hack for comments closing
792 $EMBED = false;
793 function dsq_comments_template($value) {
794 global $EMBED;
795 global $post;
796 global $comments;
797
798 if ( !( is_singular() && ( have_comments() || 'open' == $post->comment_status ) ) ) {
799 return;
800 }
801
802 if ( !dsq_is_installed() || !dsq_can_replace() ) {
803 return $value;
804 }
805
806 // TODO: If a disqus-comments.php is found in the current template's
807 // path, use that instead of the default bundled comments.php
808 //return TEMPLATEPATH . '/disqus-comments.php';
809 $EMBED = true;
810 return dirname(__FILE__) . '/includes/js-comments.php';
811 }
812
813 function dsq_comment( $comment, $args, $depth ) {
814 $GLOBALS['comment'] = $comment;
815 switch ($comment->comment_type):
816 case '' :
817 ?>
818 <li <?php comment_class(); ?> id="dsq-comment-<?php echo comment_ID(); ?>">
819 <div id="dsq-comment-header-<?php echo comment_ID(); ?>" class="dsq-comment-header">
820 <cite id="dsq-cite-<?php echo comment_ID(); ?>">
821 <?php if(comment_author_url()) : ?>
822 <a id="dsq-author-user-<?php echo comment_ID(); ?>" href="<?php echo comment_author_url(); ?>" target="_blank" rel="nofollow"><?php echo comment_author(); ?></a>
823 <?php else : ?>
824 <span id="dsq-author-user-<?php echo comment_ID(); ?>"><?php echo comment_author(); ?></span>
825 <?php endif; ?>
826 </cite>
827 </div>
828 <div id="dsq-comment-body-<?php echo comment_ID(); ?>" class="dsq-comment-body">
829 <div id="dsq-comment-message-<?php echo comment_ID(); ?>" class="dsq-comment-message"><?php echo wp_filter_kses(comment_text()); ?></div>
830 </div>
831
832 <?php
833 break;
834 case 'pingback' :
835 case 'trackback' :
836 ?>
837 <li class="post pingback">
838 <p><?php echo dsq_i('Pingback:'); ?> <?php comment_author_link(); ?><?php edit_comment_link(dsq_i('(Edit)'), ' '); ?></p>
839 </li>
840 <?php
841 break;
842 endswitch;
843 }
844
845 // Mark entries in index to replace comments link.
846 // As of WordPress 3.1 this is required to return a numerical value
847 function dsq_comments_number($count) {
848 global $post;
849
850 return $count;
851 }
852
853 function dsq_comments_text($comment_text) {
854 global $post;
855
856 if ( dsq_can_replace() ) {
857 return '<span class="dsq-postid" rel="'.htmlspecialchars(dsq_identifier_for_post($post)).'">'.$comment_text.'</span>';
858 } else {
859 return $comment_text;
860 }
861 }
862
863 function dsq_bloginfo_url($url) {
864 if ( get_feed_link('comments_rss2') == $url && dsq_can_replace() ) {
865 return 'https://' . strtolower(get_option('disqus_forum_url')) . '.' . DISQUS_DOMAIN . DISQUS_RSS_PATH;
866 } else {
867 return $url;
868 }
869 }
870
871 function dsq_plugin_action_links($links, $file) {
872 $plugin_file = basename(__FILE__);
873 if (basename($file) == $plugin_file) {
874 if (!dsq_is_installed()) {
875 $settings_link = '<a href="edit-comments.php?page=disqus">'.dsq_i('Configure').'</a>';
876 } else {
877 $settings_link = '<a href="edit-comments.php?page=disqus">'.dsq_i('Settings').'</a>';
878 }
879 array_unshift($links, $settings_link);
880 }
881 return $links;
882 }
883 add_filter('plugin_action_links', 'dsq_plugin_action_links', 10, 2);
884
885 /**
886 * Hide the default comment form to stop spammers by marking all comments
887 * as closed.
888 */
889 function dsq_comments_open($open, $post_id=null) {
890 global $EMBED;
891 if ($EMBED) return false;
892 return $open;
893 }
894 add_filter('comments_open', 'dsq_comments_open');
895
896 // Always add Disqus management page to the admin menu
897 function dsq_add_pages() {
898 add_menu_page('Disqus Settings', 'Disqus Settings', 'moderate_comments', 'disqus', 'dsq_manage', plugin_dir_url(__FILE__) . 'media/images/js-icon.png');
899 }
900 add_action('admin_menu', 'dsq_add_pages',5);
901
902
903 $js_shortcode = get_option('js_shortcode');
904 if ($js_shortcode == 'yes') {
905
906 add_shortcode('js-disqus', 'add_js_disqus_div');
907 }
908
909
910 // a little jQuery goodness to get comments menu working as desired
911 function dsq_menu_admin_head() {
912 ?>
913 <script type="text/javascript">
914 jQuery(function($) {
915 // fix menu
916 var mc = $('#menu-comments');
917 mc.find('a.wp-has-submenu').attr('href', 'edit-comments.php?page=disqus').end().find('.wp-submenu li:has(a[href="edit-comments.php?page=disqus"])').prependTo(mc.find('.wp-submenu ul'));
918 // fix admin bar
919 $('#wp-admin-bar-comments').find('a.ab-item').attr('href', 'edit-comments.php?page=disqus');
920 });
921 </script>
922 <?php
923 }
924 add_action('admin_head', 'dsq_menu_admin_head');
925
926 // only active on dashboard
927 function dsq_dash_comment_counts() {
928 global $wpdb;
929 // taken from wp-includes/comment.php - WP 2.8.5
930 $count = $wpdb->get_results("
931 SELECT comment_approved, COUNT( * ) AS num_comments
932 FROM {$wpdb->comments}
933 WHERE comment_type != 'trackback'
934 AND comment_type != 'pingback'
935 GROUP BY comment_approved
936 ", ARRAY_A );
937 $total = 0;
938 $approved = array('0' => 'moderated', '1' => 'approved', 'spam' => 'spam');
939 $known_types = array_keys( $approved );
940 foreach( (array) $count as $row_num => $row ) {
941 $total += $row['num_comments'];
942 if ( in_array( $row['comment_approved'], $known_types ) && array_key_exists($row['comment_approved'], $approved) )
943 $stats[$approved[$row['comment_approved']]] = $row['num_comments'];
944 }
945
946 $stats['total_comments'] = $total;
947 foreach ( $approved as $key ) {
948 if ( empty($stats[$key]) )
949 $stats[$key] = 0;
950 }
951 $stats = (object) $stats;
952 ?>
953 <script type="text/javascript">
954 jQuery(function($) {
955 $('#dashboard_right_now').find('.b-comments a').html('<?php echo number_format($stats->total_comments); ?>').end().find('.b_approved a').html('<?php echo number_format($stats->approved); ?>').end().find('.b-waiting a').html('<?php echo number_format($stats->moderated); ?>').end().find('.b-spam a').html('<?php echo number_format($stats->spam); ?>');
956 $('#dashboard_recent_comments div.trackback').remove();
957 $('#dashboard_right_now .inside table td.last a, #dashboard_recent_comments .inside .textright a.button').attr('href', 'edit-comments.php?page=disqus');
958 });
959 </script>
960 <?php
961 }
962 function dsq_wp_dashboard_setup() {
963 add_action('admin_head', 'dsq_dash_comment_counts');
964 }
965 add_action('wp_dashboard_setup', 'dsq_wp_dashboard_setup');
966
967 function dsq_manage() {
968 if (dsq_does_need_update() && isset($_POST['upgrade'])) {
969 dsq_install();
970 }
971
972 if (dsq_does_need_update() && !isset($_POST['reset'])) {
973 include_once(dirname(__FILE__) . '/upgrade.php');
974 } else {
975 include_once(dirname(__FILE__) . '/includes/js-manage.php');
976 }
977 }
978
979 function dsq_admin_head() {
980 if (isset($_GET['page']) && $_GET['page'] == 'disqus') {
981 ?>
982 <link rel='stylesheet' href='<?php echo plugins_url( 'media/styles/manage.css', __FILE__ ); ?>' type='text/css' />
983 <link rel='stylesheet' href='<?php echo plugins_url( 'media/styles/buttons.css', __FILE__ ); ?>' type='text/css' />
984 <style type="text/css">
985 .dsq-importing, .dsq-imported, .dsq-import-fail, .dsq-exporting, .dsq-exported, .dsq-export-fail {
986 background: url(<?php echo admin_url('images/loading.gif'); ?>) left center no-repeat;
987 line-height: 16px;
988 padding-left: 20px;
989 }
990 p.status {
991 padding-top: 0;
992 padding-bottom: 0;
993 margin: 0;
994 }
995 .dsq-imported, .dsq-exported {
996 background: url(<?php echo admin_url('images/yes.png'); ?>) left center no-repeat;
997 }
998 .dsq-import-fail, .dsq-export-fail {
999 background: url(<?php echo admin_url('images/no.png'); ?>) left center no-repeat;
1000 }
1001 </style>
1002 <script type="text/javascript">
1003 jQuery(function($) {
1004 $('#dsq-tabs li').click(function() {
1005 $('#dsq-tabs li.selected').removeClass('selected');
1006 $(this).addClass('selected');
1007 $('.dsq-main, .dsq-advanced').hide();
1008 $('.' + $(this).attr('rel')).show();
1009 });
1010 if (location.href.indexOf('#adv') != -1) {
1011 $('#dsq-tab-advanced').click();
1012 }
1013 dsq_fire_export();
1014 dsq_fire_import();
1015 });
1016 dsq_fire_export = function() {
1017 var $ = jQuery;
1018 $('#dsq_export a.button, #dsq_export_retry').unbind().click(function() {
1019 $('#dsq_export').html('<p class="status"></p>');
1020 $('#dsq_export .status').removeClass('dsq-export-fail').addClass('dsq-exporting').html('Processing...');
1021 dsq_export_comments();
1022 return false;
1023 });
1024 }
1025 dsq_export_comments = function() {
1026 var $ = jQuery;
1027 var status = $('#dsq_export .status');
1028 var export_info = (status.attr('rel') || '0|' + (new Date().getTime()/1000)).split('|');
1029 $.get(
1030 '<?php echo admin_url('index.php'); ?>',
1031 {
1032 cf_action: 'export_comments',
1033 post_id: export_info[0],
1034 timestamp: export_info[1]
1035 },
1036 function(response) {
1037 switch (response.result) {
1038 case 'success':
1039 status.html(response.msg).attr('rel', response.post_id + '|' + response.timestamp);
1040 switch (response.status) {
1041 case 'partial':
1042 dsq_export_comments();
1043 break;
1044 case 'complete':
1045 status.removeClass('dsq-exporting').addClass('dsq-exported');
1046 break;
1047 }
1048 break;
1049 case 'fail':
1050 status.parent().html(response.msg);
1051 dsq_fire_export();
1052 break;
1053 }
1054 },
1055 'json'
1056 );
1057 }
1058 dsq_fire_import = function() {
1059 var $ = jQuery;
1060 $('#dsq_import a.button, #dsq_import_retry').unbind().click(function() {
1061 var wipe = $('#dsq_import_wipe').is(':checked');
1062 $('#dsq_import').html('<p class="status"></p>');
1063 $('#dsq_import .status').removeClass('dsq-import-fail').addClass('dsq-importing').html('Processing...');
1064 dsq_import_comments(wipe);
1065 return false;
1066 });
1067 }
1068 dsq_import_comments = function(wipe) {
1069 var $ = jQuery;
1070 var status = $('#dsq_import .status');
1071 var last_comment_id = status.attr('rel') || '0';
1072 $.get(
1073 '<?php echo admin_url('index.php'); ?>',
1074 {
1075 cf_action: 'import_comments',
1076 last_comment_id: last_comment_id,
1077 wipe: (wipe ? 1 : 0)
1078 },
1079 function(response) {
1080 switch (response.result) {
1081 case 'success':
1082 status.html(response.msg).attr('rel', response.last_comment_id);
1083 switch (response.status) {
1084 case 'partial':
1085 dsq_import_comments(false);
1086 break;
1087 case 'complete':
1088 status.removeClass('dsq-importing').addClass('dsq-imported');
1089 break;
1090 }
1091 break;
1092 case 'fail':
1093 status.parent().html(response.msg);
1094 dsq_fire_import();
1095 break;
1096 }
1097 },
1098 'json'
1099 );
1100 }
1101 </script>
1102 <?php
1103 // HACK: Our own styles for older versions of WordPress.
1104 global $wp_version;
1105 if ( version_compare($wp_version, '2.5', '<') ) {
1106 echo "<link rel='stylesheet' href='" . plugins_url( 'media/styles/manage-pre25.css', __FILE__ ) . "' type='text/css' />";
1107 }
1108 }
1109 }
1110 add_action('admin_head', 'dsq_admin_head');
1111
1112 /**
1113 * Sending new installation notification to developer for counting purpose.
1114 * All downloads from WordPress may not be live.
1115 * This does only once.
1116 * Update : Removed this since it shows errors for some users.
1117 if(!get_option('count_send')):
1118 add_option('count_send', 'no');
1119 endif;
1120 if((strpos($_SERVER['http_host'], 'localhost') == false) && (strpos($_SERVER['http_host'], '127.0.0.1') == false)):
1121
1122 if( get_option('count_send')!== 'yes'):
1123 $message = 'Please note, new installation of Disqus Conditional Load on -'.get_bloginfo('siteurl').'. Add this to installation count';
1124 $headers = 'From: Admin <'.get_option('admin_email').'>' . "\r\n";
1125 $mail_sent = mail('disqus@outlook.in','Installation',$message,$headerss);
1126 if ( $foo !== false ){
1127 update_option('count_send', 'yes');
1128 }
1129 endif;
1130 endif;
1131 */
1132 /**
1133 * Wrapper for built-in __() which pulls all text from
1134 * the disqus domain and supports variable interpolation.
1135 */
1136 function dsq_i($text, $params=null) {
1137 if (!is_array($params))
1138 {
1139 $params = func_get_args();
1140 $params = array_slice($params, 1);
1141 }
1142 return vsprintf(__($text, 'disqus'), $params);
1143 }
1144
1145 // catch original query
1146 function dsq_parse_query($query) {
1147 add_action('the_posts', 'dsq_add_request_post_ids', 999);
1148 }
1149 add_action('parse_request', 'dsq_parse_query');
1150
1151 // track the original request post_ids, only run once
1152 function dsq_add_request_post_ids($posts) {
1153 dsq_add_query_posts($posts);
1154 remove_action('the_posts', 'dsq_log_request_post_ids', 999);
1155 return $posts;
1156 }
1157
1158 function dsq_maybe_add_post_ids($posts) {
1159 global $DSQ_QUERY_COMMENTS;
1160 if ($DSQ_QUERY_COMMENTS) {
1161 dsq_add_query_posts($posts);
1162 }
1163 return $posts;
1164 }
1165 add_action('the_posts', 'dsq_maybe_add_post_ids');
1166
1167 function dsq_add_query_posts($posts) {
1168 global $DSQ_QUERY_POST_IDS;
1169 if (count($posts)) {
1170 foreach ($posts as $post) {
1171 $post_ids[] = intval($post->ID);
1172 }
1173 $DSQ_QUERY_POST_IDS[md5(serialize($post_ids))] = $post_ids;
1174 }
1175 }
1176
1177 // check to see if the posts in the loop match the original request or an explicit request, if so output the JS
1178 function dsq_loop_end($query) {
1179 if ( get_option('disqus_cc_fix') == '1' || !count($query->posts) || is_single() || is_page() || is_feed() || !dsq_can_replace() ) {
1180 return;
1181 }
1182 global $DSQ_QUERY_POST_IDS;
1183 foreach ($query->posts as $post) {
1184 $loop_ids[] = intval($post->ID);
1185 }
1186 $posts_key = md5(serialize($loop_ids));
1187 if (isset($DSQ_QUERY_POST_IDS[$posts_key])) {
1188 dsq_output_loop_comment_js($DSQ_QUERY_POST_IDS[$posts_key]);
1189 }
1190 }
1191 add_action('loop_end', 'dsq_loop_end');
1192
1193 // if someone has a better hack, let me know
1194 // prevents duplicate calls to count.js
1195 $_HAS_COUNTS = false;
1196
1197 function dsq_output_loop_comment_js($post_ids = null) {
1198 global $_HAS_COUNTS;
1199 if ($_HAS_COUNTS) return;
1200 $_HAS_COUNTS = true;
1201 if (count($post_ids)) {
1202 ?>
1203 <?php if(get_option('js_count_disable') == 'no'){ ?>
1204 <script type="text/javascript">
1205 // <![CDATA[
1206 var disqus_shortname = '<?php echo strtolower(get_option('disqus_forum_url')); ?>';
1207 (function () {
1208 var nodes = document.getElementsByTagName('span');
1209 for (var i = 0, url; i < nodes.length; i++) {
1210 if (nodes[i].className.indexOf('dsq-postid') != -1) {
1211 nodes[i].parentNode.setAttribute('data-disqus-identifier', nodes[i].getAttribute('rel'));
1212 url = nodes[i].parentNode.href.split('#', 1);
1213 if (url.length == 1) { url = url[0]; }
1214 else { url = url[1]; }
1215 nodes[i].parentNode.href = url + '#disqus_thread';
1216 }
1217 }
1218 var s = document.createElement('script'); s.async = true;
1219 s.type = 'text/javascript';
1220 s.src = '//' + disqus_shortname + '.<?php echo DISQUS_DOMAIN; ?>/count.js';
1221 (document.getElementsByTagName('HEAD')[0] || document.getElementsByTagName('BODY')[0]).appendChild(s);
1222 }());
1223 //]]>
1224 </script>
1225 <?php
1226 } }
1227 }
1228
1229 function dsq_output_footer_comment_js() {
1230 if (!dsq_can_replace()) return;
1231 if (get_option('disqus_cc_fix') != '1') return;
1232 ?>
1233 <?php if(get_option('js_count_disable') == 'no'){ ?>
1234 <script type="text/javascript">
1235 // <![CDATA[
1236 var disqus_shortname = '<?php echo strtolower(get_option('disqus_forum_url')); ?>';
1237 (function () {
1238 var nodes = document.getElementsByTagName('span');
1239 for (var i = 0, url; i < nodes.length; i++) {
1240 if (nodes[i].className.indexOf('dsq-postid') != -1) {
1241 nodes[i].parentNode.setAttribute('data-disqus-identifier', nodes[i].getAttribute('rel'));
1242 url = nodes[i].parentNode.href.split('#', 1);
1243 if (url.length == 1) url = url[0];
1244 else url = url[1]
1245 nodes[i].parentNode.href = url + '#disqus_thread';
1246 }
1247 }
1248 var s = document.createElement('script'); s.async = true;
1249 s.type = 'text/javascript';
1250 s.src = '//' + disqus_shortname + '.<?php echo DISQUS_DOMAIN; ?>/count.js';
1251 (document.getElementsByTagName('HEAD')[0] || document.getElementsByTagName('BODY')[0]).appendChild(s);
1252 }());
1253 //]]>
1254 </script>
1255 <?php
1256 } }
1257 add_action('wp_footer', 'dsq_output_footer_comment_js');
1258
1259 // UPDATE DSQ when a permalink changes
1260
1261 $dsq_prev_permalinks = array();
1262
1263 function dsq_prev_permalink($post_id) {
1264 $post = get_post($post_id);
1265 // if post not published, return
1266 if ($post->post_status != 'publish') {
1267 return;
1268 }
1269 global $dsq_prev_permalinks;
1270 $dsq_prev_permalinks['post_'.$post_id] = get_permalink($post_id);
1271 }
1272 add_action('pre_post_update', 'dsq_prev_permalink');
1273
1274 function dsq_check_permalink($post_id) {
1275 global $dsq_prev_permalinks;
1276 if (!empty($dsq_prev_permalinks['post_'.$post_id]) && $dsq_prev_permalinks['post_'.$post_id] != get_permalink($post_id)) {
1277 $post = get_post($post_id);
1278 dsq_update_permalink($post);
1279 }
1280 }
1281 add_action('edit_post', 'dsq_check_permalink');
1282
1283 // Only replace comments if the disqus_forum_url option is set.
1284 add_filter('comments_template', 'dsq_comments_template');
1285 add_filter('comments_number', 'dsq_comments_text');
1286 add_filter('get_comments_number', 'dsq_comments_number');
1287 add_filter('bloginfo_url', 'dsq_bloginfo_url');
1288
1289 /**
1290 * JSON ENCODE for PHP < 5.2.0
1291 * Checks if json_encode is not available and defines json_encode
1292 * to use php_json_encode in its stead
1293 * Works on iteratable objects as well - stdClass is iteratable, so all WP objects are gonna be iteratable
1294 */
1295 if(!function_exists('cf_json_encode')) {
1296 function cf_json_encode($data) {
1297 // json_encode is sending an application/x-javascript header on Joyent servers
1298 // for some unknown reason.
1299 // if(function_exists('json_encode')) { return json_encode($data); }
1300 // else { return cfjson_encode($data); }
1301 return cfjson_encode($data);
1302 }
1303
1304 function cfjson_encode_string($str) {
1305 if(is_bool($str)) {
1306 return $str ? 'true' : 'false';
1307 }
1308
1309 return str_replace(
1310 array(
1311 '"'
1312 , '/'
1313 , "\n"
1314 , "\r"
1315 )
1316 , array(
1317 '\"'
1318 , '\/'
1319 , '\n'
1320 , '\r'
1321 )
1322 , $str
1323 );
1324 }
1325
1326 function cfjson_encode($arr) {
1327 $json_str = '';
1328 if (is_array($arr)) {
1329 $pure_array = true;
1330 $array_length = count($arr);
1331 for ( $i = 0; $i < $array_length ; $i++) {
1332 if (!isset($arr[$i])) {
1333 $pure_array = false;
1334 break;
1335 }
1336 }
1337 if ($pure_array) {
1338 $json_str = '[';
1339 $temp = array();
1340 for ($i=0; $i < $array_length; $i++) {
1341 $temp[] = sprintf("%s", cfjson_encode($arr[$i]));
1342 }
1343 $json_str .= implode(',', $temp);
1344 $json_str .="]";
1345 }
1346 else {
1347 $json_str = '{';
1348 $temp = array();
1349 foreach ($arr as $key => $value) {
1350 $temp[] = sprintf("\"%s\":%s", $key, cfjson_encode($value));
1351 }
1352 $json_str .= implode(',', $temp);
1353 $json_str .= '}';
1354 }
1355 }
1356 else if (is_object($arr)) {
1357 $json_str = '{';
1358 $temp = array();
1359 foreach ($arr as $k => $v) {
1360 $temp[] = '"'.$k.'":'.cfjson_encode($v);
1361 }
1362 $json_str .= implode(',', $temp);
1363 $json_str .= '}';
1364 }
1365 else if (is_string($arr)) {
1366 $json_str = '"'. cfjson_encode_string($arr) . '"';
1367 }
1368 else if (is_numeric($arr)) {
1369 $json_str = $arr;
1370 }
1371 else if (is_bool($arr)) {
1372 $json_str = $arr ? 'true' : 'false';
1373 }
1374 else {
1375 $json_str = '"'. cfjson_encode_string($arr) . '"';
1376 }
1377 return $json_str;
1378 }
1379 }
1380
1381 if ( !function_exists('js_check_shortcode') ) {
1382
1383 function js_check_shortcode($js_shortcode = '') {
1384
1385 global $post;
1386 $post_obj = get_post( $post->ID );
1387 $found = false;
1388
1389 if ( !$js_shortcode )
1390 return $found;
1391 if ( stripos( $post_obj->post_content, '[' . $js_shortcode ) !== false )
1392 $found = true;
1393
1394 return $found;
1395
1396 }
1397 }
1398
1399 // Single Sign-on Integration
1400
1401 function dsq_sso() {
1402 if ($key = get_option('disqus_partner_key')) {
1403 // use old style SSO
1404 $new = false;
1405 } elseif (($key = get_option('disqus_secret_key')) && ($public = get_option('disqus_public_key'))) {
1406 // use new style SSO
1407 $new = true;
1408 } else {
1409 // sso is not configured
1410 return array();
1411 }
1412 global $current_user, $dsq_api;
1413 get_currentuserinfo();
1414 if ($current_user->ID) {
1415 $avatar_tag = get_avatar($current_user->ID);
1416 $avatar_data = array();
1417 preg_match('/(src)=((\'|")[^(\'|")]*(\'|"))/i', $avatar_tag, $avatar_data);
1418 $avatar = str_replace(array('"', "'"), '', $avatar_data[2]);
1419 $user_data = array(
1420 'username' => $current_user->display_name,
1421 'id' => $current_user->ID,
1422 'avatar' => $avatar,
1423 'email' => $current_user->user_email,
1424 'url' => $current_user->user_url,
1425 );
1426 }
1427 else {
1428 $user_data = array();
1429 }
1430 $user_data = base64_encode(cf_json_encode($user_data));
1431 $time = time();
1432 $hmac = dsq_hmacsha1($user_data.' '.$time, $key);
1433
1434 $payload = $user_data.' '.$hmac.' '.$time;
1435
1436 if ($new) {
1437 return array('remote_auth_s3'=>$payload, 'api_key'=>$public);
1438 } else {
1439 return array('remote_auth_s2'=>$payload);
1440 }
1441 }
1442
1443 function dsq_sso_login() {
1444 global $current_site;
1445 $sitename = get_bloginfo('name');
1446 $siteurl = site_url();
1447 $button = get_option('disqus_sso_button');
1448 $icon = get_option('disqus_sso_icon');
1449 $sso_login_str = 'this.sso = {
1450 name: "'.wp_specialchars_decode($sitename, ENT_QUOTES).'",
1451 button: "'.$button.'",
1452 icon: "'.$icon.'",
1453 url: "'.$siteurl.'/wp-login.php",
1454 logout: "'.$siteurl.'/wp-login.php?action=logout",
1455 width: "800",
1456 height: "700"
1457 }';
1458 return $sso_login_str;
1459 }
1460
1461 // from: http://www.php.net/manual/en/function.sha1.php#39492
1462 // Calculate HMAC-SHA1 according to RFC2104
1463 // http://www.ietf.org/rfc/rfc2104.txt
1464 function dsq_hmacsha1($data, $key) {
1465 $blocksize=64;
1466 $hashfunc='sha1';
1467 if (strlen($key)>$blocksize)
1468 $key=pack('H*', $hashfunc($key));
1469 $key=str_pad($key,$blocksize,chr(0x00));
1470 $ipad=str_repeat(chr(0x36),$blocksize);
1471 $opad=str_repeat(chr(0x5c),$blocksize);
1472 $hmac = pack(
1473 'H*',$hashfunc(
1474 ($key^$opad).pack(
1475 'H*',$hashfunc(
1476 ($key^$ipad).$data
1477 )
1478 )
1479 )
1480 );
1481 return bin2hex($hmac);
1482 }
1483
1484 function dsq_identifier_for_post($post) {
1485 return $post->ID . ' ' . $post->guid;
1486 }
1487
1488 function dsq_title_for_post($post) {
1489 $title = get_the_title($post);
1490 $title = strip_tags($title, DISQUS_ALLOWED_HTML);
1491 return $title;
1492 }
1493
1494 function dsq_link_for_post($post) {
1495 return get_permalink($post);
1496 }
1497
1498 function dsq_does_need_update() {
1499 $version = (string)get_option('disqus_version');
1500 if (empty($version)) {
1501 $version = '0';
1502 }
1503
1504 if (version_compare($version, '2.49', '<')) {
1505 return true;
1506 }
1507
1508 return false;
1509 }
1510
1511 function dsq_install($allow_database_install=true) {
1512 global $wpdb, $userdata;
1513
1514 $version = (string)get_option('disqus_version');
1515 if (!$version) {
1516 $version = '0';
1517 }
1518
1519 if ($allow_database_install)
1520 {
1521 dsq_install_database($version);
1522 }
1523
1524 if (version_compare($version, DISQUS_VERSION, '=')) return;
1525
1526 // if this is a new install, we should not set disqus active
1527 if ($version == '0') {
1528 add_option('disqus_active', '0');
1529 } else {
1530 add_option('disqus_active', '1');
1531 }
1532
1533 update_option('disqus_version', DISQUS_VERSION);
1534 }
1535
1536
1537
1538 /**
1539 * Adds a simple WordPress pointer to Comments menu, to remind the user to configure the plugin
1540 */
1541 function dsq_enqueue_pointer_script_style( $hook_suffix ) {
1542
1543 // Assume pointer shouldn't be shown
1544 $enqueue_pointer_script_style = false;
1545
1546 // Get array list of dismissed pointers for current user and convert it to array
1547 $dismissed_pointers = explode( ',', get_user_meta( get_current_user_id(), 'dismissed_wp_pointers', true ) );
1548
1549 // Check if our pointer is not among dismissed ones
1550 if( !in_array( 'disqus_settings_pointer', $dismissed_pointers ) ) {
1551 $enqueue_pointer_script_style = true;
1552
1553 // Add footer scripts using callback function
1554 add_action( 'admin_print_footer_scripts', 'dsq_pointer_print_scripts' );
1555 }
1556
1557 // Enqueue pointer CSS and JS files, if needed
1558 if( $enqueue_pointer_script_style ) {
1559 wp_enqueue_style( 'wp-pointer' );
1560 wp_enqueue_script( 'wp-pointer' );
1561 }
1562
1563 }
1564 if (!dsq_is_installed()) {
1565 // Only show the pointer when Disqus isn't already configured
1566 add_action( 'admin_enqueue_scripts', 'dsq_enqueue_pointer_script_style' );
1567 }
1568
1569 function dsq_pointer_print_scripts() {
1570
1571 $pointer_content = '<h3>Disqus Conditional Load needs to be configured</h3>';
1572 $pointer_content .= '<p>Configure Disqus Conditional Load by clicking Comments to the left.</p>';
1573 ?>
1574
1575 <script type="text/javascript">
1576 //<![CDATA[
1577 jQuery(document).ready( function($) {
1578 $('#menu-comments').pointer({
1579 content: '<?php echo $pointer_content; ?>',
1580 position: {
1581 edge: 'left', // arrow direction
1582 align: 'center' // vertical alignment
1583 },
1584 pointerWidth: 350,
1585 close: function() {
1586 $.post( ajaxurl, {
1587 pointer: 'disqus_settings_pointer', // pointer ID
1588 action: 'dismiss-wp-pointer'
1589 });
1590 }
1591 }).pointer('open');
1592 });
1593 //]]>
1594 </script>
1595
1596 <?php
1597 }
1598
1599 /**
1600 * Initializes the database if it's not already present.
1601 */
1602 function dsq_install_database($version=0) {
1603 global $wpdb;
1604
1605 if (version_compare($version, '2.49', '<')) {
1606 $wpdb->query("CREATE INDEX disqus_dupecheck ON `".$wpdb->prefix."commentmeta` (meta_key, meta_value(11));");
1607 }
1608 }
1609 function dsq_reset_database($version=0) {
1610 global $wpdb;
1611
1612 if (version_compare($version, '2.49', '>=')) {
1613 $wpdb->query("DROP INDEX disqus_dupecheck ON `".$wpdb->prefix."commentmeta`;");
1614 }
1615 }
1616
1617 /**
1618 * Disable internal Wordpress commenting if Disqus is enabled - this prevents spam bots from
1619 * commenting using POST requests to /wp-comments-post.php.
1620 *
1621 * @param int $comment_post_ID
1622 * @return int
1623 */
1624 function dsq_pre_comment_on_post($comment_post_ID) {
1625 if (dsq_can_replace()) {
1626 wp_die( dsq_i('Sorry, the built-in commenting system is disabled because Disqus Conditional Load is active.') );
1627 }
1628 return $comment_post_ID;
1629 }
1630 add_action('pre_comment_on_post', 'dsq_pre_comment_on_post');
1631
1632 /**
1633 * Adding new sub menus to main menu tab
1634 * Main menu is added above
1635 */
1636
1637 add_action('admin_menu', 'js_advanced_menu');
1638 add_action('admin_menu', 'js_more_menu');
1639
1640 function js_advanced_menu() {
1641 add_submenu_page( 'disqus', 'Advanced Features', 'Advanced Features', 'manage_options', 'js-advanced', 'js_advanced' );
1642 }
1643 function js_more_menu() {
1644 add_submenu_page( 'disqus', 'Pro Features', 'Pro Features', 'manage_options', 'js-more', 'js_more' );
1645 }
1646 /**
1647 * Calling and including files for each sub menus
1648 * adding include oncle to prevent adding these file twice some where else.
1649 */
1650 function js_advanced() {
1651
1652 include_once( dirname(__FILE__) . '/includes/js-admin.php');
1653
1654 }
1655 function js_more() {
1656 include_once( dirname(__FILE__) . '/includes/js-more.php');
1657
1658 }
1659
1660 /**
1661 * Loading required styles
1662 * Loads only to admin pages since we do not need them on frontend
1663 * @param admin_init
1664 */
1665 add_action( 'admin_init', 'load_js_admin_styles' );
1666
1667 function load_js_admin_styles() {
1668 wp_enqueue_style( 'jspro', plugins_url('includes/parts/css/jspro.css', __FILE__));
1669 }
1670
1671 ?>