Wordpress 2.6: register_activation_hook Cannot See Global Variables

Posted on September 3rd, 2008 in ALM, Programming, Wordpress by mcnicholl

I have recently been trying to update an old plugin I created for Wordpress 2.3.2 so that it would be compatible with the latest version : 2.6.

I am currently having an issue where the register_activation_hook function (and this may not be limited to this one function) where it refuses to reference the global variables that I define in the plugin.

Take the below as an example (proper code attached at the bottom):

require ‘mcn_constants.php’;

$mcn_test_blabla    =   “Well ??????”;

register_activation_hook(__FILE__,’mcn_test_install’);
register_deactivation_hook(__FILE__, ‘mcn_test_uninstall’ ) ;

add_action(’parse_query’, ‘mcn_test_check’);

function mcn_test_install() {
    global $this_is_broke, $mcn_test_blabla;

    add_option(”mcn_test_value”, “The value is: $this_is_broke And :: $mcn_test_blabla “);
}

function mcn_test_uninstall() {
    delete_option(”mcn_test_value”);
}

function mcn_test_check() {
    global $this_is_broke;

    echo get_option(”mcn_test_value”);
    echo “Proper value : $this_is_broke”;
}

When you load the front page of your blog with the above plugin code activated you should see :

The value is: YES I AM BROKE!!!!!
And ::Well ??????

Proper value : YES I AM BROKE!!!!!

… but instead you see:

The value is:
And ::

Proper value : YES I AM BROKE!!!!!

As you can see - the $this_is_broke and $mcn_test_blabla variables are not being set in the Option “mcn_test_value”.

Yet calling the global variable in the function “mcn_test_check”, which is called as part of the “parse query” action, will show the global variable - as it should.

So - is this a bug or am I missing something fundamentally different in Wordpress 2.6? Using global variables in Wordpress 2.3.2 worked just fine.

I have attached a sample plugin that will replicate this issue.

Any ideas?

mcn_test.rar

Symfony Session Timeout Annoyance…

Posted on April 25th, 2008 in Programming, symfony by mcnicholl

I have recently found that symfony doesn’t attempt to properly maintain the user’s session after logout.

This is a tad annoying as any attributes that have been set during a valid login session will still be set when the user is communicating with the server. It is also a security risk.

Symfony provides the basic building blocks for creating an application, and session management is a part of that. The myUser class contains paramter, attribute, credentials classes as well as some variables like culture (for internationalisation), authenticated and timedout.

The ‘authenticated’ variable’s use should be pretty obvious - when the application is processing the users login it should set the authenticated variable to ‘true’ :

$this->getUser()->setAuthenticated(true);

The ‘timedout’ variable is set automatically be symfony when … alas … the users session has expired/timed out - pretty self explanatory.

The problem comes when your application sets any parameters or attributes during the sessions lifetime. For example, in my application when the user logs in I set a session variable ‘nickname’ so that I can reference/identify the user during any subsequent requests :

$this->getUser()->setAttribute('nickname', $user->getNickname());

This is pretty basic and normal functionality.

This attribute should die along with the session, when it times out - but it doesn’t. There are some perfectly valid reasons why this happens e.g The ‘Validated User’ and the ‘Browsing User’ are two different things to the system but the contents of the shopping cart are not. Another example would be website tracking software. It monitors where users are and what they are looking at - a very good tool for marketing. This type of software doesn’t have to care whether the user is logged in order not as its only concern is where they are and what they are doing. This information needs session data to follow the user. If all session data were cleared after the user logged out - then the monitoring software would be thinking a new user arrived - which would be wrong.

What is needed in this situation is a trigger or a test that determines if the session has expired and if it has - then action something appropriately.

The only way that I have determined to do this is by editing the myUser.class.php file for the application (and every other application) in your project.

As the myUser class is instantiated before any actions we can alter/clean up the session before any proper processing is done :

class myUser extends sfBasicSecurityUser
{
  public function initialize($context, $parameters = array()) {
    parent::initialize($context, $parameters = array());
    if($this->isTimedOut()) {
      $this->getAttributeHolder()->remove('nickname');
    }
  }
}

