WordPress.org

Make WordPress Core

Ticket #9175: 9175.3.patch

File 9175.3.patch, 8.4 KB (added by hakre, 8 years ago)

Refreshed against current trunk.

  • wp-admin/options.php

     
    9393
    9494$whitelist_options = apply_filters( 'whitelist_options', $whitelist_options );
    9595
     96switch($action) {
     97
    9698/*
    9799 * If $_GET['action'] == 'update' we are saving settings sent from a settings page
    98100 */
    99 if ( 'update' == $action ) {
     101case 'update':
    100102        if ( 'options' == $option_page && !isset( $_POST['option_page'] ) ) { // This is for back compat and will eventually be removed.
    101103                $unregistered = true;
    102104                check_admin_referer( 'update-options' );
     
    160162        $goback = add_query_arg( 'updated', 'true',  wp_get_referer() );
    161163        wp_redirect( $goback );
    162164        exit;
    163 }
    164165
     166case 'serialoption':
     167// viewer for a serialized option value.
     168
     169        // validate input       
     170        $option_name = isset( $_GET['option_name'] ) ? (string) trim( $_GET['option_name'] ) : null;
     171
     172        if ( $option_name === null )
     173                wp_die(__('Cheatin’ uh?'));
     174
     175        $r = preg_match('/^[a-z0-9_-]*$/', $option_name);
     176        if ( $r == 0 )
     177                wp_die(__('Cheatin’ uh?'));
     178
     179        $options_to_update = array(); // nothing to update right now.
     180
     181        include('./admin-header.php'); ?>
     182<div class="wrap">
     183<?php screen_icon(); ?>
     184  <h2><?php printf('%s - %s', $option_name, __('Option')); ?></h2>
     185  <form name="form" action="options.php" method="post" id="all-options">
     186  <?php wp_nonce_field('options-options') ?>
     187  <input type="hidden" name="action" value="serialoption" /> 
     188  <input type='hidden' name='option_page' value='options' /> 
     189<?php
     190        // query option value and validate serialized-ability                   
     191        $options = $wpdb->get_results(sprintf("SELECT * FROM %s WHERE option_name = '%s'", $wpdb->options, $option_name));
     192
     193        // the serialoption page can handle only one value
     194        if ( count($options) != 1)             
     195                wp_die(__('Cheatin&#8217; uh?'));
     196       
     197        $option = $options[0];
     198
     199        // $option must be stdclass to continue
     200        if ( is_object($option) == false )
     201                wp_die(__('Cheatin&#8217; uh?'));
     202       
     203        // not a serialized value? well, handeled in full options page already                 
     204        if ( !is_serialized($option->option_value) )
     205                wp_die(__('Cheatin&#8217; uh?'));
     206
     207        // this case is handeled in the full options page already as well
     208        if ( is_serialized_string($option->option_value) )
     209                wp_die(__('Cheatin&#8217; uh?'));
     210               
     211        // unserialize: false on failure, notice will be given as well (usefull for the admin)
     212        $unserialized = unserialize($option->option_value);
     213       
     214        // serialized scalar makes not much sense right now     
     215        if ( is_scalar($unserialized) )
     216                wp_die(__('Cheatin&#8217; uh?'));
     217                               
     218        // array
     219        // object - will fail/become '__PHP_Incomplete_Class_Name' if class is not defined
     220               
     221        $title = $type = 'UNDEFINED';   
     222       
     223        switch ( true ) {
     224                case is_scalar($unserialized):
     225                        $title = 'SCALAR';
     226                        $type  = 'SCALAR';
     227                        break;
     228                                               
     229                case is_object($unserialized):
     230                        $title = sprintf('OBJECT (%s)', get_class($unserialized));
     231                        $type  = 'OBJECT';
     232                        break;
     233                       
     234                case is_array($unserialized):
     235                        $title = sprintf('ARRAY (%d Elements)', count($unserialized));
     236                        $type = 'ARRAY';                       
     237                        break;
     238                       
     239                case gettype($unserialized) == 'object':
     240                        // this is a fallback since sometime is_object did not make it.
     241                        // i (hakre) encountered it with undefined classes
     242                        $title = sprintf('OBJECT (%s)', get_class($unserialized));
     243                        $type  = 'OBJECT';
     244                        break;                 
     245                       
     246                default:
     247                        $title = 'UNKNOWN TYPE ' . gettype($unserialized);
     248                        $type  = 'UNKNOWN';
     249        } // end inner switch
     250       
     251        $values = array('UNDEFINED' => '');
     252
     253        switch ( $type ) {
     254                case 'SCALAR':
     255                        $values = array($type => (string) $unserialized);
     256                        break;
     257                       
     258                case 'OBJECT':
     259                        $values = array(get_class($unserialized) => $unserialized);
     260                        break;
     261                       
     262                case 'ARRAY':
     263                        $values = $unserialized;
     264                        break;
     265                               
     266                default:
     267                        $values = array('UNKNOWN' => '');
     268        } // end inner switch
     269       
     270?>
     271  <h3><?php echo htmlspecialchars($title) ?></h3>
     272  <table class="form-table"> 
     273<?php
     274        foreach ( $values as $key => $value ):
     275                       
     276                $id = sprintf('edit-%s', htmlspecialchars($key));
     277                $html_label = sprintf( '<label for="%s">%s</label>', $id, htmlspecialchars($key));
     278               
     279                // prevent recurisions, stacked arrays and such
     280                if (! is_scalar($value) ) {
     281                        $value = print_r($value, true);
     282                }               
     283       
     284                // put values in form elements for a better editing experience
     285                // $html_input = sprintf('<div>%s</div>', htmlspecialchars(print_r($value, true)) );
     286                if ( strpos($value, "\n") !== false ) {
     287                        $html_input = sprintf('<textarea class="large-text" name="%s" id="%s" rows="10">%s</textarea>', $id, $id, htmlspecialchars($value));
     288                } else {
     289                        $html_input = sprintf('<input class="regular-text" type="text" name="%s" id="%s" value="%s" />', $id, $id, htmlspecialchars($value));
     290                }
     291?>
     292  <tr>
     293        <th scope="row"><?php echo $html_label ?></th>
     294        <td><?php echo $html_input ?></td>
     295  </tr>
     296<?php endforeach; ?>
     297  </table>
     298  <p class="submit">
     299        <a href="options.php" class="button lbutton"><?php _e('Back'); ?></a>
     300        <input type="hidden" name="page_options" value="<?php echo htmlspecialchars(implode(',', $options_to_update)); ?>" />
     301    <input type="hidden" name="Update-Ex" value="<?php _e('Save Changes') ?>" class="button-primary disabled"  disabled="disabled" />
     302  </p>
     303  </form>
     304</div>
     305<?php
     306        break;
     307       
     308default:
     309
    165310include('./admin-header.php'); ?>
    166311
    167312<div class="wrap">
     
    177322
    178323foreach ( (array) $options as $option ) :
    179324        $disabled = false;
    180         if ( $option->option_name == '' )
    181                 continue;
     325        $more     = false;
    182326        if ( is_serialized( $option->option_value ) ) {
    183                 if ( is_serialized_string( $option->option_value ) ) {
     327                if ( is_serialized_string($option->option_value) ) {
    184328                        // this is a serialized string, so we should display it
    185329                        $value = maybe_unserialize( $option->option_value );
    186330                        $options_to_update[] = $option->option_name;
    187331                        $class = 'all-options';
    188332                } else {
    189                         $value = 'SERIALIZED DATA';
     333                        $value = sprintf( 'SERIALIZED DATA (~ %s %s)', number_format( strlen( $option->option_value ) ), __( 'Bytes' ) );
    190334                        $disabled = true;
    191335                        $class = 'all-options disabled';
     336                        $more  = true;
    192337                }
    193338        } else {
    194339                $value = $option->option_value;
     
    196341                $class = 'all-options';
    197342        }
    198343        $name = esc_attr( $option->option_name );
    199         echo "
     344        $html_label = sprintf( '<label for="%1$s">%1$s</label>', $option->option_name );
     345        $html_input = '';
     346        if ( strpos($value, "\n") !== false ) {
     347                $html_input = sprintf('<textarea class="%s" name="%s" id="%s" cols="30" rows="5">%s</textarea>', $class, $option->option_name, $option->option_name, esc_html($value));
     348        } else {
     349                $html_input = sprintf('<input class="regular-text %s" type="text" name="%s" id="%s" value="%s" %s />', $class, $option->option_name, $option->option_name, esc_attr($value), $disabled);
     350        }
     351
     352        /* more info on seriazlied data, add the expand button to gain access to serialoption */
     353        if ( $more ) {
     354                $html_href  = sprintf('options.php?action=serialoption&amp;option_name=%s', urlencode($option->option_name));
     355                $html_label = sprintf('<a href="%s" class="button">%s</a>',  $html_href, $option->option_name);
     356                // uncommented: for label/expand button combo but I like the other combo more. $html_input .= sprintf(' <a href="%s" class="button-primary">%s</a>',  $html_href, _('Expand'));
     357        }
     358
     359?>
    200360<tr>
    201         <th scope='row'><label for='$name'>" . esc_html( $option->option_name ) . "</label></th>
    202 <td>";
    203         if ( strpos( $value, "\n" ) !== false )
    204                 echo "<textarea class='$class' name='$name' id='$name' cols='30' rows='5'>" . wp_htmledit_pre( $value ) . "</textarea>";
    205         else
    206                 echo "<input class='regular-text $class' type='text' name='$name' id='$name' value='" . esc_attr( $value ) . "'" . disabled( $disabled, true, false ) . " />";
    207         echo "</td>
    208 </tr>";
    209 endforeach;
    210 ?>
     361        <th scope="row"><?php echo $html_label ?></th>
     362        <td><?php echo $html_input ?></td>
     363</tr>
     364<?php endforeach; ?>
    211365  </table>
    212 <p class="submit"><input type="hidden" name="page_options" value="<?php echo esc_attr( implode( ',', $options_to_update ) ); ?>" /><input type="submit" name="Update" value="<?php esc_attr_e( 'Save Changes' ); ?>" class="button-primary" /></p>
     366<p class="submit"><input type="hidden" name="page_options" value="<?php echo esc_attr( implode(',', $options_to_update) ); ?>" /><input type="submit" name="Update" value="<?php esc_attr_e( 'Save Changes' ); ?>" class="button-primary" /></p>
    213367  </form>
    214368</div>
    215369
    216370
    217371<?php
    218372include('./admin-footer.php');
     373break;
     374} // end switch
     375
    219376?>