drupal

Replace a Function Name in Drupal Source Files

> perl -i -pe 's/oldname_/newname_/g' `find | grep "\.module$"`

Or if you want to first check the results:

> perl -pi.bak -e 's/oldname_/newname_/g' `find | grep "\.module$"`

which will create backup of original files. Those you can delete later with:

> find . -name "*.bak" -exec rm -rf {} \;

You can replace ".module" with ".inc" or "tpl\.php" if you also need those processed

Sane Backtrace in PHP

PHP error messages are quite helpful, most of the time. Sometimes they do fall short of telling us what went wrong, however. It's especially common when and if you use a development framework (e.g. Drupal). Frameworks often do output buffering and/or code eval()-ing, making debugger output incomprehensible.

In such cases PHP's debug_backtrace() function is a real savior. debug_backtrace() is also very helpful if you want to look at the execution stack in a complicated code, to better understand the code. This function shows the execution stack that lead to the current function and does it pretty well... "too well" sometimes :) Out-of-the-box version of the function shows the list of invoked functions, source files they belong to, line numbers in the source file and the argument values being passed. The latter can be a huge problem, if code is passing around large variables. Output on the screen may get so garbled (esp. if HTML is used in variables) that the entire exercise may lose its meaning.

Short snippet below sanitizes debug_backtrace() output to make it slimmer and more comprehensible:

$trace = debug_backtrace();
foreach ($trace as &$t) {
  unset($t['args']);
}
echo "<pre>".print_r ( $trace,true)."</pre>";
exit();

Drupal: Fatal error: Unsupported operand types in

If you have misfortune of having to upgrade Drupal5 website to Drupal6, there's a very good chance that at some point you will run into a fatal error:

Fatal error: Unsupported operand types in...

Fatal errors are never fun, but this one is particularly annoying and hard to hunt down. It helps to understand the cause of the problem, thought. Basically, the main problem is that Drupal url() and l() functions have changed their signatures in a major way. Function operands that used to be literals are supposed to be an array now.

Solution

You need to hunt-down all url() and l() functions and change their signature to Drupal6-compliant format. The functions can be used (and causing problem from) multiple locations: a tpl.php file, a module file or a code in a block in the database! This last one is particularly troublesome to hunt down and can cause the most problem. We suggest disabling all blocks for the time of upgrade by running:

UPDATE blocks set status=0

Also, to find which function causes the problem. open includes/common.inc and at the begining of url() and l() function definitions paste following code:

    if (!is_array($options)) {
      echo "<pre>";
      $backtrace = debug_backtrace();
      var_export($backtrace);
      exit();
    }

Typically first function call in the backtrace is the offender function.

Teaching Espresso Drupal PHP file Extensions (e.g. .module)

Espresso From MacRabbit (you may remember them for their splendid CSSEdit eidtor) is a new Web editor, for Macs, worth paying attention to. It handles the usual suspects: PHP, CSS, HTML, servers over SFTP, Amazon S3 etc with style out of the box and has numerous extensions for other things like Python, LUA, SQL, Regular Expressions etc. And it's only 1.x version, so you bet you can expect much more in coming versions.

One little shortcoming it had, for Drupal developers is that, there's no easy way to configure custom-for-Drupal PHP extensions: .module and .install to make Espresso recognize these as PHP files.

Joe Shindelar of Dreamformula has posted a nice blog post detailing the configuration of custom PHP extensions in Espresso.

Thank you, Joe!

Solving Doxygen Troubles With Drupal.

Drupal requires its source documentation to be compatible with DoxyGen. If you are working on a large project, you want to install DoxyGen and run it on cron to have nice, up-to-date API docs.

Unfortunatley, if you install Doxygen via yum (or any other auto-updater, I assume) it installs a fairly old 1.4.x branch that is incompatible with Drupal. Specifically, it completely ignores the .module and .install files and has poor support for .inc, from what I can tell. That's because Doxygen does not realize these are PHP source files.

What you want to do is to install the latest Doxygen release (1.5.8 at the time of this writing). In the new version, the author of Doxygen has generously added a configuration tag that allows mapping of arbitrary file extensions with language types. The setting you need in your doxygen configuration file is:

EXTENSION_MAPPING      = module=PHP install=PHP inc=PHP

Drupal Selector FAPI Element

