diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..fbf828d --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +log \ No newline at end of file diff --git a/includes/class.wp-bitly-admin.php b/includes/class.wp-bitly-admin.php index 239a2d5..0e74d2f 100644 --- a/includes/class.wp-bitly-admin.php +++ b/includes/class.wp-bitly-admin.php @@ -1,297 +1,312 @@ -action_filters(); - } - - return self::$_instance; - } - - - /** - * Hook any necessary WordPress actions or filters that we'll be needing for the admin. - * - * @since 2.0 - * @uses wpbitly() - */ - public function action_filters() { - - $wpbitly = wpbitly(); - $token = $wpbitly->get_option('oauth_token'); - - add_action('admin_init', array($this, 'register_settings')); - - if (empty($token)) - add_action('admin_notices', array($this, 'display_notice')); - - - $post_types = $wpbitly->get_option('post_types'); - - if (is_array($post_types)) { - foreach ($post_types as $post_type) { - add_action('add_meta_boxes_' . $post_type, array($this, 'add_metaboxes_yo')); - } - } - - } - - - /** - * Display a simple and unobtrusive notice on the plugins page after activation (and - * up until they add their oauth_token). - * - * @since 2.0 - */ - public function display_notice() { - - $screen = get_current_screen(); - - if ($screen->base != 'plugins') - return; - - - $prologue = __('WP Bit.Ly is almost ready!', 'wp-bitly'); - $link = '' . __('settings page', 'wp-bitly') . ''; - $epilogue = sprintf(__('Please visit the %s to configure WP Bit.ly', 'wp-bitly'), $link); - - $message = apply_filters('wpbitly_setup_notice', '
' . $prologue . ' ' . $epilogue . '
' . __('You will need a Bitly account to use this plugin. Click the link below for your OAuth Token, and if necessary create a new account.', 'wp-bitly') . '
'); - } - - - add_settings_field('oauth_token', '', '_f_settings_field_oauth', 'writing', 'wpbitly_settings'); - /** - * @ignore - */ - function _f_settings_field_oauth() { - - $wpbitly = wpbitly(); - - $url = apply_filters('wpbitly_oauth_url', 'https://bitly.com/a/wordpress_oauth_app'); - - $auth_css = $wpbitly->get_option('authorized') ? '' : ' style="border-color: #c00; background-color: #ffecec;" '; - $output = '' . '' . __('Please provide your', 'wp-bitly') . ' ' . __('OAuth Token', 'wp-bitly') . '
'; - - echo $output; - - } - - - add_settings_field('post_types', '', '_f_settings_field_post_types', 'writing', 'wpbitly_settings'); - /** - * @ignore - */ - function _f_settings_field_post_types() { - - $wpbitly = wpbitly(); - - $post_types = apply_filters('wpbitly_allowed_post_types', get_post_types(array('public' => true))); - $output = ''; - - echo $output; - - } - - - add_settings_field('debug', '', '_f_settings_field_debug', 'writing', 'wpbitly_settings'); - /** - * @ignore - */ - function _f_settings_field_debug() { - - $wpbitly = wpbitly(); - - $output = ''; - - echo $output; - - } - - } - - - /** - * Validate user settings. This will also authorize their OAuth token if it has - * changed. - * - * @since 2.0 - * @uses wpbitly() - * - * @param array $input WordPress sanitized data array - * - * @return array WP Bit.ly sanitized data - */ - public function validate_settings($input) { - - $wpbitly = wpbitly(); - - $input['debug'] = ('1' == $input['debug']) ? true : false; - - $input['oauth_token'] = sanitize_text_field($input['oauth_token']); - - $url = sprintf(wpbitly_api('user/info'), $input['oauth_token']); - $response = wpbitly_get($url); - - wpbitly_debug_log($response, 'Validate OAuth', $input['debug']); - - - $input['authorized'] = (isset($response['data']['member_since'])) ? true : false; - - if (!isset($input['post_types'])) { - $input['post_types'] = array(); - } else { - $post_types = apply_filters('wpbitly_allowed_post_types', get_post_types(array('public' => true))); - - foreach ($input['post_types'] as $key => $pt) { - if (!in_array($pt, $post_types)) - unset($input['post_types'][ $key ]); - } - - } - - return $input; - - } - - - /** - * Add a fun little statistics metabox to any posts/pages that WP Bit.ly - * generates a link for. There's potential here to include more information. - * - * @since 2.0 - * @TODO Should the user can turn this on or off? You heard me. - * - * @param object $post The post object passed by WordPress - */ - public function add_metaboxes_yo($post) { - - $shortlink = get_post_meta($post->ID, '_wpbitly', true); - if (!$shortlink) - return; - - add_meta_box('wpbitly-meta', 'WP Bit.ly', array( - $this, - 'display_metabox' - ), $post->post_type, 'side', 'default', array($shortlink)); - } - - - /** - * Handles the display of the metabox. - * - * @since 2.0 - * - * @param object $post WordPress passed $post object - * @param array $args Passed by our call to add_meta_box(), just the $shortlink in this case. - */ - public function display_metabox($post, $args) { - - $wpbitly = wpbitly(); - $shortlink = $args['args'][0]; - - - // Look for a clicks response - $url = sprintf(wpbitly_api('link/clicks'), $wpbitly->get_option('oauth_token'), $shortlink); - $response = wpbitly_get($url); - - if (is_array($response)) - $clicks = $response['data']['link_clicks']; - - - // Look for referring domains metadata - $url = sprintf(wpbitly_api('link/refer'), $wpbitly->get_option('oauth_token'), $shortlink); - $response = wpbitly_get($url); - - if (is_array($response)) - $refer = $response['data']['referring_domains']; - - - echo ''; - - if (isset($clicks) && isset($refer)) { - - echo '' . __('Global click through:', 'wp-bitly') . ' ' . $clicks . '
'; - - if (!empty($refer)) { - echo '' . __('There was a problem retrieving information about your link. There may be no statistics yet.', 'wp-bitly') . '
'; - } - - } - -} - -// Get... in! -WP_Bitly_Admin::get_in(); +action_filters(); + } + + return self::$_instance; + } + + + /** + * Hook any necessary WordPress actions or filters that we'll be needing for the admin. + * + * @since 2.0 + * @uses wpbitly() + */ + public function action_filters() { + + $wpbitly = wpbitly(); + $token = $wpbitly->get_option('oauth_token'); + + add_action('admin_init', array($this, 'register_settings')); + + if (empty($token)) + add_action('admin_notices', array($this, 'display_notice')); + + + $post_types = $wpbitly->get_option('post_types'); + + if (is_array($post_types)) { + foreach ($post_types as $post_type) { + add_action('add_meta_boxes_' . $post_type, array($this, 'add_metaboxes_yo')); + } + } + + } + + + /** + * Display a simple and unobtrusive notice on the plugins page after activation (and + * up until they add their oauth_token). + * + * @since 2.0 + */ + public function display_notice() { + + $screen = get_current_screen(); + + if ($screen->base != 'plugins') + return; + + + $prologue = esc_html__('WP Bit.Ly is almost ready!', 'wp-bitly'); + $link = '' . esc_html__('settings page', 'wp-bitly') . ''; + $epilogue = sprintf(esc_html__('Please visit the %s to configure WP Bit.ly', 'wp-bitly'), $link); + + $message = apply_filters('wpbitly_setup_notice', '' . $prologue . ' ' . $epilogue . '
' . esc_html__('You will need a Bitly account to use this plugin. Click the link below for your OAuth Token, and if necessary create a new account.', 'wp-bitly') . '
'); + } + + + add_settings_field('oauth_token', '', '_f_settings_field_oauth', 'writing', 'wpbitly_settings'); + /** + * @ignore + */ + function _f_settings_field_oauth() { + + $wpbitly = wpbitly(); + + $url = apply_filters('wpbitly_oauth_url', 'https://bitly.com/a/wordpress_oauth_app'); + + $auth_css = $wpbitly->get_option('authorized') ? '' : ' style="border-color: #c00; background-color: #ffecec;" '; + $output = '' . '' . esc_html__('Please provide your', 'wp-bitly') . ' ' . esc_html__('OAuth Token', 'wp-bitly') . '
'; + + echo $output; + + } + + + add_settings_field('post_types', '', '_f_settings_field_post_types', 'writing', 'wpbitly_settings'); + /** + * @ignore + */ + function _f_settings_field_post_types() { + + $wpbitly = wpbitly(); + + $post_types = apply_filters('wpbitly_allowed_post_types', get_post_types(array('public' => true))); + $output = ''; + + echo $output; + + } + + + add_settings_field('debug', '', '_f_settings_field_debug', 'writing', 'wpbitly_settings'); + /** + * @ignore + */ + function _f_settings_field_debug() { + + $wpbitly = wpbitly(); + + $output = ''; + + echo $output; + + } + + } + + + /** + * Validate user settings. This will also authorize their OAuth token if it has + * changed. + * + * @since 2.0 + * @uses wpbitly() + * + * @param array $input WordPress sanitized data array + * + * @return array WP Bit.ly sanitized data + */ + public function validate_settings($input) { + + $wpbitly = wpbitly(); + + $input['debug'] = ('1' == $input['debug']) ? true : false; + + $input['oauth_token'] = sanitize_text_field($input['oauth_token']); + + $url = sprintf(wpbitly_api('user/info'), $input['oauth_token']); + $response = wpbitly_get($url); + + wpbitly_debug_log($response, 'Validate OAuth', $input['debug']); + + + $input['authorized'] = (isset($response['data']['member_since'])) ? true : false; + + if (!isset($input['post_types'])) { + $input['post_types'] = array(); + } else { + $post_types = apply_filters('wpbitly_allowed_post_types', get_post_types(array('public' => true))); + + foreach ($input['post_types'] as $key => $pt) { + if (!in_array($pt, $post_types)) + unset($input['post_types'][ $key ]); + } + + } + + return $input; + + } + + + /** + * Add a fun little statistics metabox to any posts/pages that WP Bit.ly + * generates a link for. There's potential here to include more information. + * + * @since 2.0 + * @TODO Should the user can turn this on or off? You heard me. + * + * @param object $post The post object passed by WordPress + */ + public function add_metaboxes_yo($post) { + + $shortlink = get_post_meta($post->ID, '_wpbitly', true); + if (!$shortlink) + return; + + add_meta_box('wpbitly-meta', 'WP Bit.ly', array( + $this, + 'display_metabox' + ), $post->post_type, 'side', 'default', array($shortlink)); + } + + + /** + * Handles the display of the metabox. + * + * @since 2.0 + * + * @param object $post WordPress passed $post object + * @param array $args Passed by our call to add_meta_box(), just the $shortlink in this case. + */ + public function display_metabox($post, $args) { + + $wpbitly = wpbitly(); + $shortlink = $args['args'][0]; + + $clicks = wp_cache_get( 'bitly_clicks_' . $post->ID, 'bitly' ); + + if ( false === $clicks ) { + // Look for a clicks response + $url = sprintf( wpbitly_api( 'link/clicks' ), $wpbitly->get_option( 'oauth_token' ), $shortlink ); + $response = wpbitly_get( $url ); + + if ( is_array( $response ) ) { + $clicks = $response['data']['link_clicks']; + wp_cache_set( 'bitly_clicks_' . $post->ID, $clicks, 'bitly', 30 * MINUTE_IN_SECONDS ); + } else { + //if we don't get a good response, let stop trying for a few min + wp_cache_set( 'bitly_clicks_' . $post->ID, - 1, 'bitly', MINUTE_IN_SECONDS ); + } + } + + $refer = wp_cache_get( 'bitly_refer_' . $post->ID, 'bitly' ); + + if ( false === $refer ) { + // Look for referring domains metadata + $url = sprintf( wpbitly_api( 'link/refer' ), $wpbitly->get_option( 'oauth_token' ), $shortlink ); + $response = wpbitly_get( $url ); + + if ( is_array( $response ) ) { + $refer = $response['data']['referring_domains']; + wp_cache_set( 'bitly_refer_' . $post->ID, $refer, 'bitly', 30 * MINUTE_IN_SECONDS ); + } else { + //if we don't get a good response, let stop trying for a few min + wp_cache_set( 'bitly_refer_' . $post->ID, - 1, 'bitly', MINUTE_IN_SECONDS ); + } + } + + echo ''; + + if ( -1 !== $clicks && -1 !== $refer ) { + + echo '' . esc_html__('Global click through:', 'wp-bitly') . ' ' . esc_html( $clicks ) . '
'; + + if (!empty($refer)) { + echo '' . esc_html__('There was a problem retrieving information about your link. There may be no statistics yet.', 'wp-bitly') . '
'; + } + + } + +} + +// Get... in! +WP_Bitly_Admin::get_in(); diff --git a/includes/functions.php b/includes/functions.php index 6d0c602..827e69e 100644 --- a/includes/functions.php +++ b/includes/functions.php @@ -1,215 +1,232 @@ -get_option('debug') || !$bypass) - return; - - - $log = fopen(WPBITLY_LOG, 'a'); - - fwrite($log, '# [ ' . date('F j, Y, g:i a') . " ]\n"); - fwrite($log, '# [ ' . $message . " ]\n\n"); - // There was a reason I wanted to export vars, so despite suggestions I'm leaving this in at present. - fwrite($log, (is_array($towrite) ? print_r($towrite, true) : var_export($towrite, 1))); - fwrite($log, "\n\n\n"); - - fclose($log); - -} - - -/** - * What better way to store our api access call endpoints? I'm sure there is one, but this works for me. - * - * @since 2.0 - * - * @param string $api_call Which endpoint do we need? - * - * @return string Returns the URL for our requested API endpoint - */ -function wpbitly_api($api_call) { - - $api_links = array( - 'shorten' => '/v3/shorten?access_token=%1$s&longUrl=%2$s', - 'expand' => '/v3/expand?access_token=%1$s&shortUrl=%2$s', - 'link/clicks' => '/v3/link/clicks?access_token=%1$s&link=%2$s', - 'link/refer' => '/v3/link/referring_domains?access_token=%1$s&link=%2$s', - 'user/info' => '/v3/user/info?access_token=%1$s', - ); - - if (!array_key_exists($api_call, $api_links)) - trigger_error(__('WP Bitly Error: No such API endpoint.', 'wp-bitly')); - - return WPBITLY_BITLY_API . $api_links[ $api_call ]; -} - - -/** - * WP Bitly wrapper for wp_remote_get. Why have I been using cURL when WordPress already does this? - * Thanks to Otto, who while teaching someone else how to do it right unwittingly taught me the right - * way as well. - * - * @since 2.1 - * - * @param string $url The API endpoint we're contacting - * - * @return bool|array False on failure, array on success - */ - -function wpbitly_get($url) { - - $the = wp_remote_get($url, array('timeout' => '30',)); - - if (is_array($the) && '200' == $the['response']['code']) - return json_decode($the['body'], true); -} - - -/** - * Generates the shortlink for the post specified by $post_id. - * - * @since 0.1 - * - * @param int $post_id The post ID we need a shortlink for. - * - * @return bool|string Returns the shortlink on success. - */ - -function wpbitly_generate_shortlink($post_id) { - - $wpbitly = wpbitly(); - - // Avoid creating shortlinks during an autosave - if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) - return; - - // or for revisions - if (wp_is_post_revision($post_id)) - return; - - // Token hasn't been verified, bail - if (!$wpbitly->get_option('authorized')) - return; - - // Verify this is a post we want to generate short links for - if (!in_array(get_post_type($post_id), $wpbitly->get_option('post_types')) || - !in_array(get_post_status($post_id), array('publish', 'future', 'private'))) - return; - - - // We made it this far? Let's get a shortlink - $permalink = get_permalink($post_id); - $shortlink = get_post_meta($post_id, '_wpbitly', true); - $token = $wpbitly->get_option('oauth_token'); - - if (!empty($shortlink)) { - $url = sprintf(wpbitly_api('expand'), $token, $shortlink); - $response = wpbitly_get($url); - - wpbitly_debug_log($response, '/expand/'); - - if ($permalink == $response['data']['expand'][0]['long_url']) - return $shortlink; - } - - $url = sprintf(wpbitly_api('shorten'), $token, urlencode($permalink)); - $response = wpbitly_get($url); - - wpbitly_debug_log($response, '/shorten/'); - - if (is_array($response)) { - $shortlink = $response['data']['url']; - update_post_meta($post_id, '_wpbitly', $shortlink); - } - - return $shortlink; -} - - -/** - * Short circuits the `pre_get_shortlink` filter. - * - * @since 0.1 - * - * @param bool $shortlink False is passed in by default. - * @param int $post_id Current $post->ID, or 0 for the current post. - * - * @return string A shortlink - */ -function wpbitly_get_shortlink($original, $post_id) { - - $wpbitly = wpbitly(); - - // Verify this is a post we want to generate short links for - if (!in_array(get_post_type($post_id), $wpbitly->get_option('post_types'))) - return $original; - - if (0 == $post_id) { - $post = get_post(); - $post_id = $post->ID; - } - - $shortlink = get_post_meta($post_id, '_wpbitly', true); - - if (!$shortlink) - $shortlink = wpbitly_generate_shortlink($post_id); - - return ($shortlink) ? $shortlink : $original; -} - - -/** - * This is our shortcode handler, which could also be called directly. - * - * @since 0.1 - * - * @param array $atts Default shortcode attributes. - */ -function wpbitly_shortlink($atts = array()) { - - $post = get_post(); - - $defaults = array( - 'text' => '', - 'title' => '', - 'before' => '', - 'after' => '', - 'post_id' => $post->ID, // Use the current post by default, or pass an ID - ); - - extract(shortcode_atts($defaults, $atts)); - - $permalink = get_permalink($post_id); - $shortlink = wpbitly_get_shortlink($permalink, $post_id); - - if (empty($text)) - $text = $shortlink; - - if (empty($title)) - $title = the_title_attribute(array('echo' => false)); - - $output = ''; - - if (!empty($shortlink)) { - $output = apply_filters('the_shortlink', '' . $text . '', $shortlink, $text, $title); - $output = $before . $output . $after; - } - - return $output; -} +get_option( 'debug' ) || ! $bypass ) { + return; + } + + if ( 'direct' === get_filesystem_method() ) { + if ( ! WP_Filesystem( true ) ) { + return; + } + + /** + * @var $wp_filesystem WP_Filesystem_Direct + */ + global $wp_filesystem; + + $log = $wp_filesystem->get_contents( WPBITLY_LOG ); + $log = $log ? $log : ''; + + $log .= '# [ ' . date( 'F j, Y, g:i a' ) . " ]\n"; + $log .= '# [ ' . $message . " ]\n\n"; + $log .= ( is_array( $towrite ) ? print_r( $towrite, true ) : var_export( $towrite, 1 ) ); + $log .= "\n\n\n"; + + if ( ! $wp_filesystem->is_dir( dirname( WPBITLY_LOG ) ) ) { + $wp_filesystem->mkdir( dirname( WPBITLY_LOG ) ); + } + + $wp_filesystem->put_contents( WPBITLY_LOG, $log ); + } +} + + +/** + * What better way to store our api access call endpoints? I'm sure there is one, but this works for me. + * + * @since 2.0 + * + * @param string $api_call Which endpoint do we need? + * + * @return string Returns the URL for our requested API endpoint + */ +function wpbitly_api($api_call) { + + $api_links = array( + 'shorten' => '/v3/shorten?access_token=%1$s&longUrl=%2$s', + 'expand' => '/v3/expand?access_token=%1$s&shortUrl=%2$s', + 'link/clicks' => '/v3/link/clicks?access_token=%1$s&link=%2$s', + 'link/refer' => '/v3/link/referring_domains?access_token=%1$s&link=%2$s', + 'user/info' => '/v3/user/info?access_token=%1$s', + ); + + if (!array_key_exists($api_call, $api_links)) + trigger_error(__('WP Bitly Error: No such API endpoint.', 'wp-bitly')); + + return WPBITLY_BITLY_API . $api_links[ $api_call ]; +} + + +/** + * WP Bitly wrapper for wp_remote_get. Why have I been using cURL when WordPress already does this? + * Thanks to Otto, who while teaching someone else how to do it right unwittingly taught me the right + * way as well. + * + * @since 2.1 + * + * @param string $url The API endpoint we're contacting + * + * @return bool|array False on failure, array on success + */ +function wpbitly_get($url) { + + $the = wp_remote_get($url, array('timeout' => '30',)); + + if (is_array($the) && '200' == $the['response']['code']) + return json_decode($the['body'], true); +} + + +/** + * Generates the shortlink for the post specified by $post_id. + * + * @since 0.1 + * + * @param int $post_id The post ID we need a shortlink for. + * + * @return bool|string Returns the shortlink on success. + */ +function wpbitly_generate_shortlink($post_id) { + + $wpbitly = wpbitly(); + + // Avoid creating shortlinks during an autosave + if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) + return; + + // or for revisions + if (wp_is_post_revision($post_id)) + return; + + // Token hasn't been verified, bail + if (!$wpbitly->get_option('authorized')) + return; + + // Verify this is a post we want to generate short links for + if (!in_array(get_post_type($post_id), $wpbitly->get_option('post_types')) || + !in_array(get_post_status($post_id), array('publish', 'future', 'private'))) + return; + + + // We made it this far? Let's get a shortlink + $permalink = get_permalink($post_id); + $shortlink = get_post_meta($post_id, '_wpbitly', true); + $token = $wpbitly->get_option('oauth_token'); + + if (!empty($shortlink)) { + $url = sprintf(wpbitly_api('expand'), $token, $shortlink); + $response = wpbitly_get($url); + + wpbitly_debug_log($response, '/expand/'); + + if ($permalink == $response['data']['expand'][0]['long_url']) + return $shortlink; + } + + $url = sprintf(wpbitly_api('shorten'), $token, urlencode($permalink)); + $response = wpbitly_get($url); + + wpbitly_debug_log($response, '/shorten/'); + + if ( is_array( $response ) ) { + if ( isset( $response['status_code'] ) && 200 !== $response['status_code'] ) { + return; + } + if ( isset( $response['data']['url'] ) ) { + $shortlink = $response['data']['url']; + update_post_meta( $post_id, '_wpbitly', $shortlink ); + } + } + + return $shortlink; +} + + +/** + * Short circuits the `pre_get_shortlink` filter. + * + * @since 0.1 + * + * @param bool $shortlink False is passed in by default. + * @param int $post_id Current $post->ID, or 0 for the current post. + * + * @return string A shortlink + */ +function wpbitly_get_shortlink($original, $post_id) { + + $wpbitly = wpbitly(); + + // Verify this is a post we want to generate short links for + if (!in_array(get_post_type($post_id), $wpbitly->get_option('post_types'))) + return $original; + + if (0 == $post_id) { + $post = get_post(); + $post_id = $post->ID; + } + + $shortlink = get_post_meta($post_id, '_wpbitly', true); + + if (!$shortlink) + $shortlink = wpbitly_generate_shortlink($post_id); + + return ($shortlink) ? $shortlink : $original; +} + + +/** + * This is our shortcode handler, which could also be called directly. + * + * @since 0.1 + * + * @param array $atts Default shortcode attributes. + */ +function wpbitly_shortlink($atts = array()) { + + $post = get_post(); + + $defaults = array( + 'text' => '', + 'title' => '', + 'before' => '', + 'after' => '', + 'post_id' => $post->ID, // Use the current post by default, or pass an ID + ); + + extract(shortcode_atts($defaults, $atts)); + + $permalink = get_permalink($post_id); + $shortlink = wpbitly_get_shortlink($permalink, $post_id); + + if (empty($text)) + $text = $shortlink; + + if (empty($title)) + $title = the_title_attribute(array('echo' => false)); + + $output = ''; + + if (!empty($shortlink)) { + $output = apply_filters('the_shortlink', '' . esc_html( $text ) . '', $shortlink, $text, $title); + $output = $before . $output . $after; + } + + return $output; +} diff --git a/uninstall.php b/uninstall.php index 326d3b9..792bfc1 100644 --- a/uninstall.php +++ b/uninstall.php @@ -1,35 +1,35 @@ - - * @license GPL-2.0+ - * @link http://wordpress.org/plugins/wp-bitly - * @copyright 2014 Mark Waterous - */ - -if (!defined('WP_UNINSTALL_PLUGIN')) - die; - - -/** - * Some people just don't know how cool this plugin is. When they realize - * it and come back later, let's make sure they have to start all over. - * - * @return void - */ -function wpbitly_uninstall() { - // Delete associated options - delete_option('wpbitly-options'); - - // Grab all posts with an attached shortlink - $posts = get_posts('numberposts=-1&post_type=any&meta_key=_wpbitly'); - - // And remove our meta information from them - // @TODO benchmark this against deleting it with a quick SQL query. Probably quicker, any conflict? - foreach ($posts as $post) - delete_post_meta($post->ID, '_wpbitly'); - -} - -// G'bye! -wpbitly_uninstall(); + + * @license GPL-2.0+ + * @link http://wordpress.org/plugins/wp-bitly + * @copyright 2014 Mark Waterous + */ + +if (!defined('WP_UNINSTALL_PLUGIN')) + die; + + +/** + * Some people just don't know how cool this plugin is. When they realize + * it and come back later, let's make sure they have to start all over. + * + * @return void + */ +function wpbitly_uninstall() { + // Delete associated options + delete_option('wpbitly-options'); + + // Grab all posts with an attached shortlink + $posts = get_posts('numberposts=-1&post_type=any&meta_key=_wpbitly'); + + // And remove our meta information from them + // @TODO benchmark this against deleting it with a quick SQL query. Probably quicker, any conflict? + foreach ($posts as $post) + delete_post_meta($post->ID, '_wpbitly'); + +} + +// G'bye! +wpbitly_uninstall(); diff --git a/wp-bitly.php b/wp-bitly.php index ca1c3c2..3452a2b 100644 --- a/wp-bitly.php +++ b/wp-bitly.php @@ -1,270 +1,270 @@ - - * @author Chip Bennett - * @license GPL-2.0+ - * @link http://wordpress.org/plugins/wp-bitly - * @copyright 2014 Mark Waterous & Chip Bennett - * @wordpress-plugin - * Plugin Name: WP Bitly - * Plugin URI: http://wordpress.org/plugins/wp-bitly - * Description: WP Bitly can be used to generate shortlinks for your websites posts, pages, and custom post types. Extremely lightweight and easy to set up, give it your Bitly oAuth token and go! - * Version: 2.3.2 - * Author: Mark Waterous & Chip Bennett - * Text Domain: wp-bitly - * License: GPL-2.0+ - * License URI: http://www.gnu.org/licenses/gpl-2.0.txt - * Domain Path: /languages - * GitHub Plugin URI: https://github.com/mwaterous/wp-bitly - */ - - -if (!defined('WPINC')) - die; - - -define('WPBITLY_VERSION', '2.3.2'); - -define('WPBITLY_DIR', WP_PLUGIN_DIR . '/' . basename(dirname(__FILE__))); -define('WPBITLY_URL', plugins_url() . '/' . basename(dirname(__FILE__))); - -define('WPBITLY_LOG', WPBITLY_DIR . '/log/debug.txt'); -define('WPBITLY_ERROR', __('WP Bitly Error: No such option %1$s', 'wp-bitly')); - -define('WPBITLY_BITLY_API', 'https://api-ssl.bitly.com'); - -/** - * The primary controller class for everything wonderful that WP Bitly does. - * We're not sure entirely what that means yet; if you figure it out, please - * let us know and we'll say something snazzy about it here. - * - * @TODO : Update the class phpdoc description to say something snazzy. - * @package wp-bitly - * @author Mark Waterous - */ -final class WP_Bitly { - - /** - * @var $_instance An instance of ones own instance - */ - private static $_instance; - - /** - * @var array The WP Bitly configuration is stored in here - */ - private $_options = array(); - - - /** - * This creates and returns a single instance of WP_Bitly. - * If you haven't seen a singleton before, visit any Starbucks; they're the ones sitting on expensive laptops - * in the corner drinking a macchiato and pretending to write a book. They'll always be singletons. - * - * @since 2.0 - * @static - * @uses WP_Bitly::populate_options() To create our options array. - * @uses WP_Bitly::includes_files() To do something that sounds a lot like what it sounds like. - * @uses WP_Bitly::check_for_upgrade() You run your updates, right? - * @uses WP_Bitly::action_filters() To set up any necessary WordPress hooks. - * @return WP_Bitly - */ - public static function get_in() { - if (null === self::$_instance) { - self::$_instance = new self; - self::$_instance->populate_options(); - self::$_instance->include_files(); - self::$_instance->check_for_upgrade(); - self::$_instance->action_filters(); - } - - return self::$_instance; - } - - - /** - * Populate WP_Bitly::$options with the configuration settings stored in 'wpbitly-options', - * using an array of default settings as our fall back. - * - * @since 2.0 - */ - public function populate_options() { - - $defaults = apply_filters('wpbitly_default_options', array( - 'version' => WPBITLY_VERSION, - 'oauth_token' => '', - 'post_types' => array('post', 'page'), - 'authorized' => false, - 'debug' => false, - )); - - $this->_options = wp_parse_args(get_option('wpbitly-options'), $defaults); - - } - - - /** - * Access to our WP_Bitly::$_options array. - * - * @since 2.2.5 - * - * @param $option string The name of the option we need to retrieve - * - * @return mixed Returns the option - */ - public function get_option($option) { - if (!isset($this->_options[ $option ])) - trigger_error(sprintf(WPBITLY_ERROR, '' . $option . ''), E_USER_ERROR);
-
- return $this->_options[ $option ];
- }
-
-
- /**
- * Sets a single WP_Bitly::$_options value on the fly
- *
- * @since 2.2.5
- *
- * @param $option string The name of the option we're setting
- * @param $value mixed The value, could be bool, string, array
- */
- public function set_option($option, $value) {
- if (!isset($this->_options[ $option ]))
- trigger_error(sprintf(WPBITLY_ERROR, ' ' . $option . ''), E_USER_ERROR);
-
- $this->_options[ $option ] = $value;
- }
-
-
- /**
- * WP Bitly is a pretty big plugin. Without this function, we'd probably include things
- * in the wrong order, or not at all, and cold wars would erupt all over the planet.
- *
- * @since 2.0
- */
- public function include_files() {
- require_once(WPBITLY_DIR . '/includes/functions.php');
- if (is_admin())
- require_once(WPBITLY_DIR . '/includes/class.wp-bitly-admin.php');
- }
-
-
- /**
- * Simple wrapper for making sure everybody (who actually updates their plugins) is
- * current and that we don't just delete all their old data.
- *
- * @since 2.0
- */
- public function check_for_upgrade() {
-
- // We only have to upgrade if it's pre v2.0
- $upgrade_needed = get_option('wpbitly_options');
- if ($upgrade_needed !== false) {
-
- if (isset($upgrade_needed['post_types']) && is_array($upgrade_needed['post_types'])) {
- $post_types = apply_filters('wpbitly_allowed_post_types', get_post_types(array('public' => true)));
-
- foreach ($upgrade_needed['post_types'] as $key => $pt) {
- if (!in_array($pt, $post_types))
- unset($upgrade_needed['post_types'][ $key ]);
- }
-
- $this->set_option('post_types', $upgrade_needed['post_types']);
- }
-
- delete_option('wpbitly_options');
-
- }
-
- }
-
-
- /**
- * Hook any necessary WordPress actions or filters that we'll be needing in order to make
- * the plugin work its magic. This method also registers our super amazing slice of shortcode.
- *
- * @since 2.0
- * @todo Instead of arbitrarily deactivating the Jetpack module, it might be polite to ask.
- */
- public function action_filters() {
-
- add_filter('plugin_action_links_' . plugin_basename(__FILE__), array($this, 'add_action_links'));
-
- add_action('save_post', 'wpbitly_generate_shortlink');
- add_filter('pre_get_shortlink', 'wpbitly_get_shortlink', 10, 2);
-
- add_action('init', array($this, 'load_plugin_textdomain'));
- add_action( 'admin_bar_menu', 'wp_admin_bar_shortlink_menu', 90 );
-
- add_shortcode('wpbitly', 'wpbitly_shortlink');
-
- if (class_exists('Jetpack')) {
-
- add_filter('jetpack_get_available_modules', '_bad_wpme');
- function _bad_wpme($modules) {
- unset($modules['shortlinks']);
-
- return $modules;
- }
-
- }
-
- }
-
-
- /**
- * Add a settings link to the plugins page so people can figure out where we are.
- *
- * @since 2.0
- *
- * @param $links An array returned by WordPress with our plugin action links
- *
- * @return array The slightly modified 'rray.
- */
- public function add_action_links($links) {
-
- return array_merge(array('settings' => '' . __('Settings', 'wp-bitly') . ''), $links);
-
- }
-
-
- /**
- * This would be much easier if we all spoke Esperanto (or Old Norse).
- *
- * @since 2.0
- */
- public function load_plugin_textdomain() {
-
- $languages = apply_filters('wpbitly_languages_dir', WPBITLY_DIR . '/languages/');
- $locale = apply_filters('plugin_locale', get_locale(), 'wp-bitly');
- $mofile = $languages . $locale . '.mo';
-
- if (file_exists($mofile)) {
- load_textdomain('wp-bitly', $mofile);
- } else {
- load_plugin_textdomain('wp-bitly', false, $languages);
- }
-
- }
-
-}
-
-
-/**
- * Call this in place of WP_Bitly::get_in()
- * It's shorthand.
- * Makes life easier.
- * In fact, the phpDocumentor block is bigger than the function itself.
- *
- * @return WP_Bitly
- */
-function wpbitly() {
- return WP_Bitly::get_in(); // in.
-}
-
-wpbitly();
+
+ * @author Chip Bennett
+ * @license GPL-2.0+
+ * @link http://wordpress.org/plugins/wp-bitly
+ * @copyright 2014 Mark Waterous & Chip Bennett
+ * @wordpress-plugin
+ * Plugin Name: WP Bitly
+ * Plugin URI: http://wordpress.org/plugins/wp-bitly
+ * Description: WP Bitly can be used to generate shortlinks for your websites posts, pages, and custom post types. Extremely lightweight and easy to set up, give it your Bitly oAuth token and go!
+ * Version: 2.3.2
+ * Author: Mark Waterous & Chip Bennett
+ * Text Domain: wp-bitly
+ * License: GPL-2.0+
+ * License URI: http://www.gnu.org/licenses/gpl-2.0.txt
+ * Domain Path: /languages
+ * GitHub Plugin URI: https://github.com/mwaterous/wp-bitly
+ */
+
+
+if (!defined('WPINC'))
+ die;
+
+
+define('WPBITLY_VERSION', '2.3.2');
+
+define('WPBITLY_DIR', WP_PLUGIN_DIR . '/' . basename(dirname(__FILE__)));
+define('WPBITLY_URL', plugins_url() . '/' . basename(dirname(__FILE__)));
+
+define('WPBITLY_LOG', WPBITLY_DIR . '/log/debug.txt');
+define('WPBITLY_ERROR', esc_html__('WP Bitly Error: No such option %1$s', 'wp-bitly'));
+
+define('WPBITLY_BITLY_API', 'https://api-ssl.bitly.com');
+
+/**
+ * The primary controller class for everything wonderful that WP Bitly does.
+ * We're not sure entirely what that means yet; if you figure it out, please
+ * let us know and we'll say something snazzy about it here.
+ *
+ * @TODO : Update the class phpdoc description to say something snazzy.
+ * @package wp-bitly
+ * @author Mark Waterous
+ */
+final class WP_Bitly {
+
+ /**
+ * @var $_instance An instance of ones own instance
+ */
+ private static $_instance;
+
+ /**
+ * @var array The WP Bitly configuration is stored in here
+ */
+ private $_options = array();
+
+
+ /**
+ * This creates and returns a single instance of WP_Bitly.
+ * If you haven't seen a singleton before, visit any Starbucks; they're the ones sitting on expensive laptops
+ * in the corner drinking a macchiato and pretending to write a book. They'll always be singletons.
+ *
+ * @since 2.0
+ * @static
+ * @uses WP_Bitly::populate_options() To create our options array.
+ * @uses WP_Bitly::includes_files() To do something that sounds a lot like what it sounds like.
+ * @uses WP_Bitly::check_for_upgrade() You run your updates, right?
+ * @uses WP_Bitly::action_filters() To set up any necessary WordPress hooks.
+ * @return WP_Bitly
+ */
+ public static function get_in() {
+ if (null === self::$_instance) {
+ self::$_instance = new self;
+ self::$_instance->populate_options();
+ self::$_instance->include_files();
+ self::$_instance->check_for_upgrade();
+ self::$_instance->action_filters();
+ }
+
+ return self::$_instance;
+ }
+
+
+ /**
+ * Populate WP_Bitly::$options with the configuration settings stored in 'wpbitly-options',
+ * using an array of default settings as our fall back.
+ *
+ * @since 2.0
+ */
+ public function populate_options() {
+
+ $defaults = apply_filters('wpbitly_default_options', array(
+ 'version' => WPBITLY_VERSION,
+ 'oauth_token' => '',
+ 'post_types' => array('post', 'page'),
+ 'authorized' => false,
+ 'debug' => false,
+ ));
+
+ $this->_options = wp_parse_args(get_option('wpbitly-options'), $defaults);
+
+ }
+
+
+ /**
+ * Access to our WP_Bitly::$_options array.
+ *
+ * @since 2.2.5
+ *
+ * @param $option string The name of the option we need to retrieve
+ *
+ * @return mixed Returns the option
+ */
+ public function get_option($option) {
+ if (!isset($this->_options[ $option ]))
+ trigger_error(sprintf(WPBITLY_ERROR, ' ' . $option . ''), E_USER_ERROR);
+
+ return $this->_options[ $option ];
+ }
+
+
+ /**
+ * Sets a single WP_Bitly::$_options value on the fly
+ *
+ * @since 2.2.5
+ *
+ * @param $option string The name of the option we're setting
+ * @param $value mixed The value, could be bool, string, array
+ */
+ public function set_option($option, $value) {
+ if (!isset($this->_options[ $option ]))
+ trigger_error(sprintf(WPBITLY_ERROR, ' ' . $option . ''), E_USER_ERROR);
+
+ $this->_options[ $option ] = $value;
+ }
+
+
+ /**
+ * WP Bitly is a pretty big plugin. Without this function, we'd probably include things
+ * in the wrong order, or not at all, and cold wars would erupt all over the planet.
+ *
+ * @since 2.0
+ */
+ public function include_files() {
+ require_once(WPBITLY_DIR . '/includes/functions.php');
+ if (is_admin())
+ require_once(WPBITLY_DIR . '/includes/class.wp-bitly-admin.php');
+ }
+
+
+ /**
+ * Simple wrapper for making sure everybody (who actually updates their plugins) is
+ * current and that we don't just delete all their old data.
+ *
+ * @since 2.0
+ */
+ public function check_for_upgrade() {
+
+ // We only have to upgrade if it's pre v2.0
+ $upgrade_needed = get_option('wpbitly_options');
+ if ($upgrade_needed !== false) {
+
+ if (isset($upgrade_needed['post_types']) && is_array($upgrade_needed['post_types'])) {
+ $post_types = apply_filters('wpbitly_allowed_post_types', get_post_types(array('public' => true)));
+
+ foreach ($upgrade_needed['post_types'] as $key => $pt) {
+ if (!in_array($pt, $post_types))
+ unset($upgrade_needed['post_types'][ $key ]);
+ }
+
+ $this->set_option('post_types', $upgrade_needed['post_types']);
+ }
+
+ delete_option('wpbitly_options');
+
+ }
+
+ }
+
+
+ /**
+ * Hook any necessary WordPress actions or filters that we'll be needing in order to make
+ * the plugin work its magic. This method also registers our super amazing slice of shortcode.
+ *
+ * @since 2.0
+ * @todo Instead of arbitrarily deactivating the Jetpack module, it might be polite to ask.
+ */
+ public function action_filters() {
+
+ add_filter('plugin_action_links_' . plugin_basename(__FILE__), array($this, 'add_action_links'));
+
+ add_action('save_post', 'wpbitly_generate_shortlink');
+ add_filter('pre_get_shortlink', 'wpbitly_get_shortlink', 10, 2);
+
+ add_action('init', array($this, 'load_plugin_textdomain'));
+ add_action( 'admin_bar_menu', 'wp_admin_bar_shortlink_menu', 90 );
+
+ add_shortcode('wpbitly', 'wpbitly_shortlink');
+
+ if (class_exists('Jetpack')) {
+
+ add_filter('jetpack_get_available_modules', '_bad_wpme');
+ function _bad_wpme($modules) {
+ unset($modules['shortlinks']);
+
+ return $modules;
+ }
+
+ }
+
+ }
+
+
+ /**
+ * Add a settings link to the plugins page so people can figure out where we are.
+ *
+ * @since 2.0
+ *
+ * @param $links An array returned by WordPress with our plugin action links
+ *
+ * @return array The slightly modified 'rray.
+ */
+ public function add_action_links($links) {
+
+ return array_merge(array('settings' => '' . esc_html__('Settings', 'wp-bitly') . ''), $links);
+
+ }
+
+
+ /**
+ * This would be much easier if we all spoke Esperanto (or Old Norse).
+ *
+ * @since 2.0
+ */
+ public function load_plugin_textdomain() {
+
+ $languages = apply_filters('wpbitly_languages_dir', WPBITLY_DIR . '/languages/');
+ $locale = apply_filters('plugin_locale', get_locale(), 'wp-bitly');
+ $mofile = $languages . $locale . '.mo';
+
+ if (file_exists($mofile)) {
+ load_textdomain('wp-bitly', $mofile);
+ } else {
+ load_plugin_textdomain('wp-bitly', false, $languages);
+ }
+
+ }
+
+}
+
+
+/**
+ * Call this in place of WP_Bitly::get_in()
+ * It's shorthand.
+ * Makes life easier.
+ * In fact, the phpDocumentor block is bigger than the function itself.
+ *
+ * @return WP_Bitly
+ */
+function wpbitly() {
+ return WP_Bitly::get_in(); // in.
+}
+
+wpbitly();