Plugin Directory

Changeset 2963196


Ignore:
Timestamp:
09/05/2023 04:02:54 PM (2 years ago)
Author:
parselearn
Message:

Release V1.3

Location:
meta-optimizer
Files:
23 added
11 edited

Legend:

Unmodified
Added
Removed
  • meta-optimizer/trunk/WPMetaOptimizer.php

    r2961838 r2963196  
    33/*!
    44 * Plugin Name: Meta Optimizer
    5  * Version: 1.2.2
     5 * Version: 1.3
    66 * Plugin URI: https://parsakafi.github.io/wp-meta-optimizer
    7  * Description: You can use Meta Optimizer to make your WordPress website load faster if you use meta information, for example Post/Comment/User/Term metas.
     7 * Description: You can use Meta Optimizer to make your WordPress website load faster if you use metadata. For example, Post/Comment/User/Term metas.
    88 * Author: Parsa Kafi
    99 * Author URI: https://parsa.ws
     
    1818require_once __DIR__ . '/inc/Base.php';
    1919require_once __DIR__ . '/inc/Install.php';
     20require_once __DIR__ . '/inc/DBIndexes.php';
    2021require_once __DIR__ . '/inc/Helpers.php';
    2122require_once __DIR__ . '/inc/Options.php';
     
    3334define( 'WPMETAOPTIMIZER_PLUGIN_NAME', 'Meta Optimizer' );
    3435define( 'WPMETAOPTIMIZER_PLUGIN_FILE_PATH', __FILE__ );
    35 define( 'WPMETAOPTIMIZER_CACHE_EXPIRE', 30 );
     36define( 'WPMETAOPTIMIZER_CACHE_EXPIRE', DAY_IN_SECONDS );
     37define( 'WPMETAOPTIMIZER_DEFAULT_IMPORT_NUMBER', 5 );
    3638
    3739/**
     
    8991
    9092    /**
    91      * Updates a post meta field based on the given post ID.
     93     * Updates a post-meta field based on the given post ID.
    9294     *
    9395     * @param null|bool $check      Whether to allow updating metadata for the given type.
     
    227229     * @param mixed     $metaValue  Metadata value.
    228230     * @param bool      $deleteAll  Whether to delete the matching metadata entries
    229      *                              for all objects, ignoring the specified $object_id.
     231     *                              for all objects, ignore the specified $object_id.
    230232     *                              Default false.
    231233     *
     
    282284     * @param mixed     $metaValue  Metadata value.
    283285     * @param bool      $deleteAll  Whether to delete the matching metadata entries
    284      *                              for all objects, ignoring the specified $object_id.
     286     *                              for all objects, ignore the specified $object_id.
    285287     *                              Default false.
    286288     *
     
    498500     * @param mixed  $metaValue     Metadata value.
    499501     * @param bool   $deleteAll     Whether to delete the matching metadata entries
    500      *                              for all objects, ignoring the specified $objectID.
     502     *                              for all objects, ignore the specified $objectID.
    501503     *
    502504     * @return boolean|int
  • meta-optimizer/trunk/assets/style.min.css

    r2961342 r2963196  
    1 .wpmo-wrap{line-height:2em}.wpmo-wrap .wp-heading-inline{margin-bottom:30px;display:flex !important;align-items:center}.wpmo-wrap .wp-heading-inline span{line-height:1;font-size:2em;width:45px;height:45px;margin-right:10px;background-color:#000;background-image:linear-gradient(65deg, #0aaee1, #7d0d74);background-size:100%;background-repeat:repeat;-webkit-background-clip:text;-webkit-text-fill-color:rgba(0,0,0,0);-moz-background-clip:text;-moz-text-fill-color:rgba(0,0,0,0)}.wpmo-wrap table{border-collapse:collapse;width:100%}.wpmo-wrap table.table-sticky-head{position:relative}.wpmo-wrap table.table-sticky-head thead{position:sticky;top:32px;z-index:1;background-color:#fff;-webkit-box-shadow:0 1px 0 0 #e2e2e2;box-shadow:0 1px 0 0 #e2e2e2}.wpmo-wrap table td,.wpmo-wrap table th{padding:15px 10px;vertical-align:top;text-align:start}.wpmo-wrap table td:first-child,.wpmo-wrap table th:first-child{width:200px}.wpmo-wrap table td label+label{margin-left:15px}.wpmo-wrap table tr.black-list-column{opacity:.7;border-left:2px solid #a108f9}.wpmo-wrap table .column-name{direction:ltr;text-align:left;display:inline-block}.wpmo-wrap table .translated-column-name{font-weight:bold}.wpmo-wrap a,.wpmo-wrap span{display:inline-block}.wpmo-wrap strong{font-weight:700}.wpmo-wrap select{min-width:300px}.wpmo-wrap select[multiple]{min-width:300px;max-height:200px}.wpmo-wrap textarea{max-width:100%}.wpmo-wrap input.small-text{width:100px}.wpmo-wrap .nav-tab-wrapper{border-bottom:none}.wpmo-wrap .nav-tab-wrapper .nav-tab{border:1px solid #e0e0e0;border-bottom:none;color:#787878;border-radius:5px 5px 0 0}.wpmo-wrap .nav-tab-wrapper .nav-tab:not(.nav-tab-active){background-color:#f1f1f1;cursor:pointer}.wpmo-wrap .nav-tab-wrapper .nav-tab:focus{box-shadow:none}.wpmo-wrap .nav-tab-wrapper .nav-tab-active,.wpmo-wrap .nav-tab-wrapper .nav-tab-active:focus,.wpmo-wrap .nav-tab-wrapper .nav-tab-active:focus:active,.wpmo-wrap .nav-tab-wrapper .nav-tab-active:hover{background-color:#fff;border-bottom-color:#fff;cursor:default}.wpmo-wrap .wpmo-tab-content{padding:20px;background-color:#fff;margin-bottom:20px}.wpmo-wrap .description{color:#8a8a8a}.wpmo-wrap .description .description-notice{padding:5px 5px 5px 8px;border-left:3px solid #feb93a;background-color:#fffbf6;border-radius:3px}.wpmo-wrap .change-icons span{cursor:pointer}.wpmo-wrap .change-icons span:not(:last-child){margin-right:15px}.wpmo-wrap .dashicons-trash{color:#fe3a3a}.wpmo-wrap .dashicons-edit{color:#1c7f1f}.wpmo-wrap .dashicons-remove{color:#a108f9}.wpmo-wrap .dashicons-insert{color:#f97008}.wpmo-wrap .color-red{color:#fe3a3a}.wpmo-wrap .success-blink{animation:successBlinking 250ms infinite}.wpmo-wrap .error-blink{animation:errorBlinking 250ms infinite}body.rtl .wpmo-wrap .wp-heading-inline span{margin-left:10px;margin-right:0}body.rtl .wpmo-wrap table tr.black-list-column{border-left:none;border-right:2px solid #a108f9}body.rtl .wpmo-wrap table td label+label{margin-right:15px;margin-left:0}body.rtl .wpmo-wrap .change-icons span:not(:last-child){margin-left:15px;margin-right:0}body.rtl .wpmo-wrap .description .description-notice{padding:5px 8px 5px 5px;border-right:3px solid #feb93a;border-left:none}.wpmo-tooltip{display:none;position:absolute;padding:10px;color:#2f2f2f;background:#f6f7f7;background:linear-gradient(0deg, rgb(246, 247, 247) 0%, rgb(253, 255, 229) 100%);box-shadow:2px 2px 0 0 rgba(184,184,184,.75);-webkit-box-shadow:2px 2px 0 0 rgba(184,184,184,.75);-moz-box-shadow:2px 2px 0 0 rgba(184,184,184,.75);border-radius:2px;max-width:250px;z-index:999999}@keyframes successBlinking{0%{background-color:initial}100%{background-color:#d6ffe6}}@keyframes errorBlinking{0%{background-color:initial}100%{background-color:#fbdfdf}}/*# sourceMappingURL=style.min.css.map */
     1.wpmo-wrap{line-height:2em}.wpmo-wrap .wp-heading-inline{margin-bottom:30px;display:flex !important;align-items:center}.wpmo-wrap .wp-heading-inline span{line-height:1;font-size:2em;width:45px;height:45px;margin-right:10px;background-color:#000;background-image:linear-gradient(65deg, #0aaee1, #7d0d74);background-size:100%;background-repeat:repeat;-webkit-background-clip:text;-webkit-text-fill-color:rgba(0,0,0,0);-moz-background-clip:text;-moz-text-fill-color:rgba(0,0,0,0)}.wpmo-wrap table{border-collapse:collapse;width:100%}.wpmo-wrap table.table-sticky-head{position:relative}.wpmo-wrap table.table-sticky-head thead{position:sticky;top:32px;z-index:1;background-color:#fff;-webkit-box-shadow:0 1px 0 0 #e2e2e2;box-shadow:0 1px 0 0 #e2e2e2}.wpmo-wrap table td,.wpmo-wrap table th{padding:15px 10px;vertical-align:top;text-align:start}.wpmo-wrap table td:first-child,.wpmo-wrap table th:first-child{width:200px}.wpmo-wrap table td label+label{margin-left:15px}.wpmo-wrap table tr.black-list-column{opacity:.7;border-left:2px solid #a108f9}.wpmo-wrap table .column-name{direction:ltr;text-align:left;display:inline-block}.wpmo-wrap table .translated-column-name{font-weight:bold}.wpmo-wrap a,.wpmo-wrap span{display:inline-block}.wpmo-wrap strong{font-weight:700}.wpmo-wrap select{min-width:300px}.wpmo-wrap select[multiple]{min-width:300px;max-height:200px}.wpmo-wrap textarea{max-width:100%}.wpmo-wrap input.small-text{width:100px}.wpmo-wrap .nav-tab-wrapper{border-bottom:none}.wpmo-wrap .nav-tab-wrapper .nav-tab{border:1px solid #e0e0e0;border-bottom:none;color:#787878;border-radius:5px 5px 0 0}.wpmo-wrap .nav-tab-wrapper .nav-tab:not(.nav-tab-active){background-color:#f1f1f1;cursor:pointer}.wpmo-wrap .nav-tab-wrapper .nav-tab:focus{box-shadow:none}.wpmo-wrap .nav-tab-wrapper .nav-tab-active,.wpmo-wrap .nav-tab-wrapper .nav-tab-active:focus,.wpmo-wrap .nav-tab-wrapper .nav-tab-active:focus:active,.wpmo-wrap .nav-tab-wrapper .nav-tab-active:hover{background-color:#fff;border-bottom-color:#fff;cursor:default}.wpmo-wrap .wpmo-tab-content{padding:20px;background-color:#fff;margin-bottom:20px}.wpmo-wrap .description{color:#8a8a8a}.wpmo-wrap .description .description-notice{padding:5px 5px 5px 8px;border-left:3px solid #feb93a;background-color:#fffbf6;border-radius:3px}.wpmo-wrap .change-icons span{cursor:pointer}.wpmo-wrap .change-icons span:not(:last-child){margin-right:15px}.wpmo-wrap .dashicons-trash{color:#fe3a3a}.wpmo-wrap .dashicons-edit{color:#1c7f1f}.wpmo-wrap .dashicons-remove{color:#a108f9}.wpmo-wrap .dashicons-insert{color:#f97008}.wpmo-wrap .color-red{color:#fe3a3a}.wpmo-wrap .blue-alert{background-color:#f3fdff;padding:15px;border-radius:5px;margin-top:10px}.wpmo-wrap .change-table-index{color:#969696;text-shadow:-1px 0 #707070,0 1px #707070,1px 0 #707070,0 -1px #707070;transform:rotate(45deg);width:25px;height:25px;display:inline-flex;justify-content:center;align-items:center}.wpmo-wrap .change-table-index.active{color:#f3d767;text-shadow:-1px 0 #e1a860,0 1px #e1a860,1px 0 #e1a860,0 -1px #e1a860}.wpmo-wrap .success-blink{animation:successBlinking 250ms infinite}.wpmo-wrap .error-blink{animation:errorBlinking 250ms infinite}.wpmo-wrap .reset-db-table{background-color:#fff3f3;border-radius:5px}.wpmo-wrap .reset-db-table strong{display:block}.wpmo-wrap .reset-db-table .description{margin-bottom:20px}.wpmo-wrap .reset-db-table .button-primary{background-color:#ab1717;border:1px solid #800a0a}.wpmo-wrap .reset-db-table .button-primary:focus,.wpmo-wrap .reset-db-table .button-primary:hover{background-color:#9a0f0f;border:1px solid #5d0505}body.rtl .wpmo-wrap .wp-heading-inline span{margin-left:10px;margin-right:0}body.rtl .wpmo-wrap table tr.black-list-column{border-left:none;border-right:2px solid #a108f9}body.rtl .wpmo-wrap table td label+label{margin-right:15px;margin-left:0}body.rtl .wpmo-wrap .change-icons span:not(:last-child){margin-left:15px;margin-right:0}body.rtl .wpmo-wrap .description .description-notice{padding:5px 8px 5px 5px;border-right:3px solid #feb93a;border-left:none}.wpmo-tooltip{display:none;position:absolute;padding:5px 15px;color:#2f2f2f;background:#f6f7f7;background:linear-gradient(0deg, rgb(246, 247, 247) 0%, rgb(253, 255, 229) 100%);box-shadow:2px 2px 0 0 rgba(184,184,184,.75);-webkit-box-shadow:2px 2px 0 0 rgba(184,184,184,.75);-moz-box-shadow:2px 2px 0 0 rgba(184,184,184,.75);border-radius:5px;max-width:250px;z-index:999999}@keyframes successBlinking{0%{background-color:initial}100%{background-color:#d6ffe6}}@keyframes errorBlinking{0%{background-color:initial}100%{background-color:#fbdfdf}}/*# sourceMappingURL=style.min.css.map */
  • meta-optimizer/trunk/assets/wpmo.js

    r2960316 r2963196  
    100100            $newName = prompt(wpmoObject.renamePromptColumnMessage, $oldName);
    101101
    102         if ($newName != null && $newName != '' && $newName !== $oldName && confirm(wpmoObject.renameConfirmColumnMessage + "\n" + wpmoObject.oldName + ': ' + $oldName + "\n" + wpmoObject.newName + ': ' + $newName)) {
     102        if ($newName != null && $newName !== '' && $newName !== $oldName && confirm(wpmoObject.renameConfirmColumnMessage + "\n" + wpmoObject.oldName + ': ' + $oldName + "\n" + wpmoObject.newName + ': ' + $newName)) {
    103103            if ($metaTable === 'origin' && !confirm(wpmoObject.renameConfirmOriginMetaMessage + "\n" + wpmoObject.oldName + ': ' + $oldName + "\n" + wpmoObject.newName + ': ' + $newName))
    104104                return;
     
    144144    });
    145145
     146    $(".wpmo-wrap .change-table-index").on('click', function (e) {
     147        e.preventDefault();
     148        var $this = $(this),
     149            $tr = $this.closest('tr');
     150
     151        var data = {
     152            'action': 'wpmo_change_table_index',
     153            'type': $this.data('type'),
     154            'column': $this.data('column'),
     155            'status': $this.hasClass('active'),
     156            'nonce': wpmoObject.nonce
     157        };
     158
     159        $.post(wpmoObject.ajaxurl, data, function (response) {
     160            if (response.success) {
     161                $tr.addClass('success-blink');
     162
     163                if (response.data.active) {
     164                    $this.addClass('active');
     165                } else {
     166                    $this.removeClass('active');
     167                }
     168            } else
     169                $tr.addClass('error-blink');
     170
     171            setTimeout(function () {
     172                $tr.removeClass('success-blink').removeClass('error-blink');
     173            }, 1000);
     174        });
     175    });
     176
    146177    $(".wpmo-wrap form").on('submit', function () {
    147178        $(this).find('input[type="checkbox"]').removeAttr('disabled');
  • meta-optimizer/trunk/inc/Actions.php

    r2961404 r2963196  
    1717        add_action( 'wp_ajax_wpmo_rename_table_column', [ $this, 'renameTableColumn' ] );
    1818        add_action( 'wp_ajax_wpmo_add_remove_black_list', [ $this, 'addRemoveBlackList' ] );
     19        add_action( 'wp_ajax_wpmo_change_table_index', [ $this, 'changeTableIndex' ] );
    1920
    2021        add_action( 'deleted_post', [ $this, 'deletePostMetas' ] );
     
    7071
    7172    /**
    72      * Add or remove meta key from black list
     73     * Add or remove a meta key from black list
    7374     */
    7475    function addRemoveBlackList() {
     
    8081            $table = $this->Helpers->getMetaTableName( $type );
    8182            if ( $table && in_array( $listAction, [ 'insert', 'remove' ] ) ) {
    82                 $list         = $this->Options->getOption( $type . '_black_list', '' );
    83                 $list         = explode( "\n", $list );
    84                 $list         = str_replace( [ "\n", "\r" ], '', $list );
    85                 $list         = array_map( 'trim', $list );
    86                 $listCount    = count( $list );
    87                 $listItemInex = array_search( $column, $list );
    88                 $newAction    = $listAction === 'insert' ? 'remove' : 'insert';
    89 
    90                 if ( $listAction === 'insert' && $listItemInex === false )
     83                $list          = $this->Options->getOption( $type . '_black_list', '' );
     84                $list          = explode( "\n", $list );
     85                $list          = str_replace( [ "\n", "\r" ], '', $list );
     86                $list          = array_map( 'trim', $list );
     87                $listCount     = count( $list );
     88                $listItemIndex = array_search( $column, $list );
     89                $newAction     = $listAction === 'insert' ? 'remove' : 'insert';
     90
     91                if ( $listAction === 'insert' && $listItemIndex === false )
    9192                    $list[] = $column;
    92                 elseif ( $listAction === 'remove' && $listItemInex !== false )
    93                     unset( $list[ $listItemInex ] );
     93                elseif ( $listAction === 'remove' && $listItemIndex !== false )
     94                    unset( $list[ $listItemIndex ] );
    9495
    9596                if ( count( $list ) !== $listCount ) {
     
    145146                $result = $wpdb->query( $sql );
    146147
    147                 if ( $result )
     148                if ( $result ) {
     149                    wp_cache_delete( 'table_columns_' . $table . '_' . $type, WPMETAOPTIMIZER_PLUGIN_KEY );
    148150                    wp_send_json_success( [ 'blackListAction' => $this->Helpers->checkInBlackWhiteList( $type, $_newColumnName ) ? 'insert' : 'remove' ] );
     151                }
    149152            }
    150153
     
    172175            if ( ( $metaTable == 'origin' && $deleteOriginMetaKey || $metaTable == 'plugin' ) && $table && $this->Helpers->checkColumnExists( $table, $type, $column ) ) {
    173176                $result = $wpdb->query( "ALTER TABLE `{$table}` DROP COLUMN `{$column}`" );
     177                if ( $result ) {
     178                    wp_cache_delete( 'table_columns_' . $table . '_' . $type, WPMETAOPTIMIZER_PLUGIN_KEY );
     179                    wp_send_json_success();
     180                }
     181            }
     182
     183            wp_send_json_error();
     184        }
     185    }
     186
     187    function changeTableIndex() {
     188        if ( current_user_can( 'manage_options' ) && check_admin_referer( 'wpmo_ajax_nonce', 'nonce' ) ) {
     189            $type   = sanitize_text_field( $_POST['type'] );
     190            $column = wp_unslash( sanitize_text_field( $_POST['column'] ) );
     191            $active = sanitize_text_field( $_POST['status'] ) == 'true';
     192            $table  = $this->Helpers->getMetaTableName( $type );
     193
     194            if ( ! $table || ! $column )
     195                wp_send_json_error();
     196
     197            $column  = $this->Helpers->translateColumnName( $type, $column );
     198            $columns = $this->Helpers->getTableColumns( $table, $type );
     199
     200            if ( ! in_array( $column, $columns ) )
     201                wp_send_json_error();
     202
     203            if ( DBIndexes::checkExists( $table, $column, $this->Helpers->getIgnoreColumnNames( $type ) ) ) {
     204                $result = DBIndexes::remove( $table, $column );
    174205                if ( $result )
    175                     wp_send_json_success();
    176             }
    177 
    178             wp_send_json_error();
    179         }
     206                    $active = false;
     207            } else {
     208                if ( DBIndexes::add( $table, $column ) )
     209                    $active = true;
     210            }
     211
     212            wp_send_json_success( [ 'active' => $active ] );
     213        }
     214
     215        wp_send_json_error();
    180216    }
    181217
     
    192228            $importTables = array_keys( $importTables );
    193229
    194         $importItemsNumber = intval( $this->Options->getOption( 'import_items_number', 1 ) );
    195         if ( ! $importItemsNumber )
    196             $importItemsNumber = 1;
     230        $importItemsNumber = intval( $this->Options->getOption( 'import_items_number', WPMETAOPTIMIZER_DEFAULT_IMPORT_NUMBER ) );
     231        $importItemsNumber = apply_filters( 'wpmetaoptimizer/import_items_number', $importItemsNumber );
     232
     233        if ( ! intval( $importItemsNumber ) )
     234            $importItemsNumber = WPMETAOPTIMIZER_DEFAULT_IMPORT_NUMBER;
    197235
    198236        foreach ( $importTables as $type ) {
     
    317355     */
    318356    function addPluginActionLinks( $actions ) {
    319         $actions[] = '<a href="' . admin_url( 'options-general.php?page=' . WPMETAOPTIMIZER_PLUGIN_KEY ) . '">' . __( 'Settings' ) . '</a>';
     357        $actions[] = '<a href="' . admin_url( 'tools.php?page=' . WPMETAOPTIMIZER_PLUGIN_KEY ) . '">' . __( 'Settings' ) . '</a>';
     358        $actions[] = '<a href="https://parsakafi.github.io/wp-meta-optimizer/" target="_blank">' . __( 'Documents' ) . '</a>';
    320359
    321360        return $actions;
  • meta-optimizer/trunk/inc/Helpers.php

    r2961838 r2963196  
    160160                [ $column => $objectID ]
    161161            );
    162 
    163             wp_cache_delete( $objectID . '_' . $metaKey, WPMETAOPTIMIZER_PLUGIN_KEY . '_post_meta' );
    164162
    165163            return $result;
     
    229227    public function addTableColumn( $table, $type, $field, $metaValue ) {
    230228        global $wpdb;
    231         $addTableColumn = true;
    232         $collate        = '';
     229        $collate = '';
    233230
    234231        $value       = maybe_serialize( $metaValue );
     
    248245
    249246                if ( $currentFieldMaxLengthValue >= $valueLength && $currentColumnType === 'VARCHAR' )
    250                     return $addTableColumn;
     247                    return true;
    251248                else
    252249                    $newColumnType = 'VARCHAR(' . ( $valueLength > $currentFieldMaxLengthValue ? $valueLength : $currentFieldMaxLengthValue ) . ')';
    253250            } elseif ( $newColumnType == $currentColumnType )
    254                 return $addTableColumn;
     251                return true;
    255252
    256253            $sql = "ALTER TABLE `$table` CHANGE `{$field}` `{$field}` {$newColumnType} {$collate} NULL DEFAULT NULL";
     
    262259        }
    263260
    264         $addTableColumn = $wpdb->query( $sql );
    265 
    266         return $addTableColumn;
     261        return $wpdb->query( $sql );
     262    }
     263
     264    /**
     265     * Reset plugin meta table
     266     *
     267     * @param string $type Meta Type
     268     *
     269     * @return bool
     270     */
     271    function resetMetaTable( $type ) {
     272        global $wpdb;
     273        $table = $this->getMetaTableName( $type );
     274
     275        if ( $table ) {
     276            $columns = $this->getTableColumns( $table, $type );
     277            if ( empty( $columns ) )
     278                return false;
     279
     280            // Clear table indexes cache
     281            DBIndexes::clearCache( $table );
     282
     283            // Clear table columns cache
     284            wp_cache_delete( 'table_columns_' . $table . '_' . $type, WPMETAOPTIMIZER_PLUGIN_KEY );
     285
     286            // Delete all data in a table
     287            $sql = "TRUNCATE `$table`";
     288            $wpdb->query( $sql );
     289
     290            $drops = [];
     291            foreach ( $columns as $column ) {
     292                $drops[] = "DROP `$column`";
     293            }
     294            $drops = implode( ', ', $drops );
     295
     296            // Delete all custom meta fields from a table
     297            $sql = "ALTER TABLE `$table` $drops";
     298
     299            return $wpdb->query( $sql );
     300        }
     301
     302        return false;
    267303    }
    268304
     
    321357                return $column['Field'];
    322358            }, $columns );
    323             $tableColumns = array_diff( $columns, array_merge( $this->ignoreTableColumns, [ $type . '_id' ] ) );
     359            $tableColumns = array_diff( $columns, $this->getIgnoreColumnNames( $type ) );
    324360
    325361            wp_cache_set( 'table_columns_' . $table . '_' . $type, $tableColumns, WPMETAOPTIMIZER_PLUGIN_KEY, WPMETAOPTIMIZER_CACHE_EXPIRE );
     
    339375    public function translateColumnName( $type, $columnName ) {
    340376        $suffix       = $this->reservedKeysSuffix;
    341         $reservedKeys = array_merge( $this->ignoreTableColumns, [ $type . '_id' ] );
     377        $reservedKeys = $this->getIgnoreColumnNames( $type );
    342378
    343379        if ( substr( $columnName, - ( strlen( $suffix ) ) ) === $suffix )
     
    349385    }
    350386
    351     /**
    352      * Get new column type for exists columns
     387    public function getIgnoreColumnNames( $type ) {
     388        return array_merge( $this->ignoreTableColumns, [ $type . '_id' ] );
     389    }
     390
     391    /**
     392     * Get a new column type for existed columns
    353393     *
    354394     * @param string $currentColumnType Current column type
     
    375415
    376416    /**
    377      * Get table column type
     417     * Get a table column type
    378418     *
    379419     * @param string $table Table name
     
    388428        $columnType = $wpdb->get_col_info( 'type', 0 );
    389429
    390         if ( $columnType === 252 )
    391             return 'TEXT';
    392         else if ( $columnType === 253 )
    393             return 'VARCHAR';
    394         else if ( $columnType === 1 )
    395             return 'TINYINT';
    396         else if ( $columnType === 2 )
    397             return 'SMALLINT';
    398         else if ( $columnType === 9 )
    399             return 'MEDIUMINT';
    400         else if ( $columnType === 3 )
    401             return 'INT';
    402         else if ( $columnType === 8 )
    403             return 'BIGINT';
    404         else if ( $columnType === 4 )
    405             return 'FLOAT';
    406         else if ( $columnType === 5 )
    407             return 'DOUBLE';
    408         else if ( $columnType === 10 )
    409             return 'DATE';
    410         else if ( $columnType === 12 )
    411             return 'DATETIME';
    412         else
    413             return false;
     430        $types = array(
     431            1   => 'TINYINT',
     432            2   => 'SMALLINT',
     433            3   => 'INT',
     434            4   => 'FLOAT',
     435            5   => 'DOUBLE',
     436            8   => 'BIGINT',
     437            9   => 'MEDIUMINT',
     438            10  => 'DATE',
     439            12  => 'DATETIME',
     440            252 => 'TEXT',
     441            253 => 'VARCHAR',
     442        );
     443
     444        return $types[ $columnType ] ?? false;
    414445    }
    415446
     
    431462        //     return 'LONGTEXT';
    432463        elseif ( is_string( $value ) && $valueLength <= 65535 || is_null( $value ) )
    433             return 'TEXT'; // 'VARCHAR';
     464            return 'VARCHAR';
    434465        elseif ( is_bool( $value ) )
    435466            return 'TINYINT';
     
    468499
    469500    /**
    470      * Get meta table name base on type
     501     * Get meta table name base on a type
    471502     *
    472503     * @param string $type Meta type
     
    475506     */
    476507    public function getMetaTableName( $type ) {
    477         if ( isset( $this->tables[ $type ] ) )
    478             return $this->tables[ $type ]['table'];
    479         else
    480             return false;
    481     }
    482 
    483     /**
    484      * Get WP table name base on type
     508        return isset( $this->tables[ $type ] ) ? $this->tables[ $type ]['table'] : false;
     509    }
     510
     511    /**
     512     * Get WP table name base on a type
    485513     *
    486514     * @param string $type Meta type
     
    493521
    494522    /**
    495      * Get WordPress meta table name base on type
     523     * Get WordPress meta table name base on a type
    496524     *
    497525     * @param string $type Meta type
     
    599627
    600628    /**
    601      * Get object left items count for import process
     629     * Get the number of remaining cases of the specified type
    602630     *
    603631     * @param string $type Meta type
     
    719747    }
    720748
     749    public static function secondsToHumanReadable( $seconds ) {
     750        $seconds = intval( $seconds );
     751        $dtF     = new \DateTime ( '@0' );
     752        $dtT     = new \DateTime ( "@$seconds" );
     753        $ret     = '';
     754        if ( $seconds === 0 ) {
     755            // special case
     756            return '0 ' . __( 'Seconds', 'meta-optimizer' );
     757        }
     758        $diff = $dtF->diff( $dtT );
     759        foreach (
     760            array(
     761                'y' => __( 'Years', 'meta-optimizer' ),
     762                'm' => __( 'Months', 'meta-optimizer' ),
     763                'd' => __( 'Days', 'meta-optimizer' ),
     764                'h' => __( 'Hours', 'meta-optimizer' ),
     765                'i' => __( 'Minutes', 'meta-optimizer' ),
     766                's' => __( 'Seconds', 'meta-optimizer' )
     767            ) as $time => $timeName
     768        ) {
     769            if ( $diff->$time !== 0 ) {
     770                $ret .= $diff->$time . ' ' . $timeName;
     771                $ret .= ' ';
     772            }
     773        }
     774
     775        return substr( $ret, 0, - 1 );
     776    }
     777
    721778    /**
    722779     * Check is JSON
  • meta-optimizer/trunk/inc/Install.php

    r2961838 r2963196  
    6565                    'page' => 1
    6666                ],
    67                 'import_items_number'                    => 1
     67                'import_items_number'                    => 5
    6868            );
    6969
     
    8484
    8585                update_option( 'wp_meta_optimizer', $newPluginOptions );
     86
     87                wp_cache_delete( 'options', WPMETAOPTIMIZER_PLUGIN_KEY );
    8688            }
    8789        }
  • meta-optimizer/trunk/inc/Integration.php

    r2960316 r2963196  
    4040
    4141        if ( $type !== 'option' ) {
    42             $metaValue = get_metadata( $type, $id, "{$prefix}{$name}", true );
     42            $metaValue = get_metadata( $type, $id, $prefix . $name, true );
    4343
    4444            return is_array( $metaValue ) && isset( $metaValue[0] ) ? $metaValue[0] : $metaValue;
  • meta-optimizer/trunk/inc/Options.php

    r2961838 r2963196  
    101101                        $this->setOption( 'import_' . $type . '_latest_id', null );
    102102                }
     103
     104                wp_cache_delete( 'options', WPMETAOPTIMIZER_PLUGIN_KEY );
     105            }
     106
     107            if ( wp_verify_nonce( $_POST[ WPMETAOPTIMIZER_PLUGIN_KEY ], 'reset_tables_submit' ) ) {
     108                $importTables = $this->getOption( 'import', [] );
     109                $types        = array_keys( $this->tables );
     110
     111                $reset = false;
     112                foreach ( $types as $type ) {
     113                    if ( isset( $_POST[ 'reset_plugin_table_' . $type ] ) ) {
     114                        $Helpers->resetMetaTable( $type );
     115
     116                        if ( isset( $_POST[ 'reset_import_' . $type ] ) ) {
     117                            $importTables[ $type ] = 1;
     118                            $this->setOption( 'import_' . $type . '_latest_id', null );
     119                        }
     120
     121                        $reset = true;
     122                    }
     123                }
     124
     125                if ( $reset )
     126                    $updateMessage = $this->getNoticeMessageHTML( __( 'Plugin table(s) reseted.', 'meta-optimizer' ) );
     127
     128                $this->setOption( 'import', $importTables );
    103129            }
    104130        }
    105 
    106         $options = $this->getOption( null, [], false );
    107131
    108132        $postTypes = get_post_types( [
     
    110134        ], "objects" );
    111135
    112         $metaSaveTypes = $this->getOption( 'meta_save_types', [] );
     136        $metaSaveTypes = $this->getOption( 'meta_save_types', [], false );
    113137        ?>
    114138        <div class="wrap wpmo-wrap">
     
    130154                <?php
    131155                foreach ( $this->tables as $type => $table ) {
    132                     $columns = $Helpers->getTableColumns( $table['table'], $type );
     156                    $ignoreColumns = $Helpers->getIgnoreColumnNames( $type );
     157                    $columns       = $Helpers->getTableColumns( $table['table'], $type );
    133158                    sort( $columns );
    134159                    ?>
     
    148173                            <th style="width:30px">#</th>
    149174                            <th><?php _e( 'Field Name', 'meta-optimizer' ) ?></th>
     175                            <th><?php _e( 'Type', 'meta-optimizer' ) ?></th>
    150176                            <th><?php _e( 'Change' ) ?></th>
    151177                            <?php if ( $this->getOption( 'original_meta_actions', false ) == 1 ) { ?>
     
    161187                        if ( is_array( $columns ) && count( $columns ) )
    162188                            foreach ( $columns as $column ) {
    163                                 $_column = $column;
    164                                 $column  = $Helpers->translateColumnName( $type, $column );
     189                                $_column     = $column;
     190                                $column      = $Helpers->translateColumnName( $type, $column );
     191                                $indexExists = DBIndexes::checkExists( $table['table'], $_column, $ignoreColumns );
     192                                $columnType  = strtolower( $Helpers->getTableColumnType( $table['table'], $_column ) );
    165193
    166194                                $checkInBlackList = Helpers::getInstance()->checkInBlackWhiteList( $type, $column );
     
    178206                                echo "<tr class='" . ( $checkInBlackList ? 'black-list-column' : '' ) . "'><td>{$c}</td><td class='column-name'><span>" . esc_html( $column ) . "</span>" . ( $_column ? " <abbr class='translated-column-name tooltip-title' title='" . __( 'The meta key was renamed because it equals the name of a reserved column.', 'meta-optimizer' ) . "'>(" . esc_html( $_column ) . ")</abbr>" : '' ) . "</td>";
    179207
     208                                echo "<td>$columnType</td>";
     209
    180210                                echo "<td class='change-icons'>";
    181211                                echo "<span class='dashicons dashicons-edit rename-table-column tooltip-title' title='" . __( 'Rename', 'meta-optimizer' ) . "' data-type='" . esc_html( $type ) . "' data-meta-table='plugin' data-column='" . esc_html( $column ) . "'></span>";
    182212                                echo "<span class='dashicons dashicons-trash delete-table-column tooltip-title' title='" . __( 'Delete' ) . "' data-type='" . esc_html( $type ) . "' data-meta-table='plugin' data-column='" . esc_html( $column ) . "'></span>";
    183213                                echo "<span span class='dashicons dashicons-" . esc_html( $listAction ) . " add-remove-black-list tooltip-title' title='" . esc_html( $listActionTitle ) . "' data-action='" . esc_html( $listAction ) . "' data-type='" . esc_html( $type ) . "' data-meta-table='plugin' data-column='" . esc_html( $column ) . "'></span>";
     214                                echo "<span class='dashicons dashicons-post-status change-table-index tooltip-title" . ( $indexExists ? ' active' : '' ) . "' title='" . __( 'Index', 'meta-optimizer' ) . "' data-type='" . esc_html( $type ) . "' data-column='" . esc_html( $column ) . "'></span>";
    184215                                echo "</td>";
    185216
     
    199230                            }
    200231                        else
    201                             echo "<tr><td colspan='" . ( $this->getOption( 'original_meta_actions', false ) == 1 ? 4 : 3 ) . "'>" . __( 'Without custom field column', 'meta-optimizer' ) . "</td></tr>";
     232                            echo "<tr><td colspan='" . ( $this->getOption( 'original_meta_actions', false ) == 1 ? 5 : 4 ) . "'>" . __( 'Without custom field column', 'meta-optimizer' ) . "</td></tr>";
    202233                        ?>
    203234                        </tbody>
     
    207238                }
    208239                ?>
     240                <br>
     241                <form action="" method="post">
     242                    <?php wp_nonce_field( 'reset_tables_submit', WPMETAOPTIMIZER_PLUGIN_KEY, false ); ?>
     243                    <table class="reset-db-table">
     244                        <tr>
     245                            <th><?php _e( 'Reset Database tables', 'meta-optimizer' ) ?></th>
     246                            <td>
     247                                <strong>
     248                                    <?php _e( 'You can use this option to delete all plugin meta fields as well as data, then restart the import process.', 'meta-optimizer' ) ?>
     249                                </strong>
     250                                <p class="description">
     251                                    <span class="description-notice">
     252                                        <?php _e( 'Be very careful with this command. It will empty the contents of your database table and there is no undo.', 'meta-optimizer' ) ?>
     253                                    </span>
     254                                </p>
     255
     256                                <?php
     257                                foreach ( $this->tables as $type => $table ) {
     258                                    ?>
     259                                    <label>
     260                                        <input type="checkbox" name="reset_plugin_table_<?php echo esc_attr( $type ) ?>"
     261                                               value="1">
     262                                        <?php echo esc_html( $table['name'] ) . ' (' . $Helpers->getMetaTableName( $type ) . ')' ?>
     263                                    </label>
     264                                    <label>
     265                                        <input type='checkbox' name='reset_import_<?php echo esc_attr( $type ) ?>'
     266                                               value='1'><?php _e( 'Run Import', 'meta-optimizer' ) ?>
     267                                    </label>
     268                                    <br>
     269                                    <?php
     270                                }
     271                                ?>
     272                            </td>
     273                        </tr>
     274                        <tr>
     275                            <td colspan="2">
     276                                <input type="submit" class="button button-primary button-large"
     277                                       value="<?php _e( 'Reset', 'meta-optimizer' ) ?>">
     278                            </td>
     279                        </tr>
     280                    </table>
     281                </form>
    209282            </div>
    210283
     
    354427                        <tr>
    355428                            <td colspan="3">
    356                                 <input type="submit" class="button button-primary" value="<?php _e( 'Save' ) ?>">
     429                                <input type="submit" class="button button-primary button-large"
     430                                       value="<?php _e( 'Save' ) ?>">
    357431                            </td>
    358432                        </tr>
     
    378452                                <input type="number" name="import_items_number" id="import_items_number"
    379453                                       class="small-text" step="1" min="1" max="30"
    380                                        value="<?php echo esc_attr( $this->getOption( 'import_items_number', 5 ) ) ?>"
     454                                       value="<?php echo esc_attr( $this->getOption( 'import_items_number', WPMETAOPTIMIZER_DEFAULT_IMPORT_NUMBER ) ) ?>"
    381455                                       placeholder="1">
    382456                                <p class="description"><?php _e( 'The import scheduler runs every minute, and you can set the number of items to import.', 'meta-optimizer' ) ?></p>
     
    399473                                    <?php
    400474                                    if ( $metaTypeCanSaved && $latestObjectID ) {
    401                                         $checkedDate  = $this->getOption( 'import_' . $type . '_checked_date', false );
    402                                         $_checkedDate = '';
    403                                         if ( $checkedDate )
    404                                             $_checkedDate = ' (' . wp_date( 'Y-m-d H:i:s', strtotime( $checkedDate ) ) . ') ';
    405 
    406                                         echo '<p>';
    407 
     475                                        $checkedDate = $this->getOption( 'import_' . $type . '_checked_date', false );
     476                                        $checkedDate = $checkedDate ? ' (' . wp_date( 'Y-m-d H:i:s', strtotime( $checkedDate ) ) . ') ' : '';
     477
     478                                        echo '<div class="blue-alert">';
    408479                                        if ( $latestObjectID === 'finished' ) {
    409                                             _e( 'Finished', 'meta-optimizer' );
    410                                             echo esc_html( $_checkedDate ) . ', ';
     480                                            echo __( 'Finished', 'meta-optimizer' ) . esc_html( $checkedDate );
    411481
    412482                                        } elseif ( is_numeric( $latestObjectID ) ) {
     483                                            $leftItems   = $Helpers->getObjectLeftItemsCount( $type );
    413484                                            $objectTitle = $objectLink = false;
    414485
     
    428499
    429500                                            } elseif ( $type == 'term' ) {
    430                                                 $term = get_term( $latestObjectID );
    431                                                 if ( $term )
     501                                                if ( $term = get_term( $latestObjectID ) )
    432502                                                    $objectTitle = $term->name;
    433503                                                $objectLink = get_edit_term_link( $latestObjectID );
     
    435505
    436506                                            if ( $objectTitle && $objectLink ) {
    437                                                 _e( 'The last item checked:', 'meta-optimizer' );
    438                                                 echo " <a href='$objectLink' target='_blank'>$objectTitle</a> $_checkedDate, ";
     507                                                echo __( 'The last item checked:', 'meta-optimizer' ) . " <a href='$objectLink' target='_blank'>$objectTitle</a> $checkedDate";
    439508                                            } else {
    440                                                 _e( 'Unknown item', 'meta-optimizer' );
    441                                                 echo " $_checkedDate, ";
     509                                                echo __( 'Unknown item', 'meta-optimizer' ) . " $checkedDate";
    442510                                            }
    443511
    444                                             _e( 'Left Items: ', 'meta-optimizer' );
    445                                             echo ' ' . $Helpers->getObjectLeftItemsCount( $type ) . ", ";
     512                                            if ( $leftItems ) {
     513                                                echo sprintf( '<br>%s %d', esc_html__( 'Left Items:', 'meta-optimizer' ), $leftItems );
     514                                                echo sprintf( ', %s %s', esc_html__( 'Estimate Import Time:', 'meta-optimizer' ), $this->estimateImportTime( $leftItems ) );
     515                                            }
    446516                                        }
    447517
    448                                         echo "<label><input type='checkbox' name='reset_import_" . esc_attr( $type ) . "' value='1'> " . __( 'Reset', 'meta-optimizer' ) . '</label>';
    449                                         echo '</p>';
     518                                        echo "<br><label><input type='checkbox' name='reset_import_" . esc_attr( $type ) . "' value='1'> " . __( 'Reset', 'meta-optimizer' ) . '</label>';
     519                                        echo '</div>';
    450520                                    }
    451 
    452521                                    echo '<br>';
    453522                                }
     
    461530                        </tr>
    462531                        <tr>
    463                             <td colspan="2"><input type="submit" class="button button-primary"
    464                                                    value="<?php _e( 'Save' ) ?>"></td>
     532                            <td colspan="2">
     533                                <input type="submit" class="button button-primary button-large"
     534                                       value="<?php _e( 'Save' ) ?>">
     535                            </td>
    465536                        </tr>
    466537                        </tbody>
     
    470541        </div>
    471542        <?php
     543    }
     544
     545    function estimateImportTime( $leftItems ) {
     546        $leftItems = intval( $leftItems );
     547        $number    = intval( $this->getOption( 'import_items_number', WPMETAOPTIMIZER_DEFAULT_IMPORT_NUMBER ) );
     548        $minutes   = 1;
     549        if ( $leftItems > $number )
     550            $minutes = intval( $leftItems / $number );
     551
     552        return Helpers::secondsToHumanReadable( $minutes * 60 );
    472553    }
    473554
     
    511592        $options[ $key ] = $value;
    512593
     594        wp_cache_delete( 'options', WPMETAOPTIMIZER_PLUGIN_KEY );
     595
    513596        return update_option( WPMETAOPTIMIZER_OPTION_KEY, $options );
    514597    }
  • meta-optimizer/trunk/inc/PostQueries.php

    r2960316 r2963196  
    100100     * @param string $orderby Alias for the field to order by.
    101101     *
    102      * @return string|false Table-prefixed value to used in the ORDER clause. False otherwise.
     102     * @return string|false Table-prefixed value to use in the ORDER clause. False otherwise.
    103103     * @global \wpdb  $wpdb    WordPress database abstraction object.
    104104     *
  • meta-optimizer/trunk/inc/TermQueries.php

    r2960316 r2963196  
    117117    protected function termParseOrderby( $orderby_raw ) {
    118118        $orderbyKeys = is_array( $orderby_raw ) ? array_keys( $orderby_raw ) : [];
    119         $_orderby    = is_array( $orderby_raw ) ? reset($orderbyKeys) : strtolower( $orderby_raw );
     119        $_orderby    = is_array( $orderby_raw ) ? reset( $orderbyKeys ) : strtolower( $orderby_raw );
    120120
    121121        $maybe_orderby_meta = false;
  • meta-optimizer/trunk/readme.txt

    r2961838 r2963196  
    55Requires at least: 5.0
    66Tested up to: 6.3.1
    7 Stable tag: 1.2.2
     7Stable tag: 1.3
    88Requires PHP: 7.0
    99License: GPLv2 or later
     
    3232- And all plugins and themes use WordPress standard functions and hooks.
    3333
    34 ## Attention
    35 If you use reserved column keys such as `post_id` for post-meta, the plugin adds a suffix to the meta key. It creates a column based on the renamed key. As an example, if you save meta with key `post_id`, then plugin adds `_wpmork` suffix and creates column `post_id_wpmork`. In response to a query (WP_Query), the plugin automatically changes the meta key if necessary.
     34== Frequently Asked Questions ==
    3635
    37 [Update post meta](https://developer.wordpress.org/reference/functions/update_post_meta/) example
    38 ```
    39 update_post_meta(1, 'post_id', 222);
    40 ```
    41 The meta key has been changed to:
    42 ```
    43 update_post_meta(1, 'post_id_wpmork', 222);
    44 ```
     36= Where can I read the plugin documentation? =
    4537
    46 Example [Query](https://developer.wordpress.org/reference/classes/wp_query/#custom-field-post-meta-parameters):
    47 ```
    48 $query = new WP_Query(array(
    49     'orderby' => array(
    50         'post_id' => 'DESC'
    51     ),
    52     'meta_query' => array(
    53         'post_id' => array(
    54             'key' => 'post_id',
    55             'compare' => 'EXISTS',
    56             'type' => 'NUMERIC'
    57         )
    58     )
    59 ));
    60 ```
    61 Plugin changed query to this:
    62 ```
    63 $query = new WP_Query(array(
    64     'orderby' => array(
    65         'post_id_wpmork' => 'DESC'
    66     ),
    67     'meta_query' => array(
    68         'post_id_wpmork' => array(
    69             'key' => 'post_id_wpmork',
    70             'compare' => 'EXISTS',
    71             'type' => 'NUMERIC'
    72         )
    73     )
    74 ));
    75 ```
    76 
    77 == Frequently Asked Questions ==
     38[Meta Optimizer plugin documentation page](https://parsakafi.github.io/wp-meta-optimizer/)
    7839
    7940= What type of meta types supported? =
     
    9758
    9859== Changelog ==
     60= 1.3 =
     61* Add a filter for changing import item numbers ([Documentation](https://parsakafi.github.io/wp-meta-optimizer/#plugin-hooks))
     62* It is now possible to change the indexes of DB tables
     63* You will be able to reset the plugin's database tables
     64* The import tab now includes an estimate of import time
    9965
    10066= 1.2.2 =
Note: See TracChangeset for help on using the changeset viewer.