If you have an options page (which should be inside one form), then all data is sent from that form, regardless of whether or not the option has been changed.
The array received for validation is the data received from (your part of) the form. If the data is ’empty’ it is because the data wasn’t sent. Normally this would be because the user has deliberately not sent any data (i.e. emptied a text-area).
If you are trying to store options from different pages in one array then you are going to need to determine if blank data actually was deliberate or instead because wasn’t sent because it wasn’t on the page that has been submited.
Handling expected data only
Really what you need to determine is what data are you expecting to receive? In your case this will depend on what page you are submitting data from:
//The 'ids' of data that is expected on the respective page
$page1_options = array('textarea_on_page_1','checkbox_1','another_textarea_1');
$page2_options = array('someinput_2','another_textarea');
//An array of arrays of option names the plugin accepts:
$expected =array('page1'=>$page1_options,'page2'=>$page2_options);
Then if submitting data from page 1, the data we expect to receive is $expected['page1']
.
So we only validate those options and filter everything else out so that we end up with $valid_input
which contains all and only the keys listed $page1_options
. Then we take the current options, merge them with this new valid input to get the new settings array:
$option_array = get_option('XX_theme_settings');
$option_array = array_merge($option_array,$valid_input);
//Return this $option_array to be saved to database
Determining the page
To determine what page is being sent, on each page add another ‘option’ which is in fact hidden input with value set to the page ID I referred to above (e.g. 'page1'
). This will be sent with the options.
A better way
A more straightforward way would to have the settings for each page saved as a separate row in the database (so you have X (arrays of) options for X pages).