mani's blog

Group Add More: Simulate clicking on group of multi-value fields

A custom content type that we built recently had multiple fields which accepted unlimited values. Some of these fields were grouped together and expected to accept values together.

The fix to this problem is rather simple. Simulate clicking on individual "Add More" buttons. We generalized this idea and create a jQuery plugin to facilitate this on any group of multi-value fields inside a container. This is supported for Drupal 6 & 7. Use the plugin from the approriate github branch from: https://github.com/nkmani/group-add-more (1.0 is for D6 and 2.0 is for D7).

To use this plugin:
Include the jquery.group-add-more.js file (both development as well as minified versions are available) in your theme.
Include the javascript snippet to attach the plugin to the container that has the add-more buttons.

The rendered group field would look like as shown below.

PHP: Pre-increment vs Post-increment

If the idea is to increment a variable and not care about the intermediate value, then pre-increment might be faster than post-increment. Here is why:

e-g incrementing an object variable

$o->aa++ vs ++$o->aa

The opcodes for post-increment:

   3        POST_INC_OBJ                                     ~1      !0, 'aa'
   4        FREE                                                     ~1

has to save the incoming value (for later return) and do the actual increment. The returned value has to be "freed" even though it is not being used. Optimizers might look at these patterns and change them to pre-increment. If optimizers are not used, then this will end up wasting extra cycles.

The opcodes for pre-increment:

   3        PRE_INC_OBJ                                              !0, 'aa'

Nothing is returned and hence does not have to be freed.

e-g increment a variable

$i++ vs ++$i

   8        POST_INC                                         ~3      !1
   9        FREE                                                     ~3

   11       PRE_INC                                                  !1

The PHP opcodes can be easily dumped using tools like vld.

Filefield widget says "Access Denied" on legacy nodes

One of the media heavy sites managed by us, there is a media content type which has been around for a while (starting from Drupal 5). The images associated with the content has been managed through multiple APIs before finally being ported to make use of FileField module. As it happens, the older legacy files were distributed all over the place but the newer files where all structured in a single location.

FileField module can be given a path where all file uploads can reside. Now this path happens to be different from all the paths used in the legacy nodes. Most of the use cases this does not cause a problem. But when there is a need to edit nodes that refer to the legacy files, the FileField widget would say "Access Denied" next to the image in the node edit form.

The reason for this behavior is obvious. The file field widget wants to validate the file path to make sure it is accessible before it can display it (this happens only in the node edit mode; works fine in node view mode). Since the legacy files are in a place which the current configuration of the FileField widget does not know about, it fails the validation and hence says "Access Denied".

The validation, as it happens, is done through hook_file_download API, which is passed the filepath. So a simple work around for this problem is to add a hook_file_download() API in one of our custom modules to validate the path and return appropriate headers as shown in the following code:

/**
 * Implementation of hook_file_download().
 */
function legacyfiles_file_download($filepath) {
  // validate legacy paths
  if (file_exists($filepath)) {
    $filesize = filesize($filepath);
    return array(
      'X-Content-Length: ' . $filesize,
    );
  } else {
    return array();
  }
}
Issues with filter cache and embedding views slideshow

Scenario:
Drupal 7
Views and Views Slideshow module
Custom blocks with PHP_CODE input format to embed the views

This normally works only once after caches are cleared. After the first page load, the slideshow images would appear but the cycle would not work.

Reason:
The block system uses cached values of the content from filter module (even through blocks may not be cached), the filter content is always cached and this can't be disabled. The php input_filter evaluates the code and caches the result. Now when the code is evaluated, as a side effect, the slideshow module adds the appropriate required js files.

Subsequent page loads would not emit the required js files, but only the static html from the embed_view. If the view did not rely on additional js files, this would have worked. But in the case of slideshow plugin (or a similar plugin that adds its own extra js/css files) would break.

Work around:
Instead of building a custom block, configure the view as a block and then use display output theme override in view to add any customizations and use the views block. The views block is not cached the way filters are cached. So, this would always work.

Pages