.
*
*
* Plugin Name: Facebook Page Publish
* Plugin URI: http://wordpress.org/extend/plugins/facebook-page-publish/
* Description: Publishes your posts on the wall of a Facebook profile or page.
* Author: Martin Tschirsich
* Version: 0.3.9
* Author URI: http://www.tu-darmstadt.de/~m_t/
*/
/**********************************************************************
* Constants
**********************************************************************/
#error_reporting(E_ALL);
define('FPP_VERSION', '0.3.9');
define('FPP_BASE_DIR', dirname(__file__));
define('FPP_BASE_URL', WP_PLUGIN_URL.'/'.str_replace(basename( __FILE__), '', plugin_basename(__FILE__)));
define('FPP_ADMIN_URL', admin_url('admin.php?page='.urlencode(plugin_basename(__FILE__))));
define('FPP_DEFAULT_POST_TO_FACEBOOK', false); // Checkbox admin panel always preselected
define('FPP_FACEBOOK_LINK_DESCRIPTION_MAX_LENGTH', 340); // Facebook link description allows max. 420 characters, 340 are always shown
define('FPP_REQUEST_TIMEOUT', 20); // The default 5s are not sufficient on some servers
define('FPP_TEXT_DOMAIN', 'facebook-page-publish');
/**********************************************************************
* Exceptions
**********************************************************************/
class CommunicationException extends Exception {
public function __construct($message = null, $code = 0) {
if (!empty($message)) $message .= '
';
$message .= '[Error occured at line '.$this->getLine().']';
parent::__construct($message, $code);
}
}
class FacebookUnreachableException extends CommunicationException {
public function __construct($message = null, $code = 0) {
if (empty($message)) {
$message = __('Facebook is not reachable from your server.', FPP_TEXT_DOMAIN).' '.__('Check the connection!', FPP_TEXT_DOMAIN).'';
} else {
$message = sprintf(__('Facebook is not reachable from your server: %s', FPP_TEXT_DOMAIN), $message).'
'.__('Check your connection!', FPP_TEXT_DOMAIN).'';
}
parent::__construct($message, $code);
}
}
class FacebookErrorException extends CommunicationException {
public function __construct($message, $code = 0) {
$message = sprintf(__('Facebook returned an error: %s', FPP_TEXT_DOMAIN), $message);
parent::__construct($message, $code);
}
}
class FacebookUnexpectedErrorException extends CommunicationException {
public function __construct($message = null, $code = 0) {
if (empty($message)) {
$message = __('Facebook returned an unexpected error.', FPP_TEXT_DOMAIN).' '.__('Try to resolve this issue, update the plugin or inform the author about the problem.', FPP_TEXT_DOMAIN);
} else {
$message = sprintf(__('Facebook returned an unexpected error: %s', FPP_TEXT_DOMAIN), $message).'
'.__('Try to resolve this issue, update the plugin or inform the author about the problem.', FPP_TEXT_DOMAIN);
}
parent::__construct($message, $code);
}
}
class FacebookUnexpectedDataException extends CommunicationException {
public function __construct($message = null, $code = 0) {
if (empty($message)) {
$message = __('Facebook returned an unexpected dataset.', FPP_TEXT_DOMAIN).' '.__('Try to resolve this issue, update the plugin or inform the author about the problem.', FPP_TEXT_DOMAIN);
} else {
$message = sprintf(__('Facebook returned an unexpected dataset: %s', FPP_TEXT_DOMAIN), $message).'
'.__('Try to resolve this issue, update the plugin or inform the author about the problem.', FPP_TEXT_DOMAIN);
}
parent::__construct($message, $code);
}
}
/**********************************************************************
* Action handler
**********************************************************************/
# Add publish actions for all post types (posts, pages, attachements, custom post types):
$post_types = get_post_types(array('exclude_from_search' => false), 'objects');
foreach ($post_types as $post_type) {
add_action('future_'.$post_type->name, 'fpp_future_action');
add_action('publish_'.$post_type->name, 'fpp_publish_action');
}
add_action('admin_init', 'fpp_admin_init_action');
add_action('admin_menu', 'fpp_admin_menu_action');
add_action('wp_head', 'fpp_head_action');
add_action('post_submitbox_start', 'fpp_post_submitbox_start_action');
add_action('init', 'fpp_init_action');
function fpp_init_action() {
//global $locale; $locale='de_DE';
load_plugin_textdomain(FPP_TEXT_DOMAIN, false, dirname(plugin_basename(__FILE__)));
}
/**
* Called on html head rendering. Prints meta tags to make posts appear
* correctly in Facebook.
*/
function fpp_head_action() {
global $post;
if (is_object($post) /*&& ($post->post_type == 'post') */ && is_singular()) {
fpp_render_meta_tags($post);
}
}
/**
* Called on admin menu rendering, adds an options page and its
* rendering callback.
*
* @see fpp_render_options_page()
*/
function fpp_admin_menu_action() {
$page = add_options_page(__('Facebook Page Publish Options', FPP_TEXT_DOMAIN), __('Facebook Page Publish', FPP_TEXT_DOMAIN), 'manage_options', __FILE__, 'fpp_render_options_page');
add_action('admin_print_scripts-'.$page, 'fpp_admin_print_scripts_action');
add_action('admin_print_styles-'.$page, 'fpp_admin_print_styles_action');
}
/**
* Called when a user accesses the admin area. Registers settings and a
* sanitization callback. Initializes the plugin options when a version
* update has been detected.
*
* @see fpp_validate_options
*/
function fpp_admin_init_action() {
register_setting('fpp_options_group', 'fpp_options', 'fpp_validate_options');
$version = get_option('fpp_installed_version');
if ($version != FPP_VERSION) {
fpp_initialize_options();
}
}
/**
* Loads media gallery scripts.
*
* @last_review 0.3.0
*/
function fpp_admin_print_scripts_action() {
wp_enqueue_script('media-upload');
wp_enqueue_script('thickbox');
wp_register_script('fpp-upload', FPP_BASE_URL.'fpp_script.js', array('jquery','media-upload','thickbox'));
wp_enqueue_script('fpp-upload');
}
/**
* Loads media gallery styles.
*
* @last_review 0.3.0
*/
function fpp_admin_print_styles_action() {
wp_enqueue_style('thickbox');
}
/**
* Called when the submitbox is rendered. Renders a publish to Facebook
* button if the current user has the 'publish_posts' permission.
*
* @last_review 0.3.0
*/
function fpp_post_submitbox_start_action() {
global $post;
if (is_object($post) and /*($post->post_type == 'post') and*/ current_user_can('publish_posts')) {
fpp_render_post_button();
}
}
/**
* Called on any_to_future post state transition (scheduled post).
* Marks any given post for publishing on Facebook
* - if it was send directly from the admin panel and the
* post-to-facebook checkbox was checked.
* Marks any given post for NOT publishing on Facebook
* - if it was send directly from the admin panel and the
* post-to-facebook checkbox was NOT checked.
*
* @last_review 0.3.0
*/
function fpp_future_action($post_id) {
$send_from_admin = isset($_REQUEST['fpp_send_from_admin']);
if ($send_from_admin) {
$post = get_post($post_id);
if (/*($post->post_type == 'post')*/ true) {
if (!empty($_REQUEST['fpp_post_to_facebook'])) { // Directly send from the user (admin panel) with active checkbox
$options = get_option('fpp_options');
update_post_meta($post->ID, '_fpp_is_scheduled', true);
} else {
update_post_meta($post->ID, '_fpp_is_scheduled', false);
}
}
}
}
/**
* Called on any_to_publish post state transition (published post).
* Publishes any given non password protected post to Facebook
* - if it was send directly from the admin panel and the
* post-to-facebook checkbox was checked.
* - if it was previously marked for publishing on Facebook (scheduled).
* - if it was NOT send directly from the admin panel and the plugin
* is set to always post on Facebook and the post is not already
* published (on wordpress or Facebook).
*
* @see fpp_render_post_button()
*/
function fpp_publish_action($post_id) {
$post = get_post($post_id);
if (/*($post->post_type == 'post')*/ true) {
$object_access_token = get_option('fpp_object_access_token');
if (!empty($object_access_token)) { // Incomplete plugin configuration, do nothing, report no error
$send_from_admin = isset($_REQUEST['fpp_send_from_admin']);
unset($_REQUEST['fpp_send_from_admin']); // Sometimes fpp_publish_action is called twice in a row
$options = get_option('fpp_options');
try {
if ($send_from_admin && !empty($_REQUEST['fpp_post_to_facebook'])) { // Directly send from the user (admin panel) with active post checkbox
// If post was already published, delete it from FB:
$post_id = get_post_meta($post->ID, '_fpp_post_id', true);
if (!empty($post_id)) { // Old posts (version <= 0.3.7) do not contain a post_id
fpp_unpublish_from_facebook($post_id, $options['object_id'], get_option('fpp_object_access_token'));
}
$post_id = fpp_publish_to_facebook($post, $options['object_id'], get_option('fpp_object_access_token'));
update_post_meta($post->ID, '_fpp_is_published', true);
update_post_meta($post->ID, '_fpp_post_id', $post_id);
}
else if (get_post_meta($post->ID, '_fpp_is_scheduled', true) == true) { // Scheduled post previously marked for Facebook publishing by the user
// If post was already published, delete it from FB:
$post_id = get_post_meta($post->ID, '_fpp_post_id', true);
if (!empty($post_id)) { // Old posts (version <= 0.3.7) do not contain a post_id
fpp_unpublish_from_facebook($post_id, $options['object_id'], get_option('fpp_object_access_token'));
}
$post_id = fpp_publish_to_facebook($post, $options['object_id'], get_option('fpp_object_access_token'));
update_post_meta($post->ID, '_fpp_is_published', true);
delete_post_meta($post->ID, '_fpp_is_scheduled');
update_post_meta($post->ID, '_fpp_post_id', $post_id);
}
else if (!$send_from_admin && (array_search('_fpp_is_scheduled', get_post_custom_keys($post->ID)) === false) && !get_post_meta($post->ID, '_fpp_is_published', true) && ($_POST['original_post_status'] != 'publish')) { // not send from admin panel, not already published (FB and WP), user never decided for or against publishing
if (empty($post->post_password) and fpp_get_default_publishing($post)) { // Dont post password protected posts without the users consient
// If post was already published, delete it from FB:
$post_id = get_post_meta($post->ID, '_fpp_post_id', true);
if (!empty($post_id)) { // Old posts (version <= 0.3.7) do not contain a post_id
fpp_unpublish_from_facebook($post_id, $options['object_id'], get_option('fpp_object_access_token'));
}
$post_id = fpp_publish_to_facebook($post, $options['object_id'], get_option('fpp_object_access_token'));
update_post_meta($post->ID, '_fpp_is_published', true);
update_post_meta($post->ID, '_fpp_post_id', $post_id);
}
}
} catch (CommunicationException $exception) {
update_option('fpp_error', sprintf(__('
While publishing "%1$s" to Facebook, an error occured:
%2$s
', FPP_TEXT_DOMAIN), $post->post_title, $exception->getMessage())); } } } } /********************************************************************** * Facebook functions **********************************************************************/ /** * Publishes the given post to a Facebook page. * * @param post Wordpress post to publish * @param object_id Facebook page or wall ID * @param object_acces_token Access token for the given object * @return Facebook(!) post id * * @last_review 0.3.8 */ function fpp_publish_to_facebook($post, $object_id, $object_acces_token) { $options = get_option('fpp_options'); if (empty($post->post_password) and $options['show_post_text']) { $message = fpp_extract_message(apply_filters('the_excerpt', $post->post_excerpt), $options['show_post_link']); if (empty($message)) $message = fpp_extract_message(apply_filters('the_content', $post->post_content), $options['show_post_link']); if ($options['show_post_link']) { $message = wp_kses($message, array('a' => array('href' => array()))); $message = preg_replace('/]*?href *= *["|\']([^"|\']+).[^>]*?>(.*?)<\/a>\s*/is', '${2} ${1} ', $message); $message = trim(stripslashes(html_entity_decode($message, ENT_QUOTES, 'UTF-8'))); } else { $message = trim(stripslashes(html_entity_decode(wp_filter_nohtml_kses($message), ENT_QUOTES, 'UTF-8'))); } // Remove empty lines: $message = preg_replace("/\n\s*\n(\n|\s)*/s", "\n",$message); if (strpos($message, '') !== false) { $message = substr($message, 0, strpos($message, '')); } // Remove HTML Comments: $message = preg_replace('//Uis', '', $message); if (strlen($message) >= FPP_FACEBOOK_LINK_DESCRIPTION_MAX_LENGTH) { $last_space_pos = strrpos(substr($message, 0, FPP_FACEBOOK_LINK_DESCRIPTION_MAX_LENGTH - 3), ' '); $message = substr($message, 0, !empty($last_space_pos) ? $last_space_pos : FPP_FACEBOOK_LINK_DESCRIPTION_MAX_LENGTH - 3).__('...', FPP_TEXT_DOMAIN); } } else { $message = ''; // Password protected, no content displayed. } // Publish: $request = new WP_Http; // Facebook bug 19336 is resolved, so /links should work (usage of /feed no longer necessary): $api_url = 'https://graph.facebook.com/'.urlencode($object_id).'/links'; $body = array('message' => $message, 'link' => get_permalink($post->ID), 'access_token' => $object_acces_token); $response = $request->request($api_url, array('method' => 'POST', 'body' => $body, 'timeout' => FPP_REQUEST_TIMEOUT, 'sslverify' => fpp_get_ssl_verify())); // Error detection: if (array_key_exists('errors', $response)) throw new FacebookUnreachableException(!empty($response->errors) ? array_pop(array_pop($response->errors)) : ''); $json_response = json_decode($response['body']); if (is_object($json_response) and property_exists($json_response, 'error')) { throw new FacebookUnexpectedErrorException((is_object($json_response->error) and property_exists($json_response->error, 'message')) ? $json_response->error->message : ''); } return $json_response->id; // Return ID of the published link (usefull to delete it later). } /** * Extract a message to be posted on Facebook from a text string that * may contain html, WP shortcodes etc. * * @param string * @param include_links Include URLs from HTML links if true * @return extracted message ready to be posted on Facebook */ function fpp_extract_message($string, $include_links) { $message = do_shortcode($string); $message = preg_replace('~<\s*\bscript\b[^>]*>(.*?)<\s*\/\s*script\s*>~is', '', $message); // Remove javascript code (not only tags) $message = preg_replace('//Uis', '', $message); // Remove HTML comments (not only tags) if ($include_links) { $message = wp_kses($message, array('a' => array('href' => array()))); $message = preg_replace('/]*?href *= *["|\']([^"|\']+).[^>]*?>(.*?)<\/a>\s*/is', '${2} ${1} ', $message); $message = trim(stripslashes(html_entity_decode($message, ENT_QUOTES, 'UTF-8'))); } else { $message = trim(stripslashes(html_entity_decode(wp_filter_nohtml_kses($message), ENT_QUOTES, 'UTF-8'))); } // Remove empty lines: $message = preg_replace("/\n\s*\n(\n|\s)*/s", "\n",$message); if (strpos($message, '') !== false) { $message = substr($message, 0, strpos($message, '')); } if (strlen($message) >= FPP_FACEBOOK_LINK_DESCRIPTION_MAX_LENGTH) { $last_space_pos = strrpos(substr($message, 0, FPP_FACEBOOK_LINK_DESCRIPTION_MAX_LENGTH - 3), ' '); $message = substr($message, 0, !empty($last_space_pos) ? $last_space_pos : FPP_FACEBOOK_LINK_DESCRIPTION_MAX_LENGTH - 3).__('...', FPP_TEXT_DOMAIN); } return $message; } /** * Removes the given post from a Facebook page. If a post with the given * ID does not exist on FB, the return value is 'false. * * @param post_id Facebook(!) post ID * @param object_id Facebook page or wall ID * @param object_acces_token Access token for the given object * @return True if post was found and removed * * @last_review 0.3.8 */ function fpp_unpublish_from_facebook($post_id, $object_id, $object_acces_token) { $request = new WP_Http; $api_url = 'https://graph.facebook.com/'.urlencode($object_id).'_'.urlencode($post_id).'?method=delete'; $body = array('access_token' => $object_acces_token); $response = $request->request($api_url, array('method' => 'POST', 'body' => $body, 'timeout' => FPP_REQUEST_TIMEOUT, 'sslverify' => fpp_get_ssl_verify())); // Error detection: if (array_key_exists('errors', $response)) throw new FacebookUnreachableException(!empty($response->errors) ? array_pop(array_pop($response->errors)) : ''); $object = json_decode($response['body']); if (is_object($object) and property_exists($object, 'error')) { if (property_exists($object->error, 'message')) { if (strpos($object->error->message, 'Invalid parameter') !== false) return false; throw new FacebookUnexpectedErrorException($object->error->message); } throw new FacebookUnexpectedErrorException(''); } return $response['body'] === 'true'; } /** * Checks whether a given access_token is valid and has the give * permissions. * * @param object_id Page or profile ID * @param object_type Either 'page' or 'profile' * @param object_access_token The access token to validate * @param permissions Array of permission strings to validate * @return True if access_token valid and all permissions granted * * @last_review 0.3.1 */ function fpp_verify_profile_access_permissions($profile_access_token, $permissions) { $request = new WP_Http; $api_url = 'https://api.facebook.com/method/fql.query?access_token='.urlencode($profile_access_token).'&format=json&query='.urlencode('SELECT '.implode(',', $permissions).' FROM permissions WHERE uid = me()'); $response = $request->get($api_url, array('timeout' => FPP_REQUEST_TIMEOUT, 'sslverify' => fpp_get_ssl_verify())); if (array_key_exists('errors', $response)) throw new FacebookUnreachableException((!empty($response->errors) ? array_pop(array_pop($response->errors)) : '')); $json_response = json_decode($response['body']); if (is_object($json_response) and property_exists($json_response, 'error_msg')) { if (property_exists($json_response, 'error_code') and ($json_response->error_code == 190)) // Access token expired or invalid return false; if (property_exists($json_response, 'error_code') and ($json_response->error_code == 104)) // 'Requires valid signature'-error return false; throw new FacebookUnexpectedErrorException($json_response->error_msg); } if (!is_array($json_response)) { throw new FacebookUnexpectedDataException(); } $json_response = array_pop($json_response); if (!is_object($json_response)) { throw new FacebookUnexpectedDataException(); } foreach ($permissions as $permission) { if (!property_exists($json_response, $permission) or empty($json_response->$permission)) return false; } return true; } function fpp_verify_page_access_token($page_id, $page_access_token) { $request = new WP_Http; $api_url = 'https://graph.facebook.com/'.urlencode($page_id).'?access_token='.urlencode($page_access_token); $response = $request->get($api_url, array('timeout' => FPP_REQUEST_TIMEOUT, 'sslverify' => fpp_get_ssl_verify())); if (array_key_exists('errors', $response)) throw new FacebookUnreachableException(!empty($response->errors) ? array_pop(array_pop($response->errors)) : ''); # TODO: verify access_permissions... return ($response['response']['code'] == 200); } /** * Classifies Facebook object ids. * * @param object_ids Array of Facebook object ids * @return map with a type string for each Facebook object id * * @last_review 0.3.0 */ function fpp_classify_facebook_objects($object_ids) { $numerical_object_ids = array_filter($object_ids, 'is_numeric'); // Alphabetical id's produce a Facebook error. $request = new WP_Http; $api_url = 'https://api.facebook.com/method/fql.query?format=json&query='.urlencode('SELECT id, type FROM object_url WHERE id IN ('.implode(',', $numerical_object_ids).')'); $response = $request->get($api_url, array('timeout' => FPP_REQUEST_TIMEOUT, 'sslverify' => fpp_get_ssl_verify())); if (array_key_exists('errors', $response)) throw new FacebookUnreachableException(!empty($response->errors) ? array_pop(array_pop($response->errors)) : ''); $json_response = json_decode($response['body']); if (is_object($json_response) and property_exists($json_response, 'error')) { throw new FacebookUnexpectedErrorException((is_object($json_response->error) and property_exists($json_response->error, 'message')) ? $json_response->error->message : ''); } if (!is_array($json_response)) { throw new FacebookUnexpectedDataException(); } $result = array(); $float_object_ids = array_map('floatval', $numerical_object_ids); // PHP <= 5.2 is missing JSON_BIGINT foreach ($json_response as $json_response_entry) { if (!property_exists($json_response_entry, 'type') or !property_exists($json_response_entry, 'id')) throw new FacebookUnexpectedDataException(); $result[$numerical_object_ids[array_search($json_response_entry->id, $float_object_ids)]] = $json_response_entry->type; } foreach ($object_ids as $object_id) { if (!array_key_exists($object_id, $result)) $result[$object_id]= ''; } return $result; } /** * Checks whether a given Facebook application id and its secret are * valid. * * @param app_id Application id to verify * @param app_secret Application secret * @param redirect_uri URL equal to the URL in the Facebook app settings * @return True if the given application id and secret are valid * * @last_review 0.3.0 */ function fpp_is_valid_facebook_application($app_id, $app_secret, $redirect_uri) { $request = new WP_Http; $api_url = 'https://graph.facebook.com/oauth/access_token?client_id='.urlencode($app_id).'&client_secret='.urlencode($app_secret).'&redirect_uri='.urlencode($redirect_uri).'&code=SOME_INVALID_CODE'; $response = $request->get($api_url, array('timeout' => FPP_REQUEST_TIMEOUT, 'sslverify' => fpp_get_ssl_verify())); if (array_key_exists('errors', $response)) throw new FacebookUnreachableException(!empty($response->errors) ? array_pop(array_pop($response->errors)) : ''); $object = json_decode($response['body']); if (property_exists($object, 'error')) { if (property_exists($object->error, 'message')) { if (strpos($object->error->message, 'Error validating client secret') !== false) return false; if (strpos($object->error->message, 'Invalid verification code format') !== false) return true; if (strpos($object->error->message, 'Invalid redirect_uri') !== false) throw new FacebookErrorException(sprintf(__('The site URL in your Facebook application settings does not match your wordpress blog URL. Please refer to the detailed setup instructions.', FPP_TEXT_DOMAIN), FPP_BASE_URL.'setup.htm#site_url')); throw new FacebookUnexpectedErrorException($object->error->message); } throw new FacebookUnexpectedErrorException(); } throw new FacebookUnexpectedDataException(); } /** * Acquires an object access token with all these permissions that * were specified when retrieving the code. * * @param app_id Application ID * @param app_secret Application secret * @param object_id Facebook page or profile ID * @param object_type Either 'profile' or 'page' * @param redirect_uri URL used to get the transaction code * @param code Transaction code (refer to the OAuth protocoll docs) * * @last_rewiev 0.3.1 */ function fpp_acquire_profile_access_token($app_id, $app_secret, $redirect_uri, $code) { $request = new WP_Http; $api_url = 'https://graph.facebook.com/oauth/access_token?client_id='.urlencode($app_id).'&redirect_uri='.urlencode($redirect_uri).'&client_secret='.urlencode($app_secret).'&code='.urlencode($code); $response = $request->get($api_url, array('timeout' => FPP_REQUEST_TIMEOUT, 'sslverify' => fpp_get_ssl_verify())); if (array_key_exists('errors', $response)) throw new FacebookUnreachableException(!empty($response->errors) ? array_pop(array_pop($response->errors)) : ''); $json_response = json_decode($response['body']); if (is_object($json_response) and property_exists($json_response, 'error') and property_exists($json_response->error, 'message')) { if (is_string($json_response->error->message) and (strpos($json_response->error->message, 'Code was invalid or expired') !== false)) { throw new FacebookErrorException(__('Your authorization code was invalid or expired. Please try again. If the problem persists update the plugin or inform the author.', FPP_TEXT_DOMAIN)); } else throw new FacebookUnexpectedErrorException($json_response->error->message); } $access_token_url = $response['body']; preg_match('/^.+=\s*(.+)/', $access_token_url, $matches); if (!empty($matches[1])) return $matches[1]; throw new FacebookUnexpectedDataException(); } function fpp_acquire_page_access_token($page_id, $profile_access_token) { $request = new WP_Http; $api_url = 'https://graph.facebook.com/me/accounts?access_token='.urlencode($profile_access_token); $response = $request->get($api_url, array('timeout' => FPP_REQUEST_TIMEOUT, 'sslverify' => fpp_get_ssl_verify())); if (array_key_exists('errors', $response)) throw new FacebookUnreachableException(!empty($response->errors) ? array_pop(array_pop($response->errors)): ''); $json_response = json_decode($response['body']); if (!is_object($json_response) || !property_exists($json_response, 'data')) throw new FacebookUnexpectedErrorException(__('Can\'t access Facebook user account information.', FPP_TEXT_DOMAIN)); foreach ($json_response->data as $account) { if ($account->id == $page_id) { if (!property_exists($account, 'access_token')) throw new FacebookUnexpectedErrorException(__('Some or all access permissions for your page are missing.', FPP_TEXT_DOMAIN)); $page_access_token = $account->access_token; break; } } if (!isset($page_access_token)) throw new FacebookErrorException(__('Your Facebook user account data contains no page with the given ID. You have to be administrator of the given page.', FPP_TEXT_DOMAIN)); return $page_access_token; } /********************************************************************** * Getter **********************************************************************/ /** * Determines whether a post should be pulished by default or not, * depending on the plugin options and the post category. */ function fpp_get_default_publishing($post) { $options = get_option('fpp_options'); if ($options['default_publishing'] == 'all') return true; if ($options['default_publishing'] == 'category') { $categories = get_the_category($post->ID); foreach ($categories as $category) { if (array_search($category->cat_ID, $options['default_publishing_categories']) !== false) return true; } } return false; } /** * @return True if SSL certificates should be checked */ function fpp_get_ssl_verify() { $options = get_option('fpp_options'); return !$options['ignore_ssl']; } /** * @param object_type Array of string or string, either 'page' or 'profile' * @return Write permissions for a given Facebook object as string * @last_review 0.3.1 */ function fpp_get_required_permissions($object_type) { if (!is_array($object_type)) $object_type = array($object_type); $permissions = array('offline_access', 'share_item'); if (array_search('page', $object_type) !== false) { $permissions[] = 'manage_pages'; } if (array_search('group', $object_type) !== false) { $permissions[] = 'user_groups'; } return $permissions; } /** * @return Post author name as a string * @last_review 0.3.1 */ function fpp_get_post_author($post) { $user_info = get_userdata($post->post_author); $author = trim(apply_filters('the_author', $user_info->display_name)); if (empty($author)) { $author = $user_info->user_login; } return $author; } /** * @return Post categories as csv string * @last_review 0.3.0 */ function fpp_get_post_categories($post) { $categories = get_the_category($post->ID); $description = ''; if (!empty($categories)) { $description = $categories[0]->cat_name; for ($i = 1; $i < sizeof($categories); ++$i) $description .= ', '.apply_filters('the_category', $categories[$i]->cat_name); } return $description; } /** * @return URL of the featured or first embedded or attachement image as string * @last_review 0.3.1 */ function fpp_get_post_image($post) { $image_url = ''; if (current_theme_supports('post-thumbnails')) { // get_post_thumbnail_id must be supported by the theme! $thumbnail_id = get_post_thumbnail_id($post->ID); if ($thumbnail_id !== null) { $image_url = wp_get_attachment_image_src($thumbnail_id); $image_url = $image_url[0]; } } if (empty($image_url)) { // Image from post content and/or excerpt preg_match('/post_excerpt).apply_filters('the_content', $post->post_content), $matches); if (!empty($matches[1])) $image_url = $matches[1]; } if (empty($image_url)) { $images = get_children('post_type=attachment&post_mime_type=image&post_parent='.$post->ID); if (!empty($images)) { foreach ($images as $image_id => $value) { $image = wp_get_attachment_image_src($image_id); $image_url = $image[0]; break; } } } return $image_url; } /********************************************************************** * HTML rendering **********************************************************************/ /** * Renders the options page. Uses the settings API (options validation, checking and storing by WP). * Also validates certain options (Facebook access) that need redirecting. * @last_review 0.3.1 */ function fpp_render_options_page() { $options = get_option('fpp_options'); $error = get_option('fpp_error'); if (!empty($error)) { echo ''.$exception->getMessage().'
'.__('Your application\'s access permissions could not be granted.', FPP_TEXT_DOMAIN).'
'.$exception->getMessage().'
'.__('Your page or profile\'s access permissions could not be verified.', FPP_TEXT_DOMAIN).'
'.__('Facebook won\'t be able to display the choosen default thumbnail.', FPP_TEXT_DOMAIN).'
'); // Connection options: if ($options['app_id'] != $input['app_id']) { update_option('fpp_profile_access_token', ''); update_option('fpp_object_access_token', ''); } else if ($options['object_id'] != $input['object_id']) { update_option('fpp_object_access_token', ''); } $options['app_id'] = $input['app_id']; $options['object_id'] = $input['object_id']; $options['app_secret'] = $input['app_secret']; $options['app_id_valid'] = false; $options['object_id_valid'] = false; $options['object_type'] = ''; $options['app_secret_valid'] = false; $options['ignore_ssl'] = array_key_exists('ignore_ssl', $input) && !empty($input['ignore_ssl']); $options['default_publishing'] = $input['default_publishing']; $options['default_publishing_categories'] = array_key_exists('default_publishing_categories', $input) ? $input['default_publishing_categories'] : array(); // Validate connection options: try { if (!empty($options['app_id']) or !empty($options['object_id'])) { $object_classification = fpp_classify_facebook_objects(array($options['app_id'], $options['object_id'])); $options['app_id_valid'] = $object_classification[$options['app_id']] == 'application'; $options['object_type'] = $object_classification[$options['object_id']]; $options['object_id_valid'] = (($options['object_type'] == 'profile') or ($options['object_type'] == 'page') or ($options['object_type'] == 'group') or ($options['object_type'] == 'application')); } $options['app_secret_valid'] = (!empty($options['app_secret']) and $options['app_id_valid']) ? fpp_is_valid_facebook_application($options['app_id'], $options['app_secret'], FPP_ADMIN_URL) : false; if (!empty($options['app_id']) and !$options['app_id_valid']) { throw new FacebookErrorException(__('Invalid application ID.', FPP_TEXT_DOMAIN).' '.sprintf(__('Please refer to the detailed setup instructions.', FPP_TEXT_DOMAIN), FPP_BASE_URL.'setup.htm#app_id')); } if (!empty($options['object_id']) and !$options['object_id_valid']) { throw new FacebookErrorException(__('Invalid user or page ID.', FPP_TEXT_DOMAIN).' '.sprintf(__('Please refer to the detailed setup instructions.', FPP_TEXT_DOMAIN), FPP_BASE_URL.'setup.htm#object_id')); } if (!$options['app_secret_valid'] and $options['app_id_valid']) throw new FacebookErrorException(__('Invalid application secret.', FPP_TEXT_DOMAIN).' '.sprintf(__('Please refer to the detailed setup instructions.', FPP_TEXT_DOMAIN), FPP_BASE_URL.'setup.htm#app_secret')); } catch (CommunicationException $exception) { add_settings_error('fpp_options', 'connection_error', $exception->getMessage().''.__('Your connection options could not be validated.', FPP_TEXT_DOMAIN).'
'); } return $options; } /** * Initializes the plugin options with either default or existing * values (in case there is already a version installed). */ function fpp_initialize_options() { // default options: $options = array( 'app_id' => '', 'app_id_valid' => false, 'app_secret' => '', 'app_secret_valid' => false, 'object_id' => '', 'object_id_valid' => false, 'object_type' => '', 'ignore_ssl' => false, 'default_publishing' => 'all', 'default_publishing_categories' => array(), 'default_thumbnail_url' => '', 'show_post_categories' => true, 'show_post_author' => true, 'show_post_text' => true, 'show_post_link' => true, 'show_thumbnail' => 'gravatar'); $current_version = get_option('fpp_installed_version'); $current_options = get_option('fpp_options'); $object_access_token = get_option('fpp_object_access_token'); $profile_access_token = get_option('fpp_profile_access_token'); // Plugin previously installed: if (is_array($current_options)) { foreach ($options as $key => $value) { if (array_key_exists($key, $current_options)) { $options[$key] = $current_options[$key]; } } if (empty($current_version)) { // version <= 0.2.2 $options['app_id_valid'] = !empty($current_options['page_id']); $options['app_secret_valid'] = !empty($current_options['page_id']); $options['object_id'] = $current_options['page_id']; $options['object_id_valid'] = !empty($current_options['page_id']); $options['object_type'] = 'page'; $options['show_thumbnail'] = $current_options['show_gravatar'] ? 'gravatar' : 'post'; $object_access_token = get_option('fpp_page_access_token'); delete_option('fpp_page_access_token'); delete_option('fpp_post_to_facebook'); } } update_option('fpp_options', $options); update_option('fpp_object_access_token', $object_access_token); update_option('fpp_profile_access_token', $profile_access_token); update_option('fpp_error', ''); update_option('fpp_installed_version', FPP_VERSION); } ?>