diff --git a/.floo b/.floo new file mode 100644 index 0000000..c9fc70a --- /dev/null +++ b/.floo @@ -0,0 +1,3 @@ +{ + "url": "https://floobits.com/jaswsinc/wp-redirects" +} \ No newline at end of file diff --git a/.flooignore b/.flooignore new file mode 100644 index 0000000..ed824d3 --- /dev/null +++ b/.flooignore @@ -0,0 +1,6 @@ +extern +node_modules +tmp +vendor +.idea/workspace.xml +.idea/misc.xml diff --git a/README.md b/README.md index 240cdf6..d47eef3 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,7 @@ ## WordPress® Redirects Redirects (a new Post Type) for WordPress®. + +--- + +This project is now on Floobits too! [Watch us code](https://floobits.com/jaswsinc/wp-redirects/redirect) in real-time :-) Floobits status diff --git a/assets/icon-128x128.png b/assets/icon-128x128.png new file mode 100644 index 0000000..779e045 Binary files /dev/null and b/assets/icon-128x128.png differ diff --git a/assets/icon-256x256.png b/assets/icon-256x256.png new file mode 100644 index 0000000..2e3823a Binary files /dev/null and b/assets/icon-256x256.png differ diff --git a/wp-redirects/client-s/css/admin-style.css b/wp-redirects/client-s/css/admin-style.css new file mode 100644 index 0000000..9ebb9f0 --- /dev/null +++ b/wp-redirects/client-s/css/admin-style.css @@ -0,0 +1,2 @@ +.column-hits { width: 75px; } +.column-last_access { width: 150px; } \ No newline at end of file diff --git a/wp-redirects/includes/translations/wp-redirects.pot b/wp-redirects/includes/translations/wp-redirects.pot index 1b1956e..e0f5523 100644 --- a/wp-redirects/includes/translations/wp-redirects.pot +++ b/wp-redirects/includes/translations/wp-redirects.pot @@ -2,9 +2,9 @@ # This file is distributed under the same license as the WP Redirects package. msgid "" msgstr "" -"Project-Id-Version: WP Redirects 131121\n" +"Project-Id-Version: WP Redirects 141009\n" "Report-Msgid-Bugs-To: http://wordpress.org/tag/wp-redirects\n" -"POT-Creation-Date: 2014-01-08 06:00:06+00:00\n" +"POT-Creation-Date: 2014-10-09 19:19:10+00:00\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -12,123 +12,196 @@ msgstr "" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" -#: wp-redirects.php:58 +#: includes/wp-php53.php:64 +msgid "%1$s is NOT active." +msgstr "" + +#: includes/wp-php53.php:65 +msgid "It requires PHP v%1$s+." +msgstr "" + +#: includes/wp-php53.php:66 +msgid "↳ You're currently running an older copy of PHP v%1$s." +msgstr "" + +#: includes/wp-php53.php:67 +msgid "A simple update is necessary. Please ask your hosting company to help resolve this quickly." +msgstr "" + +#: includes/wp-php53.php:68 +msgid "To remove this message, please upgrade. Or, remove %1$s from WordPress." +msgstr "" + +#: wp-redirects.inc.php:107 msgid "Redirects" msgstr "" -#: wp-redirects.php:59 +#: wp-redirects.inc.php:108 msgid "Redirect" msgstr "" -#: wp-redirects.php:60 +#: wp-redirects.inc.php:109 msgid "Add Redirect" msgstr "" -#: wp-redirects.php:61 +#: wp-redirects.inc.php:110 msgid "Add New Redirect" msgstr "" -#: wp-redirects.php:62 +#: wp-redirects.inc.php:111 msgid "Edit Redirect" msgstr "" -#: wp-redirects.php:63 +#: wp-redirects.inc.php:112 msgid "New Redirect" msgstr "" -#: wp-redirects.php:64 +#: wp-redirects.inc.php:113 msgid "All Redirects" msgstr "" -#: wp-redirects.php:65 +#: wp-redirects.inc.php:114 msgid "View Redirect" msgstr "" -#: wp-redirects.php:66 +#: wp-redirects.inc.php:115 msgid "Search Redirects" msgstr "" -#: wp-redirects.php:67 +#: wp-redirects.inc.php:116 msgid "No Redirects found" msgstr "" -#: wp-redirects.php:68 +#: wp-redirects.inc.php:117 msgid "No Redirects found in Trash" msgstr "" -#: wp-redirects.php:227 -msgid "Redirect Configuration" +#: wp-redirects.inc.php:334 +msgid "Never" msgstr "" -#: wp-redirects.php:238 -msgid "" -"This is optional. It defaults to a value of 301 for redirection." +#: wp-redirects.inc.php:341 +msgid "Target URL" msgstr "" -#: wp-redirects.php:242 -msgid "Redirection URL * (a full URL, absolutely required):" +#: wp-redirects.inc.php:343 +msgid "Source URL" msgstr "" -#: wp-redirects.php:244 +#: wp-redirects.inc.php:345 +msgid "Additional Source URIs" +msgstr "" + +#: wp-redirects.inc.php:347 +msgid "HTTP Status Code" +msgstr "" + +#: wp-redirects.inc.php:349 +msgid "Redirection Statistics" +msgstr "" + +#: wp-redirects.inc.php:358 +msgid "The Target URL is the URL that your Source URL will be redirected to." +msgstr "" + +#: wp-redirects.inc.php:359 +msgid "This is the only required field to create a Redirect with WP Redirects, as the Source URL (see below) is generated for you automatically." +msgstr "" + +#: wp-redirects.inc.php:360 +msgid "Target URL (a full, absolute URI, e.g., http://example.com/):" +msgstr "" + +#: wp-redirects.inc.php:362 msgid "Yes, pass all $_GET query string variables to this URL." msgstr "" -#: wp-redirects.php:244 -msgid "" -"If checked, all `$_GET` query string variables will be passed to the " -"Redirection URL (adding to any that already exist)." +#: wp-redirects.inc.php:362 +msgid "If checked, all `$_GET` query string variables will be passed to the Redirection URL (adding to any that already exist)." msgstr "" -#: wp-redirects.php:244 -msgid "" -"It is also possible to use specific Replacement Codes in your Redirection " -"URL, referencing `$_GET`, `$_POST`, `$_REQUEST`, `$_COOKIE`, or `$_SESSION` " -"values." +#: wp-redirects.inc.php:362 +msgid "It is also possible to use specific Replacement Codes in your Redirection URL, referencing `$_GET`, `$_POST`, `$_REQUEST`, `$_COOKIE`, or `$_SESSION` values." msgstr "" -#: wp-redirects.php:244 +#: wp-redirects.inc.php:362 msgid "Example Replacement Codes:" msgstr "" -#: wp-redirects.php:244 -msgid "" -"* If you\\'re using an advanced regular expression, there are Replacement " -"Codes to reference parenthesized subpatterns." +#: wp-redirects.inc.php:362 +msgid "* If you\\'re using an advanced regular expression, there are Replacement Codes to reference parenthesized subpatterns." msgstr "" -#: wp-redirects.php:244 +#: wp-redirects.inc.php:362 msgid "(string matching the full pattern)" msgstr "" -#: wp-redirects.php:244 +#: wp-redirects.inc.php:362 msgid "(1st parenthesized subpattern)" msgstr "" -#: wp-redirects.php:244 +#: wp-redirects.inc.php:362 msgid "(2nd parenthesized subpattern)" msgstr "" -#: wp-redirects.php:248 -msgid "Additional Redirections From (optional pattern matching):" +#: wp-redirects.inc.php:372 +msgid "The Source URL is the URL that gets redirected to your Target URL." msgstr "" -#: wp-redirects.php:250 -msgid "" -"This is optional. By default, redirection simply occurs from the Permalink for this Redirection." +#: wp-redirects.inc.php:373 +msgid "WP Redirects automatically generates a unique Source URL for you by using the Permalink generated by WordPress for this Redirect. Once you've saved this Redirect and a Permalink has been generated, you can edit the Permalink (i.e., the Source URL) using the Edit button underneath the Title. Additional Source URIs can also be configured (optional, see Additional Source URIs below)." msgstr "" -#: wp-redirects.php:251 -msgid "" -"Redirecting from additional locations: This can be " -"accomplished here with a pattern. By default, a pattern supplied here is " -"caSe sensitive, using one exact comparison against $_SERVER" -"['REQUEST_URI']. However, it is possible to precede your pattern " -"with: regex: to enable advanced regular expression pattern " -"matching. Example: regex: /pattern/i. It is also possible to " -"use regex Replacement Codes in your Redirection URL above, referencing any " -"parenthesized subpatterns. For example: %%0%%, %%1%%, %%2%%." +#: wp-redirects.inc.php:383 +msgid "Source URL: Please enter a title above and click Save Draft to generate the default Source URL" +msgstr "" + +#: wp-redirects.inc.php:394 +msgid "If you want to redirect additional Source URIs to the Target URL, you can enter a single URI below or use a Regular Expression to redirect all URIs that match a specific pattern." +msgstr "" + +#: wp-redirects.inc.php:395 +msgid "An Additional Single Redirect URI or a Regular Expression Pattern:" +msgstr "" + +#: wp-redirects.inc.php:398 +msgid "However, it is also possible to precede your pattern with: regex: to enable advanced regular expression pattern matching. Example: regex: /pattern/i. It is also possible to use regex Replacement Codes in your Redirection URL above, referencing any parenthesized subpatterns. For example: %%0%%, %%1%%, %%2%%." +msgstr "" + +#: wp-redirects.inc.php:408 +msgid "By default, WP Redirects sends the standard 301 HTTP status code when doing a redirect. If you want to override that value, you can enter a custom HTTP Status Code below.

