Drupal FAQ

Turn off maintenance mode on separate paths in Drupal 7

We have faced with the problem. We use Ajax Login/Register module but put site in Maintenance mode.

But we need to have Sign up ability. Ajax Register module show Sign up form in popup, content is requested from "ajax_register/register". But in maintenance mode we can see Maintenance page response...

But fortunately we have hook_menu_site_status_alter. Thus we can turn off Maintenance mode in our module on separate path:

<?php
function ajax_register_fix_menu_site_status_alter(&$menu_site_status, $path) {
  if (
$menu_site_status == MENU_SITE_OFFLINE && user_is_anonymous() && $path == 'ajax_register/register') {
   
$menu_site_status = MENU_SITE_ONLINE;
  }
}
?>

This is content of ajax_register_fix.module custom module.

Don't forget to check Backup&Migrate settings after D6 to D7 upgrade!

Several days ago we upgraded simple Drupal 6 site to Drupal 7. After core upgrade process was finished we turned on all necessary modules such as Admin menu and Backup & Migrate.

Some features required custom update by scripts and some manual work, we made backup before this activity.
... something went wrong and we go back by restoring DB via Backup&Migrate module and site wend down :-(

When we took a look on DB backup script we found that there was empty dump with the structure of some tables.
So as a result the data in several tables was killed.

When we repeated upgrade process again and took a look on Backup&Migrate advanced settings we were shocked

incorrect table exclude settings

By some reason all tables was excluded from backup.

After we align B&M settings backup became works correctly :-)

The main idea of this post due to automatic upgrade process you should double check settings of contributed modules, upgrade can make them different according initial state.

And, of course, backups is necessary part of site development activity but you should be sure that your backups correct.

How to delete users without any role in Drupal 7

We faced of one of the projects that we supported with large amount of spam registrations. But there were valid users with assigned roles that should not be deleted.

Short script was written to resolve this task:

<?php
require_once './includes/bootstrap.inc';
define('DRUPAL_ROOT', '<path_to_you_Drupal_folder>'); // optional
drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL); // load Drupal to use Drupal API
$query = 'SELECT users.uid as uid FROM {users} LEFT JOIN {users_roles} ON users.uid = users_roles.uid WHERE users.uid != 0 AND users_roles.uid IS null ORDER BY users.uid DESC LIMIT 300';
$result = db_query($query);
while (
$row = $result->fetchObject()) {
 
user_delete($row->uid);
}
echo
'300 spam users were deleted!'
?>

Let me explain this code in details:

If we would like to use Drupal API and DB connection in any separate script not in our custom Drupal module we need to start with these lines:

<?php
require_once './includes/bootstrap.inc';
define('DRUPAL_ROOT', '<path_to_you_Drupal_folder>'); // optional
drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL); // load Drupal to use Drupal API
?>

Attention! You should put your path instead ''.
Some times script can work without 'DRUPAL_ROOT' definition, but some times can't like in our case.

Authenticated User role ID is 2. But there is no any record with that role ID in {users_roles} table, so we should select all user IDs that have no records in {users_roles} table users_roles.uid IS null.

And do not forget to exclude Anonymous user record users.uid != 0.
Other wise we can delete record with 0 UID from {users} table, that serve for Anonymous user purpose.

Start to delete most resent users ORDER BY users.uid DESC.

Due to user_delete() function require pretty large number of SQL requests it is reasonable to set some limit LIMIT 300.

If there are a lot of spam users you can set cron task, for example:

*/02 * * * * /usr/bin/wget -O - -q -t 1 http://your_site.com/your_script_name.php >/dev/null 2>&1

How to order node_load_multiple() function results?

For example we have simple task to load and use some set of nodes of some separate node type.
There is function node_load_multiple().

$nodes = node_load_multiple(array(), array('type' => 'my_content_type'));

But what will be the order of the nodes in array returned?
They will be ordered by NID...

