WordPress.org

Ready to get started?Download WordPress

Forums

[resolved] Trouble storing HTML entities into a serialized object (12 posts)

  1. Sayontan Sinha
    Member
    Posted 4 years ago #

    Some users of my theme (Suffusion) have been facing a weird problem. Here is the situation:
    1. I recently moved from storing each option of the theme as an individual row in the DB to storing a single array with all the options.
    2. For most people this works fine. But for some people when they try to save HTML entities for certain options, it wipes out the whole array. E.g. if they put in the "down arrow" symbol for configuring the footer, as ↓, it gets saved fine. When they re-save this page with the character showing as ↓, it corrupts the array that is stored as a serialized object.

    Is there a way to prevent this from happening?

  2. esmi
    Forum Moderator
    Posted 4 years ago #

    Sounds like there's an issue with your encoding and decoding of the input text. What steps are you taking when displaying the stored data?

  3. Sayontan Sinha
    Member
    Posted 4 years ago #

    I tried doing an "esc_attr" / "esc_html" while saving the options, but without any benefit. Mind you, this only happens with some people, not everyone.

  4. esmi
    Forum Moderator
    Posted 4 years ago #

    So perhaps some kind of server difference?

  5. Mark / t31os
    Moderator
    Posted 4 years ago #

    Could you provide the primary block of code that deals with inserting the code into the database, and also the code that retrieves it...

    At least that way, myself, esmi, or anyone else reading the thread can take the code and test it in an attempt to replicate the problem, right now anything said is speculation, or guess work...

    Can you also expand on this..

    it corrupts the array that is stored as a serialized object.

    Corrupts in what sense, it totally wipes it out? or garbles the data? etc..

  6. Sayontan Sinha
    Member
    Posted 4 years ago #

    Thanks. Here is the code I have that sets the options:

    if ( 'save' == $_REQUEST['formaction'] ) {
    			$form_category = $_REQUEST['formcategory'];
    			$filtered_options = get_options_for_category($options, $form_category);
    
    			foreach ($filtered_options as $value) {
    				if(isset($_REQUEST[$value['id']])) {
    					//update_option($value['id'], $_REQUEST[$value['id']]);
    					$suffusion_options[$value['id']] = esc_html($_REQUEST[$value['id']]);
    				}
    				else {
    					//delete_option( $value['id'] );
    					unset($suffusion_options[$value['id']]);
    				}
    			}
    			$filtered_spawned_options = get_spawned_options_for_category($options, $spawned_options, $form_category);
    			$parents = array();
    			foreach ($filtered_spawned_options as $value) {
    				$parent_children = $parents[$value['parent']];
    				if (!$parent_children) {
    					$parent_children = array();
    				}
    				if(isset($_REQUEST[$value['id']])) {
    					$parent_children[count($parent_children)] = substr($value['id'], strlen($value['parent']) + 1, strlen($value['id']) - strlen($value['parent']));
    				}
    				$parents[$value['parent']] = $parent_children;
    			}
    			foreach ($parents as $parent => $children) {
    				if (is_array($children)) {
    					$children_str = implode(',', $children);
    					//update_option($parent, $children_str);
    					$suffusion_options[$parent] = $children_str;
    				}
    				else {
    					//delete_option($parent);
    					unset($suffusion_options[$parent]);
    				}
    			}
    			update_option('suffusion_options', $suffusion_options);
    			header("Location: themes.php?page=functions.php&saved=true&category=$form_category");
    			die;
    		}

    In the above only the first "foreach" loop is relevant; the rest is for handling multi-select lists displayed as checkboxes. The call get_options_for_category is internal to the theme and it simply retrieves the options in a particular page in the theme settings.

    To display an option value within the admin pages here is what I use (for text fields):

    function create_section_for_text($value) {
    	global $suffusion_options;
    	create_opening_tag($value);
    	$text = "";
    	if (!isset($suffusion_options[$value['id']])) {
    		$text = $value['std'];
    	}
    	else {
    		$text = $suffusion_options[$value['id']];
    		$text = stripslashes($text);
    	}
    
    	echo '<input type="text" id="'.$value['id'].'" name="'.$value['id'].'" value="'.$text.'" />'."\n";
    	if ($value['hint'] != null) {
    		echo " &laquo; ".$value['hint']."<br />\n";
    	}
    	create_closing_tag();
    }

    I tried some debugging on this, like appending "&arr=".is_array($suffusion_options) to the header() call after passing a special HTML entity - that seems to indicate that $suffusion_options is an array before writing to the database. But when I try to do a print_r after the redirect, $suffusion_options is no longer an array.

    To retrieve $suffusion_options I use this call:
    $suffusion_options = get_option('suffusion_options');

    To create a variable out of each key in $suffusion_options I use the following call:

    global $options, $suffusion_options;
    foreach ($options as $value) {
        if (!isset($suffusion_options[$value['id']])) {
        	$$value['id'] = $value['std'];
        }
        else {
    		$$value['id'] = $suffusion_options[$value['id']];
        }
    }

    For testing I have tried this out on my local WAMP installation and my web host's LAMP installations - it works fine in both cases. But one of my users gave me access to his web host's lamp installation, where it breaks.

    @t31os_,
    By "corrupts" what I mean is that it probably garbles things. When I go to wp-admin/options.php I see "SERIALIZED DATA" against "suffusion_options", but when I run an is_array() call, I get the result that it is not an array.

    Thanks for any help you might be able to provide. This problem is driving me nuts.

  7. Mark / t31os
    Moderator
    Posted 4 years ago #

    Have you considered using the settings API to handle the theme options?

    What you have above reminds me of what alot of older theme's were using(i saw this alot when examining older themes), may i suggest taking a peek at some of the current popular themes and taking note of how they do it, one good example would be that of WooThemes (they provide free themes to - their news theme is one example, can't remember the name off the top of my head).

    Seems like you're working your own form of data submission and retrieval when there are functions in place in WordPress that make this process alot easier(and probably safer).

    I've always found this article best at explaining it(yes it can apply to themes to - so don't let what you read on this blog post mislead you).
    planetozh.com/blog/2009/05/handling-plugins-options-in-wordpress-28-with-register_setting/

    I've been using the settings api for themes and plugins i write(for personal use) and it's yet to suffer any such problems. All options are stored in one row of the db, as an array.

    Here's one example (it's a plugin but the appoach is pretty much the same).
    code.google.com/p/wp-dashboard-control/source/browse/trunk/dashboard-control/dashboard-control.php
    It's just to give you an idea of how you can use the settings API... which is generally the preferred and suggested method for theme and plugin authors.

  8. Sayontan Sinha
    Member
    Posted 4 years ago #

    Thanks a lot! I will take a look at this.

  9. Mark / t31os
    Moderator
    Posted 4 years ago #

    However if you storing lots of data, then there are reasons to store the options in their own table, and other approaches.

    I realise how the above may have appeared to suggest it's the preferred method "always", but that wouldn't necessarily be true, obviously if you're storing alot of data then it's perfectly acceptable to be storing that data in it's own table of the database, and writing your own methods on storing and retrieving.

    My main point was, that if you're going to utilise the options table for storing options, then the settings API exists to help facilitate that task.

  10. Sayontan Sinha
    Member
    Posted 4 years ago #

    @t31os_,

    However if you storing lots of data, then there are reasons to store the options in their own table, and other approaches.

    I would have agreed with you if this was a plugin, but I am not sure if a theme on WordPress.org will get accepted if it changes table structures / adds new tables. I believe there are some differences in the acceptance criteria for themes and plugins here.

    In any case, for this particular issue I have simply suggested to the users to not use special characters like ↓ which were causing issues. Moving to the Settings API will take me at least a few days.

    Thanks,
    Sayontan.

  11. Mark / t31os
    Moderator
    Posted 4 years ago #

    I just went and tested the ↓ character in some plugin options, to see if there was any problem saving or retrieving.

    The data saves fine, and also is rendered correctly on retrieval to..

    Options used were registered using the settings api, which are serialized, and i've not been able to replicate the problem.

    I tried a variation of entities/symbols to test, down arrow, right arrow, etc (amongst others).. just to mix it up a little..

    http://www.w3schools.com/tags/ref_entities.asp
    http://www.w3schools.com/tags/ref_symbols.asp

    All data is saving just fine for me.... perhaps the issue is with the database character set / encoding, might be something you could check with the users that experience issues (just as a wild guess).

    Just wanted to let you know i tested some characters in an effort to try and reproduce the issue, but was unsuccessful.

  12. Sayontan Sinha
    Member
    Posted 4 years ago #

    @t31os_,
    Thanks for your efforts to help me - I really appreciate it!

    Yes, I did infer that this problem had something to do with the database character encoding, because just about 4-5 users at my end have reported it - the rest seem to be having no problems. Also, it just seems to happen for ↑ and ↓. Things like ©, «, » etc seem to work perfectly.

    I am marking this as resolved for now, because it seems to be more of a MySQL problem rather than a WP problem.

    Thanks again.

Topic Closed

This topic has been closed to new replies.

About this Topic

Tags