soo_txp_obj Page 4 of 6 « »
Tutorial: a simple soo_txp_obj plugin
Summary:
Not a real plugin, but an incredible simu…
Here’s a little example of the soo_txp_obj library in action. Years ago, before I knew anything about PHP, for my own use I hacked a useful little plugin called mem_randimg, a random image selector. (I hacked it because I wanted width="100%"
instead of the usual height
and width
attributes in the img
tag; that’s another story.) So, with all due respect to the original by mem, which has served me well for years, here is a soo_txp_obj rewrite.
First, the original (my slightly hacked version):
1 : function soo_original_random_image($atts) {
2 :
3 : global $img_dir;
4 :
5 : extract(lAtts(array(
6 : 'category' => '',
7 : 'thumbnail' => 0,
8 : ), $atts));
9 :
10 : $use_thumbnail = $thumbnail;
11 : $where = '';
12 :
13 : if ($category) $where .= "`category` IN ('" .
14 : implode("','",explode(',',doSlash($category))) . "')";
15 :
16 : if ($thumbnail) $where .= ($category ? ' AND ' : '') . '`thumbnail` > 0';
17 :
18 : $qparts = array(
19 : (isset($where)) ? $where : '1',
20 : "ORDER BY rand()"
21 : );
22 :
23 : $rs = safe_row("*","txp_image",join(' ',$qparts));
24 :
25 : if ($rs) {
26 : extract($rs);
27 : $img_url = hu.$img_dir.'/'.$id.($use_thumbnail?'t':'').$ext;
28 : return '<img src="'.$img_url.'" alt="'.$alt.'" width="100%" />';
29 : }
30 :
31 : return false;
32 : }
What’s it do? Build and send this SQL query: SELECT * from `txp_image` WHERE 1 ORDER BY rand()
(with optional clauses depending on whether or not the tag attributes are set), then produce an img
tag from the resulting data record.
Here’s a rewrite based on soo_txp_obj:
1 : function soo_new_and_improved_random_image($atts) {
2 :
3 : extract(lAtts(array(
4 : 'category' => '',
5 : 'thumbnail' => 0,
6 : ), $atts));
7 :
8 : $query = new soo_txp_select('txp_image');
9 :
10 : if ($category) $query->in('category', $category);
11 :
12 : if ($thumbnail) $query->where('thumbnail', 0, '>');
13 :
14 : $query->order_by('rand()')->limit(1);
15 :
16 : if ( ! $query->count() ) return false;
17 :
18 : $image = new soo_html_img(new soo_txp_img($query), $thumbnail);
19 :
20 : return $image->set_width('100%')
21 : ->set_height('')
22 : ->tag();
23 : }
So, some observations:
- It’s not massively shorter, but it’s altogether lighter. Not quite as many lines, and the lines tend to be shorter. Overall the code is just less fussy. None of that string concatenation intermixed with PHP ternary operators.
- The new version adds the image caption as the
title
attribute, as well as thealt
attribute. This happens behind the scenes, so you don’t see it in the code. I had to setheight
to empty because that was set automatically too, when I created the new soo_html_img object from the data object. - Just a lot less conditional logic. The * soo_txp_query* classes know how many
WHERE
expressions there are and construct theWHERE
clause appropriately. I don’t have to worry about whether or not to stick anAND
between expressions. - I don’t need to declare the global
$img_dir
because soo_html_img figures out thesrc
value on instantiation. I don’t need to declare a$use_thumbnail
variable to protect the$thumbnail
attribute, because I’m notextract()
ing the data record. And so on.
I emphasize, I am not picking on the original. It does the job. For a short plugin like this it makes little difference whether the code is elegant or otherwise. It’s when you’re dealing with more demanding logic that these little differences mean more than just less typing — the whole process becomes more about the logic and less about the details of constructing a query or building a tag. It can make the difference between finishing the plugin or abandoning it in frustration.
Posted 2009-02-03 (last modified 2010-06-30)