From e1c6b13dc7292d222129d1f484d3ffda46f4fece Mon Sep 17 00:00:00 2001 From: CAYdenberg Date: Thu, 20 Aug 2015 16:48:27 -0600 Subject: [PATCH 1/8] Added ability to upload a sitemap --- wp-simple-301-redirects.php | 180 ++++++++++++++++++++++-------------- 1 file changed, 113 insertions(+), 67 deletions(-) diff --git a/wp-simple-301-redirects.php b/wp-simple-301-redirects.php index 84840f1..f524ea9 100644 --- a/wp-simple-301-redirects.php +++ b/wp-simple-301-redirects.php @@ -31,12 +31,12 @@ //@todo: notify the bulk upload author that you'll be updating the storage format. maybe even patch his plugin for him. https://wordpress.org/plugins/simple-301-redirects-addon-bulk-uploader/ if (!class_exists("Simple301redirects")) { - + class Simple301Redirects { function initialize_admin() { $this->maybe_upgrade_db(); // upgrade the storage format if needed - + // load necessary js wp_register_script( 's301r-script', plugins_url( '/js/simple-301-redirects.js', __FILE__ ), array('jquery') ); add_action('admin_enqueue_scripts', array($this,'write_scripts')); @@ -47,15 +47,15 @@ function initialize_admin() { function write_scripts() { wp_enqueue_script( 's301r-script' ); - + // make ajax_url available to the script - wp_localize_script( 's301r-script', 's301r_ajax', array( + wp_localize_script( 's301r-script', 's301r_ajax', array( 'ajax_url' => admin_url( 'admin-ajax.php' ), 'delete_nonce' => wp_create_nonce( 'delete-redirect-nonce' ), ) ); } - + /** * create_menu function * generate the link to the options page under settings @@ -65,7 +65,7 @@ function write_scripts() { function create_menu() { add_options_page('301 Redirects', '301 Redirects', 'manage_options', '301options', array($this,'options_page')); } - + /** * options_page function * generate the options page in the wordpress admin @@ -75,13 +75,13 @@ function create_menu() { function options_page() { ?>
- +

Settings saved

'; } ?> - +

Simple 301 Redirects

