Make WordPress Core

Ticket #9175: 9175-options-serialoption-viewer-fix1.patch

File 9175-options-serialoption-viewer-fix1.patch, 8.1 KB (added by hakre, 14 years ago)

fix the warning thrown by an undefined variable setting.

  • wp-admin/options.php

     
    8383        wp_redirect( $goback );
    8484        break;
    8585
     86case 'serialoption':
     87// viewer for a serialized option value.
     88       
     89        // validate input       
     90        $option_name = isset( $_GET['option_name'] ) ? (string) trim( $_GET['option_name'] ) : null;
     91               
     92        if ( $option_name === null )
     93                wp_die(__('Cheatin’ uh?'));
     94               
     95        $r = preg_match('/^[a-z0-9_]*$/', $option_name);
     96        if ( $r == 0 )
     97                wp_die(__('Cheatin’ uh?'));
     98               
     99        $options_to_update = array(); // nothing to update right now.
     100               
     101        include('admin-header.php'); ?>
     102<div class="wrap">
     103<?php screen_icon(); ?>
     104  <h2><?php printf('%s - %s', $option_name, __('Option')); ?></h2>
     105  <form name="form" action="options.php" method="post" id="all-options">
     106  <?php wp_nonce_field('options-options') ?>
     107  <input type="hidden" name="action" value="serialoption" /> 
     108  <input type='hidden' name='option_page' value='options' /> 
     109<?php
     110        // query option value and validate serialized-ability                   
     111        $options = $wpdb->get_results(sprintf("SELECT * FROM %s WHERE option_name = '%s'", $wpdb->options, $option_name));
     112
     113        // the serialoption page can handle only one value
     114        if ( count($options) != 1)             
     115                wp_die(__('Cheatin&#8217; uh?'));
     116       
     117        $option = $options[0];
     118
     119        // $option must be stdclass to continue
     120        if ( is_object($option) == false )
     121                wp_die(__('Cheatin&#8217; uh?'));
     122       
     123        // not a serialized value? well, handeled in full options page already                 
     124        if ( !is_serialized($option->option_value) )
     125                wp_die(__('Cheatin&#8217; uh?'));
     126
     127        // this case is handeled in the full options page already as well
     128        if ( is_serialized_string($option->option_value) )
     129                wp_die(__('Cheatin&#8217; uh?'));
     130               
     131        // unserialize: false on failure, notice will be given as well (usefull for the admin)
     132        $unserialized = unserialize($option->option_value);
     133       
     134        // serialized scalar makes not much sense right now     
     135        if ( is_scalar($unserialized) )
     136                wp_die(__('Cheatin&#8217; uh?'));
     137                               
     138        // array
     139        // object - will fail/become '__PHP_Incomplete_Class_Name' if class is not defined
     140               
     141        $title = $type = 'UNDEFINED';   
     142       
     143        switch ( true ) {
     144                case is_scalar($unserialized):
     145                        $title = 'SCALAR';
     146                        $type  = 'SCALAR';
     147                        break;
     148                                               
     149                case is_object($unserialized):
     150                        $title = sprintf('OBJECT (%s)', get_class($unserialized));
     151                        $type  = 'OBJECT';
     152                        break;
     153                       
     154                case is_array($unserialized):
     155                        $title = sprintf('ARRAY (%d Elements)', count($unserialized));
     156                        $type = 'ARRAY';                       
     157                        break;
     158                       
     159                case gettype($unserialized) == 'object':
     160                        // this is a fallback since sometime is_object did not make it.
     161                        // i (hakre) encountered it with undefined classes
     162                        $title = sprintf('OBJECT (%s)', get_class($unserialized));
     163                        $type  = 'OBJECT';
     164                        break;                 
     165                       
     166                default:
     167                        $title = 'UNKNOWN TYPE ' . gettype($unserialized);
     168                        $type  = 'UNKNOWN';
     169        } // end inner switch
     170       
     171        $values = array('UNDEFINED' => '');
     172
     173        switch ( $type ) {
     174                case 'SCALAR':
     175                        $values = array($type => (string) $unserialized);
     176                        break;
     177                       
     178                case 'OBJECT':
     179                        $values = array(get_class($unserialized) => $unserialized);
     180                        break;
     181                       
     182                case 'ARRAY':
     183                        $values = $unserialized;
     184                        break;
     185                               
     186                default:
     187                        $values = array('UNKNOWN' => '');
     188        } // end inner switch
     189       
     190?>
     191  <h3><?php echo htmlspecialchars($title) ?></h3>
     192  <table class="form-table"> 
     193<?php
     194        foreach ( $values as $key => $value ):
     195                       
     196                $id = sprintf('edit-%s', htmlspecialchars($key));
     197                $html_label = sprintf( '<label for="%s">%s</label>', $id, htmlspecialchars($key));
     198               
     199                // prevent recurisions, stacked arrays and such
     200                if (! is_scalar($value) ) {
     201                        $value = print_r($value, true);
     202                }               
     203       
     204                // put values in form elements for a better editing experience
     205                // $html_input = sprintf('<div>%s</div>', htmlspecialchars(print_r($value, true)) );
     206                if ( strpos($value, "\n") !== false ) {
     207                        $html_input = sprintf('<textarea class="large-text" name="%s" id="%s" rows="10">%s</textarea>', $id, $id, htmlspecialchars($value));
     208                } else {
     209                        $html_input = sprintf('<input class="regular-text" type="text" name="%s" id="%s" value="%s" />', $id, $id, htmlspecialchars($value));
     210                }
     211?>
     212  <tr>
     213        <th scope="row"><?php echo $html_label ?></th>
     214        <td><?php echo $html_input ?></td>
     215  </tr>
     216<?php endforeach; ?>
     217  </table>
     218  <p class="submit">
     219        <a href="options.php" class="button lbutton"><?php _e('Back'); ?></a>
     220        <input type="hidden" name="page_options" value="<?php echo htmlspecialchars(implode(',', $options_to_update)); ?>" />
     221    <input type="hidden" name="Update-Ex" value="<?php _e('Save Changes') ?>" class="button-primary disabled"  disabled="disabled" />
     222  </p>
     223  </form>
     224</div>
     225<?php
     226        break;
     227       
    86228default:
    87229        include('admin-header.php'); ?>
    88230
     
    99241
    100242foreach ( (array) $options as $option) :
    101243        $disabled = '';
     244        $more     = false;
    102245        $option->option_name = attribute_escape($option->option_name);
    103246        if ( is_serialized($option->option_value) ) {
    104247                if ( is_serialized_string($option->option_value) ) {
    105248                        // this is a serialized string, so we should display it
    106249                        $value = maybe_unserialize($option->option_value);
    107250                        $options_to_update[] = $option->option_name;
    108                         $class = 'all-options';
     251                        $class = 'all-options';                 
    109252                } else {
    110                         $value = 'SERIALIZED DATA';
     253                        $value = sprintf('SERIALIZED DATA (~ %s %s)', number_format(strlen($option->option_value)), __('Bytes') );                     
    111254                        $disabled = ' disabled="disabled"';
    112                         $class = 'all-options disabled';
    113                 }
    114         } else {
     255                        $class = 'all-options disabled';                       
     256                        $more  = true;
     257                }               
     258        } else {               
    115259                $value = $option->option_value;
    116                 $options_to_update[] = $option->option_name;
     260                $options_to_update[] = $option->option_name;           
    117261                $class = 'all-options';
    118262        }
    119         echo "
    120 <tr>
    121         <th scope='row'><label for='$option->option_name'>$option->option_name</label></th>
    122 <td>";
    123 
    124         if (strpos($value, "\n") !== false) echo "<textarea class='$class' name='$option->option_name' id='$option->option_name' cols='30' rows='5'>" . wp_specialchars($value) . "</textarea>";
    125         else echo "<input class='regular-text $class' type='text' name='$option->option_name' id='$option->option_name' value='" . attribute_escape($value) . "'$disabled />";
     263       
     264        $html_label = sprintf( '<label for="%1$s">%1$s</label>', $option->option_name );
     265        $html_input = '';
     266        if ( strpos($value, "\n") !== false ) {
     267                $html_input = sprintf('<textarea class="%s" name="%s" id="%s" cols="40" rows="10">%s</textarea>', $class, $option->option_name, $option->option_name, wp_specialchars($value));
     268        } else {
     269                $html_input = sprintf('<input class="regular-text %s" type="text" name="%s" id="%s" value="%s" %s />', $class, $option->option_name, $option->option_name, attribute_escape($value), $disabled);
     270        }
     271               
     272        /* more info on seriazlied data, add the expand button to gain access to serialoption */
     273        if ( $more ) {
     274                $html_href  = sprintf('options.php?action=serialoption&amp;option_name=%s', urlencode($option->option_name));
     275                $html_label = sprintf('<a href="%s" class="button">%s</a>',  $html_href, $option->option_name);
     276                // 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'));
     277        }
    126278
    127         echo "</td>
    128 </tr>";
    129 endforeach;
    130279?>
     280<tr>
     281        <th scope="row"><?php echo $html_label ?></th>
     282        <td><?php echo $html_input ?></td>
     283</tr>
     284<?php endforeach; ?>
    131285  </table>
    132286<?php $options_to_update = implode(',', $options_to_update); ?>
    133 <p class="submit"><input type="hidden" name="page_options" value="<?php echo $options_to_update; ?>" /><input type="submit" name="Update" value="<?php _e('Save Changes') ?>" class="button-primary" /></p>
     287<p class="submit"><input type="hidden" name="page_options" value="<?php echo htmlspecialchars($options_to_update); ?>" /><input type="submit" name="Update" value="<?php _e('Save Changes') ?>" class="button-primary" /></p>
    134288  </form>
    135289</div>
    136290