" +msgstr "" + +#: wp-redirects.inc.php:422 +msgid "Total Hits:" +msgstr "" + +#: wp-redirects.inc.php:424 +msgid "Last Access:" +msgstr "" + +#: wp-redirects.inc.php:429 +msgid "The hit count for this redirect has been reset. To save these changes, click Update." +msgstr "" + +#: wp-redirects.inc.php:430 +msgid "The last access date for this redirect has been reset. To save these changes, click Update." +msgstr "" + +#: wp-redirects.inc.php:497 +msgid "Hits" +msgstr "" + +#: wp-redirects.inc.php:498 +msgid "Last Access" +msgstr "" + +#: wp-redirects.inc.php:560 +msgid "WP Redirects: detected a new version of itself. Recompiling w/ latest version... all done :-)" +msgstr "" + +#: wp-redirects.inc.php:629 +msgid "You appear to be running another instance of WP-Redirects. Please disable the other instance before enabling this one." msgstr "" #. Plugin Name of the plugin/theme @@ -140,15 +213,13 @@ msgid "http://www.websharks-inc.com/product/wp-redirects/" msgstr "" #. Description of the plugin/theme -msgid "" -"Create Redirects! This plugin adds a new Post Type. Redirect from anywhere — " -"to anywhere. A very lightweight plugin!" +msgid "Create Redirects! This plugin adds a new Post Type. Redirect from anywhere — to anywhere. A very lightweight plugin!" msgstr "" #. Author of the plugin/theme -msgid "WebSharks, Inc. (Jason Caldwell)" +msgid "WebSharks, Inc." msgstr "" #. Author URI of the plugin/theme -msgid "http://www.websharks-inc.com/" +msgid "http://www.websharks-inc.com" msgstr "" diff --git a/wp-redirects/includes/wp-php53.php b/wp-redirects/includes/wp-php53.php new file mode 100644 index 0000000..68d96e8 --- /dev/null +++ b/wp-redirects/includes/wp-php53.php @@ -0,0 +1,107 @@ + + * @license GNU General Public License, version 2 + */ +if(!function_exists('wp_php53')) +{ + /** + * This server is running PHP v5.3+? + * + * @return boolean `TRUE` if running PHP v5.3+; `FALSE` otherwise. + */ + function wp_php53() // Called automatically on `include()` or `require()`. + { + return version_compare(PHP_VERSION, $GLOBALS['wp_php_rv'], '>='); + } +} +if(!function_exists('wp_php53_notice')) +{ + /** + * Creates a WP Dashboard notice regarding PHP requirements. + * + * @param string $software_name Optional. Name of the calling theme/plugin. Defaults to `ucwords([calling file basedir])`. + * @param string $software_text_domain Optional i18n text domain. Defaults to slugified `$software_name`. + * @param string $notice_cap Optional. Capability to view notice. Defaults to `activate_plugins`. + * @param string $notice_action Optional. Action hook. Defaults to `all_admin_notices`. + * @param string $notice Optional. Custom notice HTML instead of default markup. + */ + function wp_php53_notice($software_name = '', $software_text_domain = '', $notice_cap = '', $notice_action = '', $notice = '') + { + $software_name = trim((string)$software_name); + $software_text_domain = trim((string)$software_text_domain); + $notice_cap = trim((string)$notice_cap); + $notice_action = trim((string)$notice_action); + $notice = trim((string)$notice); + + if(!$notice_cap) // Use default cap? + $notice_cap = 'activate_plugins'; + + if(!$notice_action) // Use default action? + $notice_action = 'all_admin_notices'; + + if(!$software_name) // Use default generic name? + { + $software_name = 'This Software'; // Default generic value. + // Let's try to do better! We can use the basedir of the calling file. + if(($_debug_backtrace = @debug_backtrace()) && !empty($_debug_backtrace[0]['file'])) + if(($_calling_file_basedir = strtolower(basename(dirname($_debug_backtrace[0]['file']))))) + $software_name = ucwords(trim(preg_replace('/[^a-z0-9]+/i', ' ', $_calling_file_basedir))); + unset($_debug_backtrace, $_calling_file_basedir); // Housekeeping. + } + if(!$software_text_domain) // Use default text domain? + $software_text_domain = trim(preg_replace('/[^a-z0-9\-]/i', '-', strtolower($software_name)), '-'); + + if(!$notice) // Use the default notice? This will amost always suffice. + { + $notice = ''. + 'PHP'. + ''; // PHP icon served from the WebSharks™ CDN. Supports both `http://` and `https://`. + + $notice .= ' '.sprintf(__('%1$s is NOT active.', $software_text_domain), esc_html($software_name)); + $notice .= ' '.sprintf(__('It requires PHP v%1$s+.', $software_text_domain), esc_html($GLOBALS['wp_php_rv'])).'
'; + $notice .= ' '.sprintf(__('↳ You\'re currently running an older copy of PHP v%1$s.', $software_text_domain), esc_html(PHP_VERSION)).'
'; + $notice .= ' '.__('A simple update is necessary. Please ask your hosting company to help resolve this quickly.', $software_text_domain).'
'; + $notice .= ' '.sprintf(__('To remove this message, please upgrade. Or, remove %1$s from WordPress.', $software_text_domain), esc_html($software_name)); + } + add_action($notice_action, create_function('', 'if(!current_user_can(\''.str_replace("'", "\\'", $notice_cap).'\'))'. + ' return;'."\n". // User missing capability. + + 'echo \''. // Wrap `$notice` inside a WordPress error. + + '
'. + '

'. + ' '.str_replace("'", "\\'", $notice). + '

'. + '
'. + + '\';')); + } +} +if(!function_exists('wp_php53_custom_notice')) +{ + /** + * Creates a WP Dashboard notice regarding PHP requirements. + * + * @param string $notice Optional. Custom notice HTML instead of default markup. + * @param string $notice_cap Optional. Capability to view notice. Defaults to `activate_plugins`. + * @param string $notice_action Optional. Action hook. Defaults to `all_admin_notices`. + */ + function wp_php53_custom_notice($notice = '', $notice_cap = '', $notice_action = '') + { + wp_php53_notice('', '', $notice_cap, $notice_action, $notice); + } +} +/** + * Required PHP version. + * + * @var string Required PHP version. + */ +$GLOBALS['wp_php_rv'] = '5.3'; // Hard-coded. +/* + * @return boolean on `include()` or `require()`. + */ +return wp_php53(); // `TRUE` if running PHP v5.3+; `FALSE` otherwise. \ No newline at end of file diff --git a/wp-redirects/readme.txt b/wp-redirects/readme.txt index fb14b94..c31ed7c 100644 --- a/wp-redirects/readme.txt +++ b/wp-redirects/readme.txt @@ -1,14 +1,14 @@ === WP Redirects === -Stable tag: 131121 +Stable tag: 141009 Requires at least: 3.2 -Tested up to: 3.7.1 +Tested up to: 4.0 Text Domain: wp-redirects License: GPLv2 or later License URI: http://www.gnu.org/licenses/gpl-2.0.html -Contributors: WebSharks, JasWSInc +Contributors: raamdev, WebSharks, JasWSInc Donate link: http://www.websharks-inc.com/r/wp-theme-plugin-donation/ Tags: redirect, redirects, 301 redirects, links, relocate, SEO, post type, post types, utilities, posts, pages @@ -79,6 +79,14 @@ Released under the terms of the [GNU General Public License](http://www.gnu.org/ == Changelog == += v141009 = + +- **New Feature**: Hit counter. WP Redirects will now keep track of how many times a redirect has been used. There is a new, sortable Hits column in the main Redirects list that allows you to sort your redirects by the number of hits. See [#4](https://github.com/websharks/wp-redirects/issues/4). +- **New Feature**: Last Access Time. WP Redirects will now keep track of the date and time a redirect was last used. There is a new, sortable Last Access column in the main Redirects list that allows you to sort your redirect by the last access time. See [#4](https://github.com/websharks/wp-redirects/issues/4). +- **Enhancement**: Overhauled the New/Edit Redirect screen. Sections are now modular meta boxes that can be hidden/shown using the Screen Options panel. Lots of inline documentation was also added to help clarify each option. See [#13](https://github.com/websharks/wp-redirects/issues/13). +- **Enhancement**: Refactored codebase to improve readability and organization of code. See [#9](https://github.com/websharks/wp-redirects/issues/9). +- **New Maintainer**: Added raamdev to the contributors list. [Raam Dev](https://profiles.wordpress.org/raamdev/) will now be maintaining the WP Redirects plugin. + = v131121 = * General code cleanup and optimizatioon. diff --git a/wp-redirects/wp-redirects.inc.php b/wp-redirects/wp-redirects.inc.php new file mode 100644 index 0000000..a513510 --- /dev/null +++ b/wp-redirects/wp-redirects.inc.php @@ -0,0 +1,632 @@ +file = preg_replace('/\.inc\.php$/', '.php', __FILE__); + $this->text_domain = str_replace('_', '-', __NAMESPACE__); + + add_action('after_setup_theme', array($this, 'setup')); + register_activation_hook($this->file, array($this, 'activate')); + register_deactivation_hook($this->file, array($this, 'deactivate')); + } + + public function setup() + { + do_action('before__'.__METHOD__, get_defined_vars()); + + load_plugin_textdomain($this->text_domain); + + $this->default_options = array( // Default options. + 'version' => $this->version + ); // Default options are merged with those defined by the site owner. + $options = (is_array($options = get_option(__NAMESPACE__.'_options'))) ? $options : array(); + $this->default_options = apply_filters(__METHOD__.'__default_options', $this->default_options, get_defined_vars()); + $this->options = array_merge($this->default_options, $options); // This considers old options also. + $this->options = apply_filters(__METHOD__.'__options', $this->options, get_defined_vars()); + + $this->cap = apply_filters(__METHOD__.'__cap', 'activate_plugins'); + + if(WP_REDIRECT_ROLES_ALL_CAPS) // Specific Roles? + $this->roles_all_caps = // Convert these to an array. + preg_split('/[\s;,]+/', WP_REDIRECT_ROLES_ALL_CAPS, NULL, PREG_SPLIT_NO_EMPTY); + $this->roles_all_caps = apply_filters('wp_redirect_roles_all_caps', $this->roles_all_caps); + + if(WP_REDIRECT_ROLES_EDIT_CAPS) // Specific Roles? + $this->roles_edit_caps = // Convert these to an array. + preg_split('/[\s;,]+/', WP_REDIRECT_ROLES_EDIT_CAPS, NULL, PREG_SPLIT_NO_EMPTY); + $this->roles_edit_caps = apply_filters('wp_redirect_roles_edit_caps', $this->roles_edit_caps); + + add_action('wp_loaded', array($this, 'actions')); + + $this->register(); + + $this->redirect_uri_patterns(); + add_action('wp', 'wp_redirects\plugin::redirect_redirects', 1); + + add_action('add_meta_boxes_'.($post_type = 'redirect'), 'wp_redirects\plugin::meta_boxes'); + add_action('save_post', 'wp_redirects\plugin::meta_boxes_save'); + + add_action('manage_redirect_posts_custom_column', 'wp_redirects\plugin::show_admin_column_value', 10, 2); + add_action('pre_get_posts', 'wp_redirects\plugin::admin_column_orderby', 10, 1); + add_filter('manage_redirect_posts_columns', 'wp_redirects\plugin::add_admin_columns', 10, 1); + add_filter('manage_edit-redirect_sortable_columns', 'wp_redirects\plugin::register_sortable_admin_columns', 10, 1); + + add_action('admin_enqueue_scripts', array($this, 'enqueue_admin_styles')); + + add_action('admin_init', array($this, 'check_version')); + add_action('all_admin_notices', array($this, 'all_admin_notices')); + add_action('all_admin_notices', array($this, 'all_admin_errors')); + + do_action('after__'.__METHOD__, get_defined_vars()); + do_action(__METHOD__.'_complete', get_defined_vars()); + } + + public function register() + { + $post_type_args = array + ( + 'public' => TRUE, 'exclude_from_search' => TRUE, + 'map_meta_cap' => TRUE, 'capability_type' => array('redirect', 'redirects'), + 'rewrite' => array('slug' => 'r', 'with_front' => FALSE), + 'supports' => array('title', 'author', 'revisions') + ); + $post_type_args['labels'] = array + ( + 'name' => __('Redirects', 'wp-redirects'), + 'singular_name' => __('Redirect', 'wp-redirects'), + 'add_new' => __('Add Redirect', 'wp-redirects'), + 'add_new_item' => __('Add New Redirect', 'wp-redirects'), + 'edit_item' => __('Edit Redirect', 'wp-redirects'), + 'new_item' => __('New Redirect', 'wp-redirects'), + 'all_items' => __('All Redirects', 'wp-redirects'), + 'view_item' => __('View Redirect', 'wp-redirects'), + 'search_items' => __('Search Redirects', 'wp-redirects'), + 'not_found' => __('No Redirects found', 'wp-redirects'), + 'not_found_in_trash' => __('No Redirects found in Trash', 'wp-redirects') + ); + register_post_type('redirect', $post_type_args); + + $taxonomy_args = array // Categories. + ( + 'public' => TRUE, 'show_admin_column' => TRUE, + 'hierarchical' => TRUE, // This will use category labels. + 'rewrite' => array('slug' => 'redirect-category', 'with_front' => FALSE), + 'capabilities' => array('assign_terms' => 'edit_redirects', + 'edit_terms' => 'edit_redirects', + 'manage_terms' => 'edit_others_redirects', + 'delete_terms' => 'delete_others_redirects') + ); + register_taxonomy('redirect_category', array('redirect'), $taxonomy_args); + } + + public function url($file = '', $scheme = '') + { + static $plugin_directory; // Static cache. + + if(!isset($plugin_directory)) // Not cached yet? + $plugin_directory = rtrim(plugin_dir_url($this->file), '/'); + + $url = $plugin_directory.(string)$file; + + if($scheme) // A specific URL scheme? + $url = set_url_scheme($url, (string)$scheme); + + return apply_filters(__METHOD__, $url, get_defined_vars()); + } + + public function caps($action) + { + $all_caps = array // The ability to manage (all caps). + ( + 'edit_redirects', + 'edit_others_redirects', + 'edit_published_redirects', + 'edit_private_redirects', + + 'publish_redirects', + + 'delete_redirects', + 'delete_private_redirects', + 'delete_published_redirects', + 'delete_others_redirects', + + 'read_private_redirects' + ); + if($action === 'deactivate') // All on deactivate. + $_roles = array_keys($GLOBALS['wp_roles']->roles); + else $_roles = $this->roles_all_caps; + + foreach($_roles as $_role) if(is_object($_role = get_role($_role))) + foreach($all_caps as $_cap) switch($action) + { + case 'activate': + $_role->add_cap($_cap); + break; + + case 'deactivate': + $_role->remove_cap($_cap); + break; + } + unset($_roles, $_role, $_cap); // Housekeeping. + + $edit_caps = array // The ability to edit/publish/delete. + ( + 'edit_redirects', + 'edit_published_redirects', + + 'publish_redirects', + + 'delete_redirects', + 'delete_published_redirects' + ); + if($action === 'deactivate') // All on deactivate. + $_roles = array_keys($GLOBALS['wp_roles']->roles); + else $_roles = $this->roles_edit_caps; + + foreach($_roles as $_role) if(is_object($_role = get_role($_role))) + foreach((($action === 'deactivate') ? $all_caps : $edit_caps) as $_cap) switch($action) + { + case 'activate': + $_role->add_cap($_cap); + break; + + case 'deactivate': + $_role->remove_cap($_cap); + break; + } + unset($_roles, $_role, $_cap); // Housekeeping. + } + + public static function redirect_redirects() + { + if(!($is_singular_redirect = is_singular('redirect'))) + return; // Nothing to do in this case. + + $redirect_id = get_the_ID(); // Pull this one time only. + + $to = (string)get_post_meta($redirect_id, 'wp_redirect_to', TRUE); + $to = preg_replace_callback('/%%\\\$([^\[]+?)(.+?)%%/i', 'wp_redirects\plugin::_url_e_gprcs_value', $to); + $to = preg_replace('/%%(.+?)%%/i', '', $to); // Ditch any remaining replacement codes. + + $to = // Cleanup any double slashes left over by replacement codes. + plugin::trim(preg_replace('/(?wpdb()->get_results( + "SELECT `post_id`, `meta_value` AS `pattern`". // Meta value is pattern (possibly a regex pattern). + " FROM `".$this->wpdb()->postmeta."` WHERE `meta_key` = 'wp_redirect_from_uri_pattern' AND `meta_value` != ''". + " AND `post_id` IN(SELECT `ID` FROM `".$this->wpdb()->posts."`". // Every `redirect` ID. + " WHERE `post_type` = 'redirect' AND `post_status` = 'publish')"); + if(!is_array($patterns) || !$patterns) return; // Nothing to do in this case. + + foreach($patterns as $_pattern) // Iterate all redirection patterns. + { + $_pattern_matches = $_is_regex = $_is_regex_matches = FALSE; // Initialize. + $_is_regex = (stripos($_pattern->pattern, 'regex:') === 0) ? TRUE : FALSE; + + if(!$_is_regex && trim($_pattern->pattern, '/') === trim($_SERVER['REQUEST_URI'], '/')) + $_pattern_matches = TRUE; // Exact match in this case (after trimming). + + else if($_is_regex && @preg_match(trim(preg_replace('/^regex\:/i', '', $_pattern->pattern)), + $_SERVER['REQUEST_URI'], $_is_regex_matches) + ) $_pattern_matches = TRUE; // A matching regular expression. + + else continue; // Nothing to do in this case; NOT a matching pattern. + + if(!($_to = (string)get_post_meta($_pattern->post_id, 'wp_redirect_to', TRUE))) + continue; // Stop here if there is nothing to redirect to. + + $_to = (($_is_regex && $_is_regex_matches) // Regex replacement codes for captured groups. + ? preg_replace_callback('/%%([0-9]+)%%/i', function ($m) use ($_is_regex_matches) + { + return urlencode((string)@$_is_regex_matches[$m[1]]); + }, $_to) : $_to); + $_to = preg_replace_callback('/%%\\\$([^\[]+?)(.+?)%%/i', 'wp_redirects\plugin::_url_e_gprcs_value', $_to); + $_to = preg_replace('/%%(.+?)%%/i', '', $_to); // Ditch any remaining replacement codes. + + $_to = // Cleanup any double slashes left over by replacement codes. + plugin::trim(preg_replace('/(?post_id, 'wp_redirect_to_w_query_vars', TRUE)) + $_to = add_query_arg(urlencode_deep(plugin::trim_strip_deep($_GET)), $_to); + + $_status = (is_numeric($_status = get_post_meta($_pattern->post_id, 'wp_redirect_status', TRUE))) ? (integer)$_status : 301; + + // Update hit counter for this redirect + $redirect_hits = (int)get_post_meta($_pattern->post_id, 'wp_redirect_hits', TRUE) + 1; + update_post_meta($_pattern->post_id, 'wp_redirect_hits', $redirect_hits); + + // Update last access time for this redirect + update_post_meta($_pattern->post_id, 'wp_redirect_last_access', time()); + + wp_redirect($_to, $_status).exit(); // Redirection URL w/ a possible custom status code. + } + unset($_pattern, $_is_regex, $_pattern_matches, $_is_regex_matches, $_to, $_status); // Housekeeping. + } + + public static function _url_e_gprcs_value($m) + { + if(isset($m[1], $m[2]) && in_array(($gprcs = strtoupper($m[1])), array('_GET', '_POST', '_REQUEST', '_COOKIE', '_SESSION'), TRUE)) + if(strlen($element_w_brackets = $m[2]) && preg_match('/^(?:(?:\[(["\'])[a-z0-9 \._\-]+?\\1\])|(?:\[[0-9]+\]))+$/i', $element_w_brackets)) + eval('$value = urlencode(trim(stripslashes((string)@$'.$gprcs.$element_w_brackets.')));'); + + return (!empty($value)) ? $value : ''; // Default to empty string. + } + + public static function get_redirect_hits($post_id) { + if(!is_integer($post_id)) + return ''; + + $_hits = get_post_meta($post_id, 'wp_redirect_hits', TRUE); + + if($_hits == '') + update_post_meta($post_id, 'wp_redirect_hits', '0'); + + return $_hits; + } + + public static function get_redirect_last_access_date($post_id) { + if(!is_integer($post_id)) + return ''; + + $_last_access = get_post_meta($post_id, 'wp_redirect_last_access', TRUE); + + if($_last_access == '') + { + update_post_meta($post_id, 'wp_redirect_last_access', '0'); + $_last_access = '0'; + } + + if($_last_access == '0') + return __('Never', 'wp-redirects'); + else + return date(get_option('date_format'), get_post_meta($post_id, 'wp_redirect_last_access', TRUE)); + } + + public static function meta_boxes() + { + add_meta_box('wp-redirect-url', __('Target URL', 'wp-redirects'), + 'wp_redirects\plugin::redirect_meta_box_url', 'redirect', 'normal', 'high'); + add_meta_box('wp-redirect-sources', __('Source URL', 'wp-redirects'), + 'wp_redirects\plugin::redirect_meta_box_sources', 'redirect', 'normal', 'high'); + add_meta_box('wp-redirect-additional-uris', __('Additional Source URIs', 'wp-redirects'), + 'wp_redirects\plugin::redirect_meta_box_additional_uris', 'redirect', 'normal', 'high'); + add_meta_box('wp-redirect-status', __('HTTP Status Code', 'wp-redirects'), + 'wp_redirects\plugin::redirect_meta_box_status', 'redirect', 'normal', 'high'); + add_meta_box('wp-redirect-stats', __('Redirection Statistics', 'wp-redirects'), + 'wp_redirects\plugin::redirect_meta_box_stats', 'redirect', 'normal', 'high'); + } + + public static function redirect_meta_box_url($post) + { + if(!is_object($post) || empty($post->ID) || !($post_id = $post->ID)) + return; // No can-do. Should NOT happen; but just in case. + + echo __('The Target URL is the URL that your Source URL will be redirected to.', 'wp-redirects').'

