I wasn't able to attend the DrupalCamp Copenhagen that took place May 22-24, 2009. The good Danes thought of me anyway, though, and sent me this birthday wish. Thanks Morten and Jakob, and all the other Drupallers! (look closely and you can see that I turned 22 years old this year.)
For the HelpInject module I needed a multi-step form. This is pretty easy in Drupal 6. The problem I encountered was that the “destination” parameter was no longer being honored, and the form was submitting to itself after the last step. It was supposed to be redirecting to “destination”. Here’s the code that made it work. The tip is to unset $form_state['storage'] after you’re done with it because for some reason that’s FAPI’s litmus test for whether or not to redirect.
<?php
// The form is built like this
function foobar_form(&$form_state, $type) {
if (empty($form_state['storage']['foo'])) { } else { }
}
// The submit handler follows a similar pattern.
function foobar_form_submit($form, &$form_state) {
if (empty($form_state['storage']['foo'])) {
$form_state['storage']['foo'] = $form_state['values']['foo'];
$form_state['rebuild'] = TRUE;
} else {
... do CRUD ...
// if you want your form to respect destination,
// unset the storage.
unset($form_state['storage']);
}
}
?>Here is a function that will remove all duplicate nodes (based on title) for a certain content type. It keeps the most recent one.
<?php
function dedupe($type) {
$previous = array();
$result = db_query("SELECT nid, title FROM {node}
WHERE title IN
(SELECT title FROM {node}
WHERE type = '%s'
GROUP BY title HAVING count(*) > 1)
ORDER BY title, created DESC", $type);
while ($row = db_fetch_array($result)) {
if ($row['title'] == $previous['title']) {
node_delete($previous['nid']);
}
$previous = $row;
}
}
?>In this article I will show you how you can write a tiny bit of code that will reveal new fields and facets for searching with the ApacheSolr module and Acquia Search. Using Acquia Drupal we’ll write an example module that takes the file type from CCK file and image fields and makes them into their own search fields. This results in us being able to filter our search results based on file type. This code fulfils the situation where you want, for example, to find a specific post that has a JPEG image, or all of the posts with PDFs that match a particular keyword.
Sometimes you might want to alter a $form array in a systematic and declarative manner. For example, say you want to change all of the #title elements to "foo". Here's a function that Adrian Rossouw and I just wrote that does just that. It recurses through all of the children elements of the form sending them (by reference) to a callback function of your choice. That callback can then alter them in any way it wants.
<?php
/**
* Take a form element or whole form array, and a callback, and
* recurse through all children elements, passing them to
* the callback function for processing.
*/
function step_form(&$element, $callback) {
foreach (element_children($element) as $child) {
step_form($element[$child], $callback);
}
$callback($element);
}
/**
* A callback function to change #title elements to the value "foo"
*/
function change_title(&$element) {
if (isset($element['#title'])) {
$element['#title'] = 'foo';
}
}
/**
* A fictional module's hook_form_alter implementation that sends the form
* to step_form() specifying change_title() as the callback function.
*/
function foo_form_alter(&$form, $form_state, $form_id) {
step_form($form, 'change_title');
}
?>UPDATE: Now as a shell script. You may have to update the MySQL user in the script. A file version of the script is attached. Download it, make it executable with chmod +x ./doublenodes, and then run it with ./doublenodes databasename
#!/bin/sh
mysql -u root -p -e "
INSERT INTO node (nid, vid) VALUES (NULL, -1);
SET @nid:= (SELECT MAX(nid) FROM node);
DELETE FROM node WHERE nid=@nid;
INSERT INTO node_revision (nid, vid) VALUES (@nid, '');
SET @vid:= (SELECT MAX(vid) FROM node_revision);
DELETE FROM node_revision WHERE vid=@vid;
INSERT INTO node
SELECT
NULL, @vid:=@vid+1,
type, language, title, uid, status, created, changed, comment, promote,
moderate, sticky, tnid, translate
FROM node;
INSERT INTO node_revision
SELECT
@nid:=@nid+1, NULL,
uid, title, body, teaser, log, timestamp, format
FROM node_revision;" $1
This will take the existing nodes in your db and copy them. If you have 10 to start with you will have 20 when you’re finished (and they’ll be copies of the first 10). This is good for populating a test database for performance testing where you want a lot of nodes. It is much faster than using Devel module’s generate (use that to get your first 1000 nodes or so, then use this query to double them, and double them again, and double them again, etc.) Note that this query doesn’t take CCK fields, uploaded files, comments, or taxonomy terms into account. Just the nodes.
It is important that Drupal get tested on databases with millions of nodes, and we need to share techniques like this, and possibly build extra infrastructure on Drupal.org, so that we can always test patches on large datasets.
PS: Is there a better way? How do you create databases with large data sets?
I can hardly wait to go do DrupalCon 2009 in Washington DC. If you’re as excited about DrupalCon as I am, but are having a hard time finding the money you’d need to attend, perhaps you should apply for one of the 20 scholarships that are being awarded. Anybody in financial need can apply:
So who will these scholarships go to? People who are actively developing with Drupal, who would benefit from attending DrupalCon, and who are already helping the community.
The applications are being reviewed by myself and Drupal legend Károly Négyesi (aka chx). I’m proud to be able to help out with this process, just as I’m proud that the company I work for is a platinum sponsor of the DrupalCon. It makes me feel good to know that the money being raised by the DrupalCon will be used to reach out and help people attend who otherwise wouldn’t be able to. If your company isn’t already a DrupalCon sponsor, it’s not too late. You can contact the organizors online to become a sponsor and help bring Drupal to even more people.
DrupalCamp Cologne will take place on January 17th and 18th, 2009, in Cologne, Germany. Here are pictures of the organization team (known internally as OrgaNicer - say it with a German accent and you’ll get the joke) planning the sessions. We’ve got around 50 sessions and 4 rooms. There are also 12 rooms for groups of 10 people that can be used for spontaneous sessions, lightning talks, BoFs etc.



What are you doing on January 17th and 18th? Hopefully you'll be coming to DrupalCamp Cologne and hanging out with Drupallers from all over the world! This is the first ever Drupal-specific camp or conference that Germany has ever seen, so it will be quite an event.
Dries Buytaert (Drupal founder and project lead, Acquia co-founder and CTO, Mollom co-founder) will be there to talk about Drupal and his latest projects. I'll be holding an Acquia Q&A session, as well as demonstrating the latest ApacheSolr improvements. Jeffrey McGuire (Acquia's documentation lead) will be there as well, ready to help you with your Drupal 5 to Drupal 6 upgrade problems, including those pesky Views 1 to Views 2 conversions. Also not to miss is the Drupal.org Upgrade and Redesign Hackathon - your chance to get your hands dirty with the big Drupal.org redesign project.
On January 19 and 20, 2009, in Cologne Germany, Commerce Guys and AF83 will be joining forces to offer Drupal Ubercart training (registration link). Drupal is a leading web content management system, and Ubercart is a full e-Commerce solution and shopping cart that is built on top of Drupal.
In the training you will learn how to build a web site for a rock band that features blogs, audio and video content, tour dates and an event calendar, fan forums, and an Ubercart-based store where fans can buy t-shirts and music downloads. The website will be based on Acquia Drupal so you will also get a glimpse into the Acquia Network and learn about the advantages of building your site with the support of Acquia. Everybody who attends will get a free Acquia Network subscription and some Acquia schwag.
The training takes place on the two days following DrupalCamp Cologne and will be held in the same venue as DrupalCamp. If you are already planning on attending DrupalCamp Cologne and want to learn even more, this is a great opportunity. If you weren’t sure about making the trip for DrupalCamp Cologne, now you can get even more Drupal and Ubercart action out of your travels.
Commerce Guys are leading Ubercart specialists and were recently selected to build and run the official Drupal store on drupal.org. AF83 are Drupal site-building experts with much experience in providing Drupal training.




