Save multiple values in one database config field

Discussion corner for Developers of Serendipity.
Post Reply
SHRIKEE
Regular
Posts: 128
Joined: Tue Feb 21, 2006 2:49 am
Location: Netherlands
Contact:

Save multiple values in one database config field

Post by SHRIKEE »

Hi there,

Im working on a new thingy for usergallery but need to save 34 values into one database config field.

Insane you might say but i have reason.
1. The package i use is coded to have one long strong saved into a single field. So if i create 34 option fields i would have to rewrite SO much code, bleh.
2. Plus i dont want to poison the config table with 34 entries which are nearly never gonna be changed. So for efficiency its best to keep it in one field i think.
3. If for every image clicked over 34 options need to be loaded and checked and reviewed and if positive applied. it would be a slow process.

the string to be saved looks like this

Code: Select all

optionname-yes,optionname2-yes,optionname3-no etc.
optionname obviously is the option name, and yes or no is whether to show the option (exif tag) or not.

Currently i have all the options a textarea but a radio set is more easy to config for the illiterate user.

So if anyone knows a way to save 34 radiobox or checkbox options into 1 value plz help me out :)
My kingdom For i am king of my heap of trash

Developing code on:
Workstation: Windows 2000 sp4, TSW webcoder 2005
Server: fedora core 4 amd64, apache 2.0.54, php 5.0.4, mysql 4.1.11.
garvinhicking
Core Developer
Posts: 30022
Joined: Tue Sep 16, 2003 9:45 pm
Location: Cologne, Germany
Contact:

Re: Save multiple values in one database config field

Post by garvinhicking »

You could use the serialize() function to serialize an array into one string value, which you can unserialize when using, and serialize before saving.

You can implement the method "set_config" from the plugin API in your specific plugin, that takes care of serializing the string before saving it to the DB.

Look at the serendipity_plugin_adduser.php (or serendipity_event_xsstrust or serendipity_event_includeentry) plugin, it uses the set_config method to implode/explode certain values. Imploding is like serializing, but not so specific. You could replace it with serializing; or maybe imploding/exploding is already sufficient for you.
# Garvin Hicking (s9y Developer)
# Did I help you? Consider making me happy: http://wishes.garv.in/
# or use my PayPal account "paypal {at} supergarv (dot) de"
# My "other" hobby: http://flickr.garv.in/
SHRIKEE
Regular
Posts: 128
Joined: Tue Feb 21, 2006 2:49 am
Location: Netherlands
Contact:

Post by SHRIKEE »

Hi garvin,


In the original code is this snippet used to read and output/parse the string:

Code: Select all

// If any exif tags that are available.
$filepath = $serendipity['serendipityPath'] . $serendipity['uploadHTTPPath'] . $file['path'];
$exif_data = $this->getExifTags($filepath, $file['name'], $file['extension']); 
			  		
$exifsettings_one = $this->get_config('exif_data');
// Create array of exif display settings for main information table.
$exif_arr = explode(',', $exifsettings_one);
foreach ($exif_arr as $key => $value) {
	$display = explode('-', $exif_arr[$key]);
	$exif_display_one[$display[0]] = $display[1];
}
					
$data_written = false;
$exif_output = '<strong>Additional Information</strong><br />';
foreach ($exif_data as $tag => $value) {
	if ($value != 'Unknown' && $exif_display_one[$tag] == 'yes') {
		$data_written = true;
		$exif_output .= $tag.': '.$value.'<br />';			
	}
}
if (!$data_written) {
	$exif_output .= '<strong>No additional data available.</strong>';
}

Ive found this in the adduser plugin:

Code: Select all

    function set_config($name, $value)
    {
        $fname = $this->instance . '/' . $name;

        if (is_array($value)) {
            $dbval = implode(',', $value);
        } else {
            $dbval = $value;
        }

        $_POST['serendipity']['plugin'][$name] = $dbval;

        return serendipity_set_config_var($fname, $dbval);
    }
