Setup Drupal 6
The station's website will be build using Drupal an extremely powerful, open source content managment system written in PHP.
Drupal uses some PHP functions that require the installation of additional ports. You'll need:
- devel/php5-pcre - Perl regular expressions.
- textproc/php5-xml - XML parsing.
- textproc/php5-simplexml - Simple XML.
- databases/php5-mysqli - MySQL support for PHP.
- www/php5-session - Session support.
- ftp/php5-curl - cURL support.
- graphics/php5-gd - Image handing. Optional, some modules need it.
- converters/php5-mbstring - Unicode support. Optional, but Drupal prefers that it be installed.
Setup the Drupal station module
First you'll want to install these packages:
- archivers/unzip - you need this to unzip the getID3 library
Now we'll check out the necessary Drupal modules using Drush.
Correctly accessing CCK fields in SQL queries
Update: I've written a tool to help generate this code: http://drewish.com/tools/cck-query
Twice today I've had to deal with writing a SQL query that needed data in a CCK field. The naive approach is to just look at the table and field names and plug them into your query:
<?php
$result = db_query("SELECT COUNT(*) AS count FROM {node} n
INNER JOIN {term_node} tn ON n.vid = tn.vid
INNER JOIN {content_type_date} ctd ON n.vid = ctd.vid
WHERE tn.tid = 25 AND ctd.field_date_value > NOW() AND n.changed > %d", $newtime);
?>Often this will work just fine but since CCK can dynamically alter the database schema (when you add a field to a second content type or change the number of values) the query may break.
Fortunately CCK provides functions for finding a field's table and column names so it's simple to do it correctly:
<?php
$field = content_fields('field_date');
$db_info = content_database_info($field);
?>A var_dump($db_info) gives:
array(2) {
["table"]=>
string(17) "content_type_date"
["columns"]=>
array(2) {
["value"]=>
array(6) {
["type"]=>
string(7) "varchar"
["length"]=>
int(20)
["not null"]=>
bool(false)
["sortable"]=>
bool(true)
["views"]=>
bool(true)
["column"]=>
string(16) "field_date_value"
}
["value2"]=>
array(6) {
["type"]=>
string(7) "varchar"
["length"]=>
int(20)
["not null"]=>
bool(false)
["sortable"]=>
bool(true)
["views"]=>
bool(false)
["column"]=>
string(17) "field_date_value2"
}
}
}After noting that the field has two columns and making our choice, we've got the pieces to plug into the query:
<?php
$field = content_fields('field_date');
$db_info = content_database_info($field);
$result = db_query("SELECT COUNT(*) AS count FROM {node} n
INNER JOIN {term_node} tn ON n.vid = tn.vid
INNER JOIN {". $db_info['table'] ."} ctd ON n.vid = ctd.vid
WHERE tn.tid = 25 AND ctd." . $db_info['columns']['value']['column'] . " > NOW() AND n.changed > %d", $newtime);
?>The query is a bit harder to read, but you've future proofed your code so you won't be back to fix six months from now when you reuse that date field on another node type.
Using logrotate and drush for daily Drupal backups
If you've got Drush installed—and you really should—you can use the following recipe to setup a backup system that will maintain daily backups for the last two weeks. Most of the logrotate configuration is based on a Wikibooks book that I found.
Comparing a node's values with its previous version on save
There was a great question on Drupal developers mailing list the other day—one to which I've "rediscovered" the solution to a few times—so I wanted to make sure that everyone was aware of it.
The basic question is:
When a node is being saved, how can you see what values have changed?
The short answer is:
Use the 'presave' operation to load a copy of the node before it's saved, stick it back into the node object, and in your 'update' operation code compare the "before" and "after" versions:
<?php
/**
* Implementation of hook_nodeapi().
*/
function example_nodeapi(&$node, $op, $a3, $a4) {
// We want to compare nodes with their previous versions. Ignore new
// nodes with no nid since there's no previous version to load.
if ($op == 'presave' && !empty($node->nid)) {
// We don't want to collide with values set by other modules so we'll
// use the module name as a prefix and a long name to be save.
$node->example_presave_node = node_load($node->nid);
}
elseif ($op == 'update') {
// On update we pull the previous version out of the node and compare
// it to the newly saved one.
$presave = $node->example_presave_node;
// Pretend we're comparing a single value CCK number field here.
$field_name = 'field_example';
if ($node->$field_name != $presave->$field_name) {
drupal_set_message(
t("The node's value changed from %previous to %current.", array(
'%previous' => $presave->$field_name[0]['value'],
'%current' => $node->$field_name[0]['value'],
))
);
}
}
}
?>Simple loop to update nodes
For some reason I find myself rewriting this little bit of code every time I need to update a bunch of nodes on a site. Going to post it here to save myself some time. Be aware that this might time out if you've got a large number of nodes, designed for up to a couple hundred nodes:
<?php
// TODO: Set your basic criteria here:
$result = db_query("SELECT n.nid FROM {node} n WHERE n.type = '%s'", array('task'));
while ($row = db_fetch_array($result)) {
$node = node_load($row);
if ($node->nid) {
$node->date = $node->created;
// TODO: Test and set your own value here:
if (empty($node->field_task_status[0]['value'])) {
$node->field_task_status[0]['value'] = 'active';
$node = node_submit($node);
node_save($node);
drupal_set_message(t('Updated <a href="!url">%title</a>.', array('!url' => url('node/'. $node->nid), '%title' => $node->title)));
}
}
}
?>