'."\n"; + echo __('This is the only required field to create a Redirect with WP Redirects, as the Source URL (see below) is generated for you automatically.', 'wp-redirects').'

'."\n"; + echo '
'."\n"; + echo '

'."\n"; + echo ' [?]'."\n"; + + wp_nonce_field('wp-redirect-meta-boxes', 'wp_redirect_meta_boxes'); + } + + public static function redirect_meta_box_sources($post) + { + if(!is_object($post) || empty($post->ID) || !($post_id = $post->ID)) + return; // No can-do. Should NOT happen; but just in case. + + echo __('The Source URL is the URL that gets redirected to your Target URL.', 'wp-redirects').'

'."\n"; + echo __('WP Redirects automatically generates a unique Source URL for you by using the Permalink generated by WordPress for this Redirect. Once you\'ve saved this Redirect and a Permalink has been generated, you can edit the Permalink (i.e., the Source URL) using the Edit button underneath the Title. Additional Source URIs can also be configured (optional, see Additional Source URIs below).', 'wp-redirects').'

'."\n"; + + list($permalink, $post_name) = get_sample_permalink($post->ID); + if(!empty($post_name)) + { + $permalink = str_replace('%pagename%', $post_name, $permalink); + echo __('Source URL: '.$permalink.'', 'wp-redirects')."\n"; + } + else + { + echo __('Source URL: Please enter a title above and click Save Draft to generate the default Source URL', 'wp-redirects')."\n"; + } + + wp_nonce_field('wp-redirect-meta-boxes', 'wp_redirect_meta_boxes'); + } + + public static function redirect_meta_box_additional_uris($post) + { + if(!is_object($post) || empty($post->ID) || !($post_id = $post->ID)) + return; // No can-do. Should NOT happen; but just in case. + + echo __('If you want to redirect additional Source URIs to the Target URL, you can enter a single URI below or use a Regular Expression to redirect all URIs that match a specific pattern.', 'wp-redirects').'

