diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index cb6ba3f..0000000 --- a/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "lib/acTwitterConversation"] - path = lib/acTwitterConversation - url = https://github.com/adriancrepaz/acTwitterConversation.git diff --git a/importers/keyring-reactions-500px.php b/importers/keyring-reactions-500px.php index b2d8303..f5adcbd 100644 --- a/importers/keyring-reactions-500px.php +++ b/importers/keyring-reactions-500px.php @@ -141,7 +141,6 @@ class Keyring_500px_Reactions extends Keyring_Reactions_Base { */ function get_comments ( &$post_id, &$silo_id ) { $baseurl = sprintf("https://api.500px.com/v1/photos/%s/comments", $silo_id); - $results = $this->request ( $baseurl, 'comments' ); if ($results && is_array($results) && !empty($results)) { $auto = ( $this->get_option( 'auto_approve' ) == 1 ) ? 1 : 0; @@ -173,6 +172,31 @@ class Keyring_500px_Reactions extends Keyring_Reactions_Base { } } + + + // temporarily hack + $baseurl = sprintf( "https://api.500px.com/v1/photos/%s?", $silo_id ); + $params = array( + 'comments' => 1, + ); + $starturl = $baseurl . http_build_query( $params ); + $result = $this->request ( $starturl, 'photo' ); + + if ($result && is_array($result) && !empty($result)) { + $geo = array ( + 16 => 'geo_latitude', + 17 => 'geo_longitude' + ); + + foreach ($geo as $check => $meta_key ) { + if ( isset($result[$check]) && !empty($result[$check])) { + update_post_meta ($post_id, $meta_key, $result[$check]); + Keyring_Util::debug(sprintf(__('adding geo data for %s','keyring'), $post_id)); + } + } + + + } } diff --git a/importers/keyring-reactions-facebook.php b/importers/keyring-reactions-facebook.php index 62ca9d2..3bc2213 100644 --- a/importers/keyring-reactions-facebook.php +++ b/importers/keyring-reactions-facebook.php @@ -79,13 +79,13 @@ class Keyring_Facebook_Reactions extends Keyring_Reactions_Base { $auto = ( $this->get_option( 'auto_approve' ) == 1 ) ? 1 : 0; $type = $this->methods[ 'likes' ]; + $tpl = __( '%s liked this entry on facebook','keyring'); foreach ( $results as $element ) { $avatar = sprintf('https://graph.facebook.com/%s/picture', $element->id ); $author_url = 'https://facebook.com/' . $element->id; $name = $element->name; - $tpl = __( '%s liked this entry on facebook','keyring'); $c = array ( 'comment_author' => $name, diff --git a/importers/keyring-reactions-instagram.php b/importers/keyring-reactions-instagram.php new file mode 100644 index 0000000..729aed7 --- /dev/null +++ b/importers/keyring-reactions-instagram.php @@ -0,0 +1,169 @@ +methods = array ( + // method name => comment type + 'likes' => 'like', + 'comments' => 'comment' + ); + + //$this->methods = array ('votes', 'favs', 'comments'); + parent::__construct(); + } + + function make_all_requests( $method, $post ) { + extract($post); + + if (empty($post_id)) + return new Keyring_Error( + 'keyring-instagram-reactions-missing-post-id', + __( 'Missing post ID to make request for.', 'keyring') + ); + + if (empty($syndication_url)) + return new Keyring_Error( + 'keyring-instagram-reactions-missing-syndication-url', + __( 'Missing syndication URL.', 'keyring') + ); + + // get media id here + $api = file_get_contents(sprintf('https://api.instagram.com/oembed?url=%s', $syndication_url)); + $apiObj = json_decode($api,true); + if ( !isset($apiObj['media_id']) || empty($apiObj['media_id'])) + return new Keyring_Error( + 'keyring-instagram-reactions-photo-id-not-found', + __( 'Cannot get photo ID out of syndication URL.', 'keyring' ) + ); + + $silo_id = $apiObj['media_id']; + + $func = 'get_' . $method; + if ( !method_exists( $this, $func ) ) + return new Keyring_Error( + 'keyring-instagram-reactions-missing-func', + sprintf(__( 'Function is missing for this method (%s), cannot proceed!', 'keyring'), $method) + ); + + return $this->$func ( $post_id, $silo_id ); + } + + /** + * LIKES + */ + + function get_likes ( $post_id, $silo_id ) { + $baseurl = sprintf ('https://api.instagram.com/v1/media/%s/likes?', $silo_id ); + + $params = array( + 'access_token' => $this->service->token->token, + ); + + $url = $baseurl . http_build_query( $params ); + $data = $this->service->request( $url, array( 'method' => $this->request_method, 'timeout' => 10 ) ); + + if ( Keyring_Util::is_error( $data ) ) + Keyring_Util::Debug (json_encode($data)); + + if ($data->data && is_array($data->data) && !empty($data->data)) { + + $auto = ( $this->get_option( 'auto_approve' ) == 1 ) ? 1 : 0; + $type = $this->methods[ 'likes' ]; + $tpl = __( '%s liked this entry on instagram','keyring'); + + foreach ( $data->data as $element ) { + + $name = empty($element->full_name) ? $element->username : $element->full_name; + $email = $element->username .'@'. self::SILONAME; + $avatar = empty ($element->profile_picture) ? '' : $element->profile_picture; + $author_url = 'https://instagram.com/' . $element->username; + + $c = array ( + 'comment_author' => $name, + 'comment_author_url' => $author_url, + 'comment_author_email' => $email, + 'comment_post_ID' => $post_id, + 'comment_type' => $type, + //'comment_date' => date("Y-m-d H:i:s", $element->favedate ), + //'comment_date_gmt' => date("Y-m-d H:i:s", $element->favedate ), + 'comment_agent' => get_class($this), + 'comment_approved' => $auto, + 'comment_content' => sprintf( $tpl, $author_url, $name ), + ); + + $this->insert_comment ( $post_id, $c, $element, $avatar); + } + } + } + + /** + * COMMENTS + */ + + function get_comments ( $post_id, $silo_id ) { + $baseurl = sprintf ('https://api.instagram.com/v1/media/%s/comments?', $silo_id ); + + $params = array( + 'access_token' => $this->service->token->token, + ); + + $url = $baseurl . http_build_query( $params ); + $data = $this->service->request( $url, array( 'method' => $this->request_method, 'timeout' => 10 ) ); + + if ( Keyring_Util::is_error( $data ) ) + Keyring_Util::Debug (json_encode($data)); + + + if ($data->data && is_array($data->data) && !empty($data->data)) { + + $auto = ( $this->get_option( 'auto_approve' ) == 1 ) ? 1 : 0; + $type = $this->methods[ 'comments' ]; + + foreach ( $data->data as $element ) { + + $name = empty($element->from->full_name) ? $element->from->username : $element->from->full_name; + $email = $element->from->username .'@'. self::SILONAME; + $avatar = empty ($element->from->profile_picture) ? '' : $element->from->profile_picture; + $author_url = 'https://instagram.com/' . $element->from->username; + + $c = array ( + 'comment_author' => $name, + 'comment_author_url' => $author_url, + 'comment_author_email' => $email, + 'comment_post_ID' => $post_id, + 'comment_type' => $type, + 'comment_date' => date("Y-m-d H:i:s", $element->created_time ), + 'comment_date_gmt' => date("Y-m-d H:i:s", $element->created_time ), + 'comment_agent' => get_class($this), + 'comment_approved' => $auto, + 'comment_content' => $element->text + ); + + $this->insert_comment ( $post_id, $c, $element, $avatar); + } + } + } + +}} + + +add_action( 'init', function() { + Keyring_Instagram_Reactions(); // Load the class code from above + keyring_register_reactions( + Keyring_Instagram_Reactions::SLUG, + 'Keyring_Instagram_Reactions', + plugin_basename( __FILE__ ), + __( 'Import comments and likes from Instagram for your syndicated posts.', 'keyring' ) + ); +} ); diff --git a/keyring-reactions-importer.php b/keyring-reactions-importer.php index 1e8c6f8..bf11991 100644 --- a/keyring-reactions-importer.php +++ b/keyring-reactions-importer.php @@ -51,6 +51,7 @@ abstract class Keyring_Reactions_Base { const KEYRING_NAME = ''; // Keyring service name; SLUG is not used to avoid conflict with Keyring Social Importer const KEYRING_SERVICE = ''; // Full class name of the Keyring_Service this importer requires const REQUESTS_PER_LOAD = 3; // How many posts should queried before moving over to the next branch / reload the page + const REQUESTS_PER_AUTO = 16; const KEYRING_VERSION = '1.4'; // Minimum version of Keyring required const SILONAME = ''; // identifier for the silo in the syndication_url field entry @@ -60,7 +61,7 @@ abstract class Keyring_Reactions_Base { const SCHEDULE = 'daily'; // this may break many things, careful if you wish to change it const SCHEDULETIME = 36400; // in tandem with the previous - const RESCHEDULE = 30; + const RESCHEDULE = 60; // You shouldn't need to edit (or override) these ones var $step = 'greet'; @@ -100,11 +101,14 @@ abstract class Keyring_Reactions_Base { // additional comment types add_action('admin_comment_types_dropdown', array(&$this, 'comment_types_dropdown')); + // ... + add_filter('get_avatar_comment_types', array( &$this, 'add_comment_types')); + // additional cron schedules add_filter( 'cron_schedules', array(&$this, 'cron' )); // additional avatar filter - add_filter( 'get_avatar' , 'Keyring_Reactions_Base::get_avatar' , 1 , 5 ); + add_filter( 'get_avatar' , array(&$this, 'get_avatar'), 1, 5 ); // If a request is made for a new connection, pass it off to Keyring if ( @@ -127,11 +131,6 @@ abstract class Keyring_Reactions_Base { $this->service->set_token( $token ); } - // Make sure we have a scheduled job to handle auto-imports if enabled - // but delay it for good reasons - if ( $this->get_option( 'auto_import' ) && !wp_get_schedule( $this->schedule ) ) - wp_schedule_event( time() + static::SCHEDULETIME, static::SCHEDULE, $this->schedule ); - // jump to the first worker $this->handle_request(); } @@ -166,6 +165,17 @@ abstract class Keyring_Reactions_Base { return $types; } + /** + * + */ + public function add_comment_types ( $types ) { + foreach ($this->methods as $method => $type ) { + if (!in_array( $type, $types )) + array_push( $types, $type ); + } + return $types; + } + /** * add our own, ridiculously intense schedule for chanining all the requests * wee need for the imports @@ -175,12 +185,14 @@ abstract class Keyring_Reactions_Base { * @return array the filtered WP CRON schedules */ public function cron ( $schedules ) { + /* if (!isset($schedules[ $this->optname ])) { $schedules[ $this->optname ] = array( 'interval' => static::RESCHEDULE, 'display' => sprintf(__( '%s auto import' ), static::SLUG ) ); } + */ return $schedules; } @@ -208,6 +220,7 @@ abstract class Keyring_Reactions_Base { else $safe_alt = esc_attr($alt); + return sprintf( '', $safe_alt, $c_avatar, $size, $size ); } @@ -217,13 +230,31 @@ abstract class Keyring_Reactions_Base { * done, set $this->step = 'import' to continue, or 'options' to show the options form again. */ protected function handle_request_options() { - $bools = array('auto_import','auto_approve'); + $auto_import = (isset( $_POST['auto_import']) && !empty($_POST['auto_import'])) ? true : false; - foreach ( $bools as $bool ) { - if ( isset( $_POST[$bool] ) ) - $_POST[$bool] = true; - else - $_POST[$bool] = false; + $auto_approve = (isset( $_POST['auto_approve']) && !empty($_POST['auto_approve'])) ? true : false; + + /* + if ( $this->get_option('auto_import') && !wp_get_schedule( $this->schedule ) ) { + wp_schedule_event( time() + static::SCHEDULETIME, static::SCHEDULE, $this->schedule ); + } + elseif ( $this->get_option('auto_import') && wp_get_schedule( $this->schedule != static::SCHEDULE ) ) { + wp_clear_scheduled_hook ( $this->schedule ); + wp_schedule_event( time() + static::SCHEDULETIME, static::SCHEDULE, $this->schedule ); + } + elseif ( !$this->get_option('auto_import') ) { + Keyring_Util::Debug('Ez most fut?'); + wp_clear_scheduled_hook ( $this->schedule ); + } + */ + + wp_clear_scheduled_hook ( $this->schedule ); + + if ($auto_import) { + wp_schedule_event( time() + static::SCHEDULETIME, static::SCHEDULE, $this->schedule ); + } + else { + $this->cleanup(); } // If there were errors, output them, otherwise store options and start importing @@ -231,12 +262,12 @@ abstract class Keyring_Reactions_Base { $this->step = 'greet'; } else { $this->set_option( array( - 'auto_import' => (bool) $_POST['auto_import'], - 'auto_approve' => (bool) $_POST['auto_approve'], - 'limit_posts' => sanitize_text_field($_POST['limit_posts']), + 'auto_import' => $auto_import, + 'auto_approve' => $auto_approve, + 'limit_posts' => sanitize_text_field($_POST['limit_posts']), ) ); - $this->step = 'import'; + $this->step = 'done'; } } @@ -300,7 +331,7 @@ abstract class Keyring_Reactions_Base { $this->options = array_merge( (array) $this->options, $name ); else if ( is_null( $name ) && is_null( $val ) ) { // $name = null to reset all options $this->options = array(); - wp_unschedule_event( time(), $this->schedule ); + wp_clear_scheduled_hook ( $this->schedule ); } else if ( is_null( $val ) && isset( $this->options[ $name ] ) ) unset( $this->options[ $name ] ); @@ -379,9 +410,9 @@ abstract class Keyring_Reactions_Base { } // If we're "refreshing", then just act like it's an auto import - if ( isset( $_POST['refresh'] ) ) { - $this->auto_import = true; - } + //if ( isset( $_POST['refresh'] ) ) { + // $this->auto_import = true; + //} // Write a custom request handler in the extending class here // to handle processing/storing options for import. Make sure to @@ -414,7 +445,6 @@ abstract class Keyring_Reactions_Base { case 'greet': $this->greet(); break; - case 'options': $this->options(); break; @@ -423,6 +453,7 @@ abstract class Keyring_Reactions_Base { break; case 'import_single': $this->do_single_import(); + break; case 'done': $this->done(); break; @@ -738,16 +769,20 @@ abstract class Keyring_Reactions_Base { * one-by-one so one iteration of the WP CRON event will not take that long * and may not cause issues later on. */ - public function do_auto_import() { + public function do_auto_import( ) { defined( 'WP_IMPORTING' ) or define( 'WP_IMPORTING', true ); do_action( 'import_start' ); set_time_limit( 0 ); + Keyring_Util::debug( static::SLUG . sprintf(' auto import: init')); + // In case auto-import has been disabled, clear all jobs and bail if ( !$this->get_option( 'auto_import' ) ) { + Keyring_Util::debug( static::SLUG . sprintf(' auto import: clearing hook')); wp_clear_scheduled_hook( 'keyring_' . static::SLUG . '_import_auto' ); return; } + // Need a token to do anything with this if ( !$this->service->get_token() ) return; @@ -756,13 +791,13 @@ abstract class Keyring_Reactions_Base { require_once ABSPATH . 'wp-admin/includes/post.php'; require_once ABSPATH . 'wp-admin/includes/comment.php'; - $this->auto_import = true; $next = 0; $position = 0; + $num = 0; $this->get_posts(); - if ( !$this->finished ) { + while ( !$this->finished && $num < static::REQUESTS_PER_AUTO ) { $position = $this->get_option( static::OPTNAME_POSTPOS, 0); if ( !is_array($this->posts) || !isset($this->posts[$position]) ) @@ -772,8 +807,9 @@ abstract class Keyring_Reactions_Base { ); $todo = $this->posts[$position]; - $msg = sprintf(__('Starting auto import for #%s', 'keyring'), $todo['post_id']); - Keyring_Util::debug($msg); + Keyring_Util::debug( static::SLUG . sprintf(' auto import: doing %s/%s', $position, count($this->posts)-1 )); + //$msg = sprintf(__('Starting auto import for #%s', 'keyring'), $todo['post_id']); + //Keyring_Util::debug($msg); foreach ( $this->methods as $method => $type ) { $msg = sprintf(__('Processing %s for post #%s', 'keyring'), $method, $todo['post_id']); @@ -786,29 +822,30 @@ abstract class Keyring_Reactions_Base { } $next = $position+1; + $num++; // we're done, clean up - if ($next >= sizeof($this->posts)) { + if ( $next >= count($this->posts) ) { $this->finished = true; - $this->cleanup(); - Keyring_Util::debug( static::SLUG . ' auto import finished' ); - - // set the original schedule, starting with the defined next offset - wp_reschedule_event( time() + static::SCHEDULETIME, static::SCHEDULE , $this->schedule ); + break; } - // we're not finished yet else { $this->set_option( static::OPTNAME_POSTPOS, $next ); - Keyring_Util::debug( static::SLUG . ' auto import: there is more coming' ); - - // the next run of this very job should be - // near immediate, otherwise we'd never finish with all the post; - // event this way a few thousand posts will result in issues - // for sure, so there has to be something - wp_reschedule_event( time() + static::RESCHEDULE , $this->optname, $this->schedule ); } } + Keyring_Util::debug( sprintf ('%s auto import: current batch finised (%s to %s out of %s )', static::SLUG, (int) ($position - static::REQUESTS_PER_AUTO), $position, count($this->posts)-1 )); + + if ( $this->finished || $next >= count($this->posts) ) { + Keyring_Util::debug( sprintf ('%s auto import: FINISHED', static::SLUG)); + $this->cleanup(); + do_action( 'keyring_import_done', $this->optname ); + } + else { + Keyring_Util::debug( sprintf ('%s auto import: Rescheduling event', static::SLUG)); + wp_schedule_single_event( time() + static::RESCHEDULE, $this->schedule ); + } + do_action( 'import_end' ); } @@ -968,12 +1005,23 @@ abstract class Keyring_Reactions_Base { do_action( 'keyring_import_done', $this->optname ); } + /** + * When they're complete, give them a quick summary and a link back to their website. + */ + function saved() { + $this->header(); + echo '