Blog

05/10/2011

Easily select nodes with EntityFieldQuery

Remember the old times in Drupal 6 when you needed to do complicated join to select nodes.

Now it’s (quite…) easy with EntityFieldQuery. But this is not much documented so I will provide some examples.

1. select the 50 latest news (that are node referenced)

$query = new EntityFieldQuery();
$result = $query->entityCondition('entity_type', 'node', '=') // select nodes
		          ->propertyCondition('type', 'news', '=') //type news
		          ->propertyCondition('status', '1') //published, you don't need to add '=' it's added by default
		          ->fieldCondition('field_newapp', 'nid', 0, '>') // node referenced so the 2nd parameter is nid
		          ->propertyOrderBy('created', 'desc') //most recent first
		          ->range(0,50) // limit
		          ->execute();

then you can retrieve formatted result by using

$news = node_view_multiple(node_load_multiple(array_keys($result['node'])), 'full');


2. select all documents with title beginning with Management report belonging to ‘int’ and ‘both’

$query = new EntityFieldQuery();
$query->entityCondition('entity_type', 'node') // the third '=' is not necessary
 ->propertyCondition('type', 'document')
 ->propertyCondition('title', 'Management report%', 'like') // here we use the 'like' operator
->fieldCondition('field_appintext', 'value', array('int','both'), 'IN') // 'in' operator
 ->execute();


3. check if 2 conditions are met (AND)

$query = new EntityFieldQuery();
$query->entityCondition('entity_type', 'node')
 ->propertyCondition('type', 'status')
 ->fieldCondition('field_selectlistreq', 'value', $env[$current]['type'], '!=') //note the 2nd parameter 'value'
 ->fieldCondition('field_appxmlid', 'value', $id)
->fieldOrderBy('field_appname', 'value') //sort on a field property
->execute();


4. 2 conditions with OR