'."\n"; + echo '
'."\n"; + echo '

'."\n"; + echo __('By default, the value supplied here is caSe sensitive and is checked using an exact comparison against $_SERVER[\'REQUEST_URI\']. For example, to redirect '.esc_url( home_url( '/example/' ) ).' to your Target URL, simply enter /example/.', 'wp-redirects').'

'."\n"; + echo __('However, it is also possible to precede your pattern with: regex: to enable advanced regular expression pattern matching. Example: regex: /pattern/i. It is also possible to use regex Replacement Codes in your Redirection URL above, referencing any parenthesized subpatterns. For example: %%0%%, %%1%%, %%2%%.', 'wp-redirects')."\n"; + + wp_nonce_field('wp-redirect-meta-boxes', 'wp_redirect_meta_boxes'); + } + + public static function redirect_meta_box_status($post) + { + if(!is_object($post) || empty($post->ID) || !($post_id = $post->ID)) + return; // No can-do. Should NOT happen; but just in case. + + echo __('By default, WP Redirects sends the standard 301 HTTP status code when doing a redirect. If you want to override that value, you can enter a custom HTTP Status Code below.

', 'wp-redirects')."\n"; + echo '
'."\n"; + echo ''."\n"; + + wp_nonce_field('wp-redirect-meta-boxes', 'wp_redirect_meta_boxes'); + } + + public static function redirect_meta_box_stats($post) + { + if(is_object($post) && !empty($post->ID) && ($post_id = $post->ID)) + { + + $last_access_date = plugin::get_redirect_last_access_date($post_id); + + echo __('Total Hits:', 'wp-redirects').' '.((get_post_meta($post_id, 'wp_redirect_hits', TRUE)) ? esc_attr(get_post_meta($post_id, 'wp_redirect_hits', TRUE)) : '0').' (reset)

