WordPress database error: [Duplicate entry '18739' for key 1]
INSERT INTO wp_bas_visitors (visit_ip, referer, osystem, useragent, lasthere) VALUES (644300605, 1, 339, 2514, '2008-08-28 20:47:43');

DataShaman

ExtJS ComboBox shows value instead of text

January 4th, 2008

While developing an app for a client, I came across a problem with ExtJS's form handling.

Let's say you have a form with a Ext.form.ComboBox on it.

When the form's load() function is called, it sets the values of the fields on the form to the data retrieved from the form's store.

Now, if your ComboBox is pulling its data from a standard lookup table, it will usually be setup as a value/text pair.

Problem is that the form displays the value, and not the text associated with that value.

I suspected that the ComboBox had not loaded its data before the form tried to fill in the field value.

This was confirmed by watching the XMLHTTPRequests in FireBug, and also by setting the valueNotFoundText config for the ComboBox to something arbitrary like 'Not found'.

True enough, when I loaded the page again, the ComboBox field displayed 'Not found', despite being loaded with a valid value.

Poring over the code and documentation showed no way of configuring the ComboBox to immediately load and associate itself with the data store.

So I've resorted to doing this instead:

JavaScript:
  1. var form = new Ext.form.FormPanel({
  2. ...
  3. listeners:{
  4.   actioncomplete:function(form, action) {
  5.     if(action.type=='load') {
  6.       form.items.each(function(item, index, length) {
  7.         if(item.xtype=='combo') {
  8.           item.doQuery(item.allQuery, true);
  9.           item.setValue(item.getValue());
  10.         }
  11.       }
  12.     }
  13.   }
  14. }
  15. ...
  16. });

Note that this will probably only work if you use xtype's to define your form fields. YMMV.

It's a bit of a kludge, but it works well enough for me, until I figure out how to do it another more convenient way.

Block Facebook Beacon with Privoxy

December 5th, 2007

Privoxy is a web proxy with advanced filtering capabilities for protecting privacy, modifying web page data, managing cookies, controlling access, and removing ads, banners, pop-ups and other obnoxious Internet junk.

I have set it up as a filter in front of a Squid cache to stop me exposing my surfing patterns to marketing types out there.

There's been a lot of noise recently about FaceBook's new Beacon system which broadcasts your browsing breadcrumbs to your friends.

Privoxy can easily be setup to prevent FaceBook from tracking where you go - that's what it does best!

Simply edit your /etc/privoxy/user.action file, and look for an uncommented line starting with { +block }. Right underneath that type the following:

.facebook.com/beacon

You can also edit your configuration in your browser. Scroll down to the section listing an action of +block, then click the Add button and enter the same string to block the URL.

This will prevent your browser from contacting any URL in the facebook.com domain where the folder starts with beacon.

Voila!

ExtJS 2.0: Great stuff, but where’s getDoc and getBody?

December 5th, 2007

ExtJS 2.0 was released yesterday, and it's a great improvement in design and speed from the previous version.

However, either I'm doing something really wrong or there are two fundamental functions missing, namely Ext.getDoc and Ext.getBody. Ext.fly also seems to be missing...

These functions are referenced throughout the ExtJS code, and they are not defined anywhere.

For others experiencing the same problem this should work:

JavaScript:
  1. Ext.getDoc = function() {
  2.   return Ext.get(document);
  3. };
  4.  
  5. Ext.getBody = function() {
  6.   return Ext.get(document.body);
  7. };
  8.  
  9. Ext.fly = Ext.get;

JSON data format for default JsonReader in ExtJS

December 4th, 2007

Most of the components in ExtJS use a JsonReader by default which, according to the documentation, should not require configuration to fill the component's item array. However, nowhere is it clearly documented what that JSON data format should be.

After much tinkering around in the ExtJS code, I discovered that the following JSON will work correctly with loading data into the Grid without having to identify the root or totalProperty attributes:

CODE:
  1. {
  2.    "0": {"id":"1","name":"Eris"},
  3.    "1": {"id":"2","name":"Flying Spaghetti Monster"},
  4.    "length":2,
  5.    "metaData":
  6.    {
  7.       "fields":["id","name"]
  8.    }
  9. }

So, it's an object mostly made up of an array of items, with a couple of other properties added to tell ExtJS what's there:

One property is length which stores the number of indexed items. The other is metaData, which has in turn a single property (that I've identified so far) called fields which has an array of field descriptors.

The field descriptors are in the same format as when defining a Record with Ext.data.Record.create(). In my case, names suffice, but you can also add in field types, directions to sort, etc. Refer to the Ext documentation at .../docs/output/Ext.data.Record.html#create for a more thorough treatment of the subject.

Using SSL client certificates with Nginx

November 28th, 2007

Nginx or Engine X has an ssl module which can also be used for verifying client certificates.

While the documentation for the module is quite good if you're a programmer, there is a disturbing lack of howto's and tutorials in this regard.

To verify that the client is using a certificate you've signed, you have to define the module option ssl_client_certificate to point to your CA certificate file, in PEM format, which is generated for you by the OpenSSL tools when setting up your CA.

I found Marcus Redivo's SSL Certificate HOWTO to be most useful while setting up my CA.

Then you must set ssl_verify_client to on, and ssl_verify_depth to 1. That last one got me, because even though it says in the documentation that it has a default of 1, if you do not explicitly set it in your config, it doesn't work. YMMV.

The next problem I faced was how to access the client certificate information from PHP. Finding this out took a while as well...

The ssl_module exposes a few variables, which get a bare mention at the bottom of the ssl_module's documentation page.

The one which was most useful for my purposes was this:

$ssl_client_s_dn returns line subject DN of client certificate for established SSL-connection

To get that variable to pass through to PHP via FastCGI, you must define it in your conf/fastcgi_params file, or anywhere in a block where you are using FastCGI, as follows:

fastcgi_param SSL_CLIENT_S_DN $ssl_client_s_dn

You can call the parameter anything you wish, but the $ssl_client_s_dn must remain the same.

Once you've restarted nginx, opened up a secure connection to a phpinfo() page, with an appropriate client certificate loaded in your browser, you should see something like the following variable defined in the $_SERVER array under $_SERVER['SSL_CLIENT_S_DN']:

CODE:
  1. /C=ZA/ST=Western Cape/L=Cape Town/O=Data Shaman/OU=Development/CN=Marlin Forbes/emailAddress=marlinf@example.org

Now PHP knows who the client is, and can use the emailAddress substring to match against a field in a database to work out role-based permissions.

If you ensure that the file permissions en route are all watertight, this should be a secure password-less authentication mechanism.

Enjoy!

10 line accordian script for jQuery (or less)

April 9th, 2007

Anyone who's used jQuery, knows that you can write less and do more with JavaScript.

Recently I wanted to use an accordian script to present a large amount of content on one page.

After looking at the options available, I decided that I could write something better. And smaller.

So here's my jQuery accordian script:

JAVASCRIPT:
  1. $.accordian = function(container) {
  2.     $(container).children().children('.title')
  3.         .hover(function() { $(this).css('cursor', 'pointer'); },
  4.                function() { $(this).css('cursor', 'default') })
  5.         .click(function() {
  6.             $(container).children().children('.content:visible').slideUp('fast');
  7.             $('.content:hidden', this.parentNode).slideDown('fast');
  8.             return false;
  9.         });
  10. };

Short, huh? ;) Now let's explain how it works. Because jQuery coding is so short, it pretty much reads like English.

When the mouse hovers a title, the cursor is changed to a pointer or hand, and when it moves away from the title, the cursor is changed back to the default shape.

When the title is clicked, any visible content in the whole accordian slides up fast, and any content which is hidden under the current block slides down fast.

HTML:
  1.     <head>
  2.         <script type="text/javascript" src="jquery.js"></script>
  3.         <script type="text/javascript" src="accordian.js"></script>
  4.         <script type="text/javascript">
  5.             $(document).ready(function() {
  6.                 // Initialize the accordian by telling it
  7.                 // which blocks hold the content
  8.                 $.accordian('#accordian> div');
  9.             });
  10.         </script>
  11.         <style>
  12.         .content {
  13.             display: none;
  14.         }
  15.         </style>
  16.     </head>
  17.     <body>
  18.         <div id="accordian">
  19.             <div>
  20.                 <div class="title">Section 1</div>
  21.                 <div class="content">Content for section 1</div>
  22.             </div>
  23.             <div>
  24.                 <div class="title">Section 2</div>
  25.                 <div class="content">Content for section 2</div>
  26.             </div>
  27.             <div>
  28.                 <div class="title">Section 3</div>
  29.                 <div class="content">Content for section 3</div>
  30.             </div>
  31.         </div>
  32.     </body>
  33. </html>

HTML:
  1. <script type="text/javascript" src="jquery.js"></script>

This loads the jQuery library script which you should have already. If not, download it from the jQuery site.

HTML:
  1. <script type="text/javascript" src="accordian.js"></script>

This pulls in the script above, which should be saved to accordian.js or whatever you prefer. Just remember to use the same filename on this line.

In the next script block, we're using jQuery's easy onLoad replacement, which guarantees that all elements in the document will be ready, when run. If you've used jQuery, you should be familiar with this construct. If not, then you should read the jQuery documentation.

JAVASCRIPT:
  1. // Initialize the accordian by telling it
  2. // which blocks hold the content
  3. $.accordian('#accordian');

The jQuery library uses (amongst other methods) CSS selectors to target elements for manipulation. Line 9 sets up the accordian by telling it which block should be turned into an accordian.

As you can see from the source file above, the accordian block must be formatted according to the following structure for it to work correctly:

HTML:
  1. <div id="someid">
  2.     <div>
  3.         <div class="title">Some Title</div>
  4.         <div class="content">
  5.             This is some content
  6.         </div>
  7.     </div>
  8.     <div>
  9.         <div class="title">Another title</div>
  10.         <div class="content">
  11.             This is further content
  12.         </div>
  13.     </div>
  14. </div>

Use can use any id for the accordian block, just ensure that you use the same id when initializing the accordian.

Without further ado, here's a demo of the accordian script in action.


Lorem ipsum
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Morbi varius dui vitae lorem. Aenean et leo vitae nisi pellentesque molestie. Integer viverra quam. Etiam at felis. Sed consectetuer mollis metus. Quisque suscipit neque aliquam mi. Fusce porta consequat nisi. Nullam lobortis ligula sit amet lectus. Proin orci. Nulla blandit, est vel facilisis pellentesque, quam nisl condimentum metus, in euismod libero metus sit amet magna.
Quisque vitae lacus
Quisque vitae lacus. Mauris justo nibh, venenatis quis, iaculis vitae, vulputate eget, ante. In hac habitasse platea dictumst. Maecenas vitae magna id erat luctus pretium. Aliquam convallis mauris consequat quam. Etiam tincidunt tristique dui. Morbi non dui luctus elit dignissim egestas. In vitae dui. Nunc at nisi. Nam condimentum risus eget felis. Aliquam vitae nibh. Proin rhoncus neque sed mauris. In hac habitasse platea dictumst. Curabitur ipsum.
Curabitur sollicitudin
Curabitur sollicitudin leo eget sem. Nunc vel metus imperdiet libero tincidunt condimentum. Duis placerat tempor justo. Fusce eget neque. Aliquam erat volutpat. Sed et risus. Nunc vitae dui. Etiam mollis magna et purus. Suspendisse justo risus, laoreet quis, scelerisque in, tempor a, purus. Nam massa odio, suscipit ac, aliquet id, luctus vitae, libero. Maecenas cursus leo nec arcu. Suspendisse tristique. Maecenas ac nisl. Nulla lobortis nisi vitae lacus.

Get URL Parameters in JavaScript

March 30th, 2007

I needed a JavaScript function which would give me access to the URL querystring, much like PHP's $_GET associative array. Unfortunately most of the solutions I found were either wrong, incomplete or badly written. IMHO. :)

So, being a programmer, I decided to knock up my own version of the script.

Many of the scripts I saw parsed through the querystring everytime a single query parameter was required, which is inefficient, especially if you're going to be using the same function repeatedly in the same context.

My script adds a property parameters to the window.location DOM object which is where this information should be stored, in my opinion.

It should only be run once to setup the associative array of query parameters, preferably when the document is completely loaded, but I don't think that's necessary since the location object should be ready right from the start.

I'm surprised that the DOM standard hasn't given us an easy way of accessing this information. Especially since the increasing use of Ajax means that more and more decisions are made in the browser rather than in server code.

PHP:
  1. /* Copyright (c) 2007 Marlin Forbes (http://www.datashaman.com)
  2. * Dual licensed under the MIT
  3. * (http://www.opensource.org/licenses/mit-license.php)
  4. * and GPL
  5. * (http://www.opensource.org/licenses/gpl-license.php) licenses.
  6. */
  7.  
  8. /* function setupParameters
  9. * Creates an object property window.location.parameters which
  10. * is an associative array of the URL querystring parameters used
  11. * when requesting the current document.
  12. * If the parameter is present but has no value, such as the parameter
  13. * flag in http://example.com/index.php?flag&id=blah, null is stored.
  14. */
  15. function setupParameters() {
  16.     var parameters = new Object();
  17.  
  18.     if(window.location.search) {
  19.         var paramArray = window.location.search.substr(1).split(‘&’);
  20.         var length = paramArray.length;
  21.  
  22.         for (var index = 0;index <length; index++ ) {
  23.             var param = paramArray[index].split(‘=’);
  24.             var name = param[0];
  25.             var value =
  26.                 typeof param[1] == “string”
  27.                 ? decodeURIComponent(param[1].replace(/\+/g, ‘ ‘))
  28.                 : null;
  29.             parameters[name] = value;
  30.         }
  31.     }
  32.     window.location.parameters = parameters;
  33. }

For a lazy loading getParameter function, you could do this:

PHP:
  1. function getParameter(name) {
  2.     if(typeof window.location.parameters == “undefined”)
  3.         setupParameters();
  4.     return window.location.parameters[name];
  5. }

The way it works is as follows:

  • All query parameters are decoded, so any entity references, %20 and + symbols are converted to their human versions
  • If a query parameter does not have a value such as the parameter flag in:

    http://example.com/page.php?flag

    then the window.location.parameter['flag'] will return null

  • If a query parameter is not defined, then it will follow the usual JavaScript convention and return undefined

I think this covers most situations. I'm not 100% certain that the regular expression replacement of all + signs with spaces is correct, there seems to be some ambiguity about what to do with + signs. None of the supplied native decode functions decode them to spaces. Let me know if you have any answers on that one.