or seems not to be supported :(

5. select users

$query = new EntityFieldQuery();
$query->entityCondition('entity_type', 'user')
 ->fieldCondition('field_postcode', 'value', $postcode);

then select them with

$napps = user_view_multiple(user_load_multiple(array_keys($result['user'])), 'full');


6. select terms (‘projects’ vocabulary for current user)

$result = $query->entityCondition('entity_type', 'taxonomy_term')
 ->entityCondition('bundle', 'projects')
 ->fieldCondition('field_relatedusers', 'uid', $GLOBALS['user']->uid)
 ->execute();
//select with
 $tids = taxonomy_term_load_multiple(array_keys($result['taxonomy_term']));

you can select files as well…

more technical info on Drupal API. some examples on the Drupal site

19/04/2011

Hide input format and filter tips

When you are using the default Seven as your admin theme, it’s not convenient to hide the input format and filter tips because your custom theme css is not loaded at this point.

The trick is to load a css in a custom module and once your module will be enabled, the css will be integrated in the seven theme.
for instance:

function mymodule_init() {
 drupal_add_css(drupal_get_path('module', 'mymodule')."/css/myseven.css", array('group' => CSS_DEFAULT, 'every_page' => TRUE));
 }

then you can easily overwrite the css of seven and hide the input format chooser and filter tips
.filter-wrapper {display: none;}

edit: sometimes, it’s not enough to only apply custom  css formatting to your admin theme, you need custom template files. The trick is to create a simple temlate with seven as base theme.

Create a new folder “myseven” with file myseven.info inside

core = "7.x"
 engine = phptemplate
name = My Seven
 description = seven customized
 base theme = seven

and you have a new fully functionnal theme, identical to seven but ready to be customized.

23/03/2011

“Notice: Undefined index” quick fix in drupal7 error reporting

In drupal 7 , the error reporting settings in php.ini is overridden by the bootstrap sequence. Even error reporting changes in your htaccess won’t work… drupal force you to use E_ALL , the new standard for upcoming php 6

As result some modules may produce undefined variables that will be displayed as messages “Notice: Undefined index” or “Notice: Undefined variable” and your logs will grow insanely…

the solution is to add in your settings.php the line

ini_set('error_reporting', 'E_ALL ^ E_NOTICE');
to micmic the default behavior of php 5.2


02/07/2010

Image handling

filesystem

public : /sites/default/files

every files are downloadable, they can be hidden via permissions but accessible through file system

private : /system/files

drupal control file download and show 403 if no permission


cck

imagefield D7core

Depends on filefield D7core :  ajax uploads

-> restriction on image : type / size / resolution
-> features : alt / title tags with tokens, default image
-> display : image, link, path, IMAGECACHE preset

further config / features

-> “full” gd library (not default on debian like)  or this link
-> uploadprogress install it with pear  [pecl install uploadprogress]
-> max file size (htaccess or php.ini) :  [post_max_size = 100M] and [upload_max_filesize = 2M] directive

imagecache D7core : presets on cck + views

Depends on imageapi D7core and gd library [aptitude install php5-gd]
call with [print theme('imagecache', 'imagecache_preset_name', 'original_image_filepath', "alt_tag", "title_tag", "custom_attributes_as_class_or_id"); ]

-> play with size, rotation, + effects – desaturate (bw conversion) – sharpening
-> create image on demand. if file doesn’t exist, image cache create it

imagecache_actions D7 ?

-> “layer style“  : Watermark (place an image over a source picture), Background, text overlay, canvas manipulation
-> colors : colorize image, invert, darken / lighten
-> feature : rounded corners, alpha blending, file format switcher

imagecache_profiles
imagecrop / imagefield_crop :  js resizing
imagefield_extended : Add additional data to images other than the default Description, Title and Alt.
image_fupload : upload multiple images with one simple click

bonus :

image integration with wysiwyg

wysiwyg D7ready + tinymce (see wysiwyg config) + imce D7ready + imce_wysiwyg bridge D7?
activate in “button and plugin” > imce (wysiwyg > tinymce config)

alternative to imce filefield_insert “use a cck filefield for uploading images and send the image to the RTE”

lightbox integration and plenty of gallery modules…

Multisite setup

The goal is to have a single drupal core to handle multiple sites / instances

1. installation

install drupal as usual

2. directory structure

inside site/ create a directory for each of your site named yoursitename.tld

inside yoursitename.tld create

  • directories for the specific modules and themes (you can then split it in contrib/ and custom/) + files
  • copy settings.php and adapt db site’s specific values
  • put the modules used by every sites (cck, pathauto, devel, admin_menu, …) in site/all/modules

3. virtual host

  • DocumentRoot is the same for every sites : that’s where your installation sits (/var/www/drupal6 for example)
  • ServerName is the name of your site (!), drupal will use it to map the name of your site.tld with the site/ directory structure

4. pros

  • update core / shared modules only once
    => you can create a script to run cron for all sites
  • quick creation of new sites

5. cons

  • on core issues, all sites are down…
  • high load of the server
  • you have to manually run update.php on every site (it can take times when a site may be + – down)

more info on drupal’s website

6. sharing databases / tables

it’s possible to share data between sites.

example: if you want sitea and siteb using the same users, but with different content, you will have

  • 3 databases for the 2 sites, (1 for content sitea / siteb, 1 for shared tables)
  • shared tables (users, sessions,…) must be have the prefix of the shared database in settings.php / Database area ( shared_db. with . for sql join)
  • a default prefix (indicated only once) for other tables
  • $db_prefix = array( ‘default’ = ”, ‘users’ = ‘shared_db.’, ‘role’ = ‘shared_db.’, ‘sessions’ = ‘shared_db.’, );

  • to permit a same user login on sitea AND siteb, install single sign on module

note : it’s also possible to have only 1 databases with same prefixes for common table and different prefixes for the other ones (this time prefix without . ’cause we use the same db)

more info on drupal website

note : you can also take a look, at this video with interesting server settings

=> an other interresting module (not tested yet) : Domain

edit : I’ve test it on several projects and Domain module is awesome !! nice documentation, incredible functionalities , powerful hooks… a really must have module for multisite management !!