'."\n"; + + echo __('Last Access:', 'wp-redirects').' '.$last_access_date.' (reset)
'."\n"; + + echo ''; + echo ''; + + echo ''; + echo ''; + + wp_nonce_field('wp-redirect-meta-boxes', 'wp_redirect_meta_boxes'); + } + } + + public static function meta_boxes_save($post_id) + { + if(is_numeric($post_id) && (!defined('DOING_AUTOSAVE') || !DOING_AUTOSAVE) && ($_p = plugin::trim_strip_deep($_POST))) + if(!empty($_p['wp_redirect_meta_boxes']) && wp_verify_nonce($_p['wp_redirect_meta_boxes'], 'wp-redirect-meta-boxes')) + if(!empty($_p['post_type']) && $_p['post_type'] === 'redirect' && current_user_can('edit_redirect', $post_id)) + { + if(isset($_p['wp_redirect_status'])) + update_post_meta($post_id, 'wp_redirect_status', (string)$_p['wp_redirect_status']); + + if(isset($_p['wp_redirect_to'])) + update_post_meta($post_id, 'wp_redirect_to', (string)$_p['wp_redirect_to']); + + if(isset($_p)) // A checkbox may (or may NOT) be set; we update in either case. + update_post_meta($post_id, 'wp_redirect_to_w_query_vars', (int)@$_p['wp_redirect_to_w_query_vars']); + + if(isset($_p['wp_redirect_from_uri_pattern'])) + update_post_meta($post_id, 'wp_redirect_from_uri_pattern', addslashes((string)$_p['wp_redirect_from_uri_pattern'])); + + if(isset($_p['wp_redirect_hits'])) + update_post_meta($post_id, 'wp_redirect_hits', (int)$_p['wp_redirect_hits']); + + if(isset($_p['wp_redirect_last_access'])) + update_post_meta($post_id, 'wp_redirect_last_access', (int)$_p['wp_redirect_last_access']); + } + } + + public static function trim($value, $chars = NULL, $extra_chars = NULL) + { + return plugin::trim_deep($value, $chars, $extra_chars); + } + + public static function trim_deep($value, $chars = NULL, $extra_chars = NULL) + { + $chars = (is_string($chars)) ? $chars : " \r\n\t\0\x0B"; + $chars = (is_string($extra_chars)) ? $chars.$extra_chars : $chars; + + if(is_array($value) || is_object($value)) // Deeply. + { + foreach($value as &$_value) + $_value = plugin::trim_deep($_value, $chars); + unset($_value); // Housekeeping. + + return $value; + } + return trim((string)$value, $chars); + } + + public static function trim_strip_deep($value, $chars = NULL, $extra_chars = NULL) + { + return plugin::trim_deep(stripslashes_deep($value), $chars, $extra_chars); + } + + /** @return \wpdb */ + public function wpdb() + { + return $GLOBALS['wpdb']; + } + + public static function add_admin_columns($columns) + { + return array_merge($columns, + array('hits' => __('Hits'), + 'last_access' => __('Last Access'))); + } + + public static function show_admin_column_value($column, $post_id) + { + switch($column) + { + case 'hits': + echo plugin::get_redirect_hits($post_id); + break; + + case 'last_access': + echo plugin::get_redirect_last_access_date($post_id); + break; + } + } + + public static function register_sortable_admin_columns($columns) + { + $columns['hits'] = 'hit'; + $columns['last_access'] = 'last_access'; + + return $columns; + } + + public static function admin_column_orderby($query) + { + /** @var \WP_Query $query */ + + if(!is_admin()) + return; + + $orderby = $query->get('orderby'); + + if('hit' == $orderby) + { + $query->set('meta_key', 'wp_redirect_hits'); + $query->set('orderby', 'meta_value_num'); + } + elseif('last_access' == $orderby) + { + $query->set('meta_key', 'wp_redirect_last_access'); + $query->set('orderby', 'meta_value_num'); + } + } + + public function activate() + { + $this->setup(); // Setup routines. + $this->caps('activate'); + flush_rewrite_rules(); + } + + public function check_version() + { + if(version_compare($this->options['version'], $this->version, '>=')) + return; // Nothing to do in this case. + + $this->options['version'] = $this->version; + update_option(__NAMESPACE__.'_options', $this->options); + + $notices = (is_array($notices = get_option(__NAMESPACE__.'_notices'))) ? $notices : array(); + $notices[] = __('WP Redirects: detected a new version of itself. Recompiling w/ latest version... all done :-)', $this->text_domain); + update_option(__NAMESPACE__.'_notices', $notices); + } + + public function deactivate() + { + + delete_option(__NAMESPACE__.'_options'); + delete_option(__NAMESPACE__.'_notices'); + delete_option(__NAMESPACE__.'_errors'); + $this->caps('deactivate'); + flush_rewrite_rules(); + } + + public function actions() + { + if(empty($_REQUEST[__NAMESPACE__])) return; + + require_once dirname(__FILE__).'/includes/actions.php'; + } + + public function enqueue_admin_styles($hook) + { + if('edit.php' != $hook) // only load this style on the Edit posts admin screen + return; + + $deps = array(); // Plugin dependencies. + + wp_enqueue_style(__NAMESPACE__, $this->url('/client-s/css/admin-style.css'), $deps, $this->version, 'all'); + } + + public function all_admin_notices() + { + $notices = (is_array($notices = get_option(__NAMESPACE__.'_notices'))) ? $notices : array(); + if($notices) delete_option(__NAMESPACE__.'_notices'); // Process one-time only. + + $notices = array_unique($notices); // Don't show dupes. + + if(current_user_can($this->cap)) foreach($notices as $_notice) + echo apply_filters(__METHOD__.'__notice', '

'.$_notice.'

', get_defined_vars()); + unset($_notice); // Housekeeping. + } + + public function all_admin_errors() + { + $errors = (is_array($errors = get_option(__NAMESPACE__.'_errors'))) ? $errors : array(); + if($errors) delete_option(__NAMESPACE__.'_errors'); // Process one-time only. + + $errors = array_unique($errors); // Don't show dupes. + + if(current_user_can($this->cap)) foreach($errors as $_error) + echo apply_filters(__METHOD__.'__error', '

'.$_error.'

', get_defined_vars()); + unset($_error); // Housekeeping. + } + } + + /** + * @return plugin Class instance. + */ + function plugin() // Easy reference. + { + return $GLOBALS[__NAMESPACE__]; + } + + $GLOBALS[__NAMESPACE__] = new plugin(); // New plugin instance. + } + else add_action('all_admin_notices', function () // Do NOT load in this case. + { + echo '

'. // Running multiple versions of this plugin at same time. + __('You appear to be running another instance of WP-Redirects. Please disable the other instance before enabling this one.', + str_replace('_', '-', __NAMESPACE__)).'

'; + }); +} \ No newline at end of file diff --git a/wp-redirects/wp-redirects.php b/wp-redirects/wp-redirects.php index 19a02b2..490124f 100644 --- a/wp-redirects/wp-redirects.php +++ b/wp-redirects/wp-redirects.php @@ -1,11 +1,11 @@ TRUE, 'exclude_from_search' => TRUE, - 'map_meta_cap' => TRUE, 'capability_type' => array('redirect', 'redirects'), - 'rewrite' => array('slug' => 'r', 'with_front' => FALSE), - 'supports' => array('title', 'author', 'revisions') - ); - $post_type_args['labels'] = array - ( - 'name' => __('Redirects', 'wp-redirects'), - 'singular_name' => __('Redirect', 'wp-redirects'), - 'add_new' => __('Add Redirect', 'wp-redirects'), - 'add_new_item' => __('Add New Redirect', 'wp-redirects'), - 'edit_item' => __('Edit Redirect', 'wp-redirects'), - 'new_item' => __('New Redirect', 'wp-redirects'), - 'all_items' => __('All Redirects', 'wp-redirects'), - 'view_item' => __('View Redirect', 'wp-redirects'), - 'search_items' => __('Search Redirects', 'wp-redirects'), - 'not_found' => __('No Redirects found', 'wp-redirects'), - 'not_found_in_trash' => __('No Redirects found in Trash', 'wp-redirects') - ); - register_post_type('redirect', $post_type_args); - - $taxonomy_args = array // Categories. - ( - 'public' => TRUE, 'show_admin_column' => TRUE, - 'hierarchical' => TRUE, // This will use category labels. - 'rewrite' => array('slug' => 'redirect-category', 'with_front' => FALSE), - 'capabilities' => array('assign_terms' => 'edit_redirects', - 'edit_terms' => 'edit_redirects', - 'manage_terms' => 'edit_others_redirects', - 'delete_terms' => 'delete_others_redirects') - ); - register_taxonomy('redirect_category', array('redirect'), $taxonomy_args); - } - - public static function caps($action) - { - $all_caps = array // The ability to manage (all caps). - ( - 'edit_redirects', - 'edit_others_redirects', - 'edit_published_redirects', - 'edit_private_redirects', - - 'publish_redirects', - - 'delete_redirects', - 'delete_private_redirects', - 'delete_published_redirects', - 'delete_others_redirects', - - 'read_private_redirects' - ); - if($action === 'deactivate') // All on deactivate. - $_roles = array_keys($GLOBALS['wp_roles']->roles); - else $_roles = wp_redirects::$roles_all_caps; - - foreach($_roles as $_role) if(is_object($_role = get_role($_role))) - foreach($all_caps as $_cap) switch($action) - { - case 'activate': - $_role->add_cap($_cap); - break; - - case 'deactivate': - $_role->remove_cap($_cap); - break; - } - unset($_roles, $_role, $_cap); // Housekeeping. - - $edit_caps = array // The ability to edit/publish/delete. - ( - 'edit_redirects', - 'edit_published_redirects', - - 'publish_redirects', - - 'delete_redirects', - 'delete_published_redirects' - ); - if($action === 'deactivate') // All on deactivate. - $_roles = array_keys($GLOBALS['wp_roles']->roles); - else $_roles = wp_redirects::$roles_edit_caps; - - foreach($_roles as $_role) if(is_object($_role = get_role($_role))) - foreach((($action === 'deactivate') ? $all_caps : $edit_caps) as $_cap) switch($action) - { - case 'activate': - $_role->add_cap($_cap); - break; - - case 'deactivate': - $_role->remove_cap($_cap); - break; - } - unset($_roles, $_role, $_cap); // Housekeeping. - } - - public static function redirect_redirects() - { - if(!($is_singular_redirect = is_singular('redirect'))) - return; // Nothing to do in this case. - - $to = (string)get_post_meta(get_the_ID(), 'wp_redirect_to', TRUE); - $to = preg_replace_callback('/%%\\\$([^\[]+?)(.+?)%%/i', 'wp_redirects::_url_e_gprcs_value', $to); - $to = preg_replace('/%%(.+?)%%/i', '', $to); // Ditch any remaining replacement codes. - - $to = // Cleanup any double slashes left over by replacement codes. - wp_redirects::trim(preg_replace('/(?get_results( - "SELECT `post_id`, `meta_value` AS `pattern`". // Meta value is pattern (possibly a regex pattern). - " FROM `".wp_redirects::wpdb()->postmeta."` WHERE `meta_key` = 'wp_redirect_from_uri_pattern' AND `meta_value` != ''". - " AND `post_id` IN(SELECT `ID` FROM `".wp_redirects::wpdb()->posts."`". // Every `redirect` ID. - " WHERE `post_type` = 'redirect' AND `post_status` = 'publish')"); - if(!is_array($patterns) || !$patterns) return; // Nothing to do in this case. - - foreach($patterns as $_pattern) // Iterate all redirection patterns. - { - $_pattern_matches = $_is_regex = $_is_regex_matches = FALSE; // Initialize. - $_is_regex = (stripos($_pattern->pattern, 'regex:') === 0) ? TRUE : FALSE; - - if(!$_is_regex && trim($_pattern->pattern, '/') === trim($_SERVER['REQUEST_URI'], '/')) - $_pattern_matches = TRUE; // Exact match in this case (after trimming). - - else if($_is_regex && @preg_match(trim(preg_replace('/^regex\:/i', '', $_pattern->pattern)), - $_SERVER['REQUEST_URI'], $_is_regex_matches) - ) $_pattern_matches = TRUE; // A matching regular expression. - - else continue; // Nothing to do in this case; NOT a matching pattern. - - if(!($_to = (string)get_post_meta($_pattern->post_id, 'wp_redirect_to', TRUE))) - continue; // Stop here if there is nothing to redirect to. - - $_to = (($_is_regex && $_is_regex_matches) // Regex replacement codes for captured groups. - ? preg_replace_callback('/%%([0-9]+)%%/i', function ($m) use ($_is_regex_matches) - { - return urlencode((string)@$_is_regex_matches[$m[1]]); - }, $_to) : $_to); - $_to = preg_replace_callback('/%%\\\$([^\[]+?)(.+?)%%/i', 'wp_redirects::_url_e_gprcs_value', $_to); - $_to = preg_replace('/%%(.+?)%%/i', '', $_to); // Ditch any remaining replacement codes. - - if(!empty($_GET) && get_post_meta($_pattern->post_id, 'wp_redirect_to_w_query_vars', TRUE)) - $_to = add_query_arg(urlencode_deep(wp_redirects::trim_strip_deep($_GET)), $_to); - - $_to = // Cleanup any double slashes left over by replacement codes. - wp_redirects::trim(preg_replace('/(?post_id, 'wp_redirect_status', TRUE))) ? (integer)$_status : 301; - - wp_redirect($_to, $_status).exit(); // Redirection URL w/ a possible custom status code. - } - unset($_pattern, $_is_regex, $_pattern_matches, $_is_regex_matches, $_to, $_status); // Housekeeping. - } - - public static function _url_e_gprcs_value($m) - { - if(isset($m[1], $m[2]) && in_array(($gprcs = strtoupper($m[1])), array('_GET', '_POST', '_REQUEST', '_COOKIE', '_SESSION'), TRUE)) - if(strlen($element_w_brackets = $m[2]) && preg_match('/^(?:(?:\[(["\'])[a-z0-9 \._\-]+?\\1\])|(?:\[[0-9]+\]))+$/i', $element_w_brackets)) - eval('$value = urlencode(trim(stripslashes((string)@$'.$gprcs.$element_w_brackets.')));'); - - return (!empty($value)) ? $value : ''; // Default to empty string. - } - - public static function meta_boxes() - { - add_meta_box('wp-redirect', __('Redirect Configuration', 'wp-redirects'), // One meta box (for now). - 'wp_redirects::redirect_meta_box', 'redirect', 'normal', 'high'); - } - - public static function redirect_meta_box($post) - { - if(!is_object($post) || empty($post->ID) || !($post_id = $post->ID)) - return; // No can-do. Should NOT happen; but just in case. - - echo '
'."\n"; - echo '
'."\n"; - echo __('This is optional. It defaults to a value of 301 for redirection.', 'wp-redirects')."\n"; - - echo '
'."\n"; - - echo '
'."\n"; - echo '
'."\n"; - echo ' [?]'."\n"; - - echo '
'."\n"; - - echo '
'."\n"; - echo '
'."\n"; - echo __('This is optional. By default, redirection simply occurs from the Permalink for this Redirection.', 'wp-redirects').'

'."\n"; - echo __('Redirecting from additional locations: This can be accomplished here with a pattern. By default, a pattern supplied here is caSe sensitive, using one exact comparison against $_SERVER[\'REQUEST_URI\']. However, it is possible to precede your pattern with: regex: to enable advanced regular expression pattern matching. Example: regex: /pattern/i. It is also possible to use regex Replacement Codes in your Redirection URL above, referencing any parenthesized subpatterns. For example: %%0%%, %%1%%, %%2%%.', 'wp-redirects')."\n"; - - wp_nonce_field('wp-redirect-meta-boxes', 'wp_redirect_meta_boxes'); - } - - public static function meta_boxes_save($post_id) - { - if(is_numeric($post_id) && (!defined('DOING_AUTOSAVE') || !DOING_AUTOSAVE) && ($_p = wp_redirects::trim_strip_deep($_POST))) - if(!empty($_p['wp_redirect_meta_boxes']) && wp_verify_nonce($_p['wp_redirect_meta_boxes'], 'wp-redirect-meta-boxes')) - if(!empty($_p['post_type']) && $_p['post_type'] === 'redirect' && current_user_can('edit_redirect', $post_id)) - { - if(isset($_p['wp_redirect_status'])) - update_post_meta($post_id, 'wp_redirect_status', (string)$_p['wp_redirect_status']); - - if(isset($_p['wp_redirect_to'])) - update_post_meta($post_id, 'wp_redirect_to', (string)$_p['wp_redirect_to']); - - if(isset($_p)) // A checkbox may (or may NOT) be set; we update in either case. - update_post_meta($post_id, 'wp_redirect_to_w_query_vars', (int)@$_p['wp_redirect_to_w_query_vars']); - - if(isset($_p['wp_redirect_from_uri_pattern'])) - update_post_meta($post_id, 'wp_redirect_from_uri_pattern', addslashes((string)$_p['wp_redirect_from_uri_pattern'])); - } - } - - public static function trim($value, $chars = NULL, $extra_chars = NULL) - { - return wp_redirects::trim_deep($value, $chars, $extra_chars); - } - - public static function trim_deep($value, $chars = NULL, $extra_chars = NULL) - { - $chars = (is_string($chars)) ? $chars : " \r\n\t\0\x0B"; - $chars = (is_string($extra_chars)) ? $chars.$extra_chars : $chars; - - if(is_array($value) || is_object($value)) // Deeply. - { - foreach($value as &$_value) - $_value = wp_redirects::trim_deep($_value, $chars); - unset($_value); // Housekeeping. - - return $value; - } - return trim((string)$value, $chars); - } - - public static function trim_strip_deep($value, $chars = NULL, $extra_chars = NULL) - { - return wp_redirects::trim_deep(stripslashes_deep($value), $chars, $extra_chars); - } - - public static function activate() - { - wp_redirects::init(); - wp_redirects::caps('activate'); - flush_rewrite_rules(); - } - - public static function deactivate() - { - wp_redirects::caps('deactivate'); - flush_rewrite_rules(); - } - - /** @return \wpdb */ - public static function wpdb() - { - return $GLOBALS['wpdb']; - } -} - -add_action('init', 'wp_redirects::init', 1); -register_activation_hook(__FILE__, 'wp_redirects::activate'); -register_deactivation_hook(__FILE__, 'wp_redirects::deactivate'); \ No newline at end of file +if(require(dirname(__FILE__).'/includes/wp-php53.php')) // TRUE if running PHP v5.3+. + require_once dirname(__FILE__).'/wp-redirects.inc.php'; +else wp_php53_notice('WP Redirects'); \ No newline at end of file