If you don’t like the idea of having to do this for all your applications - then you can create a new class and make the myUser class extend it instead (you must ensure that the new class also extends sfBasicSecurityUser. That way you have one central place to update when you need to clean up your session.

Hope this helps…

If you have any better ways of doing this - please let me know. I’d be interested to hear your take on it.

Wordpress Plugin Annoyances

Posted on February 7th, 2008 in Programming, Website by mcnicholl

Creating a plugin for wordpress can be an extremely simple task, or altogether annoying.

I’ve recently been creating a plugin for “Featured” content on a new site that I’m pushing at the moment. Basically the plugin works like this :

  • Featured Posts belong to the “Featured” Category
  • Featured content can be controlled by the plugin menu in the Wordpress Admin screen (updated by Editor or Administrator)
    • This is important as you dont want to have to sift through a list of 1000 posts to see which are marked as Featured or not - Even with the filter active this can be annoying
  • The Featured content can only be “Featured” if it is part of another category.
    • i.e Lets say the purpose was for books (Fiction and Non-Fiction). The Featured section might only cater for Fiction books. So the posts would be in Featured and Fiction categories. Simple.
  • The admin area can state the total amount of Featured posts.

The plugin then provides functions to the template to output the featured content.

One issue I had was using query_posts to select the posts that were not featured but in the chosen category (Fiction). The plugin function :
query_posts('category_name=Fiction&category_name=-Featured')
…just wouldnt work. I tried many variations of the query_post command along with category_name only to discover that wordpress does not facilitate anything more than basic requirements when using category_name. So, I retreat to using ‘cat’ instead. Boo! Now I have to query the database to get the ids of the categories I want to query on first. Not exactly efficient. Not to mention using more memory with additional variables to accommodate this etc.

Any other annoyances that you have encountered?

Programmatical Database Optimisation…

Posted on December 5th, 2007 in ALM, Programming by mcnicholl

The application that I am programming at the moment dictates that an object can have many participants. For improved usability the owner of the object needs to be able to add and remove participants en massé.

Creating this functionality is simple but ensuring that it is done efficiently requires some further thought.

A = List of Users who currently have access to the object

B = List of Users that should have access to the object after updating

B can contain none, some or all of A.

Method 1

The easiest thing to do when updating the list of participants is to delete all current participants (A) and grant access to all new participants (B). In doing this we would be executing two, possibly bulky, of an RDBMS’s most time intensive SQL statements :

  1. DELETE FROM X WHERE Y in (A,B,C) and D=E
  2. INSERT INTO X VALUES (A, B, C)

Method 2
Another method of setting the new participants would be to only update what has changed in the list. Doing this incurs an additional SELECT statement in order to determine what needs to be added and removed :

  1. SELECT * FROM X WHERE Y=Z
  2. DELETE FROM X WHERE Y in (A,B,C)
  3. INSERT INTO X VALUES (A, B, C)

The question now is :

Which method is the most database efficient?

Method 1 gets the job done in two SQL statements but method 2 can possibly reduce the number of inserts and deletes necessary while at the same time adding an additional SELECT statement.

To emphasize this issue further - consider the following :

In my application an object (A) can contain child-objects (B). Each child-object can have an individual list of participants - this list is a subset of those participants in the parent object.

If a user is removed from the participant list of the parent - he/she should no longer be a participant in any of its child objects - and hence should be removed.

In doing this the same situation arises above :

Is it best to do a blanket DELETE statement across the participants table for the parent object and each of its child objects for the user ID?

OR

Execute a SELECT statement to find the list of objects and child objects that the user has access to and then DELETE as necessary?

Which method in these scenarios is the most efficient?

Any thoughts?

Answers on a postcard….

sfGuard and Implementing Security in Symfony…

Posted on November 11th, 2007 in ALM, Programming, Requirements by mcnicholl

Creating web-based applications using Symfony is extremely simple. This is something I stated last month in my post Symfony : Who Needs a Development Team?

Over the last 2 months I have created all modules that enable alpha release level functionality and at the moment I am attempting to secure the system.

This is where the true mental arithmetic begins. Creating the modules and UI for them in Smyfony is easy. Securing them is a different matter altogether. Security is one of the most difficult aspects of the appliciation to design. Getting it wrong can result  in major issues.

Luckily, Symfony has an active community that will help as and where they can - which is great when learning how to get the best out of a framework. This same community has provided many plugins for a vast array of uses and this adds extra value to the use of Symfony. One plugin that initially caught my eye was sfGuard. Here is the sfGuard description :
The sfGuardPlugin is a symfony plugin that provides authentication and authorization features above the standard security feature of symfony.It gives you the model (user, group and permission objects) and the modules (backend and frontend) to secure your symfony application in a minute in a configurable plugin.

After installing the plugin via the instructions here I quickly discovered that it secures at system level. System level security is great for applications that have very generic user groups - but most applications aren’t like this.

I need item level security. This allows me to specify specifically what a user can and cannot Create, Edit, View or Delete. If I have a multi-site blogging system and an Editor is assigned to each site (much as an Editor is assigned to one magazine or newspaper) - Having a system level securitiy implementation means that groups are created like this :

  • Editor
  • Journalist
  • Proof Reader

Having 3 sites means I should have 3 editors - one for each site. Giving each Editor the “Editor” privilege doesnt prevent them carrying out “Editor” functionality within each others site. This is one area where sfGuard falls short.

In creating a secure solution I am in half a mind whether to extend the sfGuard plugin to meet my needs or create an inhouse solution of my own. Extending the plugin or creating an inhouse solution means the alpha release date has to be put back. Also - extending a plugin is a bad idea as it means that any extension to in, in its current version, could be made redundant if a new version of the plugin is released.

Decisions, decisions…

Symfony : Who Needs a Development Team?

Posted on October 1st, 2007 in ALM, Programming by mcnicholl

I have recently been developing an application on a WAMP stack and found the exhaustive process of programming a framework counterproductive. At the moment my development team consists of 1 person. Me.

In order to maximise my time I found it necessary to investigate some of the available PHP frameworks that were on offer. Here are the key ones on offer :

  1. Zend
  2. CakePHP
  3. Symfony
  4. Seagull

There are many other frameworks available, but the ones highlighted above are my take on the best in the market.

After reviewing the frameworks on offer, I decided that the Symfony Framework was the one for me. I didn’t feel that PHP4 support was necessary and I wanted the framework code to be that bit more optimized. Programming for backwards compatibility means workarounds are necessary. Items such as MVC, caching, ORM were my main review points.

Onto Symfony itself.

I had read some reports of people having some difficulties understanding the folder structure that Symfony uses before I made my choice - but it turns out the people having the difficulty don’t really understand system design. I find the abstraction refreshing and after 1 week I now find it all straight forward.

The most difficult part of creating a viable application in Symfony is designing the GUI. Creating the business logic is as difficult as creating a database schema - one of the most pleasurable aspects of building a web application. Symfony takes the schema and creates modules containing all the functions necessary to update each table.

e.g If you have a notes table as follows :

`id` int(11) NOT NULL auto_increment,
`content` text,
`user_id` int(11) default NULL,
`created_at` datetime default NULL

… Symfony will create a module to interact with this table and create, retrieve, update, delete (CRUD) records in it. This is actually implemented by the Propel framework which Symfony has utilized for database abstraction.

It is this type of programming that is the usual repetitive mainstay of developers until they build up a library of low coupling modules. Since my development resources are so thin - my needs dictate that this unnecessary expenditure is focused in other areas of the systems development. In 3 weeks* from now Symfony will have created a functional application that just needs the GUI (read:: template) designed.

For this the Symfony Framework provides helper functions for creating forms, links, AJAX calls to name only 3. The possibility also exists to implement the Smarty Template Engine with Symfony as well - so I could theoretically outsource the template design - if I wanted.

It is for the above reasons that I ask the question : Who needs a development team?

Frameworks do all the leg work for you. The laborious tasks of writing SQL, adaptors for each database, individual modules that interact with the database are all taken care of. Symfony even creates the initial basic front end for you. All the developer has to do is add additional functionality, handle the interface for many to many objects and validate inputs. It will almost be embarrassing to say I programmed the application when it is released.

*3 weeks = 20hrs development time per week

Loadtesting Applications and what to use…

Posted on March 28th, 2007 in ALM, Testing by mcnicholl

All professional organisations that provide Client/Server applications to their customers must go through the testing phase of the software development lifecycle. Most people think of testing purely from a “does it do what it claims to?” point of view. Although the basics of testing is done with both black and white hat methods, some software issues will still creep through.

Black Hat and White Hat testing methods are extremely valuable at squeezing out the basic clitches - but only when Loadtesting a Client/Server application can you actually start to determine the proper efficiency, performance, durability, correctness and robustness of the system you have created.

The requirements specification stage of the SDLC should depict that the system will be able to maintain proper function with a load of X amount of users. Depending on the use and scope of the application - this number will vary.

Continue reading Loadtesting Applications and what to use…