Installing and XHProf to profile Drupal on Ubuntu

Filed under: drupal,web development — jaydublu @ 2:48 pm

The following recipe was used to install XHProf on a Ubuntu server running Drupal 6, inspired by – my PEAR installer complained about missing config.m4, and I couldn’t find Brian Mercer’s php5-xhprof Ubuntu package.

Download and manually install XHProf:

tar xvf xhprof-0.9.2.tgz
cd ./xhprof-0.9.2/extension/
./configure --with-php-config=/usr/bin/php-config
make install
make test
cd ..
cp -rp xhprof_html /usr/share/php/
cp -rp xhprof_lib /usr/share/php/
mkdir /var/tmp/xhprof
chown www-data /var/tmp/xhprof

Optional – install graphviz for the Callgraph funtionality

apt-get install graphviz

Create /etc/php5/conf.d/xhprof.ini



alias /xhprof_html "/usr/share/php/xhprof_html/"

Restart Apache

apache2ctl graceful

Configure Drupal in /admin/settings/devel

xhprof directory: /usr/share/php
xhprof URL: /xhprof_html

Now to get my head around what it all means!

Limiting access to Drupal content types

Filed under: drupal,web development — jaydublu @ 1:43 pm

There are contributed modules that extend Drupal’s innate desire that all content should be publicly visible – notably node privacy byrole and Content Access. If you’ve defined your own node in a module, you can also use node_access() to set access rights to that node type. But what if it’s a core or CCK content type and you want to keep things simple?

Well here’s a ‘light’ way to restrict access to a given content type (‘mytype’ in this instance) to the owner of the node and any given role (‘administer nodes’ in this instance although it could be anything). Put this anywhere convenient and off you go.

 * Implementation of hook_nodeapi()
 * Limit viewing of mytype nodes to owner and admins.
function mymodule_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {
  global $user;
  if ($node->type == 'mytype' && $op == 'view') {
    if (!user_access('administer nodes', $user) && $user->uid != $node->uid) {

Storing dates in Drupal Schema API

Filed under: drupal,web development — jaydublu @ 6:25 pm

This one caught me out for a good while – I’ve got my own data stored in a database using Drupal’s Schema API and one field I want is a date, so I used the ‘datetime’ type. But whenever I came to use a value anywhere I couldn’t get any of Drupal’s date formatting functions to work – they were expecting a unix timestamp (makes sense) but the Schema API uses ‘datetime’ as a field type on MySQL so was getting a MySQL date string in return.

The answer was not to use datetime as a schema type, but int, and when passing data make sure you pass a timestamp. format_data() and views_handler_field_date etc. will then work as expected.

But it makes you wonder who left this mantrap lying around for foolhardy developers like me to fall into?

Drupal Views bulk export

Filed under: drupal,web development — jaydublu @ 5:06 pm

I’ve been using Drupal in earnest since the New Year, and I have to say that I wish I’d discovered it sooner. It’s by no means perfect, but I think perfection is impossible with CMS systems and it’s doing everything I need it to.

Initially I was sceptical about using the Views module – I was thinking that Views are just for people who can’t be bothered to do proper PHP, but then I got into them and discovered the power and simplicity, and I have to say my first approach to most content display challenges in Drupal now tends to use Views.

But this leads on to one of my biggest gripes about Drupal – how much of the site configuration is stashed in the database where there is little accountability or control – I much prefer having files in the filesystem where you can use Version Control.

Then I discovered bulk export which does all of that – and it makes a big difference in safe use of Views. This is how I’ve done things several times now quite successfully:

  • Carry out rapid development using the Views UI as normal.
  • Enable the Views Exporter module – this turns on the ‘bulk export’ tab under ‘tools’ in the Views admin
  • In Site Building > Views > Tools > Bulk Export, select the views that you want to export, and enter the name of the module you want to store the views code in and hit ‘export’
  • Follow the instructions on the next page to add snippets to the .info and .module files, and to create the file
  • In Site Building > Views > Tools > Basic, click ‘Clear Views Cache’ button
  • The right hand-most link against the views you exported in the admin list should now have changed from ‘delete’ to ‘revert’ – go ahead and ‘revert’ all the views you exported

That’s it – simples!

If you need to make any changes to exported Views, there are two approaches:

  1. Modify the exported php directly in the file – these changes should be immediately reflected on the site, but you might need to hit ‘Clear Views Cache’ just to be sure.
  2. Use the Views UI, and re-export the views again, save the updated file, then hit ‘revert’ on the list to use the file version

I’ve found it very useful when there are two or more enviornments being used for development (e.g. dev and live) to be able to spot that a local change has been made to an exported view by the presense of the ‘revert’ link – using diff on exports gives you a clue to what setting changed – a bit fiddly but not as bad as trying to go through every setting the UI one at a time to spot the difference. It’s also very reassuring to have Subversion (or your vrsion control system of choice) keep all your various environments in sync.

The final trick to pass on that has made my life much simpler is proper use of names and tags in views – if all the views for your module have the same prefix to their name, and the same tag, it makes it much easier to spot them all in lists, and to select them all together when you come to re-export them – it’s very embarrassing if you miss one and a whole section disappears from the site! If you need to rename or add tags – it’s easy to spot in the exported code where they can be changed, and that’s something you can’t do through the UI.

Now if only I could get more of Drupal’s config in the filesystem this way …