Plugin Directory

Changeset 1176158


Ignore:
Timestamp:
06/07/2015 12:08:13 PM (11 years ago)
Author:
ilanraid
Message:

Updated to version 1.1.0

  • Added option to fix media upload path
  • Added options to search and replace in database
Location:
upress-link
Files:
32 added
5 edited

Legend:

Unmodified
Added
Removed
  • upress-link/trunk/admin/css/upress-link.css

    r1135956 r1176158  
    66.no-api-key, .api-error, .api-success {
    77    display: none;
     8    white-space: pre;
    89}
    910#api_key {
  • upress-link/trunk/admin/js/upress-link.js

    r1135956 r1176158  
    8787                toggleSwitchSpinner(self, 'hide');
    8888            });
     89
    8990        }).on('click', 'button[data-action], input[type=button][data-action]', function(e) {
    9091            e.preventDefault();
    9192
    9293            var self = $(this);
    93             var wrapper = self.parents('.ajax-button-wrapper');
    94             self.css({
    95                 width: self.outerWidth(),
    96                 height: self.outerHeight()
    97             }).find('.text').fadeOut('fast', function() {
    98                 self.find('.spinner').fadeIn('fast');
    99             }).end().attr('disabled', true);
     94            startAjaxSpinner(self);
    10095
    10196            $.post(ajaxurl, {
     
    120115                }
    121116
    122                 self.find('.spinner').fadeOut('fast', function () {
    123                     self.find('.text').fadeIn('fast').end().css( {
    124                         width: '',
    125                         height: ''
    126                     }).removeAttr('disabled');
    127                 });
    128             });
     117                endAjaxSpinner(self);
     118            });
     119
     120        }).on('click', '.media-path-fix-button', function(e) {
     121            e.preventDefault();
     122
     123            var self = $(this);
     124            startAjaxSpinner(self);
     125
     126            $.post(ajaxurl, {
     127                'action': 'fix_media_upload_path',
     128                '_nonce': upressAjax._nonce
     129            }, function(response) {
     130                console.log(response);
     131
     132                if (response.status == "fail") {
     133                    flashErrorMessage(response.data.message);
     134                }
     135                if(response.status == "success") {
     136                    if(self.data('success-message')) {
     137                        flashSuccessMessage(self.data('success-message'));
     138                    } else {
     139                        flashSuccessMessage(upressAjax.requestSuccess);
     140                    }
     141                }
     142
     143                endAjaxSpinner(self);
     144            });
     145        }).on('click', '.search-and-replace-button', function(e) {
     146            e.preventDefault();
     147
     148            var self = $(this);
     149            startAjaxSpinner(self);
     150
     151            $.post(ajaxurl, {
     152                'action': 'database_search_and_replace',
     153                'replace_from': $('.search-and-replace-from').val(),
     154                'replace_to': $('.search-and-replace-to').val(),
     155                '_nonce': upressAjax._nonce
     156            }, function(response) {
     157                console.log(response);
     158
     159                if (response.status == "fail") {
     160                    flashErrorMessage(response.errors_msg);
     161                }
     162                if(response.status == "success") {
     163                    $('.search-and-replace-from').val('');
     164                    $('.search-and-replace-to').val('');
     165
     166                    if(self.data('success-message')) {
     167                        flashSuccessMessage(self.data('success-message'));
     168                    } else {
     169                        if(response.success_msg) {
     170                            flashSuccessMessage(response.success_msg);
     171                        } else {
     172                            flashSuccessMessage(upressAjax.requestSuccess);
     173                        }
     174                    }
     175                }
     176
     177                endAjaxSpinner(self);
     178            });
     179        });
     180    };
     181
     182    var startAjaxSpinner = function(self) {
     183        var wrapper = self.parents('.ajax-button-wrapper');
     184        self.css({
     185            width: self.outerWidth(),
     186            height: self.outerHeight()
     187        }).find('.text').fadeOut('fast', function() {
     188            self.find('.spinner').fadeIn('fast');
     189        }).end().attr('disabled', true);
     190    };
     191    var endAjaxSpinner = function(self) {
     192        self.find('.spinner').fadeOut('fast', function () {
     193            self.find('.text').fadeIn('fast').end().css( {
     194                width: '',
     195                height: ''
     196            }).removeAttr('disabled');
    129197        });
    130198    };
    131199
    132200    var initButtons = function() {
    133         $('button[data-action]').each(function() {
     201        $('button[data-action], button[data-ajax-spinner]').each(function() {
    134202            var self = $(this);
    135203            var text = self.text();
  • upress-link/trunk/admin/options.php

    r1135956 r1176158  
    4747    </form>
    4848
     49
     50    <hr>
     51    <h3><?php esc_attr_e( 'More actions', $this->text_domain ); ?></h3>
     52    <div class="wrap">
     53        <h4><?php esc_attr_e( 'Fix media upload path', $this->text_domain ); ?></h4>
     54        <p><?php esc_attr_e( 'Sometimes after migrating a WordPress installation the media path is not set correctly and breaks uploading media content. This will fix the issue and correct the upload path.', $this->text_domain ); ?></p>
     55        <p><button class="button-secondary media-path-fix-button" type="button" data-ajax-spinner><?php esc_attr_e( 'Run media path fix', $this->text_domain ); ?></button></p>
     56
     57        <h4><?php esc_attr_e( 'Database search and replace', $this->text_domain ); ?></h4>
     58        <p><?php esc_attr_e( 'This will allow you to replace a text in your entire website in a simple click of a button', $this->text_domain ); ?></p>
     59        <p>
     60            <table class="form-table">
     61                <tr valign="top">
     62                    <th scope="row"><?php esc_attr_e( 'Search:', $this->text_domain ); ?></th>
     63                    <td><input type="text" class="regular-text search-and-replace-from" /></td>
     64                </tr>
     65                <tr valign="top">
     66                    <th scope="row"><?php esc_attr_e( 'Replace:', $this->text_domain ); ?></th>
     67                    <td><input type="text" class="regular-text search-and-replace-to" /></td>
     68                </tr>
     69            </table>
     70
     71            <button class="button-secondary search-and-replace-button" type="button" data-ajax-spinner><?php esc_attr_e( 'Search and replace', $this->text_domain ); ?></button>
     72        </p>
     73    </div>
     74
     75
    4976    <?php if( $is_api_key_set ) : ?>
    5077    <hr>
     
    198225<input type="hidden" id="api-key-valid" value="<?php echo (int)$is_api_key_correct; ?>">
    199226
     227
     228<hr>
    200229<span class="description"><?php esc_attr_e( '*Updates are queued and refreshed 1 minute after the update.', $this->text_domain ); ?></span>
  • upress-link/trunk/readme.txt

    r1135956 r1176158  
    5353
    5454== Changelog ==
     55= 1.1 =
     561. Added option to fix media upload path
     571. Added options to search and replace in database
    5558= 1.0 =
    5659Initial release
  • upress-link/trunk/upress-link.php

    r1135956 r1176158  
    2929    die;
    3030}
    31 define( 'UPL_VERSION', '1.0.0' );
     31define( 'UPL_VERSION', '1.1.0' );
    3232define( 'UPL_PATH', dirname( __FILE__ ) );
    3333define( 'UPL_PATH_INCLUDES', dirname( __FILE__ ) . '/includes' );
     
    5252            add_action( 'admin_enqueue_scripts', array( $this, 'upl_admin_enqueue_scripts' ) );
    5353
     54            //ajax actions
    5455            add_action( 'wp_ajax_check_api_key', array( $this, 'upl_ajax_check_api_key' ) );
    5556            add_action( 'wp_ajax_send_request', array( $this, 'upl_ajax_send_request' ) );
     57
     58            add_action( 'wp_ajax_fix_media_upload_path', array( $this, 'upl_ajax_fix_media_upload_path' ) );
     59            add_action( 'wp_ajax_database_search_and_replace', array( $this, 'upl_ajax_database_search_and_replace' ) );
    5660        }
    5761
     
    199203        exit;
    200204    }
     205    function upl_ajax_fix_media_upload_path() {
     206        global $wpdb;
     207
     208        $nonce = $_POST['_nonce'];
     209        if ( ! wp_verify_nonce( $nonce, $this->plugin_slug . '_ajax' ) ) { wp_die( 'Not authorized!' ); }
     210        if ( ! current_user_can( 'manage_options' ) ) { wp_die( __( 'You do not have sufficient permissions to access this page.' ) ); }
     211
     212        $result = $wpdb->update( $wpdb->options, array( 'option_value' => null ), array( 'option_name' => 'upload_path' ) );
     213
     214        $response = array(
     215            'status' => ( $result === false ? 'fail' : 'success' ),
     216            'data' => ( $result === false ? $wpdb->last_error : $wpdb->last_query ),
     217            'debug' => $wpdb
     218        );
     219
     220        $response = json_encode( $response );
     221        header( "Content-Type: application/json" );
     222        echo $response;
     223        exit;
     224    }
     225    function upl_ajax_database_search_and_replace() {
     226        global $wpdb;
     227
     228        $nonce = $_POST['_nonce'];
     229        if ( ! wp_verify_nonce( $nonce, $this->plugin_slug . '_ajax' ) ) { wp_die( 'Not authorized!' ); }
     230        if ( ! current_user_can( 'manage_options' ) ) { wp_die( __( 'You do not have sufficient permissions to access this page.' ) ); }
     231
     232        $search = $_POST['replace_from'];
     233        $replace = $_POST['replace_to'];
     234
     235        if( ! isset( $search ) || ! isset( $replace ) ) wp_die( 'Something is missing!' );
     236
     237        $result = $wpdb->get_results(
     238            'SHOW TABLES',
     239            ARRAY_N
     240        );
     241        /*$result = $wpdb->query(
     242            $wpdb->prepare(
     243                'SHOW TABLES'
     244            )
     245        );*/
     246        $tables = array();
     247        foreach ( $result as $res )
     248        {
     249            $tables[] = $res[0];
     250        }
     251
     252        $report = array( 'tables' => 0,
     253                         'rows' => 0,
     254                         'change' => 0,
     255                         'updates' => 0,
     256                         'start' => microtime( ),
     257                         'end' => microtime( ),
     258                         'errors' => array( ),
     259        );
     260
     261        if ( is_array( $tables ) && ! empty( $tables ) ) {
     262            foreach( $tables as $table ) {
     263                $report[ 'tables' ]++;
     264
     265                $columns = array( );
     266
     267                $fields = $wpdb->get_results( 'DESCRIBE ' . $table, ARRAY_A );
     268                foreach( $fields as $column ) {
     269                    $columns[ $column[ 'Field' ] ] = $column[ 'Key' ] == 'PRI' ? true : false;
     270                }
     271
     272                $rows_result = $wpdb->get_row( 'SELECT COUNT(*) FROM ' . $table, ARRAY_N );
     273                $row_count = $rows_result[ 0 ];
     274                if ( $row_count == 0 )
     275                    continue;
     276
     277                $page_size = 50000;
     278                $pages = ceil( $row_count / $page_size );
     279
     280                for( $page = 0; $page < $pages; $page++ ) {
     281                    $current_row = 0;
     282                    $start = $page * $page_size;
     283                    $end = $start + $page_size;
     284                    // Grab the content of the table
     285                    $data = $wpdb->get_results( sprintf( 'SELECT * FROM %s LIMIT %d, %d', $table, $start, $end ), ARRAY_A );
     286
     287                    if ( ! $data )
     288                        $report[ 'errors' ][] = mysql_error( );
     289
     290                    foreach( $data as $row ) {
     291                        $report[ 'rows' ]++; // Increment the row counter
     292                        $current_row++;
     293
     294                        $update_sql = array( );
     295                        $where_sql = array( );
     296                        $upd = false;
     297
     298                        foreach( $columns as $column => $primary_key ) {
     299                            $edited_data = $data_to_fix = $row[ $column ];
     300
     301                            // Run a search replace on the data that'll respect the serialisation.
     302                            $edited_data = $this->recursive_unserialize_replace( $search, $replace, $data_to_fix );
     303
     304                            // Something was changed
     305                            if ( $edited_data != $data_to_fix ) {
     306                                $report[ 'change' ]++;
     307                                $update_sql[] = $column . ' = "' . esc_sql( $edited_data ) . '"';
     308                                $upd = true;
     309                            }
     310
     311                            if ( $primary_key )
     312                                $where_sql[] = $column . ' = "' . esc_sql( $data_to_fix ) . '"';
     313                        }
     314
     315                        if ( $upd && ! empty( $where_sql ) ) {
     316                            $sql = 'UPDATE ' . $table . ' SET ' . implode( ', ', $update_sql ) . ' WHERE ' . implode( ' AND ', array_filter( $where_sql ) );
     317                            $result = $wpdb->get_results( $sql, ARRAY_A );
     318                            if ( ! $result )
     319                                $report[ 'errors' ][] = mysql_error( );
     320                            else
     321                                $report[ 'updates' ]++;
     322
     323                        } elseif ( $upd ) {
     324                            $report[ 'errors' ][] = sprintf( '"%s" has no primary key, manual change needed on row %s.', $table, $current_row );
     325                        }
     326                    }
     327                }
     328            }
     329        }
     330
     331        $report[ 'end' ] = microtime( );
     332
     333        $errors = '';
     334        if ( ! empty( $report[ 'errors' ] ) && is_array( $report[ 'errors' ] ) ) {
     335            foreach( $report[ 'errors' ] as $error )
     336                $errors .=  $error . "\n";
     337        }
     338        $time = array_sum( explode( ' ', $report[ 'end' ] ) ) - array_sum( explode( ' ', $report[ 'start' ] ) );
     339
     340        $response = array(
     341            'status' => ( $result === false ? 'fail' : 'success' ),
     342            'data' => ( $result === false ? $wpdb->last_error : $report ),
     343            'debug' => $wpdb,
     344            'time' => $time,
     345            'success_msg' => sprintf( __( 'Replace completed for the text "%s" which was replaced by "%s". %d tables scanned with %d total rows. Replacement took %f seconds.', $this->text_domain ),
     346                $search, $replace, $report[ 'tables' ], $report[ 'rows' ], $report[ 'change' ], $report[ 'updates' ], $time ),
     347            'errors_msg' => $errors
     348        );
     349
     350        $response = json_encode( $response );
     351        header( "Content-Type: application/json" );
     352        echo $response;
     353        exit;
     354    }
    201355
    202356
     
    224378        }
    225379    }
     380
     381
     382    /**
     383     * Take a serialised array and unserialise it replacing elements as needed and
     384     * unserialising any subordinate arrays and performing the replace on those too.
     385     *
     386     * @param string $from       String we're looking to replace.
     387     * @param string $to         What we want it to be replaced with
     388     * @param array  $data       Used to pass any subordinate arrays back to in.
     389     * @param bool   $serialised Does the array passed via $data need serialising.
     390     *
     391     * @return array    The original array with all elements replaced as needed.
     392     */
     393    private function recursive_unserialize_replace( $from = '', $to = '', $data = '', $serialised = false ) {
     394        // some unseriliased data cannot be re-serialised eg. SimpleXMLElements
     395        try {
     396
     397            if ( is_string( $data ) && ( $unserialized = @unserialize( $data ) ) !== false ) {
     398                $data = $this->recursive_unserialize_replace( $from, $to, $unserialized, true );
     399            }
     400
     401            elseif ( is_array( $data ) ) {
     402                $_tmp = array( );
     403                foreach ( $data as $key => $value ) {
     404                    $_tmp[ $key ] = $this->recursive_unserialize_replace( $from, $to, $value, false );
     405                }
     406
     407                $data = $_tmp;
     408                unset( $_tmp );
     409            }
     410
     411            else {
     412                if ( is_string( $data ) )
     413                    $data = str_replace( $from, $to, $data );
     414            }
     415
     416            if ( $serialised )
     417                return serialize( $data );
     418
     419        } catch( Exception $error ) {
     420
     421        }
     422
     423        return $data;
     424    }
    226425}
    227426new uPress_Link();
Note: See TracChangeset for help on using the changeset viewer.