WordPress.org

Make WordPress Core

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

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

Patch that enables infos and viewing of serialized values

  • wp-admin/options.php

    ### Eclipse Workspace Patch 1.0
    #P wordpress
     
    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                         
     112        $options = $wpdb->get_results(sprintf("SELECT * FROM %s WHERE option_name = '%s'", $wpdb->options, $option_name)); 
     113 
     114        // the serialoption page can handle only one value 
     115        if ( count($options) != 1)               
     116                wp_die(__('Cheatin&#8217; uh?')); 
     117         
     118        $option = $options[0]; 
     119 
     120        // $option must be stdclass to continue 
     121        if ( is_object($option) == false ) 
     122                wp_die(__('Cheatin&#8217; uh?')); 
     123         
     124        // not a serialized value? well, handeled in full options page already                   
     125        if ( !is_serialized($option->option_value) ) 
     126                wp_die(__('Cheatin&#8217; uh?')); 
     127 
     128        // this case is handeled in the full options page already as well 
     129        if ( is_serialized_string($option->option_value) ) 
     130                wp_die(__('Cheatin&#8217; uh?')); 
     131                 
     132        // unserialize: false on failure, notice will be given as well (usefull for the admin) 
     133        $unserialized = unserialize($option->option_value); 
     134         
     135        // serialized scalar makes not much sense right now      
     136        if ( is_scalar($unserialized) ) 
     137                wp_die(__('Cheatin&#8217; uh?')); 
     138                                 
     139        // array 
     140        // object - will fail/become '__PHP_Incomplete_Class_Name' if class is not defined 
     141                 
     142        $title = $type = 'UNDEFINED';    
     143         
     144        switch ( true ) { 
     145                case is_scalar($unserialized): 
     146                        $title = 'SCALAR'; 
     147                        $type  = 'SCALAR'; 
     148                        break; 
     149                                                 
     150                case is_object($unserialized): 
     151                        $title = sprintf('OBJECT (%s)', get_class($unserialized)); 
     152                        $type  = 'OBJECT'; 
     153                        break; 
     154                         
     155                case is_array($unserialized): 
     156                        $title = sprintf('ARRAY (%d Elements)', count($unserialized)); 
     157                        $type = 'ARRAY';                         
     158                        break; 
     159                         
     160                case gettype($unserialized) == 'object': 
     161                        // this is a fallback since sometime is_object did not make it. 
     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" %s />', $id, $id, htmlspecialchars($value), $disabled);  
     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&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