A really nice extension to Drupal Forms API has been released over the weekend: Selector Element module introduces the hip awesomeness of jQueryUI Sortable widget to Drupal's Forms API in a very easy way.

If you are using Drupal and wanted to quickly implement one of those drag-n-drop-n-sort selectors - you found a perfect module for yourself.

I have no doubt I will be using this new element a lot, myself.

Drupal: 'Views2 Returns Zero Results but SQL Is Fine' Problem

This has happened couple times, already, so I may as well blog about it. If you use Views in Drupal, you already know that it shows you the final SQL generated. Very useful feature, but there's a rare edge condition when the SQL returns results (if you run it from an SQL client), but Views shows zero elements. Extremely frustrating and confusing.

How can this happen?

The thing is, Views omits limit condition when displaying the SQL, so when you copy/paste your SQL in a client you are not running exactly the thing that Views displays.

Solution: check the pagination setting in the View settings. Most of the time the problem is an offset value indicated that is higher than number of elements in the result-set.

CVS Status Like the One in SVN - Bash Script

Yeah, I know - CVS is an archaic mess and there's not a single reason in the entire world to be using it in 2009... except if you are a Drupal contributor and need to maintain a module (or contribute to one) on drupal.org. For reasons that are complicated and don't matter to this blog post, Drupal uses CVS and there's no word that it will switch to something decent like SVN (git users - stay quiet), any time soon.

Fine, but when you actively use a version control, you need to be able to quickly see modified files. Files that need to be added or committed to version control. If you use a GUI CVS client - fine, but I don't. I do most of my development on remote Linux servers and command-line is my only cvs tool. Now that can get tricky in many ways. One of the ways is 'cvs status' command.

For reasons that I will never understand, CVS authors decided to show status of all files when you run this command over a directory. Plus they show 5 lines of information for each file. In the end - you can't see anything, if you are just looking for the names of modified files. Classic case of "less is more" (by the way - fixed in SVN, the improved CVS).

To emulate the behaviour of "svn status" that just shows a list of modified and new files, I wrote a quick bash script that hopefully somebody else, unlucky enough to be stuck with CVS, may find useful, as well:

#!/bin/sh

patterns=( 
	'?' 
	'Locally Added'
	'Locally Modified' 
	)

for i in "${patterns[@]}"
do
  cvs -Q status -R . | grep -i "$i"
done

ACL or Rules-Based Security for Drupal?

Joomla has announced availability of new ACL: http://is.gd/iA5B and they seem pretty excited about it. Is that something for Drupal community to be jealous of?

If you come from a Java/J2EE background the clear answer is: NO (yes, in capital letters). You have to actually suffer from a structured, strict ACL to really appreciate the simplicity of a security system like that of Drupal.

Now, you may argue that Drupal security is slightly over-simplistic and too code-oriented (makes us, the developers happy) for "business" use.

OK, but it does not have to be a "hierarchical ACL" or strings-based security. A flexible, rules-based security system may be the answer?

Zed Shaw, of the RoR world, has some very interesting things to say on the subject:
http://vimeo.com/2723800

Drupal: Expose a Custom Field to Views2

Disclaimer: Views2 Advanced Help contains a more detailed and comprehensive documentation on the same subject. However, that also means that you have to actually comprehend more :) This is just a quick sample code of one usage of the hook_views_data() to expose custom fields from a custom table to Views2. If you need more advanced functionality, do refer to Views2 documentation.

Let's say we are building a small job posting board and, for whatever reason, decided to store all resume-related extra fields in a table called "resume", instead of using CCK. Now we need to expose those fields to Views, to use all the beauty and flexibility of the automated query generation provided by Views.

Let's write a custom module called resume (or add it to an existing module).

The very first thing you need to do when you implement Views hooks is to tell Views that you are doing so and (optionally) - where your inc file will rely that holds all views hook implementation routines. We do that using hook_views_api(). Assuming your module is called "resume" and that you want to put views hook implementation file in the "views" subfolder:

function resume_views_api() {
  return array(
    'api' => 2,
    'path' => 
   drupal_get_path('module', 'resume') . '/views',
  );
}

If you omit the "path" argument, you will have to create the modulename.views.inc file in the root folder of your module (or "includes" subfolder). If you do indicate path - you create it on that path.

Let's create resume.views.inc file (under the "views" fubfolder of the resume module's folder, in our case) and enter following code in it:

Syndicate content