Drupal 7: Add a class to the body

Drupal Today I had to add a class to the body so know if I was logged in as “administrator” like role, it needed to have the permission to modify any content of the type MYTYPE.

To add a class to the body you have to work on the template_preprocess_html for your theme, like the snippet below.


function MYTHEME_preprocess_html(&$vars) {
  if(user_access("edit any MYTYPE content")){
   $vars['classes_array'][] = "MYCLASS";
  }
}

The user_access() will check if the current user (if there isn’t one specified) has the selected permission, the permission is the one you can see from the permission administration page, if you are using Drupal in another language then refer to the base English interface to know what to write there.

Enjoy!

Drupal 7: Manually update jQuery version

Drupal Today for a customer I had to use a special plugin for jQuery that needs a jQuery version equal or major than 1.6.1.

As you know Drupal 7 is shipped with jQuery 1.4.4 and so is not ready for the plugin I need to use, there is a plugin that update jQuery and jQuery UI but where is the fun?

The procedure is pretty quick:

  • Download the jQuery version you need from from the official source.
  • Place the jQuery version you downloaded in your theme js’s folder (like MYTHEME/js/).
  • Create/Modify your theme’s template.php file as described below.

That is.

Now for the template.php, you need to use the hook_js_alter to replace the native jQuery:

function MYTHEME_js_alter(&$javascript) {
  //We define the path of our new jquery core file
  //assuming we are using the minified version 1.8.3
  $jquery_path = drupal_get_path('theme','MYTHEME') . '/js/jquery-1.8.3.min.js';

  //We duplicate the important information from the Drupal one
  $javascript[$jquery_path] = $javascript['misc/jquery.js'];
  //..and we update the information that we care about
  $javascript[$jquery_path]['version'] = '1.8.3';
  $javascript[$jquery_path]['data'] = $jquery_path;

  //Then we remove the Drupal core version
  unset($javascript['misc/jquery.js']);
}

After we clear the cache we will have the new jQuery version.

Keep in mind that changing the jQuery version may create some incompatibility issues with the other Drupal core scripts.

Enjoy!

Drupal SA-CORE-2012-003 quick fix

Drupal Recently Drupal released the new version (7.16) to fix a security issue that would allow an attacker to reinstall an existing Drupal site with an external database server and then execute custom PHP code, more information available here: http://drupal.org/node/1815912.

There are many way to prevent this instead of updating a Drupal installation (always recommended), probably the quickest is to deny access to the interested file with few lines for the .htaccess file:


<Files install.php>
  deny from all
  ErrorDocument 403 "Access denied."
</Files>

Enjoy!

Drupal 7: how to create a form within a module

Drupal If you develop modules and you need to create a form in one of your page, there is a nice Drupal function that can render an array into a pretty HTML form: drupal_get_form().

This handy function is usually needed in a menu callback as it does not require an existing form.

You can use it like this:

/**
* Implements hook_menu()
*/
function mymodule_menu() {
 $items['mymodule'] = array(
  'title' => 'My title', //The name of the menu that will be displayed
  'page callback' => 'mymodule_page_callback', //The name of the function that will output a page
 );
 return $items;
}

function mymodule_page_callback() {
 //The argument is the name of the function with the form details
 return drupal_get_form('mymodule_form');
}

function mymodule_form($form, &$form_state) {
 $form = array (
  '#action' => '#', //The action attribute of the HTML form tag
  'name' => array ( //We define a simple text field for the "name"
   '#type' => 'textfield',
   '#title' => t('My pretty name'), //The label that will be placed with the field
   '#description' => t('My descrition'), //The description will be placed right below the field
   '#required' => TRUE, //If true the system will perform a simple check on submit so that it is never empty
  ),
  'submit' => array ( //We define a simple submit button
   '#type' => 'submit',
   '#value' => t('My submit'),
  ),
 );

 return $form;
}

After you have defined the form, you can implement 2 extra functions that will handle the validation (_validate) and the processing (_submit) of the form values.


function mymodule_form_validate($form, &$form_state){
 // My validation parameters
 if(strlen($form_state['values']['name']) > 10) {
  form_set_error('', t('Hey, your name is too long!'));
 }
}

function mymodule_form_submit($form, &$form_state) {
 //My success processing
 drupal_set_message(t('Yay, your name is fine!'));
}

And that is, pretty simple uh?

Magento headers already sent

MagentoSometime while working with Magento, especially while browsing the site with Google Chrome, you may get the following error:

Duplicate headers received from server
The response from the server contained duplicate headers. This problem is generally the result of a misconfigured website or proxy. Only the website or proxy administrator can fix this issue.
Error 349 (net::ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION): Multiple Content-Disposition headers received. This is disallowed to protect against HTTP response splitting attacks.

This will be fixed in Magento 1.7.x, but until then, if you like to fix it you need to duplicate a core file in the app/code/local/ folder modifying few lines.

The file you need is app/code/core/Mage/Core/Controller/Varien/Action.php, and you need to modify the method _prepareDownloadResponse, in particular this code:


$this->getResponse()
->setHttpResponseCode(200)
->setHeader('Pragma', 'public', true)
->setHeader('Cache-Control', 'must-revalidate, post-check=0, pre-check=0', true)
->setHeader('Content-type', $contentType, true)
->setHeader('Content-Length', is_null($contentLength) ? strlen($content) : $contentLength)
->setHeader('Content-Disposition', 'attachment; filename="'.$fileName.'"')
->setHeader('Last-Modified', date('r'));

into:


$this->getResponse()
->setHttpResponseCode(200)
->setHeader('Pragma', 'public', true)
->setHeader('Cache-Control', 'must-revalidate, post-check=0, pre-check=0', true)
->setHeader('Content-type', $contentType, true)
->setHeader('Content-Length', is_null($contentLength) ? strlen($content) : $contentLength, true)
->setHeader('Content-Disposition', 'attachment; filename="'.$fileName.'"', true)
->setHeader('Last-Modified', date('r'), true);

As said before, you have to duplicate this file before modifying, messing with the core files is always bad!
Your new file will be /app/code/local/Mage/core/Controller/Varien/Action.php.

If you plan to upgrade to Magento 1.7.x keep in mind that it is better to remove this patched file!

Enjoy!