@@ -93,36 +93,43 @@ function options_page() {

- -
- - - - - - - - - - - - - expand_redirects(); ?> - - - - - - - -
Request example: /about.htmDestination example: /about/Delete
» 
- - -

/>

- -

+ + + + + + + + + + + + + + + expand_redirects(); ?> + + + + + + + +
Request example: /about.htmDestination example: /about/Delete
» 
+ + +

/>

+ +

+ +
+ +

+

+

+
@@ -134,7 +141,7 @@ function options_page() {
  • Request: /old-page/
  • Destination: /new-page/
  • - +

    Wildcard Redirects

    Wildcard redirects can match more than one URL. They use an asterisk (*) to represent any characters. This is a powerful way to redirect an entire directory of pages with one line.

    Example

    @@ -142,7 +149,7 @@ function options_page() {
  • Request: /old-folder/*
  • Destination: /redirect-everything-here/
  • - +

    You can also use the asterisk in the destination to replace whatever it matched in the request if you like. Something like this:

    Example

    '.$redirect['request'].' » '.$redirect['destination'].' - + '; } } // end if return $output; } - + /** * save_redirects function * save the redirects from the options page to the database @@ -198,10 +205,19 @@ function expand_redirects() { function save_redirects() { if ( !current_user_can('manage_options') ) { wp_die( 'You do not have sufficient permissions to access this page.' ); } check_admin_referer( 'save_redirects', '_s301r_nonce' ); - + // get existing redirects $redirects = get_option( 's301r_redirects' ); if ($redirects == '') { $redirects = array(); } + + //insert sitemap data + if ( ($_FILES['sitemap']) ) { + $urls = $this->process_sitemap($_FILES['sitemap']); + foreach ($urls as $url) { + $redirects[] = $this->create_redirect($url, ''); + } + } + $data = $_POST['301_redirects']; // delete checked redirect @@ -212,15 +228,12 @@ function save_redirects() { } // save new redirect - if ( trim( $data['request'] ) != '' && trim( $data['destination'] != '' ) ) { - $redirects[] = array( - 'request' => trim( $data['request'] ), - 'destination' => trim( $data['destination'] ), - ); + if ( trim( $data['request'] ) != '' ) { + $redirects[] = $this->create_redirect($data['request'], $data['destination']); } update_option('s301r_redirects', $redirects); - + if (isset($data['wildcard'])) { $settings['wildcard'] = 'true'; } @@ -230,10 +243,43 @@ function save_redirects() { update_option('s301r_settings', $settings); } - + + /** + * process_sitemap + * Read sitemap from a user-uploaded sitemap.xml file and + * return the list of redirects processed from the file. + * @access private + * @param filename + * @return array redirect list + */ + private function process_sitemap($file) { + if ( $file['type'] !== 'text/xml') { + //create flash for wrong file type //!!TO DO!!!!! + return; + } + try { + $xml = simplexml_load_file($file['tmp_name']); + } catch (Exception $e) { + //create flash for no XML parser installed or not valid XML + return; + } + $urls = array(); + foreach ($xml->url as $url) { + if ( !empty($url) ) $urls[] = (string) $url->loc; + } + return $urls; + } + + private function create_redirect($request, $destination) { + return array( + 'request' => trim($request), + 'destination' => trim($destination) + ); + } + /** * redirect function - * Read the list of redirects and if the current page + * Read the list of redirects and if the current page * is found in the list, send the visitor on her way * @access public * @return void @@ -242,20 +288,20 @@ function redirect() { // this is what the user asked for (strip out home portion, case insensitive) $userrequest = str_ireplace(get_option('home'),'',$this->get_address()); $userrequest = rtrim($userrequest,'/'); - + $this->maybe_upgrade_db(); // upgrade the storage format if needed @todo: benchmark this, tune for speed $redirects = get_option('s301r_redirects'); if (!empty($redirects)) { $settings = get_option('s301r_settings'); $do_redirect = ''; - + // compare user request to each 301 stored in the db foreach ($redirects as $key => $redirect) { - // check if we should use regex search + // check if we should use regex search if ($settings['wildcard'] === 'true' && strpos($redirect['request'],'*') !== false) { // wildcard redirect - + // don't allow people to accidentally lock themselves out of admin if ( strpos($userrequest, '/wp-login') !== 0 && strpos($userrequest, '/wp-admin') !== 0 ) { // Make sure it gets all the proper decoding and rtrim action @@ -273,7 +319,7 @@ function redirect() { // simple comparison redirect $do_redirect = $redirect['destination']; } - + // redirect. the second condition here prevents redirect loops as a result of wildcards. if ($do_redirect !== '' && trim($do_redirect,'/') !== trim($userrequest,'/')) { // check if destination needs the domain prepended @@ -301,7 +347,7 @@ function ajax_delete() { $index = intval( str_replace('s301r_row_', '', $row) ); $redirects = get_option( 's301r_redirects' ); - + if (is_array( $redirects ) && isset( $redirects[$index] )) { // delete the redirect unset($redirects[$index]); update_option( 's301r_redirects', $redirects ); @@ -310,7 +356,7 @@ function ajax_delete() { } else { echo 'failure'; exit; } // something went wrong } - + /** * getAddress function * utility function to get the full address of the current request @@ -322,7 +368,7 @@ function get_address() { // return the full address return $this->get_protocol().'://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']; } // end function get_address - + function get_protocol() { // Set the base protocol to http $protocol = 'http'; @@ -330,7 +376,7 @@ function get_protocol() { if ( isset( $_SERVER["HTTPS"] ) && strtolower( $_SERVER["HTTPS"] ) == "on" ) { $protocol .= "s"; } - + return $protocol; } // end function get_protocol @@ -338,7 +384,7 @@ function maybe_upgrade_db() { $latest_db_version = 2; $db_version = ( get_option( 's301r_db_version' ) ) ? intval( get_option( 's301r_db_version' ) ) : 1; if ( $latest_db_version === $db_version ) return; // return early, don't slow down the admin - + while ($db_version < $latest_db_version) { // upgrade through each version of the database, in case users jump multiple versions if ( $db_version === 1 ) $this->upgrade_db_v2(); // elseif ( $db_version === 2 ) $this->upgrade_db_v3(); // a future version would look like this @@ -363,7 +409,7 @@ function upgrade_db_v2() { if (!empty($v1_redirects)) { update_option( 's301r_archive_data', $v1_redirects ); // save a backup in case something goes wrong during upgrade - + foreach ($v1_redirects as $request => $destination) { $v2_redirects[$counter] = array( 'request' => $request, @@ -378,9 +424,9 @@ function upgrade_db_v2() { // new db version update_option( 's301r_db_version', 2 ); } // end function upgrade_db_v2 - + } // end class Simple301Redirects - + } // end check for existance of class // instantiate @@ -410,4 +456,4 @@ function str_ireplace($search,$replace,$subject){ $subject = str_replace($token,$replace,$subject); return $subject; } -} \ No newline at end of file +} From b7cc2dc0851caddeebcc6d4cee2c678c76fa6501 Mon Sep 17 00:00:00 2001 From: CAYdenberg Date: Mon, 24 Aug 2015 12:30:51 -0600 Subject: [PATCH 2/8] Made the destination field a persistent input box --- wp-simple-301-redirects.php | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/wp-simple-301-redirects.php b/wp-simple-301-redirects.php index f524ea9..e526951 100644 --- a/wp-simple-301-redirects.php +++ b/wp-simple-301-redirects.php @@ -185,7 +185,7 @@ function expand_redirects() { '.$redirect['request'].' » - '.$redirect['destination'].' + @@ -210,8 +210,7 @@ function save_redirects() { $redirects = get_option( 's301r_redirects' ); if ($redirects == '') { $redirects = array(); } - //insert sitemap data - if ( ($_FILES['sitemap']) ) { + if ( $_FILES['sitemap']['size'] ) { $urls = $this->process_sitemap($_FILES['sitemap']); foreach ($urls as $url) { $redirects[] = $this->create_redirect($url, ''); @@ -220,6 +219,12 @@ function save_redirects() { $data = $_POST['301_redirects']; + if ( isset($data['update_destintation']) ) { + foreach ( $data['update_destintation'] as $index => $destination ) { + $redirects[$index]['destination'] = trim($destination); + } + } + // delete checked redirect if (isset($data['delete']) && is_array($data['delete'])) { foreach ($data['delete'] as $index) { From e76028024c301681a12bad56d40fbf18bfe01c8b Mon Sep 17 00:00:00 2001 From: CAYdenberg Date: Mon, 24 Aug 2015 14:51:50 -0600 Subject: [PATCH 3/8] Design tweaks --- wp-simple-301-redirects.php | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/wp-simple-301-redirects.php b/wp-simple-301-redirects.php index e526951..4dad6fb 100644 --- a/wp-simple-301-redirects.php +++ b/wp-simple-301-redirects.php @@ -76,13 +76,13 @@ function options_page() { ?>
    -

    Settings saved

    '; - } - ?> +

    Simple 301 Redirects

    -

    Simple 301 Redirects

    +

    Settings saved

    '; + } + ?>
    @@ -132,6 +132,7 @@ function options_page() {
    +

    Documentation

    Basic Redirects

    From 9e2dfd4caa7cfec4ea2444910d6c32a2f3af3016 Mon Sep 17 00:00:00 2001 From: CAYdenberg Date: Mon, 24 Aug 2015 16:32:07 -0600 Subject: [PATCH 4/8] Added ability to change destination url from a dropdown of posts --- js/simple-301-redirects.js | 9 ++++-- wp-simple-301-redirects.php | 59 +++++++++++++++++++++++++++++++++++-- 2 files changed, 64 insertions(+), 4 deletions(-) diff --git a/js/simple-301-redirects.js b/js/simple-301-redirects.js index ba8dcae..ecde62b 100644 --- a/js/simple-301-redirects.js +++ b/js/simple-301-redirects.js @@ -3,7 +3,7 @@ jQuery(document).ready(function($) { // turn delete column into edit/delete actions $('.s301r-delete-head').addClass('s301r-actions-head').removeClass('s301r-delete-head').text('Actions'); $('.s301r-delete').html('Delete'); - + // ajax delete $('.s301r-delete-link').click(function(){ var confirm_delete = confirm('Are you sure you want to delete this redirect?'); @@ -30,6 +30,12 @@ jQuery(document).ready(function($) { return false; }); + $('.s301r_set_redirect').change(function(e) { + var redirect = $(this).val(), + textboxName = (typeof $(this).data('index') === 'number') ? '301_redirects[update_destintation]['+$(this).data('index')+']' : '301_redirects[destination]'; + $('input[name="'+textboxName+'"]').val(redirect); + }); + // edit link $('.s301r-edit-link').click(function(){ // swap text for inputs @@ -50,4 +56,3 @@ jQuery(document).ready(function($) { return false; }); }); - diff --git a/wp-simple-301-redirects.php b/wp-simple-301-redirects.php index 4dad6fb..cee654f 100644 --- a/wp-simple-301-redirects.php +++ b/wp-simple-301-redirects.php @@ -34,6 +34,8 @@ class Simple301Redirects { + protected $dropdown_data = array(); + function initialize_admin() { $this->maybe_upgrade_db(); // upgrade the storage format if needed @@ -111,7 +113,12 @@ function options_page() { » - + + + +   @@ -181,12 +188,18 @@ function expand_redirects() { foreach ($redirects as $index => $redirect) { $counter++; $row_class = ($counter % 2 === 0) ? 'row_static' : 'row_static alternate'; + $destination = empty($redirect['destination']) ? '' : $redirect['destination']; $output .= ' '.$redirect['request'].' » - + + + + @@ -196,6 +209,48 @@ function expand_redirects() { return $output; } + /** + * dropdown_inner_html + * returns a list of HTML corresponding to posts, containing a redirect URL as value and a title as the menu text + * All public pages, posts, and queryable custom post types are included. + * @param string $current - the redirect URL for the current entry - so that default selected value can be set + * @return string/html - string containing all
    '; - } - ?> -
    @@ -300,8 +296,6 @@ function save_redirects() { $redirects[] = $this->create_redirect($data['request'], $data['destination']); } - update_option('s301r_redirects', $redirects); - if (isset($data['wildcard'])) { $settings['wildcard'] = 'true'; } @@ -310,6 +304,8 @@ function save_redirects() { } update_option('s301r_settings', $settings); + + return update_option('s301r_redirects', $redirects); } /** @@ -327,17 +323,17 @@ protected function process_sitemap() { $file = $_FILES['sitemap']; if ( !$file['size'] ) { - //create flash for no file uploaded + $this->messages->add( __('No file or empty file uploaded.'), 'error'); } if ( $file['type'] !== 'text/xml') { - //create flash for wrong file type //!!TO DO!!!!! + $this->messages->add( __('Uploaded file is not an XML file.'), 'error'); return; } try { $xml = simplexml_load_file($file['tmp_name']); } catch (Exception $e) { - //create flash for no XML parser installed or not valid XML + $this->messages_add( __('XML parser not installed or file could not be parsed'), 'error'); return; } @@ -353,7 +349,7 @@ protected function process_sitemap() { } } - update_option('s301r_redirects', $redirects); + return update_option('s301r_redirects', $redirects); } protected function create_redirect($request, $destination) { @@ -543,3 +539,33 @@ function str_ireplace($search,$replace,$subject){ return $subject; } } + + +if ( !class_exists('AdminMessageManager') ) { + class AdminNoticeManager { + protected $messages = array(); + + function __construct() { + add_action( 'admin_notices', array($this, 'print_all') ); + } + + public function add($text, $class) { + array_push( $this->messages, array('text' => $text, 'class' => $class) ); + } + + public function print_all() { + foreach ( $this->messages as $message ) { + $this->the_message($message); + } + } + + private function get_the_message($message) { + return sprintf('

    %s

    ', $message['class'], $message['text']); + } + + private function the_message($message) { + echo $this->get_the_message($message); + } + + } +} From a9891fc13b6249fa19e59febdcc324b6f20e9cad Mon Sep 17 00:00:00 2001 From: CAYdenberg Date: Tue, 25 Aug 2015 09:50:44 -0600 Subject: [PATCH 7/8] Replaced [] with array_push to more friendly to older PHP users --- wp-simple-301-redirects.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wp-simple-301-redirects.php b/wp-simple-301-redirects.php index f0ca027..e392f8b 100644 --- a/wp-simple-301-redirects.php +++ b/wp-simple-301-redirects.php @@ -293,7 +293,7 @@ function save_redirects() { // save new redirect if ( trim( $data['request'] ) != '' ) { - $redirects[] = $this->create_redirect($data['request'], $data['destination']); + array_push( $redirects, $this->create_redirect($data['request'], $data['destination']) ); } if (isset($data['wildcard'])) { @@ -345,7 +345,7 @@ protected function process_sitemap() { $url_str = empty($url_obj->loc) ? '' : (string) $url_obj->loc; if ( $url_str !== '' ) { $redirect = $this->create_redirect($url_str, ''); - $redirects[] = $redirect; + array_push( $redirects, $redirect ); } } From 6a85948cbbccec13f700db8e01c89055cb54e6ee Mon Sep 17 00:00:00 2001 From: CAYdenberg Date: Tue, 25 Aug 2015 10:22:44 -0600 Subject: [PATCH 8/8] Changed the XML parser to be more friendly to other sitemap formats --- wp-simple-301-redirects.php | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/wp-simple-301-redirects.php b/wp-simple-301-redirects.php index e392f8b..4cf31be 100644 --- a/wp-simple-301-redirects.php +++ b/wp-simple-301-redirects.php @@ -331,9 +331,11 @@ protected function process_sitemap() { return; } try { - $xml = simplexml_load_file($file['tmp_name']); + $dom = new DOMDocument; + $dom->loadXML( file_get_contents( $file['tmp_name'] ) ); + $locs = $dom->getElementsByTagName('loc'); } catch (Exception $e) { - $this->messages_add( __('XML parser not installed or file could not be parsed'), 'error'); + $this->messages_add( __('XML parser not installed or file is not a sitemap'), 'error'); return; } @@ -341,10 +343,10 @@ protected function process_sitemap() { $redirects = get_option( 's301r_redirects' ); if ($redirects == '') { $redirects = array(); } - foreach ($xml->url as $url_obj) { - $url_str = empty($url_obj->loc) ? '' : (string) $url_obj->loc; - if ( $url_str !== '' ) { - $redirect = $this->create_redirect($url_str, ''); + foreach ($locs as $loc) { + $url = (string) $loc->nodeValue; + if ( $url !== '' ) { + $redirect = $this->create_redirect($url, ''); array_push( $redirects, $redirect ); } }