But i cant make anything out of it :( how do i use it?
Is the function automatically used? or where is it called? And how should a radio button look like when the function is to gather its data?
My kingdom For i am king of my heap of trash

Developing code on:
Workstation: Windows 2000 sp4, TSW webcoder 2005
Server: fedora core 4 amd64, apache 2.0.54, php 5.0.4, mysql 4.1.11.
garvinhicking
Core Developer
Posts: 30022
Joined: Tue Sep 16, 2003 9:45 pm
Location: Cologne, Germany
Contact:

Post by garvinhicking »

Sorry, I can't help you right now. Maybe you can just play with it.

set_config is called when in plugin configuration you save an item in the config. set_config is called then for each configuration key/Value.

maybe just make som etest with plugin mentions above
# Garvin Hicking (s9y Developer)
# Did I help you? Consider making me happy: http://wishes.garv.in/
# or use my PayPal account "paypal {at} supergarv (dot) de"
# My "other" hobby: http://flickr.garv.in/
SHRIKEE
Regular
Posts: 128
Joined: Tue Feb 21, 2006 2:49 am
Location: Netherlands
Contact:

Post by SHRIKEE »

right, thats ok. one last question.

so the set_config is called on each value in the settings screen. right?
then it parses data (if any) and continues to save it in the database?

Ill let that float around in my head and work out something later tonight or tomorrow.

Im not to easy on 'just trying it' as i seem to crash alot of databases lately :S dunno why. just happens. so before i do anything stupid i try to find out how it works.

If only i know how the function works / is used i can work it out. Otherwise its a bit dificult.
My kingdom For i am king of my heap of trash

Developing code on:
Workstation: Windows 2000 sp4, TSW webcoder 2005
Server: fedora core 4 amd64, apache 2.0.54, php 5.0.4, mysql 4.1.11.
mgroeninger
Regular
Posts: 546
Joined: Mon Dec 20, 2004 11:57 pm
Contact:

Post by mgroeninger »

I would actually try to make this simpler if it is possible...

The settings in $this->get_config('exif_data') must be known field, right? Or you will have to build mappings no matter what exif data exists, right?

If this is the case you could just use a text box and a comma separated list (like the spam plugin does for a couple of options) and document the options some place...

Then you can have a toggle to either show those fields and nothing else, or show all the fields except those listed.

And that way you don't have to rewrite set_config...
garvinhicking
Core Developer
Posts: 30022
Joined: Tue Sep 16, 2003 9:45 pm
Location: Cologne, Germany
Contact:

Post by garvinhicking »

Hi!

I'm really sorry, if I weren't ill, I'd try to explain it more in depth.

In include/admin/plugins.inc.php is the routine that saves each setting for the plugin config:

Code: Select all

        $save_errors = array();
        foreach ($config_names as $config_item) {
            $cbag = new serendipity_property_bag;
            if ($plugin->introspect_config_item($config_item, $cbag)) {
                $value    = $_POST['serendipity']['plugin'][$config_item];

                $validate = $plugin->validate($config_item, $cbag, $value);

                if ($validate === true) {
//                    echo $config_item . " validated: $validate<br />\n";
                    $plugin->set_config($config_item, $value);
                } else {
                    $save_errors[] = $validate;
                }
            }
        }
As you can see, the set_config() method of each plugin is called there. You can look inside the include/plugin_api.inc.php for how that set_config() method saves by default. Compare that to the example of the plugins I mentioned and then you see how they make a difference...

Also the introspect_config_item() function indicates how each option is shown in the plugon config...

Hope that helps,
Garvin
# Garvin Hicking (s9y Developer)
# Did I help you? Consider making me happy: http://wishes.garv.in/
# or use my PayPal account "paypal {at} supergarv (dot) de"
# My "other" hobby: http://flickr.garv.in/
SHRIKEE
Regular
Posts: 128
Joined: Tue Feb 21, 2006 2:49 am
Location: Netherlands
Contact:

Post by SHRIKEE »

Ill look into that. THanks for the tip
My kingdom For i am king of my heap of trash

Developing code on:
Workstation: Windows 2000 sp4, TSW webcoder 2005
Server: fedora core 4 amd64, apache 2.0.54, php 5.0.4, mysql 4.1.11.
judebert
Regular
Posts: 2478
Joined: Sat Oct 15, 2005 6:57 am
Location: Orlando, FL
Contact:

Post by judebert »

You can also check out the newsbox plugin for another example. It takes multiple values from a single string in the database, and converts it into multiple selected items for a category selector. What (I think) you want is virtually the same thing, but you're storing the variable names with their values.

You could use serialize(), but your code is already set up for explode()/implode(). The documentation on php.net makes those pretty easy to understand. The Serendipity pieces you're missing are:

1) When your plugin gets called in introspect_config_item(), you'll need to add something like :