Unfortunately there is no parameter that managed the order of the results :-(

How we can resolve task if we are going to have results ordered by created time for example?

My answer: node_load_multiple() has the first argument. This is array of nids that have to be loaded.
So we should prepare such array before call node_load_multiple():

$query = new EntityFieldQuery();
$entities = $query->entityCondition('entity_type', 'node')
  ->propertyCondition('type', 'my_content_type')
  ->propertyCondition('status', 1)
  ->propertyOrderBy('created', 'ASC')
  ->execute();
$nodes = node_load_multiple(array_keys($entities['node']));

Maybe you think that I'm Cap.

Visitors can not see sweaver changes when they not logged in: how to fix it.

One of the clients inform that sweaver module does not save any changes.

I have taken a look on the problem and found out that changes are seen when I logged in as admin and not seen when I logged out.

First of all I turned off boost, css and JS optimization in Performans settings page.

Oh, I should mentioned that it was Drupal 6 project.

I have compared code in the case of authorized and anonymous users.
And in the anonymous case there were no some sweaver inline CSS.

I spent several hours to explore the isse in Google and Drupal.org and found an issue.

Let me share that with you.

I found the same issue on https://drupal.org/node/959690

There was helpful comment: https://drupal.org/node/959690#comment-6901808

Really it was CTools issue: https://drupal.org/node/1879992

I have implemented that: https://drupal.org/node/1879992#comment-6902624

You should delete only one sign ';' in line 312 in ctools/includes/css.inc

$statements = preg_split('/[;}]/', $css);

needs to be changed to:

$statements = preg_split('/[}]/', $css);

and sweaver start show changes for anonymous!

How to set image style in your own module in Drupal 7

Some time ago one of our customers asked to port gallery from Drupal 6 site to Drupal 7 one.
The module was not complex, the main difficult that I faced during the process to change Image Cache approach to the Image style one that native in Drupal 7. The main idea is to set resize rules of thumbnails in the gallery. Users should no do that themselves.

Previously in Drupal 6 there was following solution. The Image Cache preset set in the .install file.

<?php
/**
* Implementation of hook_install().
*/
function ms_gallery_install() {
 
// Create preset.
 
ms_gallery_install_imagecache_presets();
}

function
ms_gallery_install_imagecache_presets() {
 
// First, build an array of all the preset names so we do not make duplicates
  // Set the argument to TRUE to reset the cache
 
$presets = imagecache_presets(TRUE);
 
$preset_names = array();

 
// If there are any presets
 
if ($presets != '') {
    foreach (
$presets as $preset) {
     
$preset_names[] = $preset['presetname'];
    }
  }

 
// Prepare to install ImageCache presets
 
$imagecache_presets = array();
 
$imagecache_actions = array();

 
// We are checking to make sure the preset name does not exist before creating
 
if (!in_array('ms_gallery', $preset_names)) {
   
$imagecache_presets[] = array(
     
'presetname' => 'ms_gallery',
    );
   
$imagecache_actions['ms_gallery'][] = array(
     
'action' => 'imagecache_scale_and_crop',
     
'data' => array(
       
'width' => 120,
       
'height' => 67,
      ),
     
'weight' => 0,
    );
  }
 
// Need to install preset, id will be returned by function,
  // Then install action add presetid to action prior to install:
 
foreach ($imagecache_presets as $preset) {
   
$preset = imagecache_preset_save($preset);
    foreach (
$imagecache_actions[$preset['presetname']] as $action) {
     
$action['presetid'] = $preset['presetid'];
     
imagecache_action_save($action);
    }
   
drupal_set_message(t('ImageCache preset %id: %name and corresponding actions saved.', array('%id' => $preset['presetid'], '%name' => $preset['presetname'])));
  }
}
?>

Above the part of ms_gallery.install code. I would like to show how to set Image Cache preset programmatically.

In the case of Drupal 7 there is no Image Cache module. Instead it we should use Image Style approach that included in the Drupal 7 core.
I try to find any example in the Google, but the examples that I found does not work.

There is no any other option that to study Drupal.org. And after several hours I have found following beautiful HOOK:
hook_image_default_styles()

In terms of this hook to solve my task will be so easy!

<?php
function ms_gallery_image_default_styles() {
 
$styles = array();

 
$styles['carousel_gallery'] = array(
   
'effects' => array(
      array(
       
'name' => 'image_scale_and_crop',
       
'data' => array(
         
'width' => 120,
         
'height' => 67,
         
'upscale' => 1,
        ),
       
'weight' => 0,
      ),
    ),
  );

  return
$styles;
}
?>

I really like Drupal 7 :-)

The most simple way to reset password of the first Drupal 7 user by MySQL request

UPDATE users SET pass='$S$Cd059Vsxc8berFeg6hspaa7ejx2bSxyUisvCbT4h9o8XIgSUtPKz' WHERE uid=1;
this resets the password to 'password'

How to exclude the current node from a list view in Drupal 7

This is the instructions corresponds Drupal 7 + views 3.

There is a standard problem, we have the teaser of a random node in the block,
but it would be wrong to deduce the node teaser page on the page of it's full view.
Lets do following in views settings:

1. Click on the "advanced" fieldset.
2. Click on add under "contextual filters". We are going to add new contextual filter.
3. Choose Content:nid.
4. Under "when the filter variable is not available", choose "provide default value".
5. From the drop down menu select "content id from url".
6. Scroll all the way down to the bottom of the window and click on the "More" link.
7. Click "Exclude".
8. And be happy!

How to add file upload ability in comment form in Drupal 7

It is really simple question!
In Drupal 7 we can add any type of content fields to the comments entity, as well as to nodes or users.
Lets take a look on the picture below: