PHP

warning: filemtime(): stat failed for taxonomy/term/35/0/feed in /home/server/html/drupal6/sites/all/modules/cdn/cdn.basic.farfuture.inc on line 232.

Bar charts with Drupal's charts module

I started playing with the Drupal charts APIs a while ago, which uses Google's excellent charting APIs. This mostly worked well, except that the bar charts "class" did not support modifying the spacing between groups of bars. So, here's a small patch that solves this.

--- chart.module.orig   2008-12-23 09:53:48.000000000 -0800
+++ chart.module        2008-12-23 09:52:01.000000000 -0800
@@ -549,7 +549,7 @@
       
     // Bar chart bar sizing
     case 'chbh':
-      $data[$attr] .= implode(',', array($value['#size'], $value['#spacing']));
+      $data[$attr] .= implode(',', array($value['#size'], $value['#spacing'], $value['#group_spacing']));
       break;
       
      // Mixed axis positions, labels and styles
@@ -1028,10 +1028,11 @@
 * 
 * @return array
 */
-function chart_bar_size($size = 40, $spacing = 20) {
+function chart_bar_size($size = 40, $spacing = 20, $group_spacing = 30) {
   return array(       
       '#size'    => $size,  
       '#spacing' => $spacing,  
+      '#group_spacing' => $group_spacing,  
     );
 }

Drupal and SourceForge

SourceForge recently changed their site to put their Apache servers behind a "pool" of Nginx reverse proxies (accelerators). This is a good idea, but has negative impact on various Drupal features, like, logs, ACLs etc. I've made a small hack on my http://pysearch.sourceforg.net/ Drupal installation, like this:

--- includes/bootstrap.inc.5.10 2008-09-23 08:53:05.000000000 -0600
+++ includes/bootstrap.inc      2008-09-20 10:14:52.000000000 -0600
@@ -5,6 +5,9 @@
  * @file
  * Functions that need to be loaded on every Drupal request.
  */
+if ($_SERVER['HTTP_X_REMOTE_ADDR']) {
+    $_SERVER['REMOTE_ADDR'] = $_SERVER['HTTP_X_REMOTE_ADDR'];
+}
 
 /**
  * Indicates that the item should never be removed unless explicitly told to

Granted, this needs to be configurable, I'm thinking a general Drupal setting where we can tell which Header to use to replace REMOTE_ADDR.

Code

Here are some Drupal hacks and modifications that I've done.

Breadcrumb trails with node relativity (Drupal)

I couldn't get the breadcrumb trails (menu) to work with my pages / stories that I structure with node relativity (a Drupal module). I don't know if I'm doing something wrong, but looking at the code, I couldn't see any support for it. So, here it is, a quick and dirty hack to add the breadcrumb trails to your node relativity structures:

--- relativity.module-2.4       2008-09-17 19:44:07.000000000 -0700
+++ relativity.module   2008-09-18 07:49:10.000000000 -0700
@@ -378,6 +378,14 @@
     '#title' => t('Global Options'),
   );
 
+  $group['global_options']['relativity_breadcrumb_trails'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Update the breadcrumb trails menu'),
+    '#return_value' => 1,
+    '#default_value' => variable_get('relativity_breadcrumb_trails', 0),
+    '#description' => t('If checked, the ancestor hiearchy of the page is used to create the breadcrumb trail menu.'),
+  );
+
   $group['global_options']['relativity_allow_types'] = array(
     '#type' => 'select',
     '#title' => t('Node types that can be involved in relationships'),
@@ -1067,13 +1075,35 @@
       break;
 
     case 'view':
-      if ($w = variable_get('relativity_'.$node->type.'_ancestor_weight', 0)) {
+      $do_breadcrumbs = variable_get('relativity_breadcrumb_trails', FALSE);
+      $ancestors_w = variable_get('relativity_'.$node->type.'_ancestor_weight', 0);
+
+      if ($do_breadcrumbs || $ancestors_w) {
         $ancestors = relativity_load_ancestors($node);
+
         if (is_array($ancestors) && count($ancestors) > 0) {
-          $node->content['relativity_ancestors'] = array(
-            '#value' => theme('relativity_show_ancestors', $node, $ancestors),
-            '#weight' => $w,
-          );
+          if ($do_breadcrumbs) {
+            $breadcrumb[] = l(t('Home'), NULL);
+            foreach($ancestors as $ancestor) {
+              if (!is_array($ancestor)) { // Only handle single ancestors here
+                if (array_key_exists("path", $ancestor)) {
+                  $breadcrumb[] = l($ancestor->title, $ancestor->path);
+                } else {
+                  $breadcrumb[] = l($ancestor->title, 'node/'. $ancestor->nid);
+                }
+              }
+            }
+            if (count($breadcrumb) > 1) {
+              drupal_set_breadcrumb($breadcrumb);
+            }
+          }
+
+          if ($ancestors_w) {
+            $node->content['relativity_ancestors'] = array(
+              '#value' => theme('relativity_show_ancestors', $node, $ancestors),
+              '#weight' => $ancestors_w,
+            );
+          }
         }
       }

And yes, I did file a "issue" for this, with the Drupal people, http://drupal.org/node/309982 .

PHP and APC

I've been using APC for a long time on my servers, without having any problems. Recently I've been playing around with optimizing some PHP applications using APC, and I started seeing weird problems where the Apache server would hang randomly.

I can't say that I'm a PHP expert in any way, but it seems that turning on more than one shared memory segment in the APC configuration is bad mojo. With my optimizations, I needed more memory for the caches, and my previous configurations had worked fine with 2x30MB shared segments. Instead, on my Linux system, I bumped up the segment size, and set it back to just one segment, and that seems to have solved my problems. My configs are now

apc.shm_size = 64
apc.num_files_hint = 3000
apc.ttl = 7200

You can easily see your current APC "status" with a little PHP script like this:

<pre>
  <?php
    print_r(apc_sma_info());
    print_r(apc_cache_info());
  ?>
</pre&gt