Code: Select all

            case 'exif_data':
                $propbag->add('type',    'content');
                $propbag->add('default', $this->makeExifSelector());
                // Name and description aren't used for type 'content'.
                break;
This lets you make your own form inputs for the variable, instead of using the default Serendipity variables. You said you wanted to make radio buttons instead of a text area. Do it in makeExifSelector().

2) You'll assign some form variable, like $serendipity['POST']['plugin']['exif_data'][], to hold your values. In the makeExifSelector() function, check to see if this variable is set. If so, do the implode() and save the value with set_config(). Otherwise, use get_config() and explode() to make radio buttons with the current settings. You see, after they hit "save", Serendipity will return them to the config screen and do the introspection again. That gives you the chance to save your custom values during introspection. The problem is that the user will already have seen the "values saved" message. Oh well.

Hope that helps. And Garvin, I hope you feel better soon. It sounds similar to what I've had recently; you should be on your feet again in 7 days. With proper medical attention, it could take as little as a week. :wink:
Judebert
---
Website | Wishlist | PayPal
SHRIKEE
Regular
Posts: 128
Joined: Tue Feb 21, 2006 2:49 am
Location: Netherlands
Contact:

Post by SHRIKEE »

Judebert that is a very good idea. Currently im trying to work it out i think i almost got it :) just need it to parse correctly and save it.

Thanks for the tip!
My kingdom For i am king of my heap of trash

Developing code on:
Workstation: Windows 2000 sp4, TSW webcoder 2005
Server: fedora core 4 amd64, apache 2.0.54, php 5.0.4, mysql 4.1.11.
SHRIKEE
Regular
Posts: 128
Joined: Tue Feb 21, 2006 2:49 am
Location: Netherlands
Contact:

Post by SHRIKEE »

ok im clearly missing something here and im little stuck again....

Code: Select all

	
foreach($serendipity['POST']['plugin']['exifdata'] as $key => $value) {
     $exif_array[$key] = $key;
}
            
$newexifstring = implode(',', array_keys($exif_array));
$this->set_config('exif_data', $newexifstring);
That is what i come up with... It doesnt work, and i understand why. But i cannot think of something on how to solve it. Nor can i find a function or way on php.net.

