Customizing Theme Based on IP Address[Permalink]This article deals with the following topics:
Last week I set up a site that needed to have slightly different behavior depending on the IP address of the remote user. E.g. If a user is connecting from an IP address between 192.168.0.0 to 192.168.0.255 we would use a different theme than if they were connecting from a different block. In addition to different themes, we also to use different types of authentication depending on which IP block the user is visiting from. This requirement is actually common for systems that are syndicated by different organizations and should behave slightly differently depending on which organization the user belongs to (assuming they are connecting from that organization's network). To implement this behavior we need to solve one issue. How do we store a range of IP addresses in the database so that they can be queried easily to match if the user's IP address falls in that range. It turns out that this is quite easy to do, since IP addresses are actually just a 4 digit number (base 256). So we can easily convert this number to base 10 and store it as a regular unsigned integer in the database. In addition, both PHP and MySQL provide functions to convert from an IP address to an integer and back. The PHP functions are called long2ip and ip2long respectively. So we have stored a start IP address and an end IP address as integers, we could simply query the database to see if a given IP address falls in that range as follows:
It is important to note that you need to use the sprintf() function for converting $intIP into a string because PHP will convert it to an integer which could overflow if you leave it to do a default conversion. For the above query, we assuming a table with a definition like:
Now if we attach some information to the IP block, like the theme that should be used, we can check the user IP address against the available IP blocks at the beginning of each request to set the theme for that request. We will use the beforeHandleRequest method of the Application Delegate Class to house this because it allows us to set things like the theme or change the user's action. e.g.
The above snippet makes use of the df_register_skin? method that registers a theme to be used dynamically. The first parameter is the theme name, and the second parameter is the path to the theme. This code works great if we already have IP addresses stored properly as integers in our database, but how do we make it so users can work with the IP addresses as IP addresses and not integers? We need to be able to transform from integer to IP address to display in the edit record form, and then convert the resulting IP address back to an integer for storage in the database. Xataface provides two delegate class methods precisely for this purpose:
So, in our delegate class we would have:
The field__pullValue and field__pushValue method should be inverses of each other. Note that support for field__pullValue and field__pushValue are supported by Xataface since version 0.6, however support for them with the grid widget was not added until Xataface version 1.3. Now, on the edit form, users can enter and edit IP addresses in the normal format, but they will be converted to unsigned integers for storage in the database. There is only one thing remaining, though. In the list view still shows the integer version of the IP addresses. We want them to show them as regular IP addresses. So we add field__display? methods to our delegate class:
Referencesblog comments powered by Disqus |