/** * Remove the WordPress comments menu bar item, replacing with a Facebook comments link * Check if Facebook comments enabled and if the current user might be able to view a comments edit screen on Facebook * * @since 1.1 * @see WP_Admin_Bar->add_menus() */ public static function admin_bar_menu() { global $facebook_loader; if (is_network_admin() && is_user_admin()) { return; } // use moderate_comments capability as a local proxy for accounts that might be granted moderate comments permissions for the Facebook application if the application administrator fully setup the app // technically the WordPress menu item is added for users with 'edit_posts' due to the permissions of the destination page but we'll check for the specific comments permission instead // TODO: check if Facebook data stored for current user, check if Facebook user is moderator if (!current_user_can('moderate_comments')) { return; } if (!class_exists('Facebook_User')) { require_once dirname(dirname(__FILE__)) . '/facebook-user.php'; } $current_user = wp_get_current_user(); $facebook_user_data = Facebook_User::get_user_meta($current_user->ID, 'fb_data', true); if (!(is_array($facebook_user_data) && isset($facebook_user_data['fb_uid']))) { return; } // swap only. don't add a menu item if none existed if (remove_action('admin_bar_menu', 'wp_admin_bar_comments_menu', 60)) { add_action('admin_bar_menu', array('Facebook_Comments', 'admin_bar_add_comments_menu'), 60); } }
/** * Load extra assets early in the page build process to tap into proper hooks * * @since 1.1 */ public function onload() { global $facebook, $facebook_loader; // prompt to log in or update account info if (!class_exists('Facebook_Admin_Login')) { require_once dirname(__FILE__) . '/login.php'; } Facebook_Admin_Login::connect_facebook_account(array('manage_pages', 'publish_actions', 'publish_stream')); // prep user-specific functionality and comparisons $this->current_user = wp_get_current_user(); if (!class_exists('Facebook_User')) { require_once dirname(dirname(__FILE__)) . '/facebook-user.php'; } // does the current user have associated Facebook account data stored in WordPress? $facebook_user_data = Facebook_User::get_user_meta($this->current_user->ID, 'fb_data', true); if (is_array($facebook_user_data) && isset($facebook_user_data['fb_uid'])) { $this->user_associated_with_facebook_account = true; if (isset($facebook) || isset($facebook_loader) && $facebook_loader->load_php_sdk()) { $this->user_permissions = $facebook->get_current_user_permissions($this->current_user); } if (!is_array($this->user_permissions)) { $this->user_permissions = array(); } } else { $this->user_associated_with_facebook_account = false; $this->user_permissions = array(); } $this->settings_api_init(); }
/** * Check if the current user has associated his or her Facebook profile with his or her WordPress account * If the current user can edit posts and has not authorized Facebook then show a prompt encouraging action. * * @since 1.1 */ public static function connect_facebook_account($verify_permissions = null) { global $facebook; $profile_prompt = false; // check for permission to publish Open Graph action (publish article) // check for the superset permission: publish_stream if (!is_array($verify_permissions)) { $profile_prompt = true; $verify_permissions = array('publish_actions', 'publish_stream'); } $current_user = wp_get_current_user(); // no need to alert if he cannot create a post if (!user_can($current_user, 'edit_posts')) { return; } if (!class_exists('Facebook_User')) { require_once dirname(__FILE__) . '/facebook-user.php'; } $facebook_user_data_exists = false; $facebook_user_data = Facebook_User::get_user_meta($current_user->ID, 'fb_data', true); if (is_array($facebook_user_data) && isset($facebook_user_data['fb_uid'])) { if (empty($verify_permissions)) { return; } $facebook_user_data_exists = true; } // Facebook information not found $facebook_user = Facebook_User::get_current_user(array('id', 'username')); if ($facebook_user) { $permissions = $facebook->get_current_user_permissions($facebook_user); $all_permissions_exist = true; foreach ($verify_permissions as $permission_to_verify) { if (!isset($permissions[$permission_to_verify])) { $all_permissions_exist = false; break; } } if ($all_permissions_exist) { if (!$facebook_user_data_exists || $facebook_user_data['fb_uid'] != $facebook_user['id']) { $facebook_user_data = array('fb_uid' => $facebook_user['id'], 'activation_time' => time()); if (!empty($facebook_user['username'])) { $facebook_user_data['username'] = $facebook_user['username']; } Facebook_User::update_user_meta($current_user->ID, 'fb_data', $facebook_user_data); } return; } } // priority before js sdk registration needed to add JS inside FbAsyncInit add_action('admin_enqueue_scripts', array('Facebook_Admin_Login', 'add_async_load_javascript_filter'), -1, 0); // add all others at P11 after scripts registered add_action('admin_enqueue_scripts', array('Facebook_Admin_Login', 'enqueue_scripts'), 11); if ($profile_prompt) { add_action('admin_notices', array('Facebook_Admin_Login', 'admin_notice'), 1, 0); } // up top }
/** * Add Open Graph protocol markup to <head> * We use full IRIs for consistent mapping between mapped CURIE prefixes defined in a parent element and self-contained properties using a full IRI * * @since 1.0 * @link http://www.w3.org/TR/rdfa-syntax/#s_curieprocessing RDFa Core 1.1 CURIE and IRI processing */ public static function add_og_protocol() { global $post, $facebook_loader; $meta_tags = array(self::OGP_NS . 'site_name' => get_bloginfo('name'), self::OGP_NS . 'type' => 'website'); if (isset($facebook_loader)) { if (isset($facebook_loader->locale)) { $meta_tags[self::OGP_NS . 'locale'] = $facebook_loader->locale; } if (isset($facebook_loader->credentials) && isset($facebook_loader->credentials['app_id']) && $facebook_loader->credentials['app_id']) { $meta_tags[self::FB_NS . 'app_id'] = $facebook_loader->credentials['app_id']; } } if (is_home() || is_front_page()) { $meta_tags[self::OGP_NS . 'title'] = get_bloginfo('name'); $meta_tags[self::OGP_NS . 'description'] = get_bloginfo('description'); $meta_tags[self::OGP_NS . 'url'] = home_url(); } else { if (is_single() && empty($post->post_password)) { setup_postdata($post); $post_type = get_post_type(); $meta_tags[self::OGP_NS . 'url'] = apply_filters('facebook_rel_canonical', get_permalink()); if (post_type_supports($post_type, 'title')) { $meta_tags[self::OGP_NS . 'title'] = get_the_title(); } if (post_type_supports($post_type, 'excerpt')) { $description = ''; // did the publisher specify a custom excerpt? use it if (!empty($post->post_excerpt)) { $description = apply_filters('get_the_excerpt', $post->post_excerpt); } else { $description = $post->post_content; } $description = self::clean_description($description); if ($description) { $meta_tags[self::OGP_NS . 'description'] = $description; } } $meta_tags[self::OGP_NS . 'type'] = 'article'; $meta_tags[self::ARTICLE_NS . 'published_time'] = date('c', strtotime($post->post_date_gmt)); $meta_tags[self::ARTICLE_NS . 'modified_time'] = date('c', strtotime($post->post_modified_gmt)); if (post_type_supports($post_type, 'author') && isset($post->post_author)) { $meta_tags[self::ARTICLE_NS . 'author'] = get_author_posts_url($post->post_author); // adding an fb:admin grants comment moderation permissions for Comment Box if (get_option('facebook_comments_enabled') && user_can($post->post_author, 'moderate_comments')) { if (!class_exists('Facebook_Comments')) { require_once dirname(__FILE__) . '/social-plugins/class-facebook-comments.php'; } if (Facebook_Comments::comments_enabled_for_post_type($post)) { if (!class_exists('Facebook_User')) { require_once dirname(__FILE__) . '/facebook-user.php'; } $facebook_user_data = Facebook_User::get_user_meta($post->post_author, 'fb_data', true); if (is_array($facebook_user_data) && isset($facebook_user_data['fb_uid'])) { $meta_tags[self::FB_NS . 'admins'] = $facebook_user_data['fb_uid']; } unset($facebook_user_data); } } } // add the first category as a section. all other categories as tags $cat_ids = get_the_category(); if (!empty($cat_ids)) { $no_category = apply_filters('the_category', __('Uncategorized')); $cat = get_category($cat_ids[0]); if (!empty($cat) && isset($cat->name) && $cat->name !== $no_category) { $meta_tags[self::ARTICLE_NS . 'section'] = $cat->name; } //output the rest of the categories as tags unset($cat_ids[0]); if (!empty($cat_ids)) { $meta_tags[self::ARTICLE_NS . 'tag'] = array(); foreach ($cat_ids as $cat_id) { $cat = get_category($cat_id); if (isset($cat->name) && $cat->name !== $no_category) { $meta_tags[self::ARTICLE_NS . 'tag'][] = $cat->name; } unset($cat); } } } // add tags. treat tags as lower priority than multiple categories $tags = get_the_tags(); if ($tags) { if (!array_key_exists(self::ARTICLE_NS . 'tag', $meta_tags)) { $meta_tags[self::ARTICLE_NS . 'tag'] = array(); } foreach ($tags as $tag) { $meta_tags[self::ARTICLE_NS . 'tag'][] = $tag->name; } } // does current post type and the current theme support post thumbnails? if (post_type_supports($post_type, 'thumbnail') && function_exists('has_post_thumbnail') && has_post_thumbnail()) { list($post_thumbnail_url, $post_thumbnail_width, $post_thumbnail_height) = wp_get_attachment_image_src(get_post_thumbnail_id($post->ID), 'full'); if (!empty($post_thumbnail_url)) { $image = array('url' => $post_thumbnail_url); if (!empty($post_thumbnail_width)) { $image['width'] = absint($post_thumbnail_width); } if (!empty($post_thumbnail_height)) { $image['height'] = absint($post_thumbnail_height); } $meta_tags[self::OGP_NS . 'image'] = array($image); } } $gallery_images = self::gallery_images($post); if (!empty($gallery_images)) { foreach ($gallery_images as $gallery_image) { // do not repeat the thumbnail if (isset($post_thumbnail_url) && $post_thumbnail_url === $gallery_image['url']) { continue; } $meta_tags[self::OGP_NS . 'image'][] = $gallery_image; } } unset($gallery_images); } else { if (is_author()) { $author = get_queried_object(); if (!($author && isset($author->ID))) { break; } $author_id = $author->ID; $meta_tags[self::OGP_NS . 'type'] = 'profile'; $meta_tags[self::OGP_NS . 'title'] = get_the_author_meta('display_name', $author_id); $meta_tags[self::OGP_NS . 'url'] = get_author_posts_url(get_the_author_meta('ID', $author_id)); $meta_tags[self::PROFILE_NS . 'first_name'] = get_the_author_meta('first_name', $author_id); $meta_tags[self::PROFILE_NS . 'last_name'] = get_the_author_meta('last_name', $author_id); $description = self::clean_description(get_the_author_meta('description', $author_id)); if ($description) { $meta_tags[self::OGP_NS . 'description'] = $description; } if (!class_exists('Facebook_User')) { require_once dirname(__FILE__) . '/facebook-user.php'; } $facebook_user_data = Facebook_User::get_user_meta($author_id, 'fb_data', true); if (is_array($facebook_user_data) && isset($facebook_user_data['third_party_id'])) { $meta_tags[self::FB_NS . 'profile_id'] = $facebook_user_data['third_party_id']; } unset($facebook_user_data); // no need to show username if there is only one if (is_multi_author()) { $meta_tags[self::PROFILE_NS . 'username'] = get_the_author_meta('login', $author_id); } } else { if (is_page()) { $meta_tags[self::OGP_NS . 'type'] = 'article'; $meta_tags[self::OGP_NS . 'title'] = get_the_title(); $meta_tags[self::OGP_NS . 'url'] = apply_filters('facebook_rel_canonical', get_permalink()); } } } } $meta_tags = apply_filters('fb_meta_tags', $meta_tags, $post); // default: true while Facebook crawler corrects its indexing of full IRI values if (apply_filters('facebook_ogp_prefixed', true)) { $meta_tags = self::prefixed_properties($meta_tags); } foreach ($meta_tags as $property => $content) { self::meta_elements($property, $content); } }
/** * Initialize the backend, administrative views * * @since 1.1 */ public function admin_init() { $admin_dir = $this->plugin_directory . 'admin/'; $sdk = $this->load_php_sdk(); if ($sdk) { if (!class_exists('Facebook_User')) { require_once dirname(__FILE__) . '/facebook-user.php'; } Facebook_User::extend_access_token(); } if (!class_exists('Facebook_Settings')) { require_once $admin_dir . 'settings.php'; } Facebook_Settings::init(); if (!class_exists('Facebook_Social_Publisher')) { require_once $admin_dir . 'social-publisher/social-publisher.php'; } new Facebook_Social_Publisher(); if (!class_exists('Facebook_Mentions_Search')) { require_once $admin_dir . 'social-publisher/mentions/mentions-search.php'; } Facebook_Mentions_Search::wp_ajax_handlers(); }
/** * Save custom user information * * @since 1.2 * @param int $wordpress_user_id WordPress user identifier */ public static function save_data($wordpress_user_id) { remove_filter('user_contactmethods', array('Facebook_User_Profile', 'user_contactmethods'), 1, 2); if (!($wordpress_user_id && current_user_can('edit_user', $wordpress_user_id))) { return; } if (isset($_POST['facebook_timeline']) && $_POST['facebook_timeline'] == '1') { if (!class_exists('Facebook_User')) { require_once dirname(dirname(__FILE__)) . '/facebook-user.php'; } Facebook_User::delete_user_meta($wordpress_user_id, 'facebook_timeline_disabled'); // delete if stored } else { if (!class_exists('Facebook_User')) { require_once dirname(dirname(__FILE__)) . '/facebook-user.php'; } Facebook_User::update_user_meta($wordpress_user_id, 'facebook_timeline_disabled', '1'); } }
/** * Does the current WordPress user have Facebook data stored? * Has the current viewer authorized the current application to post on his or her behalf? * * @since 1.1 * @return bool true if Facebook information present for current user and publish permissions exist */ public static function can_publish_to_facebook() { global $facebook; if (!isset($facebook)) { return false; } $current_user = wp_get_current_user(); // does the current user have associated Facebook account data stored in WordPress? $facebook_user_data = self::get_user_meta($current_user->ID, 'fb_data', true); if (!(is_array($facebook_user_data) && isset($facebook_user_data['fb_uid']))) { return false; } if (Facebook_User::get_user_meta($current_user->ID, 'facebook_timeline_disabled', true)) { return false; } $permissions = $facebook->get_current_user_permissions($current_user); if (!(is_array($permissions) && !empty($permissions) && isset($permissions['publish_stream']) && isset($permissions['publish_actions']))) { return false; } return true; }
/** * Delete data persisted by the Facebook PHP SDK using WordPress-specific access method * * @since 1.0 */ protected function clearPersistentData($key) { if (!in_array($key, self::$kSupportedKeys)) { self::errorLog('Unsupported key passed to clearPersistentData.'); return; } // load user functions if (!class_exists('Facebook_User')) { require_once dirname(dirname(dirname(__FILE__))) . '/facebook-user.php'; } Facebook_User::delete_user_meta(get_current_user_id(), $key); }
/** * Publish a post to a Facebook User Timeline. * * @since 1.0 * * @global \Facebook_Loader $facebook_loader Access Facebook application credentials * @param int $post_id WordPress post identifier * @param stdClass|WP_Post $post WordPress post object * @return void */ public static function publish_to_facebook_profile($post_id, $post) { global $facebook_loader; $post_id = absint($post_id); if (!(isset($facebook_loader) && $facebook_loader->app_access_token_exists() && $post && $post_id)) { return; } // does the current post have an existing Facebook post id stored? no need to publish again if (get_post_meta($post_id, 'fb_author_post_id', true)) { return; } $meta_box_present = true; if (defined('XMLRPC_REQUEST') && XMLRPC_REQUEST) { $meta_box_present = false; } if (!class_exists('Facebook_Social_Publisher_Meta_Box_Profile')) { require_once dirname(__FILE__) . '/publish-box-profile.php'; } if ($meta_box_present && get_post_meta($post_id, Facebook_Social_Publisher_Meta_Box_Profile::POST_META_KEY_FEATURE_ENABLED, true) === '0') { return; } setup_postdata($post); $post_type = get_post_type($post); if (!(self::post_type_is_public($post_type) && post_type_supports($post_type, 'author') && isset($post->post_author))) { return; } $post_author = (int) $post->post_author; if (!$post_author) { return; } // test the author, not the current actor if (!self::user_can_publish_to_facebook($post_author)) { return; } if (!class_exists('Facebook_User')) { require_once $facebook_loader->plugin_directory . 'facebook-user.php'; } $author_facebook_id = Facebook_User::get_facebook_profile_id($post_author); if (!$author_facebook_id) { return; } // check our assumptions about a valid link in place // fail if a piece of the filter process killed our response $link = apply_filters('facebook_rel_canonical', get_permalink($post_id)); if (!$link) { return; } $og_action = false; if (!class_exists('Facebook_Social_Publisher_Settings')) { require_once $facebook_loader->plugin_directory . 'admin/settings-social-publisher.php'; } if (get_option(Facebook_Social_Publisher_Settings::OPTION_OG_ACTION)) { $og_action = true; } if (!class_exists('Facebook_Open_Graph_Protocol')) { require_once $facebook_loader->plugin_directory . 'open-graph-protocol.php'; } $path = $author_facebook_id . '/'; if ($og_action && Facebook_Open_Graph_Protocol::get_post_og_type($post) === 'article') { $story = array('article' => $link); $path .= 'news.publishes'; if ($meta_box_present) { $story['fb:explicitly_shared'] = 'true'; } } else { $story = array('link' => $link); $path .= 'feed'; } $message = get_post_meta($post_id, Facebook_Social_Publisher_Meta_Box_Profile::POST_META_KEY_MESSAGE, true); if (is_string($message) && $message) { $story['message'] = trim($message); } if (!class_exists('Facebook_WP_Extend')) { require_once $facebook_loader->plugin_directory . 'includes/facebook-php-sdk/class-facebook-wp.php'; } $status_messages = array(); try { $publish_result = Facebook_WP_Extend::graph_api_with_app_access_token($path, 'POST', $story); if (isset($publish_result['id'])) { update_post_meta($post_id, 'fb_author_post_id', sanitize_text_field($publish_result['id'])); delete_post_meta($post_id, Facebook_Social_Publisher_Meta_Box_Profile::POST_META_KEY_MESSAGE); delete_post_meta($post_id, Facebook_Social_Publisher_Meta_Box_Profile::POST_META_KEY_FEATURE_ENABLED); } } catch (WP_FacebookApiException $e) { $error_result = $e->getResult(); $status_messages[] = array('message' => esc_html(__('Failed posting to your Facebook Timeline.', 'facebook')) . ' ' . esc_html(__('Error', 'facebook')) . ': ' . esc_html(json_encode($error_result['error'])), 'error' => true); } if (isset($publish_result) && isset($publish_result['id'])) { $link = '<a href="' . esc_url('https://www.facebook.com/' . $publish_result['id'], array('http', 'https')) . '" target="_blank">' . esc_html(__('Facebook Timeline', 'facebook')) . '</a>'; if (empty($message)) { $message = sprintf(esc_html(__('Posted to %s', 'facebook')), $link); } else { $message = sprintf(esc_html(__('Posted to %1$s with message "%2$s"', 'facebook')), $link, esc_html($message)); } $status_messages[] = array('message' => $message, 'error' => false); } // add new status messages if (!empty($status_messages)) { $existing_status_messages = get_post_meta($post_id, 'fb_status_messages', true); if (is_array($existing_status_messages) && !empty($existing_status_messages)) { $status_messages = array_merge($existing_status_messages, $status_messages); } update_post_meta($post_id, 'facebook_status_messages', $status_messages); add_filter('redirect_post_location', array('Facebook_Social_Publisher', 'add_new_post_location')); } }
/** * Set the appropriate settings for each form component * * @since 1.1 * @param array $options social publisher options * @return array clean option sets. */ public static function sanitize_publish_options($options) { global $facebook; if (!is_array($options) || empty($options)) { return array(); } if (!class_exists('Facebook_User')) { require_once dirname(dirname(__FILE__)) . '/facebook-user.php'; } // publish to timeline is really a per-user setting, not a per-site setting // handle the special user case $user_meta_key = 'facebook_timeline_disabled'; $current_user = wp_get_current_user(); if (isset($options['author_timeline']) && $options['author_timeline'] == 1) { Facebook_User::delete_user_meta($current_user->ID, $user_meta_key); } else { Facebook_User::update_user_meta($current_user->ID, $user_meta_key, '1'); } // is a new page chosen? // if the same page selected on new_page_timeline as currently stored don't overwrite the access token // it is possible multiple users can create content from the page but should not overwrite each other when editing the page without changing the target page if (isset($options['new_page_timeline'])) { $page_id = trim($options['new_page_timeline']); if (!$page_id && isset($options['page_timeline']['id'])) { delete_option(self::OPTION_PUBLISH_TO_PAGE); } else { if ($page_id && !(isset($options['page_timeline']['id']) && $options['page_timeline']['id'] == $options['new_page_timeline'])) { $pages_for_current_user = self::get_publishable_pages_for_current_user(); foreach ($pages_for_current_user as $page) { if (isset($page['id']) && $page['id'] === $page_id) { self::update_publish_to_page($page); break; } } } } } return false; }
/** * Add Subscribe Button(s) to post content * Adds a subscribe button above the post, below the post, or both above and below the post depending on stored preferences. * * @since 1.1 * @param string $content existing content * @return string passed content with Subscribe Button markup prepended, appended, or both. */ function facebook_the_content_subscribe_button($content) { global $post; // Send Button should not be the only content if (!$content) { return $content; } $options = get_option('facebook_subscribe_button'); if (!is_array($options)) { $options = array(); } if (!class_exists('Facebook_User')) { require_once dirname(dirname(__FILE__)) . '/facebook-user.php'; } $facebook_user = Facebook_User::get_user_meta(get_the_author_meta('ID'), 'fb_data', true); if (!($facebook_user && isset($facebook_user['fb_uid']))) { return $content; } if (isset($facebook_user['username'])) { $options['href'] = 'https://www.facebook.com/' . $facebook_user['username']; } else { $options['href'] = 'https://www.facebook.com/profile.php?' . http_build_query(array('id' => $facebook_user['fb_uid'])); } if ($options['position'] === 'top') { $options['ref'] = 'above-post'; return facebook_get_subscribe_button($options) . $content; } else { if ($options['position'] === 'bottom') { $options['ref'] = 'below-post'; return $content . facebook_get_subscribe_button($options); } else { if ($options['position'] === 'both') { $options['ref'] = 'above-post'; $above = facebook_get_subscribe_button($options); $options['ref'] = 'below-post'; return $above . $content . facebook_get_subscribe_button($options); } } } // don't break the filter return $content; }
/** * Get all users with edit_posts capabilities broken out into Facebook-permissioned users and non-Facebook permissioned users * * @since 1.1.6 */ public static function get_all_wordpress_facebook_users() { if (!class_exists('Facebook_User')) { require_once dirname(dirname(__FILE__)) . '/facebook-user.php'; } // fb => [], wp => [] $users = Facebook_User::get_wordpress_users_associated_with_facebook_accounts(); $users_with_app_permissions = array(); if (!empty($users['fb'])) { if (!class_exists('Facebook_WP_Extend')) { require_once dirname(dirname(__FILE__)) . '/includes/facebook-php-sdk/class-facebook-wp.php'; } foreach ($users['fb'] as $user) { if (!isset($user->fb_data['fb_uid'])) { $users['wp'][] = $user; continue; } $facebook_user_permissions = Facebook_WP_Extend::get_permissions_by_facebook_user_id($user->fb_data['fb_uid']); if (!is_array($facebook_user_permissions) || !isset($facebook_user_permissions['installed'])) { $users['wp'][] = $user; continue; } $user->fb_data['permissions'] = $facebook_user_permissions; unset($facebook_user_permissions); $users_with_app_permissions[] = $user; } } $users['fb'] = $users_with_app_permissions; return $users; }
/** * Map WordPress post data to Open Graph article object properties. * * @since 1.5 * * @param stdClass|WP_Post $post the post of interest * @return array { * Associative array of OGP properties and values related to the post * * @type string Full IRI Open Graph protocol property * @type string|array Open Graph protocol property value * } */ public static function get_article_properties($post) { global $facebook_loader; $ogp = array(self::ARTICLE_NS . 'published_time' => date('c', strtotime($post->post_date_gmt)), self::ARTICLE_NS . 'modified_time' => date('c', strtotime($post->post_modified_gmt))); if (post_type_supports(get_post_type($post), 'author') && isset($post->post_author)) { if (!class_exists('Facebook_User')) { require_once $facebook_loader->plugin_directory . 'facebook-user.php'; } $facebook_user_data = Facebook_User::get_user_meta($post->post_author, 'fb_data', true); if (is_array($facebook_user_data) && isset($facebook_user_data['link'])) { $ogp[self::ARTICLE_NS . 'author'] = $facebook_user_data['link']; } else { $ogp[self::ARTICLE_NS . 'author'] = get_author_posts_url($post->post_author); } unset($facebook_user_data); } $facebook_page = get_option('facebook_publish_page'); if (is_array($facebook_page) && isset($facebook_page['link'])) { $ogp[self::ARTICLE_NS . 'publisher'] = $facebook_page['link']; } unset($facebook_page); // add the first category as a section. all other categories as tags $cat_ids = get_the_category($post->ID); if (!empty($cat_ids)) { $no_category = apply_filters('the_category', __('Uncategorized')); $cat = get_category($cat_ids[0]); if (!empty($cat) && isset($cat->name) && $cat->name !== $no_category) { $ogp[self::ARTICLE_NS . 'section'] = $cat->name; } // output the rest of the categories as tags unset($cat_ids[0]); if (!empty($cat_ids)) { $ogp[self::ARTICLE_NS . 'tag'] = array(); foreach ($cat_ids as $cat_id) { $cat = get_category($cat_id); if (isset($cat->name) && $cat->name !== $no_category) { $ogp[self::ARTICLE_NS . 'tag'][] = $cat->name; } unset($cat); } } } // add tags. treat tags as lower priority than multiple categories $tags = get_the_tags($post->ID); if ($tags) { if (!isset($ogp[self::ARTICLE_NS . 'tag'])) { $ogp[self::ARTICLE_NS . 'tag'] = array(); } foreach ($tags as $tag) { $ogp[self::ARTICLE_NS . 'tag'][] = $tag->name; } } return $ogp; }
/** * Update the Facebook page information stored for the site. * * @since 1.1 * * @uses update_option() * @global Facebook_Loader $facebook_loader request app access secret to hash app access token * @param array $page_data data returned from Facebook Graph API permissions call * @return void */ public static function update_publish_to_page($page_data) { global $facebook_loader; if (!(is_array($page_data) && !empty($page_data) && isset($page_data['id']))) { return; } $current_user_id = get_current_user_id(); if (!$current_user_id) { return; } if (!class_exists('Facebook_User')) { require_once dirname(dirname(__FILE__)) . '/facebook-user.php'; } // request access token based on current user session and specified page $write_pages = Facebook_User::get_permissioned_pages('CREATE_CONTENT'); if (!($write_pages && is_array($write_pages) && isset($write_pages[$page_data['id']]) && isset($write_pages[$page_data['id']]['name']) && isset($write_pages[$page_data['id']]['access_token']))) { return; } if (!class_exists('Facebook_WP_Extend')) { require_once dirname(dirname(__FILE__)) . '/includes/facebook-php-sdk/class-facebook-wp.php'; } // get long lived access token $access_token = Facebook_WP_Extend::exchange_token($write_pages[$page_data['id']]['access_token']); if (!$access_token) { return; } $value = array('id' => $page_data['id'], 'name' => $write_pages[$page_data['id']]['name'], 'access_token' => $access_token, 'set_by_user' => $current_user_id); if (isset($write_pages[$page_data['id']]['link'])) { $value['link'] = $write_pages[$page_data['id']]['link']; } if (isset($facebook_loader->credentials['app_secret'])) { $value['appsecret_proof'] = hash_hmac('sha256', $access_token, $facebook_loader->credentials['app_secret']); } update_option(self::OPTION_PUBLISH_TO_PAGE, $value); }
/** * Get all users with edit_posts capabilities broken out into Facebook-permissioned users and non-Facebook permissioned users * * @since 1.1.6 */ public static function get_all_wordpress_facebook_users() { global $facebook; if (!isset($facebook)) { return array('fb' => array(), 'wp' => array()); } if (!class_exists('Facebook_User')) { require_once dirname(dirname(__FILE__)) . '/facebook-user.php'; } // fb => [], wp => [] $users = Facebook_User::get_wordpress_users_associated_with_facebook_accounts(); $users_with_app_permissions = array(); foreach ($users['fb'] as $user) { if (!isset($user->fb_data['fb_uid'])) { $users['wp'] = $user; continue; } $facebook_user_permissions = $facebook->get_permissions_by_facebook_user_id($user->fb_data['fb_uid']); if (!is_array($facebook_user_permissions) || !isset($facebook_user_permissions['installed'])) { $users['wp'] = $user; continue; } $user->fb_data['permissions'] = $facebook_user_permissions; unset($facebook_user_permissions); $users_with_app_permissions[] = $user; } $users['fb'] = $users_with_app_permissions; return $users; }
/** * Add Follow Button(s) to post content * * Adds a follow button above the post, below the post, or both above and below the post depending on stored preferences. * * @since 1.1 * * @param string $content existing content * @return string passed content with Follow Button markup prepended, appended, or both. */ function facebook_the_content_follow_button($content) { // Follow Button should not be the only content if (!$content) { return $content; } $options = get_option('facebook_follow_button'); if (!is_array($options)) { $options = array(); } if (!class_exists('Facebook_User')) { require_once dirname(dirname(__FILE__)) . '/facebook-user.php'; } $facebook_user = Facebook_User::get_user_meta(get_the_author_meta('ID'), 'fb_data', true); if (!($facebook_user && isset($facebook_user['fb_uid']))) { return $content; } $options['href'] = Facebook_User::facebook_profile_link($facebook_user); if (!$options['href']) { return $content; } if ($options['position'] === 'top') { $options['ref'] = 'above-post'; return facebook_get_follow_button($options) . $content; } else { if ($options['position'] === 'bottom') { $options['ref'] = 'below-post'; return $content . facebook_get_follow_button($options); } else { if ($options['position'] === 'both') { $options['ref'] = 'above-post'; $above = facebook_get_follow_button($options); $options['ref'] = 'below-post'; return $above . $content . facebook_get_follow_button($options); } } } // don't break the filter return $content; }
/** * Save custom user information. * * @since 1.2 * * @uses current_user_can() current user must be able to edit the passed WordPress user ID * @param int $wordpress_user_id WordPress user identifier * @return void */ public static function save_data($wordpress_user_id) { if (!($wordpress_user_id && current_user_can('edit_user', $wordpress_user_id))) { return; } // allow decoupling of a WordPress account and a Facebook account if (isset($_POST['facebook_remove'])) { // WordPress Facebook User helper functions if (!class_exists('Facebook_User')) { require_once dirname(dirname(__FILE__)) . '/facebook-user.php'; } $facebook_user_id = Facebook_User::get_facebook_profile_id($wordpress_user_id); if ($facebook_user_id) { // delete mapped FBID and other data Facebook_User::delete_user_meta($wordpress_user_id, 'fb_data'); // delete post to Timeline opt-in if stored Facebook_User::delete_user_meta($wordpress_user_id, 'facebook_timeline_disabled'); // Load WP HTTP helpers if (!class_exists('Facebook_WP_Extend')) { require_once dirname(dirname(__FILE__)) . '/includes/facebook-php-sdk/class-facebook-wp.php'; } // Revoke connection to app and all permissions Facebook_WP_Extend::graph_api_with_app_access_token($facebook_user_id . '/permissions', 'DELETE'); } unset($facebook_user_id); // no need to store any other Facebook data return; } if (isset($_POST['facebook_fbid']) && ctype_digit($_POST['facebook_fbid'])) { // WordPress Facebook User helper functions if (!class_exists('Facebook_User')) { require_once dirname(dirname(__FILE__)) . '/facebook-user.php'; } try { $facebook_user = Facebook_User::get_facebook_user($_POST['facebook_fbid'], array('fields' => array('id', 'username', 'link', 'third_party_id'))); if (isset($facebook_user['id'])) { $facebook_user_data = array('fb_uid' => $facebook_user['id'], 'activation_time' => time()); if (!empty($facebook_user['username'])) { $facebook_user_data['username'] = $facebook_user['username']; } if (!empty($facebook_user['link'])) { $facebook_user_data['link'] = $facebook_user['link']; } if (!empty($facebook_user['third_party_id'])) { $facebook_user_data['third_party_id'] = $facebook_user['third_party_id']; } Facebook_User::update_user_meta($wordpress_user_id, 'fb_data', $facebook_user_data); unset($facebook_user_data); } unset($facebook_user); } catch (Exception $e) { } } if (isset($_POST['facebook_timeline']) && $_POST['facebook_timeline'] == '1') { // WordPress Facebook User helper functions if (!class_exists('Facebook_User')) { require_once dirname(dirname(__FILE__)) . '/facebook-user.php'; } Facebook_User::delete_user_meta($wordpress_user_id, 'facebook_timeline_disabled'); // delete if stored } else { // WordPress Facebook User helper functions if (!class_exists('Facebook_User')) { require_once dirname(dirname(__FILE__)) . '/facebook-user.php'; } Facebook_User::update_user_meta($wordpress_user_id, 'facebook_timeline_disabled', '1'); } }
/** * Search Facebook friends with names matching a given string up to a maximum number of results * * @since 1.2 * * @param string $search_term search string * @param int $limit maximum number of results * @return array { * friend results * * @type string 'object_type' user. Differentiate between User and Page results combined in one search. * @type string 'id' Facebook User identifier. * @type string 'name' Facebook User name. * @type string 'picture' Facebook User picture URL. * } */ public static function search_friends($search_term, $limit = 4) { if (!class_exists('Facebook_User')) { require_once dirname(dirname(dirname(dirname(__FILE__)))) . '/facebook-user.php'; } $facebook_user_id = Facebook_User::get_facebook_profile_id(get_current_user_id()); if (!$facebook_user_id) { return array(); } // cached list of all friends $cache_key = 'facebook_13_friends_' . $facebook_user_id; $friends = get_transient($cache_key); if ($friends === false) { if (!class_exists('Facebook_WP_Extend')) { require_once dirname(dirname(dirname(dirname(__FILE__)))) . '/includes/facebook-php-sdk/class-facebook-wp.php'; } try { $friends = Facebook_WP_Extend::graph_api_with_app_access_token($facebook_user_id . '/friends', 'GET', array('fields' => 'id,name,picture', 'ref' => 'fbwpp')); } catch (WP_FacebookApiException $e) { return array(); } if (isset($friends['data']) && is_array($friends['data'])) { $friends = $friends['data']; $clean_friends = array(); foreach ($friends as $friend) { // FBID and name required if (!(isset($friend['name']) && $friend['name'] && isset($friend['id']) && $friend['id'])) { continue; } $clean_friend = array('id' => $friend['id'], 'name' => $friend['name'], 'name_lower' => strtolower($friend['name'])); if (isset($friend['picture']['data']['url'])) { $clean_friend['picture'] = $friend['picture']['data']['url']; } $clean_friends[] = $clean_friend; unset($clean_friend); } $friends = $clean_friends; unset($clean_friends); } else { $friends = array(); } set_transient($cache_key, $friends, 60 * 15); // cache friends list for 15 minutes } // no friends to match against if (empty($friends)) { return array(); } $search_term = strtolower($search_term); // nothing to search against if (!$search_term) { return array(); } $matched_friends = array(); $matched_count = 0; foreach ($friends as $friend) { if ($matched_count === $limit) { break; } // does the search term appear in the name? if (strpos($friend['name_lower'], $search_term) !== false) { $friend['object_type'] = 'user'; unset($friend['name_lower']); $matched_friends[] = $friend; $matched_count++; } } return $matched_friends; }
* Remove data written by the Facebook plugin for WordPress after an administrative user clicks "Delete" from the plugin management page in the WordPress administrative interface (wp-admin). * * @since 1.1 * * @todo post meta data */ // only execute as part of an uninstall script if (!defined('WP_UNINSTALL_PLUGIN')) { exit; } // Facebook user helpers if (!class_exists('Facebook_User')) { require_once dirname(__FILE__) . '/facebook-user.php'; } // user data $__user_id = get_current_user_id(); foreach (array('state', 'code', 'access_token', 'user_id', 'fb_data', 'facebook_timeline_disabled') as $meta_key) { Facebook_User::delete_user_meta($__user_id, $meta_key); } unset($__user_id); // site options $__options = array('fb_options', 'facebook_application', 'facebook_comments', 'facebook_comments_enabled', 'facebook_kid_directed_site', 'facebook_like_button', 'facebook_recommendations_bar', 'facebook_send_button', 'facebook_mentions', 'facebook_publish_page', 'facebook_follow_button', 'facebook_home_features', 'facebook_archive_features', 'facebook_migration_10', 'facebook_migration_115', 'facebook_migration_118'); $__public_post_types = get_post_types(array('public' => true)); foreach ($__public_post_types as $post_type) { $__options[] = 'facebook_' . $post_type . '_features'; } unset($__public_post_types); foreach ($__options as $option_name) { delete_option($option_name); } unset($__options);
/** * Can the current user publish to Facebook? * * @since 1.1 * @return bool true if Facebook data stored for user and permissions exist */ public static function user_can_publish_to_facebook() { if (!class_exists('Facebook_User')) { require_once dirname(dirname(dirname(dirname(__FILE__)))) . '/facebook-user.php'; } $current_user = wp_get_current_user(); if (Facebook_User::can_publish_to_facebook() && !Facebook_User::get_user_meta($current_user->ID, 'facebook_timeline_disabled', true)) { return true; } return false; }
/** * Save submitted post after create / update * * @since 1.1 * @param int $post_id post identifier */ public static function save($post_id) { // verify if this is an auto save routine. // If it is our form has not been submitted, so we dont want to do anything if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) { return; } if (!class_exists('Facebook_User')) { require_once dirname(dirname(dirname(dirname(__FILE__)))) . '/facebook-user.php'; } $facebook_user = Facebook_User::get_current_user(); if (!$facebook_user) { return; } // verify this came from the our screen and with proper authorization, // because save_post can be triggered at other times if (!isset($_POST[self::FIELD_AUTOCOMPLETE]) || empty($_POST[self::NONCE_NAME]) || !wp_verify_nonce($_POST[self::NONCE_NAME], plugin_basename(__FILE__))) { return; } // Check permissions $post_type = get_post_type($post_id); if (!($post_type && post_type_supports($post_type, 'author'))) { return; } if (!class_exists('Facebook_Social_Publisher')) { require_once dirname(dirname(__FILE__)) . '/social_publisher.php'; } $capability_singular_base = Facebook_Social_Publisher::post_type_capability_base($post_type); if (!current_user_can('edit_' . $capability_singular_base, $post_id)) { return; } // process data then save it preg_match_all('/\\[(\\d*?)\\|(.*?)\\]/su', $_POST[self::FIELD_AUTOCOMPLETE], $friend_details, PREG_SET_ORDER); $friends_details_meta = array(); foreach ($friend_details as $friend_detail) { $friends_details_meta[] = array('id' => $friend_detail[1], 'name' => sanitize_text_field($friend_detail[2])); } if (!empty($friends_details_meta)) { update_post_meta($post_id, self::POST_META_KEY_MENTIONS, $friends_details_meta); } $message = trim(sanitize_text_field($_POST[self::FIELD_MESSAGE])); if ($message) { update_post_meta($post_id, self::POST_META_KEY_MESSAGE, $message); } }
/** * Detail site users and their association with Facebook * * @since 1.1.6 * * @global wpdb $wpdb escape SQL * @return void */ public static function users_section() { global $wpdb; $users = self::get_all_wordpress_facebook_users(); // should only happen if errors if (empty($users['fb']) && empty($users['wp'])) { return; } echo '<section id="debug-users"><header><h3>' . esc_html(__('Authors')) . '</h3></header>'; if (!empty($users['fb'])) { if (!class_exists('Facebook_User')) { require_once dirname(dirname(__FILE__)) . '/facebook-user.php'; } echo '<table><caption>' . esc_html(_x('Connected to Facebook', 'Local user account has an associated Facebook account stored', 'facebook')) . '</caption><colgroup><col><col span="2" class="permissions"></colgroup><thead><tr><th>' . esc_html(__('Name')) . '</th><th title="' . esc_attr(__('Facebook account', 'facebook')) . '"></th><th>' . esc_html(__('Post to timeline', 'facebook')) . '</th><th>' . esc_html(__('Manage pages', 'facebook')) . '</th></tr></thead><tbody>'; foreach ($users['fb'] as $user) { echo '<tr><th><a href="' . esc_url(get_author_posts_url($user->id)) . '">' . esc_html($user->display_name) . '</a></th>'; echo '<td>'; $profile_link = Facebook_User::facebook_profile_link($user->fb_data); if ($profile_link) { echo '<a class="facebook-icon" href="' . esc_url($profile_link, array('http', 'https')) . '"></a>'; } unset($profile_link); echo '</td>'; echo '<td>'; if (isset($user->fb_data['permissions']['publish_actions']) && $user->fb_data['permissions']['publish_actions']) { echo self::EXISTS; } else { echo self::DOES_NOT_EXIST; } echo '</td>'; echo '<td>'; if (isset($user->fb_data['permissions']['manage_pages']) && $user->fb_data['permissions']['manage_pages'] && isset($user->fb_data['permissions']['publish_stream']) && $user->fb_data['permissions']['publish_stream']) { echo self::EXISTS; } else { echo self::DOES_NOT_EXIST; } echo '</td></tr>'; } echo '</tbody></table>'; } if (!empty($users['wp'])) { // last 90 days $where = ' AND ' . $wpdb->prepare('post_date > %s', date('Y-m-d H:i:s', time() - 90 * 24 * 60 * 60)); $public_post_types = get_post_types(array('public' => true)); if (is_array($public_post_types) && !empty($public_post_types)) { $public_post_types = array_values($public_post_types); $where .= ' AND post_type'; if (count($public_post_types) === 1) { $where .= $wpdb->prepare(' = %s', $public_post_types[0]); } else { $s = ''; foreach ($public_post_types as $post_type) { $s .= "'" . $wpdb->escape($post_type) . "',"; } $where .= ' IN (' . rtrim($s, ',') . ')'; unset($s); } } $public_states = get_post_stati(array('public' => true)); if (is_array($public_states) && !empty($public_states)) { $public_states = array_values($public_states); $where .= ' AND post_status'; if (count($public_states) === 1) { $where .= $wpdb->prepare(' = %s', $public_states[0]); } else { $s = ''; foreach ($public_states as $state) { $s .= "'" . $wpdb->escape($state) . "',"; } $where .= ' IN (' . rtrim($s, ',') . ')'; unset($s); } } unset($public_states); echo '<table><caption>' . esc_html(__('Not connected to Facebook', 'facebook')) . '</caption><thead><th>' . esc_html(__('Name')) . '</th><th><abbr title="' . esc_attr(sprintf(__('Number of published posts in the last %u days', 'facebook'), 90)) . '">' . esc_html(_x('# of recent posts', 'recent articles. used as a table column header', 'facebook')) . '</abbr></th></thead><tbody>'; foreach ($users['wp'] as $user) { echo '<tr><th><a href="' . esc_url(get_author_posts_url($user->id)) . '">' . esc_html($user->display_name) . '</a></th>'; echo '<td>' . $wpdb->get_var($wpdb->prepare("SELECT COUNT(*) FROM {$wpdb->posts} WHERE post_author = %d {$where}", $user->id)) . '</td>'; echo '</tr>'; } echo '</tbody></table>'; } echo '</section>'; }