The result of this code is (this gets into the database):
Camera Make,Camera Model,Orientation,Resolution Unit,X Resolution,Y Resolution,Date and Time,YCbCr Positioning,Exposure Time,Aperture,Exposure Program,ISO,Exif Version,Date (Original),Date (Digitized),APEX Exposure Bias,APEX Max Aperture,Metering Mode,Light Source,Flash,FocalLength,User Comment,FlashPix Version,Colour Space,Pixel X Dimension,Pixel Y Dimension,File Source,Special Processing,Exposure Mode,White Balance,Digital Zoom Ratio,Scene Capture Type,Gain Control,Contrast,Saturation,Sharpness,Components Config
As you can see it has a bunch of text, which is good. But the value (option) is not attached to it. It should look some thing like this:
Camera Make-yes,Camera Model-yes,Orientation-yes,Resolution Unit-yes,X Resolution-yes,Y Resolution-yes,Date and Time-yes,YCbCr Positioning-yes,Exposure Time-no,Aperture-yes,Exposure Program-yes,ISO-yes,Exif Version-yes,Date (Original)-yes,Date (Digitized)-yes,APEX Exposure Bias-yes,APEX Max Aperture-yes,Metering Mode-yes,Light Source-yes,Flash-yes,FocalLength-yes,User Comment-yes,FlashPix Version-yes,Colour Space-yes,Pixel X Dimension-yes,Pixel Y Dimension-yes,File Source-yes,Special Processing-yes,Exposure Mode-yes,White Balance-yes,Digital Zoom Ratio-yes,Scene Capture Type-yes,Gain Control-yes,Contrast-yes,Saturation-yes,Sharpness-yes,Components Config-yes
-yes and -no being values (options).

What i want to do is:

this is a array: $serendipity['POST']['plugin']['exifdata']
The key and value of this array should be combined and saved in the database. Making it look like:
Camera Make-yes,Camera Model-yes,Orientation-yes,Resolution Unit-yes,X Resolution-yes,Y Resolution-yes,Date and Time-yes,YCbCr Positioning-yes,Exposure Time-no,Aperture-yes,Exposure Program-yes, etc...
I think the line in the foreach should look like something liike this:

Code: Select all

     $exif_array[] = $key.'-'.$value;
but that gets me nothing... empty string...

i tried creating 2 arrays and use array_combine but that ended up in a empty string somehow and i tried several other things but none works. Im sure its something simple... but i cant think of anything so plz help me out :)

Thanks!
My kingdom For i am king of my heap of trash

Developing code on:
Workstation: Windows 2000 sp4, TSW webcoder 2005
Server: fedora core 4 amd64, apache 2.0.54, php 5.0.4, mysql 4.1.11.
SHRIKEE
Regular
Posts: 128
Joined: Tue Feb 21, 2006 2:49 am
Location: Netherlands
Contact:

Post by SHRIKEE »

and indeed i missed something

*sigh*

Code: Select all

			foreach($serendipity['POST']['plugin']['exifdata'] as $key => $value) {
                $exif_array[$key] = $key.'-'.$value;
            }
            
            $newexifstring = implode(',', array_values($exif_array));
        	$this->set_config('exif_data', $newexifstring);
this kinda works :) the data is saved properly.
My kingdom For i am king of my heap of trash

Developing code on:
Workstation: Windows 2000 sp4, TSW webcoder 2005
Server: fedora core 4 amd64, apache 2.0.54, php 5.0.4, mysql 4.1.11.
judebert
Regular
Posts: 2478
Joined: Sat Oct 15, 2005 6:57 am
Location: Orlando, FL
Contact:

Post by judebert »

Judebert as LAUNCELOT rushes into the room

Oh, fair one, behold your humble servant, Sir Launcelot, from the
Court of Camelot. I have come to take you ... (he looks up for the
first time and his voice trails away) away ... I'm terribly sorry ...
Judebert
---
Website | Wishlist | PayPal
SHRIKEE
Regular
Posts: 128
Joined: Tue Feb 21, 2006 2:49 am
Location: Netherlands
Contact:

Post by SHRIKEE »

eh.. lol?

^^
My kingdom For i am king of my heap of trash

Developing code on:
Workstation: Windows 2000 sp4, TSW webcoder 2005
Server: fedora core 4 amd64, apache 2.0.54, php 5.0.4, mysql 4.1.11.
judebert
Regular
Posts: 2478
Joined: Sat Oct 15, 2005 6:57 am
Location: Orlando, FL
Contact:

Post by judebert »

Sorry. It's a Monty Python and the Quest for the Holy Grail reference.

Basically, I knew your problem, I knew how to fix it, and by the time I got there, it was entirely moot.
Judebert
---
Website | Wishlist | PayPal
Post Reply