PageRenderTime 70ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 1ms

/blog/wp-content/plugins/intensedebate/intensedebate.php

https://bitbucket.org/sergiohzlz/reportaprod
PHP | 2951 lines | 2265 code | 405 blank | 281 comment | 471 complexity | 7265dc7324e3bd692a086dfe27109a04 MD5 | raw file
Possible License(s): GPL-2.0, GPL-3.0, AGPL-1.0, LGPL-2.1
  1. <?php
  2. /*
  3. Plugin Name: IntenseDebate
  4. Plugin URI: http://intensedebate.com/wordpress
  5. Description: <a href="http://www.intensedebate.com">IntenseDebate Comments</a> enhance and encourage conversation on your blog or website. Full comment and account data sync between IntenseDebate and WordPress ensures that you will always have your comments. Custom integration with your WordPress admin panel makes moderation a piece of cake. Comment threading, reply-by-email, user accounts and reputations, comment voting, along with Twitter and friendfeed integrations enrich your readers' experience and make more of the internet aware of your blog and comments which drives traffic to you! To get started, please activate the plugin and adjust your <a href="./options-general.php?page=id_settings">IntenseDebate settings</a> .
  6. Version: 2.9
  7. Author: IntenseDebate & Automattic
  8. Author URI: http://intensedebate.com
  9. */
  10. // CONSTANTS
  11. // This plugin's version
  12. define( 'ID_PLUGIN_VERSION', '2.9' );
  13. // API Endpoints
  14. define( 'ID_BASEURL', 'http://intensedebate.com' );
  15. define( 'ID_SERVICE', ID_BASEURL . '/services/v1/operations/postOperations.php' );
  16. define( 'ID_USER_LOOKUP_SERVICE', ID_BASEURL . '/services/v1/users' );
  17. define( 'ID_BLOG_LOOKUP_SERVICE', ID_BASEURL . '/services/v1/sites' );
  18. // Local queue option name
  19. define( 'ID_REQUEST_QUEUE_NAME', 'id_request_queue' );
  20. // Application identifier, passed with all API transactions
  21. define( 'ID_APPKEY', 'wpplugin' );
  22. // Minimum tested version of WordPress for this version of the plugin
  23. define( 'ID_MIN_WP_VERSION', '2.8' );
  24. // URL bases for linkage
  25. define( 'ID_COMMENT_MODERATION_PAGE', ID_BASEURL . '/wpIframe.php?acctid=' );
  26. define( 'ID_REGISTRATION_PAGE', ID_BASEURL . '/signup' );
  27. // Set to true to get a detailed log of operations in your error_log
  28. define( 'ID_DEBUG', false );
  29. // Pre WP 2.6 compatibility
  30. if ( ! defined( 'WP_CONTENT_URL' ) )
  31. define( 'WP_CONTENT_URL', get_option( 'siteurl' ) . '/wp-content' );
  32. if ( ! defined( 'WP_PLUGIN_URL' ) )
  33. define( 'WP_PLUGIN_URL', WP_CONTENT_URL . '/plugins' );
  34. // Load textdomain for internationalization
  35. load_plugin_textdomain( 'intensedebate' );
  36. // Global var to ensure link wrapper script only outputs once
  37. $id_link_wrapper_output = false;
  38. // Override core mail notification functions with stubs
  39. if ( !function_exists( 'wp_notify_postauthor' ) ) {
  40. function wp_notify_postauthor() { }
  41. }
  42. if ( !function_exists( 'wp_notify_moderator' ) ) {
  43. function wp_notify_moderator() { }
  44. }
  45. // JSON support
  46. function id_got_json() {
  47. // WP 2.9+ handles everything for us
  48. if ( version_compare( get_bloginfo( 'version' ), '2.9', '>=' ) )
  49. return true;
  50. // Functions exists already, assume they're good to go
  51. if ( function_exists( 'json_encode' ) && function_exists( 'json_decode' ) )
  52. return true;
  53. // Load Services_JSON if we need it at this point
  54. if ( !class_exists( 'Services_JSON' ) )
  55. include_once( dirname( __FILE__ ) . '/class.json.php' );
  56. // This indicates that we need to define the functions.
  57. // Services_JSON *is* available one way or another at this point
  58. return false;
  59. }
  60. if ( !id_got_json() ) {
  61. function json_encode( $data ) {
  62. $json = new Services_JSON();
  63. return( $json->encode( $data ) );
  64. }
  65. function json_decode( $data ) {
  66. $json = new Services_JSON();
  67. return( $json->decode( $data ) );
  68. }
  69. }
  70. function id_get_user_meta( $id, $val ) {
  71. if ( function_exists( 'get_user_meta' ) )
  72. return get_user_meta( $id, $val, true );
  73. return get_usermeta( $id, $val );
  74. }
  75. function id_delete_user_meta( $id, $val ) {
  76. if ( function_exists( 'delete_user_meta' ) )
  77. return delete_user_meta( $id, $val );
  78. return delete_usermeta( $id, $val );
  79. }
  80. function id_get_author_name() {
  81. if ( function_exists( 'get_the_author_meta' ) )
  82. return get_the_author_meta( 'display_name' );
  83. return get_author_name();
  84. }
  85. // Debug logging
  86. function id_debug_log( $text ) {
  87. if ( defined( 'ID_DEBUG' ) && true === ID_DEBUG ) {
  88. error_log( 'ID/' . ID_PLUGIN_VERSION . ': ' . $text );
  89. }
  90. }
  91. // HOOK ASSIGNMENT
  92. function id_activate_hooks() {
  93. global $wpmu_version;
  94. // warning that we don't support this version of WordPress
  95. if ( empty( $wpmu_version ) && version_compare( get_bloginfo( 'version' ), ID_MIN_WP_VERSION, '<' ) ) {
  96. add_action( 'admin_head', 'id_wordpress_version_warning' );
  97. return;
  98. }
  99. // hooks onto incoming requests
  100. add_action( 'init', 'id_request_handler' );
  101. // IntenseDebate individual settings
  102. add_action( 'admin_notices', 'id_admin_notices' );
  103. // IntenseDebate server settings
  104. add_action( 'admin_menu', 'id_menu_items' );
  105. add_action( 'init', 'id_process_settings_page' );
  106. if ( id_do_admin_hooks() ) {
  107. // scripts for admin settings page
  108. add_action( "admin_head", 'id_settings_head' );
  109. // allow options.php to handle updates in WPMU and future WP versions
  110. add_filter( 'whitelist_options', 'id_whitelist_options' );
  111. // add comment counts in best way available
  112. if ( id_is_active() ) {
  113. if ( version_compare( get_bloginfo( 'version' ), '2.8', '>=' ) )
  114. add_action( 'admin_print_footer_scripts', 'id_get_comment_footer_script', 21 );
  115. else
  116. add_action( 'admin_footer', 'id_get_comment_footer_script', 100 );
  117. }
  118. }
  119. if ( is_admin() ) {
  120. // Always add comment moderation count in the admin area
  121. if ( version_compare( get_bloginfo( 'version' ), '2.8', '>=' ) )
  122. add_action( 'admin_print_footer_scripts', 'id_admin_footer', 21 );
  123. else
  124. add_action( 'admin_footer', 'id_admin_footer', 100 );
  125. }
  126. if ( id_is_active() ) {
  127. // crud hooks
  128. add_action( 'wp_insert_comment', 'id_save_comment' );
  129. add_action( 'trackback_post', 'id_save_comment' );
  130. add_action( 'pingback_post', 'id_save_comment' );
  131. add_action( 'edit_comment', 'id_save_comment' );
  132. add_action( 'save_post', 'id_save_post' );
  133. add_action( 'delete_post', 'id_delete_post' );
  134. add_action( 'wp_set_comment_status', 'id_comment_status', 10, 2 );
  135. add_action( 'trashed_comment', 'id_comment_trashed', 10 );
  136. add_action( 'untrashed_comment', 'id_comment_untrashed', 10 );
  137. // individual registration
  138. add_action( 'show_user_profile', 'id_show_user_profile' );
  139. add_action( 'profile_update', 'id_profile_update' );
  140. // Settings > Discussion sync
  141. add_action( 'load-options.php', 'id_discussion_settings_page' );
  142. // Load ID comment template
  143. if ( 0 == get_option( 'id_useIDComments') ) {
  144. if ( !id_is_mobile() || ( id_is_mobile() && 0 != get_option( 'id_revertMobile' ) ) ) {
  145. add_filter( 'comments_template', 'id_comments_template' );
  146. // swap out the comment count links
  147. add_filter( 'comments_number', 'id_get_comment_number' );
  148. add_action( 'wp_footer', 'id_get_comment_footer_script', 21 );
  149. add_action( 'get_footer', 'id_get_comment_footer_script', 100 );
  150. }
  151. }
  152. // Disable email notifications properly
  153. add_filter( 'option_moderation_notify', create_function( '$a', 'return 0;' ) );
  154. add_filter( 'option_comments_notify', create_function( '$a', 'return 0;' ) );
  155. }
  156. if ( id_is_active() || id_queue_not_empty() ) {
  157. // fires the outgoing HTTP request queue for ID synching
  158. add_action( 'shutdown', 'id_ping_queue' );
  159. }
  160. }
  161. // only load ID resources where they're needed
  162. function id_do_admin_hooks() {
  163. if ( !is_admin() )
  164. return false;
  165. $basename = basename( $_SERVER['PHP_SELF'] );
  166. // ID Comment moderation
  167. if ( 'admin.php' == $basename && !empty( $_REQUEST['page'] ) && 'intensedebate' == $_REQUEST['page'] )
  168. return true;
  169. // ID Settings page
  170. if ( 'options-general.php' == $basename && !empty( $_REQUEST['page'] ) && 'id_settings' == $_REQUEST['page'] )
  171. return true;
  172. // Whitelisted files
  173. if ( in_array( $basename, array( 'profile.php', 'options.php' ) ) )
  174. return true;
  175. // Posts/Pages when ID comment links are enabled
  176. if ( 0 == get_option( 'id_jsCommentLinks' ) && ( 'edit.php' == $basename || 'edit-pages.php' == $basename ) )
  177. return true;
  178. return false;
  179. }
  180. // adds new menu options to wp admin
  181. function id_menu_items() {
  182. // Replace the default Comments menu with the ID-enhanced one
  183. if ( id_is_active() && 0 == get_option( 'id_moderationPage' ) ) {
  184. global $menu;
  185. if ( function_exists( 'add_object_page' ) ) { // WP 2.7+
  186. unset( $menu[25] );
  187. add_object_page(
  188. __( 'Comments', 'intensedebate' ),
  189. __( 'Comments', 'intensedebate' ),
  190. 'moderate_comments',
  191. 'intensedebate',
  192. 'id_moderate_comments',
  193. WP_CONTENT_URL . '/plugins/intensedebate/comments.png'
  194. );
  195. } else { // < WP 2.7
  196. unset( $menu[20] );
  197. add_menu_page(
  198. __( 'Comments', 'intensedebate' ),
  199. __( 'Comments', 'intensedebate' ),
  200. 'moderate_comments',
  201. 'intensedebate',
  202. 'id_moderate_comments'
  203. );
  204. }
  205. }
  206. add_options_page(
  207. __( 'IntenseDebate Settings', 'intensedebate' ),
  208. 'IntenseDebate',
  209. 'manage_options',
  210. 'id_settings',
  211. 'id_settings_page'
  212. );
  213. if ( !get_option( 'id_pdxsync' ) )
  214. id_clear_orphan_comments();
  215. }
  216. function id_whitelist_options( $options ) {
  217. $options['intensedebate'] = array( 'id_auto_login', 'id_moderationPage', 'id_useIDComments', 'id_jsCommentLinks', 'id_revertMobile' );
  218. return $options;
  219. }
  220. function id_activate() {
  221. update_option( 'thread_comments', 1 );
  222. }
  223. register_activation_hook( __FILE__, 'id_activate' );
  224. function id_deactivate() {
  225. $fields = array(
  226. 'appKey' => ID_APPKEY,
  227. 'blogKey' => get_option( 'id_blogKey' ),
  228. 'blogid' => get_option( 'id_blogID' ),
  229. );
  230. $queue = id_get_queue();
  231. $op = $queue->add( 'plugin_deactivated', $fields, 'id_generic_callback' );
  232. $queue->ping( array( $op ) );
  233. }
  234. register_deactivation_hook( __FILE__, 'id_deactivate' );
  235. // UTILITIES
  236. // Load Snoopy if WP HTTP isn't here, and Snoopy's not already loaded (< WP 2.7 compat)
  237. if ( !function_exists( 'wp_remote_get' ) && !function_exists( 'get_snoopy' ) ) {
  238. function get_snoopy() {
  239. include_once( ABSPATH.'/wp-includes/class-snoopy.php' );
  240. return new Snoopy;
  241. }
  242. }
  243. function id_http_query( $url, $fields, $method = 'GET' ) {
  244. $results = '';
  245. if ( function_exists( 'wp_remote_get' ) ) {
  246. // The preferred WP HTTP library is available
  247. if ( 'POST' == $method ) {
  248. $response = wp_remote_post( $url, array( 'body' => $fields ) );
  249. if ( !is_wp_error( $response ) ) {
  250. $results = wp_remote_retrieve_body( $response );
  251. id_debug_log( "Successfully Sent: " . serialize( $fields ) . " - " . $results );
  252. } else {
  253. id_debug_log( "Failed to Send: " . serialize( $fields ) . " - " . $response->get_error_message() );
  254. }
  255. } else {
  256. $url .= '?' . http_build_query( $fields );
  257. $response = wp_remote_get( $url );
  258. if ( !is_wp_error( $response ) ) {
  259. $results = wp_remote_retrieve_body( $response );
  260. id_debug_log( "Successfully Sent: " . serialize( $fields ) . " - " . $results );
  261. } else {
  262. id_debug_log( "Failed to Send: " . serialize( $fields ) . " - " . $response->get_error_message() );
  263. }
  264. }
  265. } else {
  266. // Fall back to Snoopy
  267. $snoopy = get_snoopy();
  268. if ( 'POST' == $method ) {
  269. if ( $snoopy->submit( $url, $fields ) ) {
  270. $results = $snoopy->results;
  271. id_debug_log( "Successfully Sent: " . serialize( $fields ) . " - " . $results );
  272. } else {
  273. id_debug_log( "Failed to Send: " . serialize( $fields ) . " - " . $results );
  274. }
  275. } else {
  276. $url .= '?' . http_build_query( $fields );
  277. if ( $snoopy->fetch( $url ) ) {
  278. $results = $snoopy->results;
  279. id_debug_log( "Successfully Sent: " . serialize( $fields ) . " - " . $results );
  280. } else {
  281. id_debug_log( "Failed to Send: " . serialize( $fields ) . " - " . $results );
  282. }
  283. }
  284. }
  285. return $results;
  286. }
  287. // blog option
  288. function id_save_option( $name, $value ) {
  289. global $wpmu_version;
  290. if ( false === get_option( $name ) && empty( $wpmu_version ) ) { // Avoid WPMU options cache bug
  291. add_option( $name, $value, '', 'no' );
  292. } else {
  293. update_option( $name, $value );
  294. }
  295. id_debug_log( 'Save option: ' . $name . ' = ' . print_r( $value, true ) );
  296. }
  297. // user options
  298. function id_save_usermeta_array( $user_id, $meta = array() ) {
  299. foreach( $meta as $n => $v ) {
  300. id_save_usermeta( $user_id, $n, $v );
  301. }
  302. }
  303. // saves or wipes an individual meta field
  304. function id_save_usermeta( $user_id, $name, $value = null ) {
  305. if ( isset( $value ) && !empty( $value ) ) {
  306. update_usermeta( $user_id, $name, $value );
  307. } else {
  308. id_delete_user_meta( $user_id, $name );
  309. }
  310. }
  311. function id_user_connected() {
  312. $current_user = wp_get_current_user();
  313. $user_id = $current_user->ID;
  314. $userID = id_get_user_meta( $user_id, 'id_userID' );
  315. $userKey = id_get_user_meta( $user_id, 'id_userKey' );
  316. return ( $userID && $userKey );
  317. }
  318. // returns first non-null and non empty argment
  319. function id_coalesce() {
  320. $args = func_get_args();
  321. foreach ( $args as $v ) {
  322. if ( isset( $v ) && !empty( $v ) )
  323. return $v;
  324. }
  325. return null;
  326. }
  327. // hash generator
  328. function id_generate_token( $fields ) {
  329. return md5( time() . implode( '&', $fields ) );
  330. }
  331. // determines whether ID has been activated via the settings page
  332. function id_is_active() {
  333. return (
  334. get_option( 'id_blogID' ) &&
  335. get_option( 'id_blogKey' ) &&
  336. get_option( 'id_userID' ) &&
  337. get_option( 'id_userKey' ) &&
  338. get_option( 'id_blogAcct' )
  339. );
  340. }
  341. // pulls a passed parameter from indicated scopes
  342. function id_param( $name, $default = null, $scopes = null ) {
  343. if ( $scopes == null ) {
  344. $scopes = array( $_POST, $_GET );
  345. }
  346. foreach ( $scopes as $thisScope ) {
  347. if ( isset( $thisScope[$name] ) ) {
  348. return $thisScope[$name];
  349. }
  350. }
  351. return $default;
  352. }
  353. // inits queue object
  354. function id_get_queue() {
  355. global $id_q;
  356. if ( !$id_q ) {
  357. $id_q = new id_queue();
  358. }
  359. return $id_q;
  360. }
  361. // pings queue object
  362. function id_ping_queue() {
  363. $queue = id_get_queue();
  364. $queue->ping();
  365. }
  366. function id_queue_not_empty() {
  367. $queue = id_get_queue();
  368. $queue->load();
  369. if ( count( $queue->operations ) ) {
  370. return true;
  371. }
  372. else {
  373. return false;
  374. }
  375. }
  376. // deconstructs query string
  377. if ( !function_exists( 'http_parse_query' ) ) {
  378. function http_parse_query( $array = NULL, $convention = '%s' ) {
  379. if ( count( $array ) == 0 ) {
  380. return '';
  381. } else {
  382. if ( function_exists( 'http_build_query' ) ) {
  383. $query = http_build_query( $array );
  384. } else {
  385. $query = '';
  386. foreach ( $array as $key => $value ) {
  387. if ( is_array( $value ) ) {
  388. $new_convention = sprintf( $convention, $key ) . '[%s]';
  389. $query .= http_parse_query( $value, $new_convention );
  390. } else {
  391. $key = urlencode( $key );
  392. $value = urlencode( $value );
  393. $query .= sprintf( $convention, $key ) . "=$value&";
  394. }
  395. }
  396. }
  397. return $query;
  398. }
  399. }
  400. }
  401. // CRUD OPERATION HOOKS
  402. function id_save_comment( $comment_ID = 0 ) {
  403. if ( 0 == $comment_ID )
  404. return;
  405. $comment = new id_comment( array( 'comment_ID' => $comment_ID ) );
  406. $comment->loadFromWP();
  407. if ( $comment->comment_approved != 'spam' ) {
  408. // Don't send the spam
  409. $queue = id_get_queue();
  410. $queue->add( 'save_comment', $comment->export(), 'id_generic_callback' );
  411. }
  412. }
  413. function id_comment_status( $comment_id, $status ) {
  414. if ( $status == "delete" ) {
  415. $packet = new stdClass;
  416. $packet->comment_id = $comment_id;
  417. $packet->status = $status;
  418. $queue = id_get_queue();
  419. $queue->add( 'update_comment_status', $packet, 'id_generic_callback' );
  420. } else {
  421. $comment = new id_comment( array( 'comment_ID' => $comment_id ) );
  422. $comment->loadFromWP();
  423. if ( $status == "hold" )
  424. $comment->comment_approved = 0;
  425. if ( $status == "approve" )
  426. $comment->comment_approved = 1;
  427. if ( $status == "spam" )
  428. $comment->comment_approved = "spam";
  429. $queue = id_get_queue();
  430. $queue->add( 'save_comment', $comment->export(), 'id_generic_callback' );
  431. }
  432. }
  433. // Trash in WP == delete on ID
  434. function id_comment_trashed( $comment_id ) {
  435. id_comment_status( $comment_id, 'delete' );
  436. }
  437. // Untrash on WP == new comment on ID
  438. function id_comment_untrashed( $comment_id ) {
  439. id_save_comment( $comment_id );
  440. }
  441. function id_save_post( $post_id ) {
  442. $post = get_post( $post_id );
  443. if ( 0 == $post->post_parent || 'page' == $post->post_type ) {
  444. $p = new id_post( $post );
  445. $packet = $p->export();
  446. $queue = id_get_queue();
  447. $queue->add( 'save_post', $packet, 'id_generic_callback' );
  448. }
  449. }
  450. function id_delete_post( $post_id ) {
  451. $packet = new stdClass;
  452. $packet->post_id = $post_id;
  453. $queue = id_get_queue();
  454. $queue->add( 'delete_post', $packet, 'id_generic_callback' );
  455. }
  456. // callbacks return true to remove from queue
  457. function id_generic_callback( $result, $response, $operation ) {
  458. $args = func_get_args();
  459. if ( $result ) return true;
  460. if ( $response['attempt_retry'] ) return false;
  461. return true;
  462. }
  463. // DATA WRAPPERS
  464. class id_data_wrapper {
  465. var $properties = array();
  466. // generic constructor. You can pass in an array/stdClass of
  467. // values for $props and prepopulate your object either using
  468. // local or remote names
  469. function id_data_wrapper( $props = null, $bRemoteLabels = false ) {
  470. if ( isset( $props ) ) {
  471. if ( $bRemoteLabels ) {
  472. $this->loadFromRemote( $props );
  473. } else {
  474. $this->loadFromLocal( $props );
  475. }
  476. }
  477. }
  478. // registers a property with the object. $localname is the WordPress column
  479. // name and also the internal property name, $remoteName is the ID field name
  480. function addProp( $localName, $remoteName = null, $defaultValue = null ) {
  481. $remoteName = isset( $remoteName ) ? $remoteName : $localName;
  482. $this->properties[$localName] = $remoteName;
  483. $this->$localName = $defaultValue;
  484. }
  485. // loads object with props from passed object, assumption is that the passed
  486. // object is keyed using local variable names
  487. function loadFromLocal( $o ) {
  488. $incomingProps = $this->scrubInputHash($o);
  489. foreach ( $this->properties as $local => $remote ) {
  490. if ( isset( $incomingProps[$local] ) ) {
  491. $this->$local = $incomingProps[$local];
  492. }
  493. }
  494. }
  495. // loads object with props from remote object hash
  496. function loadFromRemote( $o ) {
  497. $props = array_flip( $this->properties );
  498. $incomingProps = $this->scrubInputHash( $o );
  499. foreach( $props as $remote => $local ) {
  500. if ( isset( $incomingProps[$remote] ) ) {
  501. $this->$local = $incomingProps[$remote];
  502. }
  503. }
  504. }
  505. // makes an array out of whatever is passed in
  506. function scrubInputHash( $o ) {
  507. $incomingProps = $o;
  508. if ( !is_array( $o ) ) {
  509. $incomingProps = get_object_vars( $o );
  510. }
  511. return $incomingProps;
  512. }
  513. function loadFromRemoteJson( $jsonString ) {
  514. $o = json_decode( $jsonString );
  515. $this->loadFromRemote( $o );
  516. }
  517. // exports object properties into remote property names
  518. function export( $bRemote = true ) {
  519. $o = array();
  520. foreach ( $this->properties as $local => $remote ) {
  521. if ( $remote == "comment_text" )
  522. $o[$remote] = trim( $this->$local ); // trim the comment text
  523. else
  524. $o[$remote] = $this->$local;
  525. }
  526. return $o;
  527. }
  528. function props() {
  529. $props = array();
  530. foreach ( $this->properties as $n => $v ) {
  531. $props[$n] = $this->$n;
  532. }
  533. return $props;
  534. }
  535. }
  536. // COMMENT WRAPPER
  537. class id_comment extends id_data_wrapper {
  538. var $post = null;
  539. function id_comment( $props = null, $bRemoteLabels = false ) {
  540. $this->addProp( 'intensedebate_id' );
  541. $this->addProp( 'comment_ID', 'comment_id' );
  542. $this->addProp( 'comment_post_ID', 'comment_post_id' );
  543. $this->addProp( 'comment_author' );
  544. $this->addProp( 'comment_author_email' );
  545. $this->addProp( 'comment_author_url' );
  546. $this->addProp( 'comment_author_IP', 'comment_author_ip' );
  547. $this->addProp( 'comment_date' );
  548. $this->addProp( 'comment_date_gmt' );
  549. $this->addProp( 'comment_content', 'comment_text' );
  550. // $this->addProp( 'comment_karma' );
  551. $this->addProp( 'comment_approved', 'comment_status' );
  552. $this->addProp( 'comment_agent' );
  553. $this->addProp( 'comment_type' );
  554. $this->addProp( 'comment_parent' );
  555. $this->addProp( 'user_id' );
  556. $this->id_data_wrapper( $props, $bRemoteLabels );
  557. }
  558. // loadFromWP
  559. // loads comment from WP database
  560. function loadFromWP() {
  561. if ( $this->comment_ID ) {
  562. $wp_comment = get_comment( $this->comment_ID, ARRAY_A );
  563. $this->loadFromLocal( $wp_comment );
  564. }
  565. }
  566. // saves back to WP database
  567. function save() {
  568. // Invalid comment?
  569. if ( !$this->valid() )
  570. return false;
  571. if ( empty( $this->comment_date ) && !empty( $this->comment_date_gmt ) )
  572. $this->comment_date = get_date_from_gmt( $this->comment_date_gmt );
  573. $result = 0;
  574. remove_action( 'edit_comment', 'id_save_comment' );
  575. remove_action( 'wp_insert_comment', 'id_save_comment' );
  576. if ( $this->comment_ID && get_comment( $this->comment_ID ) ) { // Added by duplicateCheck() if matched against existing comment
  577. $result = wp_update_comment( $this->props() );
  578. } else {
  579. $result = wp_insert_comment( wp_filter_comment( $this->props() ) );
  580. if ( !$result ) {
  581. add_action( 'edit_comment', 'id_save_comment' );
  582. add_action( 'wp_insert_comment', 'id_save_comment' );
  583. return false;
  584. }
  585. $this->comment_ID = $result;
  586. }
  587. add_action( 'edit_comment', 'id_save_comment' );
  588. add_action( 'wp_insert_comment', 'id_save_comment' );
  589. return true;
  590. }
  591. // evaluates whether the comment is valid
  592. function valid() {
  593. $this->duplicateCheck();
  594. return ( !empty( $this->comment_content ) && is_numeric( $this->comment_post_ID ) );
  595. }
  596. // based on code in wp_allow_comment, updates internal reference so that updates happen on duplicates
  597. function duplicateCheck() {
  598. global $wpdb;
  599. extract( $this->props() );
  600. // SQL to check for duplicate comment post
  601. $dupe = $wpdb->prepare( "SELECT comment_ID FROM $wpdb->comments WHERE comment_post_ID = %d AND ( comment_author = %s ", $comment_post_ID, $comment_author );
  602. if ( $comment_author_email )
  603. $dupe .= $wpdb->prepare( "OR comment_author_email = %s ", $comment_author_email );
  604. $dupe .= $wpdb->prepare( ") AND comment_content = %s LIMIT 1", $comment_content );
  605. // Duplicates don't actually cause an error, they just update the comment_ID internally to force an update
  606. if ( $id = $wpdb->get_var( $dupe ) )
  607. $this->comment_ID = $id;
  608. }
  609. // associated post parent object
  610. function post() {
  611. if ( !$this->post ) {
  612. $this->post = new id_post( get_post( $this->comment_post_ID, ARRAY_A ) );
  613. }
  614. return $this->post;
  615. }
  616. function export() {
  617. $o = parent::export();
  618. $p = $this->post();
  619. $o['post'] = $p->export();
  620. return $o;
  621. }
  622. // the intensedebate_id actually has to be stored with the post because
  623. // there is no comment metadata
  624. function intensedebate_id( $intensedebate_id = null ) {
  625. $post = $this->post();
  626. return $post->setRemoteID( $this->comment_ID, $intensedebate_id );
  627. }
  628. }
  629. // POST WRAPPER
  630. class id_post extends id_data_wrapper {
  631. function id_post( $props = null, $bRemoteLabels = false ) {
  632. $this->addProp( 'ID', 'postid' );
  633. $this->addProp( 'post_title', 'title' );
  634. $this->addProp( 'guid' );
  635. $this->addProp( 'url' );
  636. $this->addProp( 'post_author_name', 'author' );
  637. $this->addProp( 'post_author', 'authorid' );
  638. $this->addProp( 'post_modified_gmt', 'date_gmt' );
  639. $this->addProp( 'comment_status' );
  640. $this->addProp( 'ping_status' );
  641. // load passed props
  642. $this->id_data_wrapper( $props, $bRemoteLabels );
  643. // load up inferred props
  644. $this->loadProprietaryProps();
  645. }
  646. function loadProprietaryProps() {
  647. if ( $this->post_author ) {
  648. $a = get_userdata( $this->post_author );
  649. $this->post_author_name = trim( $a->display_name );
  650. }
  651. }
  652. // need the category names in an array
  653. function categories() {
  654. if ( function_exists( 'wp_get_post_categories' ) ) {
  655. $category_ids = (array) wp_get_post_categories( $this->ID );
  656. $categories = array();
  657. foreach ( $category_ids as $id ) {
  658. $c = get_category( $id );
  659. $categories[] = $c->cat_name;
  660. }
  661. } else {
  662. global $wpdb;
  663. $results = $wpdb->get_results( $wpdb->prepare( "SELECT c.cat_name FROM {$wpdb->categories} c, {$wpdb->post2cat} pc WHERE pc.category_id = c.cat_ID AND pc.post_id = %d", $this->ID ), ARRAY_A );
  664. $categories = array();
  665. foreach ( $results as $row ) {
  666. $categories[] = $row['cat_name'];
  667. }
  668. }
  669. return $categories;
  670. }
  671. function comments() {
  672. return null;
  673. }
  674. function export() {
  675. $me = parent::export();
  676. $me['comments'] = $this->comments();
  677. $me['categories'] = $this->categories();
  678. $me['url'] = get_permalink( $this->ID );
  679. return $me;
  680. }
  681. function mapCategory( $categoryID ) {
  682. $c = get_category( $categoryID );
  683. return $c->name;
  684. }
  685. function mapComment( $o ) {
  686. return $o->comment_ID;
  687. }
  688. function save() {
  689. if ( !$this->valid() )
  690. return false;
  691. // watch for text-link-ads.com plugin
  692. if ( function_exists( "tla_send_updated_post_alert" ) )
  693. remove_action( 'edit_post', 'tla_send_updated_post_alert' );
  694. remove_action( 'save_post', 'id_save_post' );
  695. $result = wp_update_post( get_object_vars( $this ) );
  696. add_action( 'save_post', 'id_save_post' );
  697. // add hooks for text-link-ads.com back in
  698. if ( function_exists( "tla_send_updated_post_alert" ) )
  699. add_action( 'edit_post', 'tla_send_updated_post_alert' );
  700. return $result;
  701. }
  702. function valid() {
  703. return $this->ID;
  704. }
  705. }
  706. // QUEUE
  707. class id_queue_operation {
  708. var $action, $callback, $operation_id, $time_gmt, $data, $response, $success;
  709. function id_queue_operation( $action, $data, $callback = null ) {
  710. $this->action = $action;
  711. $this->callback = $callback;
  712. $this->data = $data;
  713. $this->time_gmt = gmdate( "Y-m-d H:i:s" );
  714. $this->operation_id = $this->id();
  715. $this->success = false;
  716. $this->wp_version = get_bloginfo( 'version' );
  717. $this->id_plugin_version = ID_PLUGIN_VERSION;
  718. }
  719. function id() {
  720. return md5( $this->action . $this->callback . $this->time_gmt . serialize( $this->data ) );
  721. }
  722. }
  723. class id_queue {
  724. var $queueName = ID_REQUEST_QUEUE_NAME;
  725. var $url = ID_SERVICE;
  726. var $operations = array();
  727. var $needs_save = false;
  728. function id_queue() {
  729. $this->load();
  730. }
  731. function load() {
  732. $this->operations = get_option( $this->queueName );
  733. if ( !is_array( $this->operations ) ) {
  734. $this->create();
  735. }
  736. }
  737. function create() {
  738. $this->operations = array();
  739. }
  740. function store() {
  741. if ( $this->needs_save ) {
  742. $this->compact_operations();
  743. id_save_option( $this->queueName, $this->operations );
  744. }
  745. }
  746. function compact_operations() {
  747. $num_ops = count( $this->operations );
  748. for ( $o = 0; $o < $num_ops; $o++ ) {
  749. if ( in_array( $this->operations[ $o ]->action, array( 'save_comment', 'comment_status' ) ) && isset( $this->operations[ $o ]->data['comment_id'] ) ) {
  750. $this->operations[ $o ]->data = array( 'comment_id' => $this->operations[ $o ]->data['comment_id'] );
  751. }
  752. }
  753. }
  754. function add( $action, $data, $callback = null ) {
  755. $op = new id_queue_operation( $action, $data, $callback );
  756. return $this->queue( $op );
  757. }
  758. function queue( $operation ) {
  759. $this->needs_save = true;
  760. if ( in_array( $operation->action, array( 'save_comment', 'comment_status' ) ) && isset( $operation->data->comment_id ) )
  761. $operation->data = array( 'comment_id' => $operation->data->comment_id );
  762. $this->operations[] = $operation;
  763. return $operation;
  764. }
  765. function ping( $operations = null ) {
  766. $this->process( $this->send( $operations ) );
  767. $this->store();
  768. }
  769. function send( $operations = null ) {
  770. if ( null == $operations )
  771. $operations = $this->operations;
  772. if ( !count( $operations ) )
  773. return false;
  774. if ( get_option( 'id_lock_queue' ) && get_option( 'id_lock_queue' ) > time() )
  775. return false;
  776. // Filter out/limit requests
  777. $count = 0;
  778. $send = array();
  779. $hold = array();
  780. foreach ( $operations as $op ) {
  781. // Got enough requests for this time?
  782. // Sent less than 30s ago?
  783. if ( $count >= 10 || ( !empty( $op->running ) && ( time() - $op->running < 30 ) ) ) {
  784. $hold[] = $op;
  785. continue;
  786. }
  787. // Refresh comment data for certain requests
  788. if ( !empty( $op->action )
  789. && in_array( $op->action, array( 'save_comment', 'comment_status' ) )
  790. && !empty( $op->data )
  791. && isset( $op->data[ 'comment_id' ] )
  792. && ( substr( gmdate( 'Y-m-d H:i:s' ), 0, 18 ) != substr( $op->time_gmt, 0, 18 ) || empty( $op->data['comment_text'] ) ) ) { // Reload if not from this minute or if no comment text
  793. $comment = new id_comment( array( 'comment_ID' => $op->data[ 'comment_id' ] ) );
  794. $comment->loadFromWP();
  795. $data = $comment->export();
  796. $op->data = $data;
  797. }
  798. // Send this one along with a timestamp to avoid doubling up
  799. $op->running = time();
  800. $send[] = $op;
  801. $count++;
  802. }
  803. // Update queue to save timestamps
  804. $this->needs_save = true;
  805. $this->operations = array_merge( $hold, $send );
  806. $fields = array(
  807. 'appKey' => ID_APPKEY,
  808. 'blogKey' => get_option( 'id_blogKey' ),
  809. 'blogid' => get_option( 'id_blogID' ),
  810. 'operations' => json_encode( $send )
  811. );
  812. $this->store();
  813. if ( !count( $send ) )
  814. return false;
  815. return id_http_query( $this->url . '?blogid=' . urlencode( get_option( 'id_blogID' ) ), $fields, 'POST' );
  816. }
  817. function process( $rawResults ) {
  818. // HTTP request failed? Leave queue alone and attempt to resend later
  819. if ( false == $rawResults )
  820. return;
  821. // Need to update queue when we're done
  822. $this->needs_save = true;
  823. // Decode results string
  824. $results = json_decode( $rawResults );
  825. // flip the array around using operation_id as the key
  826. $results = $this->reIndex( $results, 'operation_id' );
  827. // loop through current queue and see if there are results for them
  828. $newQueue = array();
  829. foreach ( $this->operations as $operation ) {
  830. if ( isset( $results[ $operation->operation_id ] ) ) {
  831. $result = $results[ $operation->operation_id ];
  832. if ( isset( $operation->callback ) && function_exists( $operation->callback ) ) {
  833. // callback returns true == remove from queue
  834. // callback returns false == add back to queue
  835. $finished = call_user_func_array( $operation->callback, array( "result" => &$result->result, "response" => &$result->response, "operation" => &$operation ) );
  836. $operation->success = $finished;
  837. $operation->response = $result->response;
  838. if ( !$finished ) {
  839. $newQueue[] = $operation;
  840. }
  841. }
  842. } else {
  843. // no result returned for that operation, requeue
  844. $newQueue[] = $operation;
  845. }
  846. }
  847. // store new queue
  848. $this->operations = $newQueue;
  849. }
  850. function testResults() {
  851. $results = array();
  852. foreach ( $this->operations as $op ) {
  853. $result = new stdClass;
  854. $result->operation_id = $op->operation_id;
  855. $result->result = $op->data;
  856. $results[] = $result;
  857. }
  858. return json_encode( $results );
  859. }
  860. function reIndex( $arrIn, $prop ) {
  861. $arrOut = array();
  862. if ( isset( $arrIn ) ) {
  863. foreach ( $arrIn as $item ) {
  864. $arrOut[$item->$prop] = $item;
  865. }
  866. }
  867. return $arrOut;
  868. }
  869. }
  870. // REST SERVICE FUNCS
  871. function id_request_handler() {
  872. global $wpmu_version;
  873. // Blanket protection against accidental access to edit-comments.php
  874. $basename = basename( $_SERVER['REQUEST_URI'] );
  875. if ( stristr( $basename, '?' ) )
  876. $basename = substr( $basename, 0, strpos( $basename, '?' ) );
  877. if ( 0 == get_option( 'id_moderationPage') && 'edit-comments.php' == $basename )
  878. wp_redirect( get_bloginfo( 'wpurl' ) . '/wp-admin/admin.php?page=intensedebate' );
  879. // determine requested action
  880. $action = id_param( 'id_action' );
  881. if ( !$action )
  882. return;
  883. id_debug_log( 'Request for: ' . $action );
  884. // translated func name
  885. $fn = 'id_REST_' . $action;
  886. if ( !function_exists( $fn ) ) {
  887. id_debug_log( 'Unknown action requested: ' . $fn );
  888. id_request_error( 'Unknown action: ' . $fn );
  889. return;
  890. }
  891. if ( 'id_REST_test_connection' == $fn ) {
  892. id_response_render( call_user_func( $fn ) );
  893. }
  894. // token key
  895. $token = id_param( 'id_token' );
  896. if ( $token !== get_option( 'id_import_token' ) ) {
  897. id_request_error( 'Missing or invalid token' );
  898. return;
  899. }
  900. // calls named func
  901. $result = call_user_func( $fn );
  902. //id_debug_log( 'Response: ' . print_r( $result, true ) );
  903. id_response_render( $result );
  904. }
  905. function id_request_error( $msg ) {
  906. $result = new stdClass();
  907. $result->success = false;
  908. $result->error = $msg;
  909. id_response_render( $result );
  910. }
  911. function id_request_message( $msg ) {
  912. $result = new stdClass();
  913. $result->success = true;
  914. $result->data = null;
  915. $result->message = $msg;
  916. id_response_render( $result );
  917. }
  918. function id_response_render( $result, $contentType = "application/json" ) {
  919. while ( @ob_end_clean() ) {} // Clear all buffers
  920. $charSet = get_bloginfo( 'charset' );
  921. header( "Content-Type: {$contentType}; charset={$charSet}" );
  922. die( json_encode( $result ) );
  923. }
  924. function id_REST_ping() {
  925. return array( 'id_plugin_version' => ID_PLUGIN_VERSION, 'wp_version' => ( !empty( $wpmu_version ) ? 'WPMU/' : '' ) . get_bloginfo( 'version' ) );
  926. }
  927. function id_REST_test_connection() {
  928. if ( !empty( $_POST['hash'] ) )
  929. return array( 'hash' => preg_replace( '/[^a-f0-9]/', '', $_POST['hash'] ), 'random' => md5( mt_rand( 0, 1000 ) ) );
  930. else
  931. wp_redirect( get_option( 'siteurl' ) );
  932. }
  933. function id_REST_get_comments_by_user() {
  934. global $wpdb;
  935. $email = id_param( 'id_email', false );
  936. $postid = id_param( 'id_postid', false );
  937. $where = array();
  938. if ( $email )
  939. $where[] = $wpdb->prepare( "comment_author_email = %s", $email );
  940. if ( $postid )
  941. $where[] = $wpdb->prepare( "comment_post_ID = %d", $postid );
  942. if ( !count( $where ) )
  943. id_request_error( "Must supply id_email and optionally id_postid." );
  944. $where[] = "comment_approved = 1";
  945. $results = $wpdb->get_results( "SELECT * FROM {$wpdb->comments} WHERE " . implode( ' AND ', $where ) . " ORDER BY comment_ID DESC" );
  946. if ( !count( $results ) ) {
  947. id_request_message( 'No comments' );
  948. return array();
  949. }
  950. return array_map( "id_export_comment", $results );
  951. }
  952. // ACTION: import
  953. function id_REST_import() {
  954. global $wpdb;
  955. $curr_params = array();
  956. $tot_params = array();
  957. $remaining_params = array();
  958. $post_where = '';
  959. $post = id_param( 'id_post_id', false );
  960. if ( false != $post ) {
  961. $post_where = ' comment_post_ID = ' . (int) $post . ' AND';
  962. $tot_params[] = $post;
  963. $remaining_params[] = $post;
  964. }
  965. $current = get_option( 'id_import_comment_id' ); // Defaults to 0
  966. if ( $current >= id_get_latest_comment_id() )
  967. id_request_message( 'Import complete.' );
  968. $import_offset = id_param( 'id_start_cid', 0 );
  969. if ( $import_offset < 0 )
  970. id_request_error( 'Start commentid must be a non-negative integer.' );
  971. if ( $import_offset > 0 )
  972. $current = $import_offset;
  973. id_debug_log( "Initiating import response with current = $current" );
  974. $sql = "SELECT * FROM {$wpdb->comments} WHERE$post_where comment_ID >= " . (int) $current . " AND comment_approved != 'spam' ORDER BY comment_ID ASC LIMIT 100";
  975. id_debug_log( $sql );
  976. $results = $wpdb->get_results( $sql );
  977. if ( !count( $results ) ) {
  978. id_debug_log( 'No comments to import.' );
  979. id_save_option( 'id_signup_step', 3 );
  980. id_request_message( 'Import complete.' );
  981. }
  982. // Update each comment to use "external" names
  983. $comments = array_map( "id_export_comment", $results );
  984. // mark the next comment_id for the next import request
  985. $lastCommentIndex = count( $comments ) - 1;
  986. $next_id = max( 0, (int) $comments[$lastCommentIndex]['comment_id'] + 1 );
  987. id_save_option( 'id_import_comment_id', $next_id );
  988. $result = new stdClass;
  989. $result->totalCommentCount = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(comment_ID) FROM {$wpdb->comments} WHERE$post_where comment_approved != 'spam'", $tot_params ) );
  990. $remaining_params[] = $next_id;
  991. $result->totalRemainingCount = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(comment_ID) FROM {$wpdb->comments} WHERE$post_where comment_ID >= %d AND comment_approved != 'spam' ORDER BY comment_ID ASC", $remaining_params ) );
  992. $result->time_gmt = gmdate( "Y-m-d H:i:s" );
  993. $result->time = date( "Y-m-d H:i:s" );
  994. $result->success = "true";
  995. $result->next_id = $next_id;
  996. $result->data = $comments;
  997. return $result;
  998. }
  999. function id_export_comment( $o ) {
  1000. $c = new id_comment( $o );
  1001. return $c->export();
  1002. }
  1003. // ACTION: sync moderation settings from ID
  1004. function id_REST_sync_moderation_settings() {
  1005. $settings = id_param( 'settings' );
  1006. if ( empty( $settings ) )
  1007. return 'false';
  1008. id_debug_log( 'Updating moderation settings: ' . print_r( $settings, true ) );
  1009. // Decode and UnJSON the settings so we can work with them
  1010. $settings = rawurldecode( stripslashes( $settings ) );
  1011. $opt = json_decode( $settings );
  1012. // Moderation links
  1013. if ( isset( $opt->min_links_for_moderations ) )
  1014. update_option( 'comment_max_links', $opt->min_links_for_moderations );
  1015. // Update all the boolean values
  1016. if ( 'T' == $opt->all_comments_require_approval )
  1017. update_option( 'comment_moderation', '1' );
  1018. else if ( 'F' == $opt->all_comments_require_approval )
  1019. update_option( 'comment_moderation', '' );
  1020. if ( 'T' == $opt->require_previously_approved )
  1021. update_option( 'comment_whitelist', '1' );
  1022. else if ( 'F' == $opt->require_previously_approved )
  1023. update_option( 'comment_whitelist', '' );
  1024. if ( 'T' == $opt->email_new_comments )
  1025. update_option( 'comments_notify', '1' );
  1026. else if ( 'F' == $opt->email_new_comments )
  1027. update_option( 'comments_notify', '' );
  1028. if ( 'T' == $opt->email_requires_moderation )
  1029. update_option( 'moderation_notify', '1' );
  1030. else if ( 'F' == $opt->email_requires_moderation )
  1031. update_option( 'moderation_notify', '' );
  1032. if ( 'T' == $opt->show_threads )
  1033. update_option( 'thread_comments', '1' );
  1034. else if ( 'F' == $opt->show_threads )
  1035. update_option( 'thread_comments', '' );
  1036. // Need to do some magic on the moderate/blacklist strings
  1037. if ( isset( $opt->moderate_words ) || isset( $opt->moderate_ips ) || isset( $opt->moderate_emails ) ) {
  1038. if ( !isset( $opt->moderate_words ) ) $opt->moderate_words = '';
  1039. if ( !isset( $opt->moderate_ips ) ) $opt->moderate_ips = '';
  1040. if ( !isset( $opt->moderate_emails ) ) $opt->moderate_emails = '';
  1041. $moderate_words = explode( ' ', $opt->moderate_words );
  1042. $moderate_ips = explode( ' ', $opt->moderate_ips );
  1043. $moderate_emails = explode( ' ', $opt->moderate_emails );
  1044. $moderate = array_merge( $moderate_words, $moderate_ips, $moderate_emails );
  1045. $moderate = implode( "\n", id_cleanup_moderation_array( $moderate ) );
  1046. update_option( 'moderation_keys', $moderate );
  1047. }
  1048. if ( isset( $opt->blacklisted_words ) || isset( $opt->blacklisted_ips ) || isset( $opt->blacklisted_emails ) ) {
  1049. if ( !isset( $opt->blacklisted_words ) ) $opt->blacklisted_words = '';
  1050. if ( !isset( $opt->blacklisted_ips ) ) $opt->blacklisted_ips = '';
  1051. if ( !isset( $opt->blacklisted_emails ) ) $opt->blacklisted_emails = '';
  1052. $blacklist_words = explode( ' ', $opt->blacklisted_words );
  1053. $blacklist_ips = explode( ' ', $opt->blacklisted_ips );
  1054. $blacklist_emails = explode( ' ', $opt->blacklisted_emails );
  1055. $blacklist = array_merge( $blacklist_words, $blacklist_ips, $blacklist_emails );
  1056. $blacklist = implode( "\n", id_cleanup_moderation_array( $blacklist ) );
  1057. update_option( 'blacklist_keys', $blacklist );
  1058. }
  1059. if ( 'T' == $opt->akismet && get_option( 'wordpress_api_key' ) )
  1060. return get_option( 'wordpress_api_key' );
  1061. else
  1062. return 'true';
  1063. }
  1064. function id_cleanup_moderation_array( $arr ) {
  1065. $clean = array();
  1066. foreach ( $arr as $val ) {
  1067. $val = trim( $val );
  1068. if ( !$val )
  1069. continue;
  1070. if ( !in_array( $val, $clean ) )
  1071. $clean[] = $val;
  1072. }
  1073. return $clean;
  1074. }
  1075. // ACTION: save_comment
  1076. // Enter a new comment in to the system
  1077. function id_REST_save_comment() {
  1078. $rawComment = stripslashes( id_param( 'id_comment_data' ) );
  1079. id_debug_log( "Receive Comment: $rawComment" );
  1080. $comment = new id_comment();
  1081. $comment->loadFromRemoteJson( $rawComment );
  1082. $result = array(
  1083. 'success' => $comment->save(),
  1084. 'comment' => $comment->export()
  1085. );
  1086. if ( 'delete' == $comment->comment_status ) {
  1087. remove_action( 'wp_set_comment_status', 'id_comment_status', 10, 2 );
  1088. wp_delete_comment( $comment->comment_ID );
  1089. add_action( 'wp_set_comment_status', 'id_comment_status', 10, 2 );
  1090. }
  1091. return $result;
  1092. }
  1093. // ACTION: set_comment_status
  1094. // ***Deleting is done by passing status=delete
  1095. function id_REST_set_comment_status() {
  1096. $newStatus = id_param( 'status', '' );
  1097. $comment_id = id_param( 'comment_id', 0 );
  1098. $rawComment = stripslashes( id_param( 'comment_data' ) );
  1099. if ( !$comment_id ) {
  1100. if ( !$rawComment )
  1101. return false;
  1102. $comment = new id_comment();
  1103. $comment->loadFromRemoteJson( $rawComment );
  1104. $comment->duplicateCheck(); // Will locate a match and update with the WP id
  1105. if ( $comment->comment_ID ) {
  1106. // Found it, carry on
  1107. $comment_id = $comment->comment_ID;
  1108. } else {
  1109. // No match
  1110. if ( 'delete' == $newStatus )
  1111. return true; // We were going to delete it anyway
  1112. else
  1113. return false;
  1114. }
  1115. }
  1116. id_debug_log( "Receive Comment Status: $newStatus $comment_id" );
  1117. // Check if the status is already set, if so, still return true
  1118. if ( $newStatus == wp_get_comment_status( $comment_id ) )
  1119. return true;
  1120. else if ( $newStatus == "delete" && in_array( wp_get_comment_status( $comment_id ), array( "deleted", "trash" ) ) ) // handle cases that don't quite line up (delete=deleted and hold=unapproved)
  1121. return true;
  1122. else if ( $newStatus == "hold" && wp_get_comment_status( $comment_id ) == "unapproved" )
  1123. return true;
  1124. // If not already set, then rename to local status, then attempt to set it and return the result
  1125. remove_action( 'wp_set_comment_status', 'id_comment_status', 10, 2 );
  1126. if ( 'delete' == $newStatus )
  1127. $result = wp_delete_comment( $comment_id );
  1128. else
  1129. $result = wp_set_comment_status( $comment_id, $newStatus );
  1130. add_action( 'wp_set_comment_status', 'id_comment_status', 10, 2 );
  1131. return $result;
  1132. }
  1133. // ACTION: save_post
  1134. function id_REST_save_post() {
  1135. $rawPost = stripslashes( id_param( 'id_post_data' ) );
  1136. id_debug_log( "Receive Post Status: $rawPost" );
  1137. $data = json_decode( $rawPost );
  1138. if ( !isset( $data->postid ) )
  1139. return false;
  1140. // Load current post
  1141. $post = new id_post( get_post( $data->postid ) );
  1142. // Replace any incoming values
  1143. foreach ( $data as $key => $val ) {
  1144. if ( isset( $post->$key ) ) {
  1145. $post->$key = $val;
  1146. }
  1147. }
  1148. return array(
  1149. 'success' => $post->save(),
  1150. 'post' => $post->export()
  1151. );
  1152. }
  1153. // ACTION: reset queue
  1154. function id_REST_reset_queue() {
  1155. $queue = id_get_queue();
  1156. $queue->create();
  1157. return true;
  1158. }
  1159. // ACTION: get all operations queued in WP
  1160. function id_REST_get_queue() {
  1161. $queue = id_get_queue();
  1162. $queue->load();
  1163. return $queue->operations;
  1164. }
  1165. // ACTION: cancel a specific operation
  1166. function id_REST_cancel_operation() {
  1167. $queue = id_get_queue();
  1168. $queue->load();
  1169. $hash = id_param( 'id_operation_hash', false );
  1170. if ( !$hash )
  1171. return array( 'success' => false, 'hash' => $hash, 'operations' => count( $queue->operations ) );
  1172. $new_ops = array();
  1173. foreach ( $queue->operations as $operation ) {
  1174. if ( $hash != $operation->operation_id )
  1175. $new_ops[] = $operation;
  1176. }
  1177. $queue->operations = $new_ops;
  1178. $queue->needs_save = true;
  1179. $queue->store();
  1180. return array( 'success' => true, 'hash' => $hash, 'operations' => count( $new_ops ) );
  1181. }
  1182. // ACTION: restart import
  1183. function id_REST_reset_import() {
  1184. id_save_option( 'id_import_comment_id', '0' );
  1185. return true;
  1186. }
  1187. // ACTION: return the highest comment id in WP
  1188. function id_REST_get_last_wp_comment_id() {
  1189. return id_get_latest_comment_id();
  1190. }
  1191. // ACTION: get the total number of approved comments
  1192. // optionally provide &post_id= to get count for a specific post only
  1193. function id_REST_get_approved_comment_count() {
  1194. include_once ABSPATH . '/wp-admin/includes/template.php';
  1195. if ( $p = id_param( 'post_id', 0 ) )
  1196. $result = wp_count_comments( $p );
  1197. else
  1198. $result = wp_count_comments();
  1199. return $result->approved;
  1200. }
  1201. // ACTION: Lock queue from sending requests for the next x seconds
  1202. function id_REST_lock_queue() {
  1203. $lock = id_param( 'id_lock_period', 300 ); // Defaults to 5 mins
  1204. update_option( 'id_lock_queue', ( time() + $lock ) );
  1205. return get_option( 'id_lock_queue' );
  1206. }
  1207. // AUTOLOGIN
  1208. // drops autologin js after user has logged in via profile page, makes it so
  1209. // user does not need to login to IntenseDebate if they've already logged in here
  1210. function id_auto_login() {
  1211. global $userdata;
  1212. if ( empty( $userdata->ID ) || get_option( 'id_auto_login' ) == 1 )
  1213. return false;
  1214. $wp_userID = $userdata->ID;
  1215. $appKey = ID_APPKEY;
  1216. $userID = id_get_user_meta( $wp_userID, 'id_userID' );
  1217. $userKey = id_get_user_meta( $wp_userID, 'id_userKey' );
  1218. if ( id_user_connected() ) {
  1219. echo "<script type=\"text/javascript\" src=\"" . ID_BASEURL . "/services/v1/jsLogin.php?appKey={$appKey}&amp;userid={$userID}&amp;userKey={$userKey}\"></script>\n";
  1220. }
  1221. }
  1222. // ADMIN BANNERS
  1223. // displays prompt to login on the admin pages if user has not logged into IntenseDebate
  1224. function id_admin_notices() {
  1225. // global administrative settings prompt
  1226. if ( !id_is_active() && !empty( $_GET['page'] ) && $_GET['page'] != 'id_settings' ) {
  1227. $settingsurl = get_bloginfo( 'wpurl' ) . '/wp-admin/options-general.php?page=id_settings';
  1228. ?>
  1229. <div class="updated fade-ff0000">
  1230. <p><strong><?php printf( __( 'The IntenseDebate plugin is enabled but you need to adjust <a href="%s">your settings</a>.', 'intensedebate' ), $settingsurl ); ?></strong></p>
  1231. </div>
  1232. <?php
  1233. return;
  1234. }
  1235. // user profile settings prompt
  1236. if ( !id_user_connected() && !empty( $_GET['page'] ) && $_GET['page'] != 'id_settings' && $_GET['page'] != 'id_registration' ) {
  1237. $profileurl = get_bloginfo( 'wpurl' ) . '/wp-admin/profile.php#intensedebatelogin';
  1238. ?>
  1239. <div class="updated fade-ff0000">
  1240. <p><strong><?php printf( __( 'Connect to your IntenseDebate account. Go to your <a href="%s">WordPress profile</a> to log in or register.', 'intensedebate' ), $profileurl ); ?></strong></p>
  1241. </div>
  1242. <?php
  1243. return;
  1244. }
  1245. // import reset via link
  1246. if ( isset( $_GET['id_reset'] ) && 'true' == $_GET['id_reset'] ) {
  1247. ?>
  1248. <div class="updated fade-ff0000">
  1249. <p><strong><?php _e( 'Your comments are now being re-imported in the background.', 'intensedebate' ); ?></strong></p>
  1250. </div>
  1251. <?php
  1252. return;
  1253. }
  1254. }
  1255. function id_wordpress_version_warning() {
  1256. ?>
  1257. <div class="updated fade-ff0000">
  1258. <p><strong><?php printf( __( "We're sorry, but the IntenseDebate plugin is not supported for versions of WordPress lower than %s.", 'intensedebate' ), ID_MIN_WP_VERSION ); ?></strong></p>
  1259. </div>
  1260. <?php
  1261. }
  1262. // PROFILE PAGE
  1263. function id_show_user_profile() {
  1264. if ( id_user_connected() ) {
  1265. id_show_user_disconnect();
  1266. return;
  1267. }
  1268. global $userdata;
  1269. $id_username = id_coalesce( $userdata->id_username );
  1270. ?>
  1271. <a name="intensedebatelogin">&nbsp;</a><br/>
  1272. <h2><img src="<?php echo ID_BASEURL ?>/images/intensedebate.png" alt="IntenseDebate Logo" class="idwp-logo" /> <?php _e( 'User Synchronization', 'intensedebate' ); ?></h2>
  1273. <table class="form-table">
  1274. <tbody>
  1275. <tr>
  1276. <th><label for="id_username"><?php _e( 'Username', 'intensedebate' ); ?></label></th>
  1277. <td><input type="text" id="id_username" name="id_username" value="<?php echo $id_username; ?>" /></td>
  1278. </tr>
  1279. <tr>
  1280. <th><label for="id_password"><?php _e( 'Password', 'intensedebate' ); ?></label></th>
  1281. <td><input type="password" id="id_password" class="required" name="id_password" value="" /></td>
  1282. </tr>
  1283. </tbody>
  1284. </table>
  1285. <p><?php printf( __( 'Not registered with IntenseDebate yet? <a target="_blank" href="%s">It\'s easy</a>.', 'intensedebate' ), ID_REGISTRATION_PAGE ); ?></p>
  1286. <?php
  1287. }
  1288. function id_profile_update( $wp_userID = 0 ) {
  1289. // validation
  1290. if ( !$wp_userID ) {
  1291. return false;
  1292. }
  1293. // Don't clear credentials when they were just being displayed
  1294. if ( 'true' == id_param( 'id_connected' ) )
  1295. return;
  1296. $username = id_param( 'id_username' );
  1297. $password = id_param( 'id_password' );
  1298. if ( !$username || !$password ) {
  1299. id_save_usermeta_array( $wp_userID, array(
  1300. 'id_username' => $username,
  1301. 'id_userID' => null,
  1302. 'id_userKey' => null
  1303. ) );
  1304. return false;
  1305. }
  1306. // outgoing fields
  1307. $fields = array();
  1308. $fields['username'] = $username;
  1309. $fields['password'] = $password;
  1310. $fields['wp_userID'] = $wp_userID;
  1311. $fields['admin'] = current_user_can( 'manage_options' );
  1312. $queue = id_get_queue();
  1313. $op = $queue->add( 'user_login', $fields, 'id_profile_update_callback' );
  1314. $queue->ping( array( $op ) );
  1315. return true;
  1316. }
  1317. function id_profile_update_callback( &$result, &$response, &$operation ) {
  1318. $args = func_get_args();
  1319. if ( $wp_userID = id_coalesce( @$operation->data['wp_userID'] ) ) {
  1320. id_save_usermeta_array( $wp_userID, array(
  1321. 'id_username' => id_coalesce( $operation->data['username'] ),
  1322. 'id_userID' => id_coalesce( $response->userID ),
  1323. 'id_userKey' => id_coalesce( $response->userKey )
  1324. ) );
  1325. }
  1326. return true;
  1327. }
  1328. // user disconnect form
  1329. function id_show_user_disconnect() {
  1330. $current_user = wp_get_current_user();
  1331. $user_ID = $current_user->ID;
  1332. ?>
  1333. <a name="intensedebatelogin">&nbsp;</a><br/>
  1334. <input type="hidden" name="id_connected" value="true" />
  1335. <h2><img src="<?php echo ID_BASEURL ?>/images/intensedebate.png" alt="IntenseDebate Logo" class="idwp-logo" /> <?php _e( 'User Synchronization', 'intensedebate' ); ?></h2>
  1336. <table class="form-table">
  1337. <tbody>
  1338. <tr>
  1339. <td colspan="2">
  1340. <img src="<?php echo ID_BASEURL ?>/midimages/<?php echo id_get_user_meta( $user_ID, 'id_userID' ); ?>" alt="[Avatar]" class="idwp-avatar" />
  1341. <h3 class="idwp-floatnone"><?php printf( __( 'Synchronizing as %s', 'intensedebate' ), '<a href="' . ID_BASEURL . '/people/' . id_get_user_meta( $user_ID, 'id_username' ) . '">' . id_get_user_meta( $user_ID, 'id_username' ) . '</a>' ); ?></h3>
  1342. <p class="idwp-floatnone"><a href="<?php echo ID_BASEURL ?>/userDash"><?php _e( 'Dashboard', 'intensedebate' ); ?></a> | <a href="<?php echo ID_BASEURL ?>/editprofile"><?php _e( 'Edit profile', 'intensedebate' ); ?></a></p>
  1343. <p><a href="?id_settings_action=user_disconnect" id="id_user_disconnect"><?php _e( 'Disconnect from IntenseDebate', 'intensedebate' ) ?></a></p>
  1344. <span class="idwp-clear"></span>
  1345. <p class="idwp-nomargin"><?php printf( __( 'All WordPress comments are now synchronized with the IntenseDebate account above. <a href="%s">Read more here</a>.', 'intensedebate' ), ID_BASEURL . '/wordpress#userSync' ); ?></p>
  1346. <p></p>
  1347. </td>
  1348. </tr>
  1349. </tbody>
  1350. </table>
  1351. <?php
  1352. }
  1353. // user disconnect postback
  1354. function id_SETTINGS_user_disconnect() {
  1355. $current_user = wp_get_current_user();
  1356. $user_id = $current_user->ID;
  1357. $fields = array(
  1358. 'userKey' => get_option( 'id_userKey' ),
  1359. 'userid' => get_option( 'id_userID' ),
  1360. );
  1361. $queue = id_get_queue();
  1362. $op = $queue->add( 'user_disconnect', $fields, 'id_generic_callback' );
  1363. $queue->ping( array( $op ) );
  1364. $meta = array(
  1365. 'id_username'
  1366. , 'id_displayname'
  1367. , 'id_email'
  1368. , 'id_userID'
  1369. , 'id_userKey'
  1370. );
  1371. foreach ( $meta as $key ) {
  1372. id_save_usermeta( $user_id, $key, null );
  1373. }
  1374. }
  1375. // DISCUSSION SETTINGS PAGE
  1376. /**
  1377. * When discussion settings are changed in WP, queue the change over to ID
  1378. * as well to keep things in sync.
  1379. *
  1380. * @param boolean $merge_moderation_strings Whether or not to request a merging (rather than overwrite) of moderation strings
  1381. **/
  1382. function id_discussion_settings_page( $merge_moderation_strings = false ) {
  1383. global $wpmu_version;
  1384. if ( ( isset( $_POST['option_page'] ) && 'discussion' == $_POST['option_page'] ) || ( isset( $_POST['page_options'] ) && stristr( $_POST['page_options'], 'comment_moderation' ) ) ) {
  1385. $settings = array();
  1386. // We only sync to ID if one of the relevant options was changed
  1387. $sync = false;
  1388. $options = array( 'comments_notify', 'moderation_notify', 'comment_moderation', 'comment_whitelist', 'comment_max_links', 'moderation_keys', 'blacklist_keys', 'thread_comments' );
  1389. foreach ( $options as $option ) {
  1390. $current = get_option( $option );
  1391. if ( ( isset( $_POST[$option] ) && $_POST[$option] != $current ) || !isset( $_POST[$option] ) && $current ) {
  1392. $sync = true;
  1393. break;
  1394. }
  1395. }
  1396. if ( $sync ) {
  1397. // Simple boolean options
  1398. $settings = array(
  1399. 'all_comments_require_approval' => ( '1' == $_POST['comment_moderation'] ? 'T' : 'F' ),
  1400. 'require_previously_approved' => ( '1' == $_POST['comment_whitelist'] ? 'T' : 'F' ),
  1401. 'email_new_comments' => ( '1' == $_POST['comments_notify'] ? 'T' : 'F' ),
  1402. 'email_requires_moderation' => ( '1' == $_POST['moderation_notify'] ? 'T' : 'F' ),
  1403. 'min_links_for_moderations' => (int) $_POST['comment_max_links'],
  1404. );
  1405. // Some custom ones
  1406. // If Akismet is active here, then send the key so that ID can use it as well
  1407. if ( get_option( 'wordpress_api_key' ) && is_plugin_active( 'akismet/akismet.php' ) )
  1408. $settings['akismet'] = get_option( 'wordpress_api_key' );
  1409. // Need to handle like this to avoid older versions turning threading off
  1410. if ( version_compare( get_bloginfo( 'version' ), '2.7', '>=' ) )
  1411. $settings['show_threads'] = ( '1' == $_POST['thread_comments'] ? 'T' : 'F' );
  1412. // Need to do some parsing to get moderation strings into the same format as ID
  1413. $mods = id_separate_tokens( $_POST['moderation_keys'] );
  1414. $settings['moderate_words'] = implode( ' ', $mods['words'] );
  1415. $settings['moderate_ips'] = implode( ' ', $mods['ips'] );
  1416. $settings['moderate_emails'] = implode( ' ', $mods['emails'] );
  1417. $blacklist = id_separate_tokens( $_POST['blacklist_keys'] );
  1418. $settings['blacklisted_words'] = implode( ' ', $blacklist['words'] );
  1419. $settings['blacklisted_ips'] = implode( ' ', $blacklist['ips'] );
  1420. $settings['blacklisted_emails'] = implode( ' ', $blacklist['emails'] );
  1421. // Optionally merge (rather than overwrite) ID moderation strings
  1422. $settings['merge_moderation_strings'] = $merge_moderation_strings;
  1423. id_discussion_sync_now( $settings );
  1424. }
  1425. }
  1426. }
  1427. /**
  1428. * Helper function to trigger an update of IntenseDebate options, based
  1429. * on what's stored in the database here (WP).
  1430. *
  1431. * @param boolean $merge_moderation_strings Whether or not to request a merging (rather than overwrite) of moderation strings
  1432. **/
  1433. function id_discussion_sync_from_db( $merge_moderation_strings = false ) {
  1434. $settings = array(
  1435. 'all_comments_require_approval' => ( '1' == get_option( 'comment_moderation' ) ? 'T' : 'F' ),
  1436. 'require_previously_approved' => ( '1' == get_option( 'comment_whitelist' ) ? 'T' : 'F' ),
  1437. 'email_new_comments' => ( '1' == get_option( 'comments_notify' ) ? 'T' : 'F' ),
  1438. 'email_requires_moderation' => ( '1' == get_option( 'moderation_notify' ) ? 'T' : 'F' ),
  1439. 'min_links_for_moderations' => (int) get_option( 'comment_max_links' ),
  1440. );
  1441. // Some custom ones
  1442. // If Akismet is active here, then send the key so that ID can use it as well
  1443. include_once( ABSPATH . '/wp-admin/includes/plugin.php' );
  1444. if ( get_option( 'wordpress_api_key' ) && is_plugin_active( 'akismet/akismet.php' ) )
  1445. $settings['akismet'] = get_option( 'wordpress_api_key' );
  1446. // Need to handle like this to avoid older versions turning threading off
  1447. if ( version_compare( get_bloginfo( 'version' ), '2.7', '>=' ) )
  1448. $settings['show_threads'] = ( '1' == get_option( 'thread_comments' ) ? 'T' : 'F' );
  1449. // Need to do some parsing to get moderation strings into the same format as ID
  1450. $mods = id_separate_tokens( get_option( 'moderation_keys' ) );
  1451. $settings['moderate_words'] = implode( ' ', $mods['words'] );
  1452. $settings['moderate_ips'] = implode( ' ', $mods['ips'] );
  1453. $settings['moderate_emails'] = implode( ' ', $mods['emails'] );
  1454. $blacklist = id_separate_tokens( get_option( 'blacklist_keys' ) );
  1455. $settings['blacklisted_words'] = implode( ' ', $blacklist['words'] );
  1456. $settings['blacklisted_ips'] = implode( ' ', $blacklist['ips'] );
  1457. $settings['blacklisted_emails'] = implode( ' ', $blacklist['emails'] );
  1458. // Optionally merge (rather than overwrite) ID moderation strings
  1459. $settings['merge_moderation_strings'] = ('1' == $merge_moderation_strings ? 1 : 0 );
  1460. id_discussion_sync_now( $settings );
  1461. }
  1462. /**
  1463. * Send the array of options over to IntenseDebate to update the settings
  1464. * there to match here (WP)
  1465. *
  1466. * @param array $settings The moderation/discussion settings to sync back to ID
  1467. **/
  1468. function id_discussion_sync_now( $settings ) {
  1469. if ( is_array( $settings ) ) {
  1470. $queue = id_get_queue();
  1471. $op = $queue->add( 'moderation_settings', $settings, 'id_discussion_options_update_callback' );
  1472. $queue->ping( array( $op ) );
  1473. }
  1474. }
  1475. /**
  1476. * Very basic separation of moderation tokens into Email addresses, IPs
  1477. * and normal strings. Required because ID stores them separately.
  1478. *
  1479. * @param string $str The string containing all moderation tokens
  1480. * @return Array containing all tokens, split into an associative array,
  1481. * keyed with "emails", "words" and "ips"
  1482. **/
  1483. function id_separate_tokens( $str ) {
  1484. $out = array( 'emails' => array(), 'words' => array(), 'ips' => array() );
  1485. if ( !strlen( $str ) )
  1486. return $out;
  1487. $str = preg_replace( '/\s+/', ' ', $str );
  1488. $tokens = explode( ' ', $str );
  1489. foreach ( $tokens as $token ) {
  1490. if ( false !== strstr( $token, '@' ) && false !== strstr( $token, '.' ) )
  1491. $out['emails'][] = trim( $token );
  1492. else if ( preg_match( '/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/', $token ) )
  1493. $out['ips'][] = trim( $token );
  1494. else
  1495. $out['words'][] = trim( $token );
  1496. }
  1497. return $out;
  1498. }
  1499. /**
  1500. * Handle response from ID when a request to update moderation settings is made.
  1501. *
  1502. * @param string $result The result string returned from ID ('success' or 'failure')
  1503. * @param object $response Data returned from ID
  1504. * @param object $operation The queue operation object sent to ID
  1505. * @return Boolean, true to remove from queue, false to try again later
  1506. **/
  1507. function id_discussion_options_update_callback( &$result, &$response, &$operation ) {
  1508. if ( 'failure' == $result )
  1509. return false; // Try again later
  1510. else
  1511. return true; // Remove from queue
  1512. }
  1513. // SETTINGS PAGE
  1514. // js/css for settings page
  1515. // form validation doesn't work in older versions of WordPress due to jQuery version conflicts
  1516. function id_settings_head() {
  1517. ?>
  1518. <style type="text/css">
  1519. #id_settings_menu {
  1520. list-style: none;
  1521. padding: 0;
  1522. }
  1523. #id_settings_menu li {
  1524. background: #E4F2FD url(<?php echo ID_BASEURL ?>/images1/idwp-signup_arrow.png) no-repeat 8px 50%;
  1525. display: block;
  1526. padding: 8px 8px 8px 35px;
  1527. width: 250px;
  1528. }
  1529. #id_user_login .form-table,
  1530. #id_email_lookup .form-table,
  1531. #id_user_registration .form-table {
  1532. margin-top: 0;
  1533. }
  1534. #id_user_login .submit,
  1535. #id_email_lookup .submit,
  1536. #id_user_registration .submit {
  1537. background: #EAF3FA;
  1538. border: none;
  1539. padding: 10px;
  1540. }
  1541. #id_user_login .form-table td,
  1542. #id_email_lookup .form-table td,
  1543. #id_user_registration .form-table td,
  1544. #id_user_login .form-table th,
  1545. #id_email_lookup .form-table th,
  1546. #id_user_registration .form-table th {
  1547. border: none;
  1548. margin: 0;
  1549. }
  1550. #id_user_login .form-table th,
  1551. #id_email_lookup .form-table th,
  1552. #id_user_registration .form-table th {
  1553. line-height: 25px;
  1554. }
  1555. .idwp-form_info {
  1556. margin: .4em 0 0;
  1557. }
  1558. .idwp-form_info_fade {
  1559. color: #666;
  1560. margin: .2em 0 1em;
  1561. }
  1562. .idwp-logo {
  1563. margin: 0 -4px 0 0;
  1564. }
  1565. .idwp-clear {
  1566. clear: both;
  1567. display: block;
  1568. }
  1569. .idwp-importstatus {
  1570. float: left;
  1571. font-size: 12px; line-height: 1.3em;
  1572. margin: 0;
  1573. outline: 3px solid #fff;
  1574. padding: 4px;
  1575. }
  1576. .id_settings_menu {
  1577. list-style: none;
  1578. padding: 0;
  1579. }
  1580. .id_settings_menu li {
  1581. background: #E4F2FD url(<?php echo ID_BASEURL ?>/images1/idwp-signup_arrow.png) no-repeat 8px 50%;
  1582. display: block;
  1583. padding: 8px 8px 8px 35px;
  1584. width: 250px;
  1585. }
  1586. .idwp-popup {
  1587. background: url(<?php echo ID_BASEURL ?>/images1/idwp-popup_bg.png);
  1588. height: 100%;
  1589. position: fixed;
  1590. width: 100%;
  1591. z-index: 100;
  1592. }
  1593. .idwp-popup-inner {
  1594. color: #ccc;
  1595. display: block;
  1596. float: none;
  1597. margin: 65px auto 0;
  1598. width: 994px;
  1599. }
  1600. .idwp-popup-inner a {
  1601. color: #ccc;
  1602. }
  1603. .idwp-popup-inner a:hover {
  1604. color: #fff;
  1605. }
  1606. .idwp-popup-iframe {
  1607. height: 480px;
  1608. margin: 0 auto;
  1609. width: 990px;
  1610. }
  1611. .idwp-close {
  1612. background: url(<?php echo ID_BASEURL ?>/images1/idwp-close.png) no-repeat;
  1613. display: block;
  1614. float: right;
  1615. height: 24px;
  1616. margin: 0 0 0 8px;
  1617. width: 24px;
  1618. }
  1619. a.idwp-floatright:hover .idwp-close, .idwp-close:hover {
  1620. background-position: 0 100%;
  1621. }
  1622. .idwp-floatright {
  1623. float: right;
  1624. }
  1625. .idwp-logo-more {
  1626. display: inline-block;
  1627. float: right;
  1628. font-size: 15px;
  1629. margin: 26px 0 0;
  1630. }
  1631. #id_settings h2 {
  1632. padding-right: 0;
  1633. }
  1634. #id_plugin_reset {
  1635. margin-top: 1em;
  1636. border-top: solid 1px #e3e3e3;
  1637. }
  1638. <!--[if IE]>
  1639. .idwp-popup {
  1640. background: none;
  1641. position: absolute !important;
  1642. top: 0; left: 0;
  1643. overflow: hidden;
  1644. }
  1645. .idwp-popup-inner {
  1646. background: #333;
  1647. }
  1648. .idwp-close {
  1649. background: url(<?php echo ID_BASEURL ?>/images1/idwp-close_ie6.png) no-repeat;
  1650. margin: 0;
  1651. }
  1652. a.idwp-floatright:hover .idwp-close, .idwp-close:hover {
  1653. background-position: 0 100%;
  1654. }
  1655. .idwp-popup-inner, .idwp-popup-inner a, .idwp-popup-inner a:hover {
  1656. color: #fff;
  1657. }
  1658. .idwp-popup-inner {
  1659. width: 994px;
  1660. }
  1661. .idwp-popup-inner p {
  1662. margin: 10px 10px 0;
  1663. }
  1664. .idwp-popup-iframe {
  1665. margin: 5px 10px 10px;
  1666. width: 974px;
  1667. }
  1668. .idwp-close {
  1669. display: none;
  1670. }
  1671. <![endif]-->
  1672. </style>
  1673. <script type="text/javascript">
  1674. /* <![CDATA[ */
  1675. jQuery(document).ready(function() {
  1676. jQuery('#id_settings_menu a').click(function(e) {
  1677. e.preventDefault();
  1678. jQuery('#id_user_registration, #id_user_login, #id_email_lookup').addClass('hidden');
  1679. jQuery('#id_settings_menu a').removeClass('selected');
  1680. var target = jQuery(this).attr('href');
  1681. jQuery(this).addClass('selected');
  1682. jQuery(target).toggleClass('hidden');
  1683. jQuery('#id_active_form').val(target.replace('#', ''));
  1684. });
  1685. jQuery('#id_plugin_reset').submit(function() {
  1686. return confirm('<?php _e( 'Are you sure you want to delete all of your settings and reset the IntenseDebate plugin?', 'intensedebate' ); ?>');
  1687. });
  1688. jQuery('#id_user_disconnect').click(function() {
  1689. return confirm('<?php _e( 'Are you sure you want to disconnect your WordPress account from your IntenseDebate account?', 'intensedebate' ); ?>');
  1690. });
  1691. <?php if ( 0 == get_option( 'id_moderationPage' ) ) : ?>
  1692. jQuery('#adminmenu a[href=edit-comments.php]').attr('id', "id_moderate_comment_link");
  1693. jQuery('#adminmenu a[href=edit-comments.php]').attr('href', "admin.php?page=intensedebate");
  1694. jQuery('#favorite-actions a[href=edit-comments.php]').attr('href', "admin.php?page=intensedebate");
  1695. <?php endif; ?>
  1696. });
  1697. /* ]]> */
  1698. </script>
  1699. <?php
  1700. }
  1701. // main settings page handler
  1702. function id_settings_page() {
  1703. global $wpmu_version;
  1704. // errors & alerts
  1705. id_message();
  1706. // Restart the process of connecting if we don't have a blogKey yet
  1707. if ( !get_option( 'id_blogKey' ) ) {
  1708. id_debug_log( 'Restarting import due to empty id_blogKey.' );
  1709. id_save_option( 'id_signup_step', 0 );
  1710. }
  1711. ?>
  1712. <div id="id_settings" class="wrap">
  1713. <div class="clear"></div>
  1714. <h2>
  1715. <?php if ( get_option( 'id_blogID' ) && get_option( 'id_signup_step' ) >= 3 ) : ?>
  1716. <span class="idwp-logo-more"><?php printf( __( '<strong>Note:</strong> For more customization options please visit your <a href="%s">blog settings</a> page', 'intensedebate' ), ID_BASEURL . '/editacct/' . get_option( 'id_blogID' ) ); ?></span>
  1717. <?php endif; ?>
  1718. <img src="<?php echo ID_BASEURL ?>/images/intensedebate.png" alt="IntenseDebate" class="idwp-logo" /> <?php _e('Settings', 'intensedebate'); ?>
  1719. </h2>
  1720. <?php
  1721. if ( id_param( 'login_msg' ) && id_param( 'login_msg' ) == "Login successful" )
  1722. id_save_option( 'id_signup_step', 1 );
  1723. else if ( id_param( 'new_status' ) && id_param( 'new_status' ) == "importcomplete" )
  1724. id_save_option( 'id_signup_step', 3 );
  1725. else if ( id_param( 'hideSettingsTop' ) && id_param( 'hideSettingsTop' ) == "true" )
  1726. id_save_option( 'id_hideSettingsTop', 1 );
  1727. if ( !id_is_active() || get_option( 'id_hideSettingsTop' ) == 0) : ?>
  1728. <style type="text/css">
  1729. /* !Install */
  1730. .idwp-install h3 {
  1731. display: block !important;
  1732. float: none !important;
  1733. clear: none !important;
  1734. font-size: 15px;
  1735. }
  1736. .idwp-install h4 {
  1737. font-size: 13px;
  1738. }
  1739. .idwp-install {
  1740. background: #dfdfdf url(<?php echo ID_BASEURL ?>/images1/_wordpress/gray-grad.png);
  1741. border: 1px solid #dfdfdf;
  1742. margin: 0 0 20px;
  1743. padding: 14px;
  1744. /* Rounded corners in most browsers! */
  1745. -moz-border-radius: 4px; /* For Mozilla Firefox */
  1746. -khtml-border-radius: 4px; /* For Konqueror */
  1747. -webkit-border-radius: 4px; /* For Safari */
  1748. border-radius: 4px; /* For future native implementations */
  1749. }
  1750. .idwp-install-logo {
  1751. background: url(<?php echo ID_BASEURL ?>/images1/_wordpress/idwp.png) no-repeat 100% 0;
  1752. display: inline;
  1753. float: right;
  1754. margin: -14px -14px 0 0;
  1755. height: 51px;
  1756. width: 252px;
  1757. }
  1758. /* Steps */
  1759. .idwp-install-steps {
  1760. background: url(<?php echo ID_BASEURL ?>/images1/_wordpress/idwp.png) no-repeat 0 25px;
  1761. cursor: default;
  1762. /*float: left;*/
  1763. height: 45px;
  1764. width: 189px;
  1765. margin: 0;
  1766. padding: 0;
  1767. }
  1768. .idwp-install-steps li {
  1769. background: url(<?php echo ID_BASEURL ?>/images1/_wordpress/idwp.png) no-repeat 24px -132px;
  1770. color: #464646;
  1771. float: left;
  1772. height: 45px;
  1773. list-style: none;
  1774. margin: 0;
  1775. text-align: center;
  1776. width: 63px;
  1777. }
  1778. .idwp-install-steps .idwp-sel {
  1779. background: url(<?php echo ID_BASEURL ?>/images1/_wordpress/idwp.png) no-repeat 24px -222px;
  1780. font-weight: bold;
  1781. }
  1782. .idwp-install-steps .idwp-completed {
  1783. background: url(<?php echo ID_BASEURL ?>/images1/_wordpress/idwp.png) no-repeat 24px -43px;
  1784. color: #999;
  1785. }
  1786. /* Main */
  1787. .idwp-install-main {
  1788. background: #fff;
  1789. /*clear: left;*/
  1790. padding: 18px;
  1791. /* Rounded corners in most browsers! */
  1792. -moz-border-radius: 2px; /* For Mozilla Firefox */
  1793. -khtml-border-radius: 2px; /* For Konqueror */
  1794. -webkit-border-radius: 2px; /* For Safari */
  1795. border-radius: 2px; /* For future native implementations */
  1796. }
  1797. .idwp-install-main form h4 {
  1798. clear: left;
  1799. float: left;
  1800. line-height: 20px;
  1801. margin: 0;
  1802. width: 160px;
  1803. }
  1804. .idwp-input-text-wrap {
  1805. margin: 0 0 10px 160px;
  1806. }
  1807. .idwp-install-main .idwp-fade {
  1808. margin: 4px 0 1em;
  1809. }
  1810. .idwp-install-form_elements {
  1811. margin: 20px 0;
  1812. }
  1813. /* message_error */
  1814. .idwp-message_error {
  1815. background: #fcc;
  1816. padding: 5px;
  1817. /* Rounded corners in most browsers! */
  1818. -moz-border-radius: 2px; /* For Mozilla Firefox */
  1819. -khtml-border-radius: 2px; /* For Konqueror */
  1820. -webkit-border-radius: 2px; /* For Safari */
  1821. border-radius: 2px; /* For future native implementations */
  1822. }
  1823. .idwp-message_error-symbol {
  1824. background: url(<?php echo ID_BASEURL ?>/images1/_wordpress/idwp.png) no-repeat -131px -133px;
  1825. display: inline-block;
  1826. float: left;
  1827. margin: 0 6px 0 0;
  1828. height: 17px;
  1829. width: 17px;
  1830. }
  1831. /* Import status */
  1832. .idwp-install-importstatus {
  1833. background: url(<?php echo ID_BASEURL ?>/images1/_wordpress/idwp.png) no-repeat -131px -163px;
  1834. cursor: default;
  1835. display: inline-block;
  1836. float: left;
  1837. margin: 0 0 2px;
  1838. }
  1839. .idwp-install-importstatus .idwp-install-importstatus-inner {
  1840. background: url(<?php echo ID_BASEURL ?>/images1/_wordpress/idwp.png) no-repeat 100% -163px;
  1841. font-size: 13px;
  1842. line-height: 28px;
  1843. margin: 0 0 0 12px;
  1844. padding: 0 12px 0 0;
  1845. }
  1846. .idwp-install-importstatus-inner strong {
  1847. margin: 0 12px 0 0;
  1848. }
  1849. .idwp-install-importstatus-info {
  1850. clear: left;
  1851. font-size: 11px;
  1852. padding: 0 0 0 12px;
  1853. }
  1854. .idwp-install-loading_indicator {
  1855. margin: 6px 0 0 6px;
  1856. }
  1857. /* Import complete! */
  1858. .idwp-success {
  1859. background: url(<?php echo ID_BASEURL ?>/images1/_wordpress/idwp.png) no-repeat -131px -201px;
  1860. line-height: 38px;
  1861. margin-top: 0;
  1862. padding: 0 0 0 45px;
  1863. }
  1864. /* !idwp-list-arrows */
  1865. .idwp-list-arrows {
  1866. }
  1867. .idwp-list-arrows li {
  1868. background: url(<?php echo ID_BASEURL ?>/images1/_wordpress/idwp.png) no-repeat -532px -248px;
  1869. line-height: 18px;
  1870. padding: 0 0 0 25px;
  1871. list-style: none;
  1872. }
  1873. /* !WP-style big buttons */
  1874. .idwp-bigbutton {
  1875. background: #f2f2f2 url(<?php echo ID_BASEURL ?>/images1/_wordpress/idwp.png) no-repeat -133px -63px;
  1876. font-family: "Lucida Grande", Verdana, Arial, "Bitstream Vera Sans", sans-serif;
  1877. text-decoration: none;
  1878. font-size: 14px !important;
  1879. line-height: 16px;
  1880. padding: 6px 12px;
  1881. cursor: pointer;
  1882. border: 1px solid #bbb;
  1883. color: #464646;
  1884. -moz-border-radius: 15px;
  1885. -khtml-border-radius: 15px;
  1886. -webkit-border-radius: 15px;
  1887. border-radius: 15px;
  1888. -moz-box-sizing: content-box;
  1889. -webkit-box-sizing: content-box;
  1890. -khtml-box-sizing: content-box;
  1891. box-sizing: content-box;
  1892. }
  1893. .idwp-bigbutton:hover {
  1894. color: #000;
  1895. border-color: #666;
  1896. }
  1897. .idwp-bigbutton:active {
  1898. background: #eee url(<?php echo ID_BASEURL ?>/images1/_wordpress/idwp.png) no-repeat -133px -93px;
  1899. }
  1900. /* ID WP Plugin Special Classes */
  1901. .idwp-secondary {
  1902. color: #999;
  1903. font-size: 11px;
  1904. line-height: 33px;
  1905. margin: 0 0 0 10px;
  1906. }
  1907. .idwp-shortline {
  1908. padding: 0 45% 0 0;
  1909. }
  1910. .idwp-fade {
  1911. color: #999;
  1912. }
  1913. .idwp-nomargin {
  1914. margin: 0 !important;
  1915. }
  1916. .idwp-clear {
  1917. clear: both;
  1918. display: block;
  1919. }
  1920. </style>
  1921. <div class="idwp-install" style="display: block;">
  1922. <div class="idwp-install-logo"></div>
  1923. <ul class="idwp-install-steps">
  1924. <li class="<?php if ( get_option( 'id_signup_step' ) == 0 ) echo 'idwp-sel'; else if ( get_option( 'id_signup_step' ) > 0 ) echo 'idwp-completed'; ?>">
  1925. <?php _e( 'Login', 'intensedebate' ); ?>
  1926. </li>
  1927. <li class="<?php if ( get_option( 'id_signup_step' ) == 1 || get_option( 'id_signup_step' ) == 2 ) echo 'idwp-sel'; else if ( get_option( 'id_signup_step' ) > 2 ) echo 'idwp-completed'; ?>">
  1928. <?php _e( 'Import', 'intensedebate' ); ?>
  1929. </li>
  1930. <li class="<?php if ( get_option( 'id_signup_step' ) == 3 ) echo 'idwp-sel'; else if ( get_option( 'id_signup_step' ) > 3 ) echo 'idwp-completed'; ?>">
  1931. <?php _e( 'Tweak', 'intensedebate' ); ?>
  1932. </li>
  1933. </ul>
  1934. <div class="idwp-install-main">
  1935. <?php if ( get_option( 'id_signup_step' ) == 0 ) : // first step (login/signup) ?>
  1936. <h3 class="idwp-nomargin"><?php _e( 'Please log in to your IntenseDebate account', 'intensedebate' ); ?></h3>
  1937. <p style="margin-top: 4px;"><?php _e( "Don't have an account?", 'intensedebate' ); ?> <a href="<?php echo ID_BASEURL ?>/signup" target="_blank"><?php _e( 'Sign up here', 'intensedebate' ); ?></a>. </p>
  1938. <p <?php if ( !id_param( 'login_msg' ) ) echo 'style="display:none"'; ?> class="idwp-message_error"><span class="idwp-message_error-symbol"></span> Login failed. Please check your credentials and try again.</p>
  1939. <?php $username = id_param( 'username' ); ?>
  1940. <form id="id_user_login" action="options-general.php?page=id_settings" method="POST">
  1941. <input type="hidden" name="id_settings_action" value="user_login" />
  1942. <div class="idwp-install-form_elements form-table">
  1943. <h4><label for="txtType"><?php _e( 'Log in using...', 'intensedebate' ); ?></label></h4>
  1944. <div class="idwp-input-text-wrap">
  1945. <input type="radio" name="id_remote_fields[account_type]" value="ID" id="radioTypeID" checked="checked" /> <label for="radioTypeID"><?php printf( __( '%s Account', 'intensedebate' ), 'IntenseDebate' ); ?></label>
  1946. <input type="radio" name="id_remote_fields[account_type]" value="WPC" id="radioTypeWP" /> <label for="radioTypeWP"> <?php printf( __( '%s Account' ), '<a href="http://wordpress.com/">WordPress.com</a>' ); ?></label>
  1947. </div>
  1948. <h4><label for="txtEmail"><?php _e( 'Email/Username', 'intensedebate' ); ?></label></h4>
  1949. <div class="idwp-input-text-wrap">
  1950. <input id="txtEmail" autocomplete="off" type="text" class="required regular-text" name="id_remote_fields[username]" value="<?php echo $username; ?>" />
  1951. <p class="idwp-fade"><?php _e( 'The email address or username you use for your IntenseDebate.com account.', 'intensedebate' ); ?></p>
  1952. </div>
  1953. <h4><label for="txtPassword"><?php _e( 'Password/User Key', 'intensedebate' ); ?></label></h4>
  1954. <div class="idwp-input-text-wrap" style="margin-bottom: 20px;">
  1955. <input id="txtPassword" autocomplete="off" type="password" class="required regular-text" name="id_remote_fields[password]" value="" /><a href='#' style="text-decoration:none" onclick='document.getElementById("useOpenID").style.display="block";'><img style="padding-left: 5px; padding-right: 2px" src="<?php echo ID_BASEURL ?>/images/icon-openid.png" /> Signed up with OpenID? </a>
  1956. <p class="idwp-fade"><a href="<?php echo ID_BASEURL ?>/forgot" target="_blank"><?php _e( 'Forgot your IntenseDebate password?', 'intensedebate' ); ?></a></p>
  1957. </div>
  1958. <span style="display:none" id="useOpenID"><?php printf( __( 'Unfortunately IntenseDebate and WordPress account syncing with OpenID is currently not directly available. Please use your IntenseDebate username and user key to sync your account. You can obtain your username and user key <a href="%s" target="_blank">here</a>.', 'intensedebate' ), ID_BASEURL . '/edit-user-account' ); ?></span>
  1959. </div><!--/ idwp-install-form_elements -->
  1960. <p>
  1961. <input type="submit" value="<?php _e( 'Login to IntenseDebate', 'intensedebate' ); ?>" class="idwp-bigbutton" />
  1962. <span id="test-connection"><img src="<?php echo ID_BASEURL ?>/images/ajax-loader.gif" align="absmiddle" alt="*" border="0" /> Testing connection to IntenseDebate.com...</span>
  1963. </p>
  1964. <p><strong><?php _e( 'Note:', 'intensedebate' ); ?></strong> <?php printf( __( "As is the case when installing any plugin, it's always a good idea to <a href=\"%s\">backup</a> your blog data before proceeding.", 'intensedebate' ), 'export.php' ); ?></p>
  1965. </form>
  1966. <script src="<?php echo ID_BASEURL; ?>/js/wordpress-test-connection.php?url=<?php echo urlencode( get_option( 'siteurl' ) ); ?>" type="text/javascript" charset="utf-8"></script>
  1967. <?php elseif ( get_option( 'id_signup_step' ) == 1 ) : //second step (start import) ?>
  1968. <h3 class="idwp-nomargin"><?php _e( 'Import your WordPress comments into IntenseDebate', 'intensedebate' ); ?></h3>
  1969. <div class="idwp-shortline">
  1970. <p><strong><?php global $userdata; $id_username = id_coalesce( $userdata->id_username ); printf( __( 'Welcome %s!', 'intensedebate' ), $id_username ); ?></strong> <?php _e( 'For your old WordPress comments to show up in the plugin, they need to be imported to give them all the IntenseDebate comment goodness.', 'intensedebate' ); ?> <a href="<?php echo ID_BASEURL ?>/wordpress#import" target="_blank">&raquo; <?php _e( 'Learn more', 'intensedebate' ); ?></a>.</p>
  1971. <p><?php _e( "The process usually takes less than a few hours, but times may vary depending on how many comments you're importing. You'll be notified via email when the import is complete.", 'intensedebate' ); ?></p>
  1972. <p><strong><?php _e( 'Note:', 'intensedebate' ); ?></strong> <?php _e( "Until your comments are imported they will not show up in the IntenseDebate comment system. Don't worry though, your comments are still safe and will be ready as soon as the import completes.", 'intensedebate' ); ?></p>
  1973. </div>
  1974. <form id="id_user_login" action="options-general.php?page=id_settings" method="POST">
  1975. <input type="hidden" name="id_settings_action" value="start_import" />
  1976. <p><input type="checkbox" name="use_id_moderation_strings" id="use_id_moderation_strings" value="1" checked="checked" /> <label for="use_id_moderation_strings"><?php _e( "Use IntenseDebate's default moderation settings (recommended)" ); ?></label> <span style="cursor:pointer;" onclick="jQuery('#explain_id_moderation_strings').slideToggle();"><img src="<?php echo ID_BASEURL ?>/images1/wp-info.png" /></span></p>
  1977. <p id="explain_id_moderation_strings" style="display: none;" class="idwp-shortline"><?php _e( "By enabling this option, IntenseDebate will add commonly-abused keywords and phrases to your moderation settings, so that you can avoid spam in your comments. You can always edit/delete these values later if you don't want them any more." ); ?></p>
  1978. <input type="submit" value="<?php _e( 'Start Importing Comments', 'intensedebate' ); ?>" class="idwp-bigbutton" /> <a href="javascript: document.getElementById('id_skip_import').submit();" class="idwp-secondary"><?php _e( 'Skip Import', 'intensedebate' ); ?></a>
  1979. </form>
  1980. <form id="id_skip_import" action="options-general.php?page=id_settings" method="POST">
  1981. <input type="hidden" name="id_settings_action" value="skip_import" />
  1982. </form>
  1983. <?php elseif ( get_option( 'id_signup_step' ) == 2 ) : //third step (import in progress) ?>
  1984. <h3 style="margin-top: 0;"><?php _e( 'Import in progress...', 'intensedebate' ); ?></h3>
  1985. <p class="idwp-message_error" id="id_importError" style="display: none"><span class="idwp-message_error-symbol"></span> <?php printf( __( 'An import error occured. Please <a href="%s">contact us</a> to get help!', 'intensedebate' ), ID_BASEURL . '/contactus' ); ?></p>
  1986. <div class="idwp-install-importstatus" id="id_importStatus_wrapper">
  1987. <div class="idwp-install-importstatus-inner" id="id_importStatus">
  1988. <strong>0%</strong>
  1989. </div>
  1990. </div><img id='id_loadingImage' src="<?php echo ID_BASEURL ?>/images/ajax-loader.gif" alt="Loading..." class="idwp-install-loading_indicator" title="Importing comments..." />
  1991. <div class="idwp-shortline">
  1992. <p><?php _e( "<strong>Please note:</strong> While comments are being imported you might notice some of your comments appear to be missing from the IntenseDebate comment system. Don't worry though, your comments will be back as soon as they are imported.", 'intensedebate' ); ?></p>
  1993. <p class="idwp-nomargin"><?php _e( "The process usually takes a few hours or less, but times may vary depending on how many comments you're importing. Feel free to go about your business in the mean time. You'll be notified via email when the import is complete.", 'intensedebate' ); ?></p>
  1994. </div>
  1995. <script type="text/javascript" src="<?php echo ID_BASEURL ?>/js/importStatus2.php?acctid=<?php echo get_option( "id_blogID" ); ?>&time=<?php echo time(); ?>"></script>
  1996. <?php elseif ( get_option( 'id_signup_step' ) >= 3 ) : //fourth step (fine tune) ?>
  1997. <h3 class="idwp-success"><?php _e( 'Success! IntenseDebate is now fully activated on your blog.', 'intensedebate' ); ?> <a href="<?php echo get_option( 'home' ); ?>" target="_blank">&raquo; <?php _e( 'View blog', 'intensedebate' ); ?></a></h3>
  1998. <h4><?php _e( 'Here are a few other customization options you might want to check out:', 'intensedebate' ); ?></h4>
  1999. <ul class="idwp-list-arrows">
  2000. <li><a href="<?php echo ID_BASEURL ?>/editacct/<?php echo get_option( 'id_blogID' ); ?>" target="_blank"><?php _e( 'Edit your blog settings on IntenseDebate.com', 'intensedebate' ); ?></a></li>
  2001. <li><a href="<?php echo ID_BASEURL ?>/bTheme/<?php echo get_option( 'id_blogID' ); ?>" target="_blank"><?php _e( 'Customize the comment layout', 'intensedebate' ); ?></a></li>
  2002. <li><a href="<?php echo ID_BASEURL ?>/addOns" target="_blank"><?php _e( 'Grab some comment widgets for your blog.', 'intensedebate' ); ?></a></li>
  2003. </ul>
  2004. <form id="id_close_box" action="options-general.php?page=id_settings&hideSettingsTop=true" method="POST">
  2005. </form>
  2006. <p style="margin: 20px 0 0;"><a href="javascript: document.getElementById('id_close_box').submit();"><?php _e( 'Close this box', 'intensedebate' ); ?></a></p>
  2007. <?php endif; ?>
  2008. </div><!--/ idwp-install-main -->
  2009. <span class="idwp-clear"></span>
  2010. </div><!--/ idwp-install -->
  2011. <?php endif; ?>
  2012. <?php if ( get_option( 'id_signup_step' ) >= 3 ) : ?>
  2013. <!-- post-activation settings -->
  2014. <div style="overflow:hidden;width:100%;">
  2015. <form id="id_manual_settings" class="ui-tabs-panel" action="options.php" method="post">
  2016. <input type="hidden" name="action" value="update" />
  2017. <input type="hidden" name="option_page" value="intensedebate" />
  2018. <?php
  2019. if ( version_compare( get_bloginfo( 'version' ), '2.7', '<' ) && empty( $wpmu_version ) )
  2020. wp_nonce_field( 'update-options' );
  2021. else
  2022. wp_nonce_field( 'intensedebate-options' );
  2023. ?>
  2024. <table class="form-table">
  2025. <tbody>
  2026. <tr valign="top">
  2027. <th scope="row" style="white-space: nowrap;" ><?php _e( 'Comment Template', 'intensedebate' ); ?> <span style="cursor:pointer;" onclick="jQuery('#divCommentSystemInfo').slideToggle();"><img src="<?php echo ID_BASEURL ?>/images1/wp-info.png" /></span></th>
  2028. <td>
  2029. <input type="radio" name="id_useIDComments" value="0" <?php if ( get_option( 'id_useIDComments' ) == 0 ) echo "checked"; ?> id="id_useIDComments_0"> <label for="id_useIDComments_0"><?php _e( 'IntenseDebate Comment Template', 'intensedebate' ); ?></label> <br />
  2030. <input type="radio" name="id_useIDComments" value="1" <?php if ( get_option( 'id_useIDComments' ) == 1 ) echo "checked"; ?> id="id_useIDComments_1"> <label for="id_useIDComments_1"><?php _e( 'WordPress Comment Template', 'intensedebate' ); ?></label>
  2031. <span class="idwp-clear"></span>
  2032. <p id="divCommentSystemInfo" class="hidden"><?php _e( "If you select to use the WordPress comment template, then we won't load the IntenseDebate comment system on your blog.", 'intensedebate' ); ?></p>
  2033. </td>
  2034. </tr>
  2035. <tr valign="top">
  2036. <th scope="row" style="white-space: nowrap;" ><?php _e( 'Comment Links', 'intensedebate' ); ?> <span style="cursor:pointer;" onclick="jQuery('#divCommentLinkInfo').slideToggle();"><img src="<?php echo ID_BASEURL ?>/images1/wp-info.png" /></span></th>
  2037. <td>
  2038. <input type="radio" name="id_jsCommentLinks" value="0" <?php if ( get_option( 'id_jsCommentLinks' ) == 0 ) echo "checked"; ?> id="id_jsCommentLinks_0"> <label for="id_jsCommentLinks_0"><?php _e( 'IntenseDebate Enhanced Comment Links', 'intensedebate' ); ?></label> (<a href="<?php echo ID_BASEURL ?>/editacct/<?php echo get_option('id_blogID'); ?>" target="_blank" title="Customize Comment Links"><?php _e( 'Customize Links', 'intensedebate' ); ?></a>)<br />
  2039. <input type="radio" name="id_jsCommentLinks" value="1" <?php if ( get_option( 'id_jsCommentLinks' ) == 1 ) echo "checked"; ?> id="id_jsCommentLinks_1"> <label for="id_jsCommentLinks_1"><?php _e( 'WordPress Standard Comment Links', 'intensedebate' ); ?></label>
  2040. <span class="idwp-clear"></span>
  2041. <p id="divCommentLinkInfo" class="hidden"><?php printf( __( 'Use customized comment link text by enabling IntenseDebate Enhanced Comment Links. <a href="%s">Learn more</a> about customizing your comment links.', 'intensedebate' ), ID_BASEURL . '/faq#li181' ); ?></p>
  2042. </td>
  2043. </tr>
  2044. <tr valign="top">
  2045. <th scope="row" style="white-space: nowrap;" ><?php _e( 'Comments for mobile devices', 'intensedebate' ); ?> <span style="cursor:pointer;" onclick="jQuery('#divRevertMobileInfo').slideToggle();"><img src="<?php echo ID_BASEURL ?>/images1/wp-info.png" /></span></th>
  2046. <td>
  2047. <input type="radio" name="id_revertMobile" value="0" <?php if ( get_option( 'id_revertMobile' ) == 0 ) echo "checked"; ?> id="id_revertMobile_0"> <label for="id_revertMobile_0"><?php _e( 'Revert to WordPress comments for visitors on mobile devices', 'intensedebate' ); ?></label> <br />
  2048. <input type="radio" name="id_revertMobile" value="1" <?php if ( get_option( 'id_revertMobile' ) == 1 ) echo "checked"; ?> id="id_revertMobile_1"> <label for="id_revertMobile_1"><?php _e( 'Use IntenseDebate comments for visitors on mobile devices', 'intensedebate' ); ?></label>
  2049. <span class="idwp-clear"></span>
  2050. <p id="divRevertMobileInfo" class="hidden"><?php _e( 'This setting will determine if we show IntenseDebate comments or WordPress comments when a reader on a mobile device visits your blog. Because IntenseDebate is not yet fully compatible with all mobile devices, we suggest reverting to the standard WordPress comments when mobile devices access your blog.', 'intensedebate' ); ?></p>
  2051. </td>
  2052. </tr>
  2053. <tr valign="top">
  2054. <th scope="row" style="white-space: nowrap;" ><?php _e( 'Comment Moderation Page', 'intensedebate' ); ?> <span style="cursor:pointer;" onclick="jQuery('#divModPageInfo').slideToggle();"><img src="<?php echo ID_BASEURL ?>/images1/wp-info.png" /></span></th>
  2055. <td>
  2056. <input type="radio" name="id_moderationPage" value="0" <?php if ( get_option( 'id_moderationPage' ) == 0 ) echo "checked"; ?> id="id_moderationPage_0"> <label for="id_moderationPage_0"><?php _e( 'IntenseDebate Enhanced Moderation', 'intensedebate' ); ?></label> <br />
  2057. <input type="radio" name="id_moderationPage" value="1" <?php if ( get_option( 'id_moderationPage' ) == 1 ) echo "checked"; ?> id="id_moderationPage_1"> <label for="id_moderationPage_1"><?php _e( 'WordPress Standard Moderation', 'intensedebate' ); ?></label>
  2058. <span class="idwp-clear"></span>
  2059. <p id="divModPageInfo" class="hidden"><?php _e( "Moderate and reply to IntenseDebate comments from your WordPress admin panel using our custom moderation page that mirrors the WordPress page that you're already used to. The only difference is the extra IntenseDebate zest we've added by including IntenseDebate avatars, reputation points, profile links and all of our other metadata gravy that you'll love.", 'intensedebate' ); ?></p>
  2060. </td>
  2061. </tr>
  2062. <tr valign="top">
  2063. <th scope="row" style="white-space: nowrap;" ><?php _e( 'Auto Login', 'intensedebate' ); ?> <span style="cursor:pointer;" onclick="jQuery('#divAutoLoginInfo').slideToggle();"><img src="<?php echo ID_BASEURL ?>/images1/wp-info.png" /></span></th>
  2064. <td>
  2065. <input type="radio" name="id_auto_login" value="0" <?php if ( get_option( 'id_auto_login' ) == 0 ) echo "checked"; ?> id="id_auto_login_0"> <label for="id_auto_login_0"><?php printf( __( 'Automatically log me in to IntenseDebate when possible (<a href="%s">Connect your IntenseDebate account to your WordPress profile</a>)', 'intensedebate' ), 'profile.php#intensedebatelogin' ); ?></label> <br />
  2066. <input type="radio" name="id_auto_login" value="1" <?php if ( get_option( 'id_auto_login' ) == 1 ) echo "checked"; ?> id="id_auto_login_1"> <label for="id_auto_login_1"><?php _e( "Don't automatically log me in to IntenseDebate", 'intensedebate' ); ?></label>
  2067. <span class="idwp-clear"></span>
  2068. <p id="divAutoLoginInfo" class="hidden"><?php _e( "This setting will determine if we attempt to log you (or any users that have synced a WordPress account to an IntenseDebate account) in to IntenseDebate automatically when you're signed into your WordPress account. Note: this might not work in Safari if third party cookies are not enabled.", 'intensedebate' ); ?></p>
  2069. </td>
  2070. </tr>
  2071. </tbody>
  2072. </table>
  2073. <p class="submit">
  2074. <input type="submit" name="Submit" value="<?php _e( 'Save Changes', 'intensedebate' ) ?>" class="button-primary" />
  2075. </p>
  2076. </form>
  2077. </div>
  2078. <?php endif; ?>
  2079. <?php
  2080. if ( get_option( 'id_signup_step' ) > 0 )
  2081. id_reset_plugin_form();
  2082. ?>
  2083. </div>
  2084. <?php
  2085. }
  2086. // errors, etc at top of settings page
  2087. function id_message() {
  2088. if ( $msg = id_param( 'msg' ) ) {
  2089. ?>
  2090. <div id="message" class="updated fade"><p><strong><?php echo htmlspecialchars( $msg ); ?></strong></p></div>
  2091. <?php
  2092. }
  2093. }
  2094. function id_reset_plugin_form() {
  2095. if ( get_option( 'id_signup_step' ) > 0 ) :
  2096. ?>
  2097. <form id="id_plugin_reset" action="options-general.php?page=id_settings" method="POST">
  2098. <input type="hidden" name="id_settings_action" value="settings_reset" />
  2099. <p><?php _e( 'Click the button below to remove/reset all IntenseDebate settings.', 'intensedebate' ); ?></p>
  2100. <p class="submit" style="border: 0; padding: 0 0 10px;">
  2101. <input type="submit" name="Submit" value="<?php _e( 'Reset IntenseDebate Plugin', 'intensedebate' ) ?>" />
  2102. </p>
  2103. <p id="id_restartLink"><?php printf( __( 'If you\'re experiencing import/sync problems you can <a href="%s">do a clean import</a> to see if that fixes it (duplicates will be skipped).', 'intensedebate' ), ID_BASEURL . '/resetWPImport.php?acctid=' . get_option( "id_blogID" ) . '&blogKey=' . get_option( 'id_blogKey' ) ); ?></p>
  2104. </form><?php
  2105. endif;
  2106. }
  2107. // postback for settings page
  2108. function id_process_settings_page() {
  2109. $id_settings_action = 'id_SETTINGS_' . id_param( 'id_settings_action' );
  2110. if ( function_exists( $id_settings_action ) )
  2111. call_user_func( $id_settings_action );
  2112. }
  2113. function id_clear_blog_settings() {
  2114. $settings = array(
  2115. 'id_blogAcct'
  2116. , 'id_blogID'
  2117. , 'id_blogKey'
  2118. , 'id_import_comment_id'
  2119. , 'id_import_post_id'
  2120. , 'id_import_token'
  2121. , 'id_userID'
  2122. , 'id_userKey'
  2123. , 'id_jsCommentLinks'
  2124. , 'id_moderationPage'
  2125. , ID_REQUEST_QUEUE_NAME
  2126. , 'id_revertMobile'
  2127. , 'id_useIDComments'
  2128. , 'id_hideSettingsTop'
  2129. , 'id_signup_step'
  2130. , 'id_auto_login'
  2131. , 'id_lock_queue'
  2132. );
  2133. foreach ( $settings as $setting ) {
  2134. delete_option( $setting );
  2135. }
  2136. }
  2137. function id_SETTINGS_settings_reset() {
  2138. id_clear_blog_settings();
  2139. global $wpdb;
  2140. $users = get_users_of_blog();
  2141. $meta = array( 'id_username', 'id_userID', 'id_userKey' );
  2142. foreach ( $users as $user ) {
  2143. foreach ( $meta as $key ) {
  2144. id_delete_user_meta( $user->user_id, $key );
  2145. }
  2146. }
  2147. // notify ID
  2148. $fields = array();
  2149. $queue = id_get_queue();
  2150. $op = $queue->add( 'plugin_reset', $fields, 'id_generic_callback' );
  2151. $queue->ping( array( $op ) );
  2152. }
  2153. // Skip import
  2154. function id_SETTINGS_skip_import() {
  2155. id_save_option( 'id_signup_step', 3 );
  2156. $goback = remove_query_arg( 'updated', $_SERVER['REQUEST_URI'] );
  2157. $goback = remove_query_arg( 'login_msg', $goback );
  2158. wp_redirect( $goback );
  2159. }
  2160. // Start import
  2161. function id_SETTINGS_start_import() {
  2162. id_REST_reset_import();
  2163. // Send request to start importing comments
  2164. $fields = array( "blog_id" => get_option( 'id_blogID' ), "blog_key" => get_option( 'id_blogKey' ) );
  2165. $queue = id_get_queue();
  2166. $queue->create();
  2167. $op = $queue->add( 'start_import', $fields, 'id_process_start_import_callback' );
  2168. $queue->ping( array( $op ) );
  2169. $queue->create();
  2170. // Trigger initial sync of moderation/discussion settings
  2171. id_discussion_sync_from_db( id_param( 'use_id_moderation_strings') );
  2172. // Go to the next step
  2173. id_save_option( 'id_signup_step', 2 );
  2174. $goback = remove_query_arg( 'updated', $_SERVER['REQUEST_URI'] );
  2175. $goback = remove_query_arg( 'login_msg', $goback );
  2176. wp_redirect( $goback );
  2177. }
  2178. function id_process_start_import_callback( &$result, &$response, &$operation ) {
  2179. // empty
  2180. }
  2181. function id_get_blog_name() {
  2182. $str = get_option( 'blogname' );
  2183. if ( !strlen( $str ) ) {
  2184. $url = parse_url( get_option( 'siteurl' ) );
  2185. $url = str_replace( 'www.', '', $url['host'] );
  2186. $str = sprintf( __( 'WordPress blog at %s', 'intensedebate' ), $url );
  2187. }
  2188. return $str;
  2189. }
  2190. // login form post-back
  2191. function id_SETTINGS_user_login() {
  2192. global $userdata;
  2193. $goback = remove_query_arg( 'updated', $_SERVER['REQUEST_URI'] );
  2194. $goback = remove_query_arg( 'login_msg', $goback );
  2195. $messages = array();
  2196. $fields = id_param( 'id_remote_fields', array() );
  2197. $fields['admin'] = current_user_can( 'manage_options' );
  2198. $fields['blog_url'] = get_option( 'siteurl' );
  2199. $fields['blog_rss'] = get_bloginfo( 'rss_url' );
  2200. $fields['blog_title'] = id_get_blog_name();
  2201. $fields['blog_sitetype'] = "wordpress";
  2202. $fields['rest_service'] = $fields['blog_url'] . '/index.php?id_action=import';
  2203. $fields['token'] = id_generate_token( $fields );
  2204. $fields['wp_userID'] = $userdata->ID;
  2205. $fields['start_import'] = "false";
  2206. foreach ( $fields as $n => $v ) {
  2207. if ( !strlen( $v ) ) {
  2208. $messages[] = 'Missing field: ' . $n;
  2209. }
  2210. }
  2211. if ( !count( $messages ) ) {
  2212. $queue = id_get_queue();
  2213. $queue->create();
  2214. $op = $queue->add( 'user_login', $fields, 'id_process_user_login_callback' );
  2215. $queue->ping( array( $op ) );
  2216. $loginOperation = $queue->operations[0];
  2217. $loginResponse = $loginOperation->response;
  2218. $messages[] = id_coalesce( @$loginResponse->error_msg, "Login successful" );
  2219. }
  2220. if ( count( $messages ) ) {
  2221. $msg = implode( '<br/>', $messages );
  2222. $goback = add_query_arg( 'login_msg', urlencode( $msg ), $goback );
  2223. } else {
  2224. $goback = add_query_arg( 'updated', 'true', $goback );
  2225. }
  2226. wp_redirect( $goback );
  2227. }
  2228. // login api callback
  2229. function id_process_user_login_callback( &$result, &$response, &$operation ) {
  2230. global $userdata;
  2231. $args = func_get_args();
  2232. if (
  2233. strtolower( $result ) == "success"
  2234. && $response->userID
  2235. && $response->userKey
  2236. && $response->blogID > 0
  2237. && $response->blogKey
  2238. && $response->blogAcct != ''
  2239. ) {
  2240. id_save_option( 'id_userID', $response->userID );
  2241. id_save_option( 'id_userKey', $response->userKey );
  2242. id_save_option( 'id_blogID', $response->blogID );
  2243. id_save_option( 'id_blogKey', $response->blogKey );
  2244. id_save_option( 'id_blogAcct', $response->blogAcct );
  2245. //Save default options
  2246. id_save_option( 'id_jsCommentLinks', 0 );
  2247. id_save_option( 'id_moderationPage', 0 );
  2248. id_save_option( 'id_useIDComments', 0 );
  2249. id_save_option( 'id_revertMobile', 0 );
  2250. //Set to go to next step
  2251. id_save_option( 'id_signup_step', 1 );
  2252. id_save_usermeta_array( $userdata->ID, array(
  2253. 'id_userID' => $response->userID,
  2254. 'id_userKey' => $response->userKey,
  2255. 'id_username' => $response->username
  2256. ) );
  2257. // password IntenseDebate uses to request imported comments
  2258. id_save_option( 'id_import_token', $operation->data['token'] );
  2259. // start importing from the beginning of time
  2260. id_save_option( 'id_import_comment_id', '0' );
  2261. return true;
  2262. }
  2263. return false;
  2264. }
  2265. // returns highest comment ID in wp database
  2266. function id_get_latest_comment_id() {
  2267. global $wpdb;
  2268. return $wpdb->get_var( "SELECT MAX(comment_ID) FROM $wpdb->comments" );
  2269. }
  2270. // COMMENT MODERATION PAGE
  2271. function id_moderate_comments() {
  2272. global $userdata;
  2273. $wp_userID = $userdata->ID;
  2274. $userID = id_get_user_meta( $wp_userID, 'id_userID' );
  2275. $userKey = id_get_user_meta( $wp_userID, 'id_userKey' );
  2276. $curSysTime = gmdate( "U" );
  2277. $iframe_url = ID_COMMENT_MODERATION_PAGE;
  2278. if ( is_ssl() )
  2279. $iframe_url = str_replace( 'http://', 'https://secure.', $iframe_url );
  2280. ?>
  2281. <div class="wrap">
  2282. <?php if ( function_exists( 'screen_icon' ) ) screen_icon( 'edit-comments' ); ?>
  2283. <h2><?php _e( 'Edit Comments', 'intensedebate' ); ?></h2>
  2284. <iframe frameborder="0" id="id_iframe_moderation" src="<?php echo $iframe_url . get_option( 'id_blogID' ) . "&userid=$userID&time=$curSysTime&authstr=" . md5( $userKey . $curSysTime ); ?>" style="width: 100%; height: 500px; border: none;" onload="addScript()" scrolling="auto"></iframe>
  2285. </div>
  2286. <script type="text/javascript">
  2287. jQuery('#adminmenu a[href=edit-comments.php]').addClass('current');
  2288. function addScript() {
  2289. setTimeout("addScript2();", 100);
  2290. }
  2291. function addScript2() {
  2292. var idScript = document.createElement("script");
  2293. idScript.type = "text/javascript";
  2294. idScript.src = "<?php echo ID_BASEURL ?>/js/updateWindowHeightForWPPlugin.php?acctid=<?php echo get_option( 'id_blogID' ); ?>";
  2295. document.getElementsByTagName("head")[0].appendChild(idScript);
  2296. }
  2297. </script>
  2298. <?php
  2299. }
  2300. // Load our own custom comments template
  2301. function id_comments_template( $file ) {
  2302. if ( !is_singular() )
  2303. return $file;
  2304. return dirname( __FILE__ ) . '/intensedebate-comment-template.php';
  2305. }
  2306. // Force-load the original template (fall-back)
  2307. function id_get_original_comment_template() {
  2308. remove_filter( 'comments_template', 'id_comments_template' );
  2309. comments_template();
  2310. add_filter( 'comments_template', 'id_comments_template' );
  2311. }
  2312. function id_get_comment_number( $comment_text ) {
  2313. global $post;
  2314. if ( get_option( "id_jsCommentLinks" ) == 0 ) {
  2315. $id = $post->ID;
  2316. $posttitle = urlencode( $post->post_title );
  2317. $posttime = urlencode( $post->post_date_gmt );
  2318. $postauthor = urlencode( id_get_author_name() );
  2319. $permalink = urlencode( get_permalink( $post->ID ) );
  2320. $guid = urlencode( $post->guid );
  2321. return "<span class='IDCommentsReplace' style='display:none'>$id</span>$comment_text<span style='display:none' id='IDCommentPostInfoPermalink$id'>$permalink</span><span style='display:none' id='IDCommentPostInfoTitle$id'>$posttitle</span><span style='display:none' id='IDCommentPostInfoTime$id'>$posttime</span><span style='display:none' id='IDCommentPostInfoAuthor$id'>$postauthor</span><span style='display:none' id='IDCommentPostInfoGuid$id'>$guid</span>";
  2322. } else {
  2323. return $comment_text;
  2324. }
  2325. }
  2326. // Output JS required to load an external script file via safely
  2327. // appending an object to the DOM once the rest of the page is loaded.
  2328. function id_postload_js( $url, $id = false ) {
  2329. ?>
  2330. <script type="text/javascript">
  2331. /* <![CDATA[ */
  2332. var s = document.createElement("script"); s.type = "text/javascript";<?php echo $id ? " s.id = '" . addslashes( $id ) . "';" : ''; ?> s.src = "<?php echo addslashes( $url ); ?>"; document.getElementsByTagName("head")[0].appendChild(s);
  2333. /* ]]> */
  2334. </script>
  2335. <?php
  2336. }
  2337. function id_admin_footer() {
  2338. if ( 0 == get_option( 'id_moderationPage' ) )
  2339. id_postload_js( ID_BASEURL . "/js/wpModLink.php?acct=" . get_option( "id_blogAcct" ) );
  2340. }
  2341. function id_get_comment_footer_script() {
  2342. global $id_link_wrapper_output;
  2343. if ( !$id_link_wrapper_output ) {
  2344. $id_link_wrapper_output = true;
  2345. if ( get_option( "id_blogAcct" ) )
  2346. id_postload_js( ID_BASEURL . '/js/wordpressTemplateLinkWrapper2.php?acct=' . get_option( "id_blogAcct" ) );
  2347. }
  2348. }
  2349. function id_clear_orphan_comments() {
  2350. global $wpdb;
  2351. remove_action( 'trashed_comment', 'id_comment_trashed', 10 );
  2352. remove_action( 'wp_set_comment_status', 'id_comment_status', 10, 2 );
  2353. // Get comments with post=0
  2354. $offset = 0;
  2355. // Using direct queries because get_comments() doesn't give access to post_ID=0, or date ranges
  2356. while ( $comments = $wpdb->get_col( $wpdb->prepare( "SELECT `comment_ID` FROM {$wpdb->comments} WHERE `comment_post_ID` = 0 AND `comment_date_gmt` BETWEEN '2010-07-16 00:00:00' AND '2010-07-23 00:00:00' LIMIT $offset, 50" ) ) ) {
  2357. foreach ( $comments as $comment ) {
  2358. // Check date
  2359. wp_delete_comment( $comment, true );
  2360. }
  2361. $offset += 50;
  2362. }
  2363. // Ping ID for a resync
  2364. $fields = array( 'sync_type' => 'PDX' );
  2365. $queue = id_get_queue();
  2366. $op = $queue->add( 'request_resync', $fields, 'id_generic_callback' );
  2367. $queue->ping( array( $op ) );
  2368. add_option( 'id_pdxsync', time() );
  2369. add_action( 'trashed_comment', 'id_comment_trashed', 10 );
  2370. add_action( 'wp_set_comment_status', 'id_comment_status', 10, 2 );
  2371. }
  2372. // Add ID blog stats widget
  2373. function widget_id_blog_stats($args) {
  2374. extract($args);
  2375. echo $before_widget;
  2376. echo "<script type='text/javascript' src='http://www.intensedebate.com/widgets/blogStats/" . get_option( "id_blogID" ) . "'></script>";
  2377. echo $after_widget;
  2378. }
  2379. function id_blog_stats_init() {
  2380. wp_register_sidebar_widget( 'id-stats', __( 'IntenseDebate - Site Stats' ), 'widget_id_blog_stats' );
  2381. }
  2382. add_action( "plugins_loaded", "id_blog_stats_init" );
  2383. // Add ID recent comments widget
  2384. function widget_id_recent_comments( $args ) {
  2385. extract( $args );
  2386. echo $before_widget;
  2387. $count = intval( get_option( 'id_recent_comments_count' ) );
  2388. if ( $count <= 0 )
  2389. $count = 5;
  2390. echo "<script type='text/javascript' src='http://www.intensedebate.com/widgets/acctComment/" . get_option( "id_blogID" ) . "/$count'></script>";
  2391. echo $after_widget;
  2392. }
  2393. function widget_id_recent_comments_control() {
  2394. $count = get_option( 'id_recent_comments_count' );
  2395. ?>
  2396. <p><label>Number of comments to display:<input name="id_recent_comments_count" type="text" value="<?php echo $count; ?>" /></label></p>
  2397. <?php
  2398. if ( isset( $_POST['id_recent_comments_count'] ) ) {
  2399. if ( !is_numeric( $_POST['id_recent_comments_count'] ) ) {
  2400. echo "Please enter a number";
  2401. return;
  2402. }
  2403. $count = intval( $_POST['id_recent_comments_count'] );
  2404. if ( $count <= 0 ) {
  2405. echo "Please enter an integer greater than zero.";
  2406. return;
  2407. }
  2408. update_option( 'id_recent_comments_count', attribute_escape( $_POST['id_recent_comments_count'] ) );
  2409. }
  2410. }
  2411. function id_recent_comments_init() {
  2412. wp_register_sidebar_widget( 'id-recent', __( 'IntenseDebate - Recent Comments' ), 'widget_id_recent_comments' );
  2413. wp_register_widget_control( 'id-recent', __( 'IntenseDebate - Recent Comments' ), 'widget_id_recent_comments_control' );
  2414. }
  2415. add_action( "plugins_loaded", "id_recent_comments_init" );
  2416. // Add ID top commenters widget
  2417. function widget_id_top_commenters( $args ) {
  2418. extract($args);
  2419. echo $before_widget;
  2420. $count = intval( get_option( 'id_top_commenters_count' ) );
  2421. if ( $count <= 0 )
  2422. $count = 10;
  2423. echo "<script type='text/javascript' src='http://www.intensedebate.com/widgets/topCommenters/" . get_option( "id_blogID" ) . "/$count'></script>";
  2424. echo $after_widget;
  2425. }
  2426. function widget_id_top_commenters_control() {
  2427. $count = get_option( 'id_top_commenters_count' );
  2428. ?>
  2429. <p><label>Number of commenters to display:<input name="id_top_commenters_count" type="text" value="<?php echo $count; ?>" /></label></p>
  2430. <?php
  2431. if ( isset( $_POST['id_top_commenters_count'] ) ) {
  2432. if ( !is_numeric( $_POST['id_top_commenters_count'] ) ) {
  2433. echo "Please enter a number";
  2434. return;
  2435. }
  2436. $count = intval( $_POST['id_top_commenters_count'] );
  2437. if ( $count <= 0 ) {
  2438. echo "Please enter an integer greater than zero.";
  2439. return;
  2440. }
  2441. update_option( 'id_top_commenters_count', attribute_escape( $_POST['id_top_commenters_count'] ) );
  2442. }
  2443. }
  2444. function id_top_commenters_init() {
  2445. wp_register_sidebar_widget( 'id-top', __( 'IntenseDebate - Top Commenters' ), 'widget_id_top_commenters' );
  2446. wp_register_widget_control( 'id-top', __( 'IntenseDebate - Top Commenters' ), 'widget_id_top_commenters_control' );
  2447. }
  2448. add_action( "plugins_loaded", "id_top_commenters_init" );
  2449. // Add ID most commented posts widget
  2450. function widget_id_most_commented_posts( $args ) {
  2451. extract( $args );
  2452. echo $before_widget;
  2453. $count = intval( get_option( 'id_most_commented_posts_count' ) );
  2454. if ( $count <= 0 )
  2455. $count = 10;
  2456. echo "<script type='text/javascript' src='http://www.intensedebate.com/widgets/mostComments/" . get_option( "id_blogID" ) . "/$count'></script>";
  2457. echo $after_widget;
  2458. }
  2459. function widget_id_most_commented_posts_control() {
  2460. $count = get_option( 'id_most_commented_posts_count' );
  2461. ?>
  2462. <p><label>Number of posts to display:<input name="id_most_commented_posts_count" type="text" value="<?php echo $count; ?>" /></label></p>
  2463. <?php
  2464. if ( isset( $_POST['id_most_commented_posts_count'] ) ) {
  2465. if ( !is_numeric( $_POST['id_most_commented_posts_count'] ) ) {
  2466. echo "Please enter a number";
  2467. return;
  2468. }
  2469. $count = intval( $_POST['id_most_commented_posts_count'] );
  2470. if ( $count <= 0 ) {
  2471. echo "Please enter an integer greater than zero.";
  2472. return;
  2473. }
  2474. update_option( 'id_most_commented_posts_count', attribute_escape( $_POST['id_most_commented_posts_count'] ) );
  2475. }
  2476. }
  2477. function id_most_commented_posts_init() {
  2478. wp_register_sidebar_widget( 'id-commented', __( 'IntenseDebate - Most Commented Posts' ), 'widget_id_most_commented_posts' );
  2479. wp_register_widget_control( 'id-commented', __( 'IntenseDebate - Most Commented Posts'), 'widget_id_most_commented_posts_control' );
  2480. }
  2481. add_action("plugins_loaded", "id_most_commented_posts_init");
  2482. // Detect if this is a mobile client based on the user agent
  2483. function id_is_mobile() {
  2484. $op = !empty( $_SERVER['HTTP_X_OPERAMINI_PHONE'] ) ? strtolower( $_SERVER['HTTP_X_OPERAMINI_PHONE'] ) : '';
  2485. $ua = strtolower( $_SERVER['HTTP_USER_AGENT'] );
  2486. $ac = !empty( $_SERVER['HTTP_ACCEPT'] ) ? strtolower( $_SERVER['HTTP_ACCEPT'] ) : '';
  2487. $ip = $_SERVER['REMOTE_ADDR'];
  2488. if ( strpos( $ua, 'ipad' ) )
  2489. return false;
  2490. $isMobile = strpos( $ac, 'application/vnd.wap.xhtml+xml' ) !== false
  2491. || $op != ''
  2492. || strpos( $ua, 'sony' ) !== false
  2493. || strpos( $ua, 'webos/' ) !== false
  2494. || strpos( $ua, 'symbian' ) !== false
  2495. || strpos( $ua, 'nokia' ) !== false
  2496. || strpos( $ua, 'samsung' ) !== false
  2497. || strpos( $ua, 'mobile' ) !== false
  2498. || strpos( $ua, 'windows ce' ) !== false
  2499. || strpos( $ua, 'epoc' ) !== false
  2500. || strpos( $ua, 'opera mini' ) !== false
  2501. || strpos( $ua, 'nitro' ) !== false
  2502. || strpos( $ua, 'j2me' ) !== false
  2503. || strpos( $ua, 'midp-' ) !== false
  2504. || strpos( $ua, 'cldc-' ) !== false
  2505. || strpos( $ua, 'netfront' ) !== false
  2506. || strpos( $ua, 'mot' ) !== false
  2507. || strpos( $ua, 'up.browser' ) !== false
  2508. || strpos( $ua, 'up.link' ) !== false
  2509. || strpos( $ua, 'audiovox' ) !== false
  2510. || strpos( $ua, 'blackberry' ) !== false
  2511. || strpos( $ua, 'ericsson,' ) !== false
  2512. || strpos( $ua, 'panasonic' ) !== false
  2513. || strpos( $ua, 'philips' ) !== false
  2514. || strpos( $ua, 'sanyo' ) !== false
  2515. || strpos( $ua, 'sharp' ) !== false
  2516. || strpos( $ua, 'sie-' ) !== false
  2517. || strpos( $ua, 'portalmmm' ) !== false
  2518. || strpos( $ua, 'blazer' ) !== false
  2519. || strpos( $ua, 'avantgo' ) !== false
  2520. || strpos( $ua, 'danger' ) !== false
  2521. || strpos( $ua, 'palm' ) !== false
  2522. || strpos( $ua, 'series60' ) !== false
  2523. || strpos( $ua, 'palmsource' ) !== false
  2524. || strpos( $ua, 'pocketpc' ) !== false
  2525. || strpos( $ua, 'smartphone' ) !== false
  2526. || strpos( $ua, 'rover' ) !== false
  2527. || strpos( $ua, 'ipaq' ) !== false
  2528. || strpos( $ua, 'au-mic,' ) !== false
  2529. || strpos( $ua, 'alcatel' ) !== false
  2530. || strpos( $ua, 'ericy' ) !== false
  2531. || strpos( $ua, 'up.link' ) !== false
  2532. || strpos( $ua, 'vodafone/' ) !== false
  2533. || strpos( $ua, 'wap1.' ) !== false
  2534. || strpos( $ua, 'wap2.' ) !== false;
  2535. return $isMobile;
  2536. }
  2537. // ACTIVATE HOOKS
  2538. id_activate_hooks();