Planet Drupal

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

Swipe Photo Gallery

We are happy to inform you that we have put new beautiful photo gallery module on Drupal.org

Project page: https://drupal.org/project/swipe_photo_gallery

This module show the matrix of images on one separate page. User can see only one page in matrix and go to the next with Up, Down, Right or Left key or using swipe in Up, Down, Right or Left direction.

You can see demo on http://carolsachs.com/overview
We have done site of Carol Sachs and understand that there are some custom solutions that we must share with world Drupal community.

The simple instruction how to use this module:

  1. Turn on module as usual drupal module.
  2. Check that you use Jquery 1.7 or higher with Jquery Update module!
  3. Put several nodes with Slide content type. This content type will appear automatically.
  4. Go to the configuration page admin/config/media/swipe_photo_gallery and set path where you would like to show your slides.
  5. Go to this page and enjoy your slides.

Feel free to send us any recommendations and ideas that can improve this module!

Blog tags:

How to Add Circle Image Style into Rotating Banner SlideShow

During update work of the site of our Drupal department (http://php.sfdev.com) we faced following task: to upload rectangular images but to show circle ones on the pages of our site.

In the case if we are going to display circle image form Image or Media field it is easy to set image style preset and use it in the field display. But Rotating banner (https://drupal.org/project/rotating_banner) does not allow to use image styles without hack module.

It is extremely worth practice to hack contributes module even in no feather development status :-)

But how can avoid to hack module and use image style to make image be circle?

By the way to do circle images with image style preset you can use ImageCache Action Module (https://drupal.org/project/imagecache_actions)

Ok, back to our task. We can try to use hook_preprocess_image(). In our theme template.php file we put following code:

<?php
function sfdev_preprocess_image(&$vars) {
  if(isset(
$vars['attributes']['class']) && $vars['attributes']['class'] == 'rb-background-image') {
   
$url_splits = explode(variable_get('file_public_path', conf_path() . '/files/'), $vars['path']);
   
$vars['path'] = image_style_url('circle', file_build_uri($url_splits[1]));
  }
}
?>

Fortunately each rotating banner add 'rb-background-image' to each image. So we can separate this kind of images from the other ones:
if(isset($vars['attributes']['class']) && $vars['attributes']['class'] == 'rb-background-image') {

Before implementing hook_preprocess_image we should create 'circle' image style to use it in this function.
To make Drupal create circle image we should just simply request it via image style URL:
image_style_url('circle', file_build_uri($url_splits[1]));
So the main idea to put image style URL instead original one.

By the way, after some discussions we decide to create circle images manually, because in some cases they should not be circle :-)
And these cases are not predictable :-(

Blog tags:

We should not use a drupal_goto function in our module hooks!

Today one of my colleague nortmas had explained to the young developers one not obvious but extremely important point. In the begin of my career of Drupal developer I often did that kind of mistake.

I would like to share with us his message:

You should not put drupal_goto() into the hooks of our custom module!

Why?

Because our hook function is into the queue of the other functions that represent the same hook in the other contributed and custom modules. The order depends on the weight of the module and alphabetic order in the case of equal weights.

In the case if you will put drupal_goto in your hook function code, you will take away the ability to do necessary actions of the modules that located in the back of the hook order queue.

In any case you should avoid drupal_goto() function in your code because it indicated poor codding style like for example goto operator in classic C language.

Thank you, Dmitry for that helpful blog topic!

Blog tags:

Cursor Easy Change module

We, like any active Drupal team, faced with the task of recruiting new staff. To begin with, to cut off unwanted people, the usual step is the test task. Commonly in our practice we ask the applicant to create simple module. But Drupal has a lot of contributed modules that cover all needs of ordinary developer. So if we ask applicants to repeat some existing solution they can look for contributed solution... Yes, it is good skill to easy implementation of contributed solution with some customization. But we would like to see how applicant will create solution from scratch. Recently we have to propose the most amazing tasks, which may be completely useless, just for fun only.

Below I would like to show the result of such test task, that was successfully done.

Every beginner in the web development area is seeking to add to the site as many different effects as it possible, wanting to impress site visitor. A little creative effects, which can easily to surprise is custom cursor on the site. We ask the applicant create Drupal module that will provide to the admin of the site the set of cursors to apply via CSS.
You can find the result in the sandbox project.
Also one can download archive here.

The solution is really simple. The form of theme settings is altered.

There is no ability to upload cursors but there are several cases that we can use to show the ability of such kind of effect.
In addition in the module there is function that stores the selected version of the cursor in the system variable and hook_init, which adds the necessary CSS file.

It is really easy module so the main question to the community:

Whether it should stay in the sandbox?

Or we should modify it by adding the ability to load custom cursors and make a full project?

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 :-)

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 each own 404 page to each section of the site.

Several days ago I have following task:

there is a site with URLs content structure:

section-1/title-1
section-1/title-2
section-1/title-3
...
section-n/title-1
section-n/title-2
...
etc.

Task, to provide the ability of separate 404 page for each section of the site,
that is
section-1/404
...
section-n/404

Of course, we can use Rules API to set complex rules but there is more simple way to solve this problem.

I think arg() function helps us. See http://api.drupal.org/api/drupal/includes%21path.inc/function/arg/6
Without any argument arg() returns the array of the current path components.
If it will be correct node alias arg() returns following array:

[0] = 'node'
[1] = some node id

in the case of wrong path it returns for example:

[0] = 'section-1'
[1] = 'wrong-title'

Let's create simple "section_404" module.

<?php
function section_404_init() {
 
$args = arg();
  if(
$args[0]  != 'node' && $args[0]  != 'admin') // in the case if we are going to use not simple node content but views etc. the condition can be more complex
   
drupal_goto($args[0] . '/404');
}
?>

As was indicated in the comment in the code the real condition that you should use on production site should be more complex.

Blog tags:

Start You Own Drupal Distribution with Drush Make. Part 1.

As a rule, we get used to enjoy some limited set of trusted modules, especially if we often have to work on typical projects.

I remember when I started working with Drupal, every time for each new project I collected fresh new versions of my favorite modules on Drupal.org. It was monotonic mannual work and I wast a lot of time before starting new Drupal installation.

But after meeting with Drush Make I was really happy!

I will not tell about the installing this extension of Drupal Shell, yet immediately move on to writing .make file.

First of all we should start with two service lines:
; Core version
; ------------
; Each makefile should begin by declaring the core version of Drupal that all
; projects should be compatible with.
core = 7.x

; API version
; ------------
; Every makefile needs to declare it's Drush Make API version. This version of
; drush make uses API version "2".
api = 2

After that we need to indicate core version that we are going to use. To use the latest Drupal version we should write only following:
projects[drupal][type] = core

We can also type the version of the core that we need. In this case our .make file will be following:
core = 7.x
api = 2
projects[drupal][type] = core
projects[drupal][version] = 7.8

But we can use also PressFlow as core for our distribution. There is no any other way to obtaine PressFlow only to get it from GitHub.
For this porpouse pressflow.make was created:
core = 7.x
api = 2
projects[pressflow][type] = core
projects[pressflow][download][type] = git
projects[pressflow][download][url] = git://github.com/pressflow/7.git

If you have this file you can type:
$ drush make --prepare-install --tar pressflow.make pressflow

And in several minutes have pressflow.tar.gz

Ok, I describe below what each argument of drush make command means.

--prepare-install mean that Drush Make prepare "files" folder and "settings.php" file future installation, I remember I had often had to do it manually :-)

--tar will do archive .tar.gz with your distro.

The following parameters are the name of the our make file and the name of the target archive or folder if we miss --tar parameter.

Let's talk about how to add modules and themes in our distribution. Fairly complete documentation you can be find on http://drupalcode.org/project/drush_make.git/blob_plain/refs/heads/6.x-2.x:/README.txt. But I'm going to provide several examples to cover main part of content of the document.

Lets start with modules. There is a good practice to put all contributed modules in the folder "sites/all/modules/contrib", and put your custom modules into "sites/all/modules/custom". I like Backup&Migrate module so I put it into each my distribution:

projects[backup_migrate][subdir] = "contrib"

In this case Drush Make get recommended version of the module and put it into "sites/all/modules/contrib".
But in some cases there is no recommended version, or if you want to use some selected version, you should input it in the instructions to Drush Make:

For example, if you want to use Defaul Content module, you should indicate the version of the module, because this modul have no recommended version yet:

projects[defaultcontent][subdir] = "contrib"
projects[defaultcontent][version] = "1.0-alpha4"

Also you can get latest version of module directly from GIT:

projects[addthis][subdir] = "contrib"
projects[addthis][download][type] = "git"
projects[addthis][download][url] = "http://git.drupal.org/project/addthis.git"
projects[addthis][download][branch] = "7.x-2.x"

How to add themes?

projects[omega][type] = "theme"

We should touch at list one parameter to include project into distro, so we indicate that Omega is theme, but it is obvious for us.

And finnaly we can include in our distributions third party libraries, for example lets add colorbox to our distribution:

libraries[colorbox][download][type] = "get"
libraries[colorbox][download][url] = "http://colorpowered.com/colorbox/latest"
libraries[colorbox][directory_name] = "colorbox"

The code will be putted into "sites/all/libraries/colorbox" folder.

I think this information will be enough to start you own experiments. I'm going to create the second part of the tutorial. Waiting the updates in my Blog.

Thanks!

How to transfer the content type settings by Features?

In the post How to Create Content Type in Drupal 7 Programmatically I told about creating content type with using .install file.

But more often during development, we are dealing with a situation where some type of content is created in the admin to set up a specific field. These settings are made on staging while production site lived his own life, filled with new content and users. Obviously, it would be inexcusable mistake to overwrite production DB by staging ones.

On the other hand, we can transfer all the settings manually, but it takes a long time, moreover, there is no guarantee that we do not forget anything.

A simple solution to this issue is to use Features module.

Lets we have the type of content portfolio (admin/structure/types/manage/portfolio/fields):

We should be sure that module Features exitsts and enabled.

Lets go Administration » Structure » Features
and click "Create Feature" tab.

We should input "Name" and "Description" of our new feature. Also you can see "Version" and "URL of update XML", do not pay attention on them. Just now we are not going to provide our feature to somebody and make some new versions.

Lets go ahead! Take a look on the second fieldset. We should select content type that we would like to export. On the right we can see dependencies.

After we press download the feature will be ready for downloading.
In the current case got portfolio_content_type.tar

If you will take a look on content of this archive you can find module.
Pay attention to the .info file. Module has dependencies:

dependencies[] = "colorbox"
dependencies[] = "features"
dependencies[] = "image"
dependencies[] = "strongarm"

So on the site, where you would like to copy content type, these modules should be enabled.

Copy this module to the other site and you can see it in the list of modules:

But you should not turn on it here. Please, go to Administration » Structure » Features:

You can see the list of all features available. On this cas there is only one Feature.
You can turn on it to click on "Disabled". And new content type with corresponding field settings will appear!

Good! It is more simple way to create content on the site by one click that I told in the topic How to Create Content Type in Drupal 7 Programmatically. But it is feature based method, in the post that I mention content type was created without Features module, it is more native way, more preferable for the Code Driven Development approach.

Pages

Subscribe to RSS - Planet Drupal