Archive for the 'Drupal' Category

Drupal 7 – Handling file uploads

When trying to deal with custom forms with file upload fields, you may sometimes get a error regarding extensions:

The specified file “your file name here” could not be uploaded. Only files with the following extensions are allowed: “jpg jpeg gif png txt doc xls pdf ppt pps odt ods odp”

To allow all extensions, you have to manually set the ‘file_validate_extensions’ validator to an empty array.

e.g.
$validators = array('file_validate_extensions' => array());
$file = file_save_upload('upload', $validators);

For more information, check out Drupal API’s documentation at http://api.drupal.org/api/drupal/includes–file.inc/function/file_save_upload/7

The bare requirements for a file upload form is the “multipart/form-data” enctype, a “file” field, and the standard “submit” button. An example of a basic structure:


$form ['upload'] = array (
'#type' => 'file',
'#title' => 'Choose file',
'#description' => 'Upload a file.' );
$form ['submit'] = array ('#type' => 'submit', '#value' => t ( 'Submit' ) );
$form ['#attributes'] = array ('enctype' => "multipart/form-data" );

Drupal Tip #6 – Missing Groups When Altering Node Forms

In customizing your node forms, hook_form_alter is a great way to restructure your forms before it is displayed. If you are using views2 and use groupings to organize your forms, its necessary to use hook_form_alter to bring certain form elements into groups because you’re not allowed to do so from the UI. Fields such as the title and body cannot be dragged under any groups in the manage fields page of the content type.

When a field is not in any groups, it will appear as a direct child key of the form, e.g.

$form['field_example'].

When it is under a group, it will be nested in a key with the group’s name, e.g.

$form['group_example']['field_example'].

To move the field, simply assign its value into the appropriate group key, and unset the original key:

$form['group_example']['field_example'] = $form['field_example'];
unset($form['field_example']);

One common problem though, is that the group keys are not appearing in the $form array passed into your_module_form_alter. You double checked the content type in the admin page (/admin/content/node-type/[your-node-type]/fields) but they are still not showing. Do not panic, they simply have not been created yet. The reason for this is that the CCK module’s hooks responsible for creating these keys are fired later than your form_alter hook, and this is a simple problem to solve.

Making sure your hooks are called after CCK

Drupal determines which modules are called when using their weight in the system table. To reorder your module to after CCK, you can manually set it’s weight:

db_query("UPDATE {system} SET weight = 50 WHERE name = 'your_node_type'");

One common place to do this is in the your_module.install file, so that its set only once during installation. My choice of weight (50) is purely arbitrary, you may need to inspect your own system table to determine the most appropriate weight.

Now your group keys should be appearing in the $form array.

Drupal Tip #5 – Custom Theme Function for Forms

Defining a custom theme function for forms involves writing the actual theme function and registering it with your own hook_theme function.

Custom Theme Function

The name of the function would be your form ID (replacing dashes with underscores) prepended by ‘theme_’:

function theme_your_form_id($form){
$output = 'Any html you need here';
$output .= drupal_render($form['subject']);
$output = ' and here';
$output .= drupal_render($form['submit']);
$output .= drupal_render($form);
$output .= '';
return $output;
}

Registering the theme function

In your hook_theme implementation, add a key to the returned array. The key should be your form id, do not include the ‘theme_’ prefix.

function deepgreen_theme() {
$themes = array(
. . . other theme functions here . . .
'your_form_id' => array (
'arguments' => array('form' => NULL),
'type' => 'module',
),
);
return $themes;
}

Drupal Tip #4 – Normal buttons with Drupal Form API

Drupal 6′s form API does not support input elements of type “button”. If you define one with ‘#type’=>’button’, it will be converted to a ‘#type’=>’submit’ automatically. So, how do you do it other than placing the button in a template file or function? You can use the ‘markup’ type, which is the default if no ‘#type’ key is defined. Example:

$form['submit'] = array(
'#value' => '<input type="button" onclick="return submitForm();" />',
);

Drupal 6 Form API Reference

Drupal Tip #3 – Determining Drupal Version

http://www.mydrupal.ca/2010-06-23/what-version-drupal-your-site-using has a helpful check list to go through when you need to determine the drupal version with missing Changelog files:

1. First thing to do is to read the CHANGELOG.txt file. It’s located in the root directory of your Drupal website. All versions of Drupal from 4.5-present have this file. Check the top entry in this file. It will have the Drupal version number. Unfortunately for our purposes today, many developers delete this file on live sites because it is perceived as a security risk.
2. Second thing to do is to check the VERSION constant in modules/system.module. This was added in Drupal 5.0.
3. If you can’t find the VERSION constant in modules/system.module then your version number is most likely 4.7 or earlier. In Drupal 4.7, the site ‘offline for maintenance’ feature was added.
4. In Drupal 4.6, a site-wide contact form (modules/contact.module) and search block were added.
5. In Drupal 4.5, all GIF’s in the default themes were replaced with PNG’s. If you can’t find the modules/contact.module, then your site is most likely Drupal 4.5.
6. You can actually download the 4.x versions on Drupal.org. Then you can compare the files in more detail. This article covers the major releasees and not the minor releases. For example upgrading from 4.51-4.52, is called a minor release.

Drupal Tip #2 – Limiting long strings

Use truncate_utf8 to quickly limit strings to certain lengths, and define whether the break should occur at character level or word level. Also optionally appends ‘ …’. Point to take note is that the ‘ …’ would not add to the resultant length – drupal compensates it by limiting the original string 4 characters less. This would be obvious in the example below, as each output never exceeds the 20 character limit.

For example:

$sentence = 'a quick brown fox jumps over the lazy dog';
echo truncate_utf8($sentence, 20); //a quick brown fox ju
echo truncate_utf8($sentence, 20, TRUE); //a quick brown fox
echo truncate_utf8($sentence, 20, TRUE, TRUE); //a quick brown ...
echo truncate_utf8($sentence, 20, FALSE, TRUE); //a quick brown fo ...

// Output side-by-side:
//a quick brown fox ju
//a quick brown fox
//a quick brown ...
//a quick brown fo ...

Drupal 4.7 – 6:
truncate_utf8($string, $len, $wordsafe = FALSE, $dots = FALSE)

Drupal Api Reference: truncate_utf8

Drupal Tip #1 – Formating Time Ago

Drupal has a nice little function called format_interval that formats a time interval in a “x secs ago” fashion. Note that it accepts a time interval, not an absolute time value, thus you need to subtract the time value from time().

For example, to print your node’s created time, use:

<?php echo 'Submitted ',format_interval(time()-$node->created),' ago'; ?>

Drupal API ref for format_interval()