Who love to Drupal

Cool module: Simple Hierarchical Select

Posted by drupallovers on April 21, 2015

Cool module: Simple Hierarchical Select.


Posted in Drupal7 | Leave a Comment »

Showing node count per term in views listing

Posted by drupallovers on July 28, 2014

Here are the step needed to show the count of nodes that are tagged with each term in a term list view!

  1. In your term list view, add a relationship (in the ‘Advanced’ section, which is collapsed by default) to the nodes tagged with that term.  In my example, my term is called ‘Topic
  2. When you are configuring this relationship, you have the choice to exclude terms that don’t contain the relationship (so to exclude terms that have no nodes tagged with it) or not.  In my case, I want to display all terms, even if they have 0 nodes with that topic, so I will leave that box unchecked. I have also renamed this relationship to make it easier for me to reference in the future:
  3. Next, we want to enable aggregation in our view
  4. Finally we are ready to add node info along with each of the listed terms.  Go back to the ‘Fields‘ section of your view and add a node field.  We won’t actually display it, but will just use it for counting.  In my example, I’m choosing to add ‘Node: nid‘ because that’s unique.  After you add your field, it’ll ask you what type of Aggregation you want, since we enabled aggregation for this view.  Choose ‘Count DISTINCT
  5. If you just leave the field like that, you’ll see that it’ll print out the count of the node nids for each of the taxonomy terms it has listed, but it won’t be very pretty!  So, in the configuration screen for this field, I prefer to have the following settings.  Note that I am not including a label and am surrounding the field output with parentheses:
  6. Now your view output should be something like this:
  7. To make it even better, let’s click to edit the Field Settings in the ‘Format’ section.  We can make these fields inline, so they appear in one line
  8. Now, this will be your final output



Posted in Drupal, Drupal7 | Leave a Comment »

Drupal feature Module example

Posted by drupallovers on July 13, 2012

In this example we create an Online Videos feature. The site builder configured a lot in preparation of this feature we are currently not interested in.

Step 1. admin/build/features/export

As you can see we added a name, description and a version. Next step will be defining what this feature provides.

Step 2. Select features components.

From the “Add Components” dropdown we have to select the components the feature consists off. This is about a video node so we select “Node”. From the checklist we only need the video node type.

The auto-detect functionality grabs the required building blocks node (video), content (video-field_video), modules (emvideo, features). Therefore, when we want to install the feature, we need to make sure we have installed the required modules.

Step 3. Download the feature.

When satisfied with all components, click the download button and save the tarball (in this case, online_videos-6.x-1.0-alpha1.tar.gz).

Step 4. Install and enable the feature.

Best thing to do is untar the file in your current project. As described above, features are not listed on the site/build/modules page even though they are technically modules. To keep them separate, you should consider putting all of your features in a separate directory — e.g., site/all/modules/custom/your-feature.

The feature now appears at admin/build/features. Checking the box next to the feature’s name and saving page causes the features module to check for the current state all features.

Step 5. Visit admin/build/modules

When checking for the module online video module it’s not there. Searching for the name would show you a dependency on online_video module. To disable such a module you have to disable the feature first.


  • We have said nothing about what drupal projects you need to install to be able to install our example feature.
  • If we had created a view this would be exported too. test it yourself.

Posted in Drupal6, Drupal7, Modules | Leave a Comment »

Deploy Content from Development Server to Destination Server On Drupal 7

Posted by drupallovers on July 4, 2012

Deploy Content Development Server to  Destination Server On Drupal 7 :

We have two Server  1 is source and another is Destination

http://localhost:81/dev         (Source)                                          2. http://localhost:81/live (Destination)



Source server Configuration :

  1. Download the following modules. For now, you need latest dev version of at least deploy, services, uuid, ctools and entity_dependency : DeploymentServicesEntity APIUUIDCToolsViewsEntity Dependency:
2. Enable the following modules: Deployment, Deployment UI, Chaos Tools, Universally Unique ID, Services, REST Server, UUID entity resource, Entity Dependency
3.Put spyc.php into the /sites/all/modules/contrib/services/servers/rest_server/lib folder, it can be found at http://drupal.org/node/1313976#comment-5317796.
4. Go to admin/structure/deploy/endpoints and click “Add”.
5. Enter ‘Live Server’ (or whatever you want to call your destination server) for the Name. Choose “Session authentication” for Authenticator, and “REST JSON” for Service. Click “Continue.”
6. When prompted for a username and password, choose the username and password for user 1 on the destination site. Click “Continue.”
7. For Endpoint URL, enter ‘http://localhost:81/live/services/rest‘. Click ‘Finish’. Note that it appears that any path other than ‘/services/rest’ on either origin or destination generates a Request response error: -1002 missing schema.
8. Now, create a deployment plan. Go to admin/structure/deploy/plans and click “Add”.
9. Give it a name like “Push to live server.” Aggregator: Managed aggregator. Fetch only: unchecked. Deployment processor: Queue API. Endpoints: the endpoint you just created. Click “Continue.”

10. Delete successfully deployed items: unchecked. Continue.

11. No plugin to configure. Click Finish.


Destination Server

  1. Download the following modules: ServicesEntity APIUUIDCToolsViews:
2. Enable the following modules: Chaos Tools, Universally Unique ID, Services, REST Server, UUID entity resource
3. Go to admin/structure/services and click “Add”.
4. Under Name fill in ‘live’ (or whatever you want to call your destination server — must be a machine name). Server: REST, path to endpoint services/rest, Authentication: Session authentication. Click ‘Save’.
5. Back at the listing page, click the “Edit resources” link and check off the things you want to be pushable form the source site, e.g. file: create/retrieve, node: create/retrieve…You must enable the User actions “Login” and “Logout” in the resources section for Session Authentication to work.
6. Back at the listing page, click on the arrow next to the “Edit resources” link and click on “Edit server”. Check “application/x-www-form-urlencoded” and save.


Now I have created  Two Basic page About and Page1 on http://localhost:81/dev/ site.


And go http://localhost:81/dev/admin/content and select “Push To Live Server” option from Update Option. Click Deploy link on http://localhost:81/dev/admin/structure/deploy

Run Cron On Dev Site

Bot content can be found on http://localhost:81/live/ Destination Server.

Posted in Drupal7, Modules | 5 Comments »

Drupal and Varnish

Posted by drupallovers on June 12, 2012

Varnish is a HTTP accelerator (or reverse proxy) capable of serving 100,000 requests a second. Somewhat faster than Drupal, even with page-caching on!

How does it work?

Diagram of the varnish process, explained in more detail in the list below.

  • Cache-hit
    1. User requests a URL
    2. Varnish checks it’s cache
    3. Varnish retrieves the data from the cache
    4. Varnish delivers the data to the user.
  • Cache-miss
    1. User requests a URL
    2. Varnish checks it’s cache – but the data isn’t cached
    3. Varnish requests the URL from the backend
    4. Drupal processes the request and delivers a response to Varnish
    5. Varnish caches the response
    6. Varnish forwards the response to the user

Varnish magic

Varnish is capable of some cool features. It can be used for:

  • Load balancing between a series of backend Drupal servers
  • Serving assets (images/css/swfs…) from a light-weight backend whilst serving content from Drupal
  • ESI – Edge Side Includes – allowing personalised pages to be cached
  • Maintainance-mode, where Varnish can serve a “Site is being updated” page without traffic hitting the backend

What are the cons?

Like any solution, Varnish brings its own set of issues.

  • Statistics – content served by Varnish won’t hit the backend, so traditional stats (log files, the statistics module) won’t show the correct results. Use a client-side solution such as Google Analytics instead.
  • Personalisation – personalised pages are hard to cache. You will need things like ESI and custom VCL logic. Not for the faint-hearted.
  • Caching-rules complexity – choosing what to cache, how long to cache it for, and how to purge the cache if content is updated, is all complex, and needs more modules, more VCL rules. Choose a balance between complexity, performance, and investment in hardware.
  • Decreased performance – What? I hear you cry…I thought Varnish was meant to improve performance! Well, if something’s cached, it’s quicker. But cache-misses are generally slower via varnish than a direct request, because every additional system in the request-route decreases performance. In reality, most web-sites would benefit (if only to cache images and css), but it might not be suitable for a web-service.

Getting setup: How to add varnish to your existing web site

This how-to presumes that you already have your drupal site up and running, using apache on port 80.

  1. install varnish (apt-get install varnish / yum install varnish)
  2. change the varnish config to listen on port 80 Edit /etc/default/varnish Change the VARNISH_LISTEN_PORT to 80 NB: the behaviour has changed somewhat across varnish – check the docs for your version!
  3. change apache config to listen on port 8080 (or another suitable port, if something’s already running on 8080)
  4. edit the VCL to forward backend requests to apache Edit /etc/varnish/default.vcl
    backend default {
      .host = "";
      .port = "8080"; 
  5. restart apache
    I usually use “apache2ctl graceful”, rather than “/etc/init.d/apache2 restart” because this sanity-checks the configs before restarting!
  6. restart varnish: “/etc/init.d/varnish restart”
    NB: each time Varnish is restarted, its cache is cleared.

This will give you a very basic implementation – to see the benefit of varnish, you’ll want to do more.

Optimising Varnish and Drupal to work together

  • Varnish module: The varnish module provides an admin dashboard to show you the status of the Varnish server(s), and provides integration points which will clear the Varnish cache when a node is edited (when integrated with the expire module).
  • Expire module: The expire module has been separated out from Boost, and provides a generic cache-management tool which runs at page-level. Expire will purge the appropriate pages from the varnish cache when the content changes.
  • Memcache et al: use all of the normal performance tools as well. So memcache, APC, cache-sets/gets in your custom modules, etc. Varnish is an addition to the performance tools, not a replacement.
  • ESI module: Edge-side includes are difficult, but the ESI module makes them a little easier.

Some custom VCL logic

Long live assets!

Assets should live a long time. CSS, images, JS, SWFs: should all hang around in the cache.

sub vcl_recv {
  # Assets are pulled from the cache, even if we have a NO_CACHE cookie.
  if (req.url ~ "\.(png|gif|jpg|swf|css|js)$") {
    return (lookup);
sub vcl_fetch {
  # Don't cache cookies
  remove beresp.http.Set-Cookie;
  # Set a long TTL (1 day)
  set beresp.ttl = 86400s;

Is it working?

To give you some reassurance that Varnish is doing it’s job, it’s nice to see if you’re getting hits or misses. This code will add an HTTP header to report back.

sub vcl_deliver {
  if (obj.hits > 0) {
    set resp.http.X-Cache = "HIT";
  } else {
    set resp.http.X-Cache = "MISS";

How to clear the varnish cache

In case you follow all these instructions, but end up with some really private data in your cache, here’s a quick clear-cache how-to!

  • command-line: SSH into the server, and run:/etc/init.d/varnish restart
  • Telnet: Telnet to the admin port of Varnish (by default port 6082) and use the purge command
    telnet 6082
    url.purge /

    url.purge will take regex – see the Varnish docs for more info.

Posted in Drupal7, Modules | Leave a Comment »

MySql replication on same Windows machine

Posted by drupallovers on June 7, 2012

1. First install mysql-5.5.11-win32.msi on windows machine. While installing choose custom installation and change
installation path to D:\MySQL\MySQL Server 5.5
2. Use all the default parameter like Service name is MYSQL and port number is 3306 and setup bin path.
3. And also modify root password to mysql.
3. Now check whether your installation is correct or not.
4.Open dos prompt and type below command.
c:\> mysql -uroot -pmysql -hlocalhost -P3306;

If you get mysql command then everything is ok.
We will treat mysql 5.5 is MASTER.
Now create one database:

mysql> create database santosh;

5. Now install another version of mysql (mysql-5.1.56-win32.msi)  for SLAVE. Again while installing choose custome
installation and change installation path to D:\MySQL\MySQL Server 5.1
6. Change service name to MYSQL2 and port number to 3307
7. Modify root password to root.
8.Now check whether your installation is correct or not.
9.Open new dos prompot and type below command.

c:\> mysql -uroot -proot -hlocalhost -P3307;

If you get mysql command then everything is ok.
We will treat mysql 5.1 is SLAVE.
Now create one database:
mysql> create database santosh;

Up to here two mysql instance are running in your windows machine.

Now start the replication implementation.

1. Open D:\MySQL\MySQL Server 5.5\my.ini then add four options to the [mysqld] section of the my.ini file


save it.
Restart the MYSQL service from your pc. MyComputer -> Right click -> click on Manage -> Services and Application -> Services ->
search MYSQL on right side, right click on that MYSQL and click on restart.

The next step in setting up replication is creating an account that will be used exclusively for replication. We strongly advise creating a dedicated replication user be created for better security so you won’t need to grant any additional privileges besides replication permissions. Create an account on the master server that the slave server can use to connect. As mentioned, this account must be given the REPLICATION SLAVE privilege.

Open one dos windows for all MASTER operation.
c:\>mysql -uroot -pmysql -hlocalhost -P3306;
mysql> create user ‘replication_user’ identified by ‘password’;
mysql> grant replication slave on *.* to ‘replication_user’@’%’ identified by ‘password’;
mysql> flush privileges;

| File               | Position | Binlog_Do_DB | Binlog_Ignore_DB |
| dellxp1-bin.000001 |     338 |              |                  |
1 row in set (0.00 sec)

Please note down this file name and position, it will use to later.

Now take your backup of your MASTER database as we have new database so this below step are not required. But when you have to create SLAVE of running database then it step must be required, so lets go these below step too.

Open new dos prompt.

Taking backup from MASTER:
C:\>mysqldump -uroot -pmysql -hlocalhost -P3306 santosh> d:\test2.sql

Now export this back to SLAVE, run below command on same dos windows.
C:\Users\sumankbi>mysql -uroot -proot -hlocalhost -P3307 santosh< d:\test2.sql

Now some change on SLAVE side:
1. Open D:\MySQL\MySQL Server 5.1\my.ini then add four options to the [mysqld] section of the my.ini file


save it.
Restart the MYSQL2 service from your pc. MyComputer -> Right click -> click on Manage -> Services and Application -> Services ->
search MYSQL on right side, right click on that MYSQL2 and click on restart.

Open one dos windows for all SLAVE operation.
c:\>mysql -uroot -proot -hlocalhost -P3307;

mysql> stop slave;

mysql> show slave status\G;
Output will come huge, among two line should be like:
Slave_IO_Running: No
Slave_SQL_Running: No

Because slave is stopped now.
Now time came to start slave.
on slave side:

mysql> start slave;
Now check slave status:
mysql> show slave status\G;
Output will come huge, among two line should be like:
Slave_IO_Running: Yes
Slave_SQL_Running: Yes

If both values are Yes, then everything are ok.

Now you can check your replication work.

Create some table in MASTER santosh database or any database (those should be there at SLAVE side) then check at slave side.

Now you stop slave again then you change of MASTER will not come but once again you will start slave then  slave will get automatically updated from last time stopped pointer.

More details on http://dev.mysql.com/doc/refman/5.0/en/replication.html



Posted in Mysql | Leave a Comment »

Drupal 7 database layer

Posted by drupallovers on June 5, 2012

This post is my effort to guide you through the whole new abstraction layer for accessing the database server, which comes with the Drupal 7 core distribution. In this blog-post I’ll try to explain to you guys (girls) how this new layer works, without diving into all the details, in order to give you a clear view on this new system.

First of all I’ll explain the benefits of this new system to you. Drupal needed a database system that could easily support multiple database servers in a unified way which preserves the syntax power of SQL. The system was also build to enforce the security checks. There are 6 different types of Query’s which can be called in this database system: Insert, Update, Delete, Merge, Static and Dynamic.

Now lets get it started!


We should start by taking a look at the renewed database definition in the settings.php. In most cases you will be using a drupal site with only one database. For this you should use the following structure.


$databases['default']['default'] = array(
‘driver’ => ‘mysql’,
‘database’ => ‘drupaldb’,
‘username’ => ‘username’,
‘password’ => ’secret’,
‘host’ => ‘localhost’,


The first thing you should notice are the values “default” in the $database array. The first one is the CONNECTION KEY, the second one is the TARGET.

The connection key is a unique identifier for a database connection, there must ALWAYS be a ‘default’ connection key available.

The target is used to define master/slave database structures. If the master (default) isn’t available, the system will search for the slave database. It is also possible to flag a query to run on the slave database. To make this a bit clearer I’ll give you a more complicated database structure.

$databases['default']['default'] = array(
‘driver’ => ‘mysql’,
‘database’ => ‘drupaldb1′,
‘username’ => ‘username’,
‘password’ => ’secret’,
‘host’ => ‘dbserver1′,
$databases['default']['slave'][] = array(
‘driver’ => ‘mysql’,
‘database’ => ‘drupaldb2′,
‘username’ => ‘username’,
‘password’ => ’secret’,
‘host’ => ‘dbserver2‘,

In this case, the first database is the default database, the second is the slave databases.

It is also possible to define separate database structures.

$databases['default']['default'] = array(
‘driver’ => ‘mysql’,
‘database’ => ‘drupaldb1′,
‘username’ => ‘username’,
‘password’ => ’secret’,
‘host’ => ‘dbserver1′,
$databases['extra']['default'][] = array(
‘driver’ => ‘mysql’,
‘database’ => ‘drupaldb2′,
‘username’ => ‘username’,
‘password’ => ’secret’,
‘host’ => ‘dbserver2‘,

Note that no matter how many connections are defined in the settings file, These connections will not be used by Drupal until they are actually opened.


Select Query

So far for the database connections, now lets take a look at the actual use of query’s in this new database layer. For the regular select query’s not much changes. Here is an example of a select query with a short explanation.

$result = db_query(“SELECT nid, title FROM {node} WHERE type = :type”, array(
‘:type’ => ‘page’,

The db_query function uses three arguments, first one is the query string, the second one are the values used to fill up the placeholders. The third one will be explained at the next example.

Note that the placeholder (:type) doesn’t use quotes. Another thing you should take in to account is to put your database names between {}. This is needed for the database system to attache a prefix string if this is defined in your settings.

Now for the third argument of the db_query we will take a look at the following code:

$result = db_query(“SELECT nid, title FROM {node}”, array(), array(
‘target’ => ’slave’,

The third argument is an array of configuration directives to detect the way the query should run. In this case the query runs on the slave database. I won’t go into the details here, because (as I said before) in this blog post I will only pick up the basics of the new database system.

The following is just a handy guide about the way you can use the database query’s results. (Not 100% relevant to this post, but this might come in handy for some of you. The others should just scroll through the code, as if it doesn’t exist).

$result = db_query(“SELECT nid, title FROM {node}”);
foreach ($result as $record) {
// Do something with each $record

$record = $result->fetch(); // Use the default fetch mode.

$record = $result->fetchObject(); // Fetch as a stdClass object

$record = $result->fetchField($column_index); // Fetch only one field.

$number_of_rows = $result->rowCount(); //Count the results.


Insert Query

Now we’ve arrived to he fun part. The INSERT, DELETE and UPDATE query’s require that you use the query builder object in order to behave consistently across all different databases. This is where the new object-oriented query API comes in.

The compact INSERT form is the following:

$nid = db_insert(‘node’)
‘title’ => ‘Example’,
‘uid’ => 1,
‘created’ => REQUEST_TIME,

This will result in the following query:

INSERT INTO {node} (title, uid, created) VALUES (’Example’, 1, 1221717405);

Note: If you don’t call the execute() method, the query will not run!

The insert query object can also be used with multiple values. To insert multiple rows you shouldn’t only use fields() but also values(). In this case fields() only defines the fields, but doesn’t put any content into the selected fields. The values() may be called multiple times in order to add more than one line to your database.

$query = db_insert(’node’)

->fields(array(‘title’, ‘uid’, ‘created’))
‘title’ => ‘Example’,
‘uid’ => 1,
‘created’ => REQUEST_TIME,
‘title’ => ‘Example 2′,
‘uid’ => 1,
‘created’ => REQUEST_TIME,

Using a ‘foreach’ the code will look like this:

$values = array(
‘title’ => ‘Example’,
‘uid’ => 1,
‘created’ => REQUEST_TIME,
‘title’ => ‘Example 2′,
‘uid’ => 1,
‘created’ => REQUEST_TIME,
$query = db_insert(‘node’)->fields(array(‘title’, ‘uid’, ‘created’));
foreach ($values as $record) {


Update Query

Next stop is the UPDATE query. The update query is pretty straight forward, if you understand how the insert query’s work, it shouldn’t be a problem to understand the update query. Here it goes:

$num_updated = db_update(‘node’)
‘uid’ => 5,
’status’ => 1,
->condition(‘created’, REQUEST_TIME - 3600, ‘>=’)

This will result in the following query:

UPDATE {node} SET uid=5, status=1 WHERE created >= 1221717405;

Not much to explain here, so let’s go to the DELETE query’s.


Delete Query

Again the same story here. The DELETE query is probabily the easiest form of the query object:

$num_deleted = db_delete(‘node’)
->condition(‘nid’, 5)

This will result in the following query:

DELETE FROM {node} WHERE nid=5;


Merge Query

Finally we’ve got to the last one. The MERGE query. This one is a bit more complicated. If you would strip this one down to it’s original form, you will finde that a merge query is actually just the combination of an insert and an update query. In php it would be something like this:

if (db_query(”SELECT COUNT(*) FROM {example} WHERE id=:id”, array(’:id’ => $id)->fetchField()) {
// Run an update using WHERE id = $id
else {
// Run an insert, inserting $id for id

In the new database API structure the merge query’s are build up like this:

->key(array(‘name’ => $name))
‘field1′ => $value1,
‘field2′ => $value2,

Here the “example” table is used. The specified key field ‘name’ has the value of $name. Now two things could happen.

First option: If the $name value exists in the database, then fields “field1” and “field2” will get an update with the correspondingvalues.

Second option: If the $name value doesn’t exist in the database, a new row will be created in which “name” gets the value $name, “field1” gets the value $field1 and “field2” gets the value $field2.

In some cases the values you want to set will have to be different, according to the fact that the key field does or doesn’t already exist. This can be handled in two ways.

->key(array(‘name’ => $name))
‘field1′ => $value1,
‘field2′ => $value2,
‘field1′ => $alternate1,

In this case, if the “name” already exists the value of “field1” will be $alternate1, and the value of “field2” will be $value2. If the “name” doesn’t allready exist, $value1 and $value2 will be used.

It is also possible to use expressions. I’ll give you an example in which, if the ‘name’ already exists, the “value1” field will become the current value +1:

->key(array(‘name’ => $name))
‘field1′ => $value1,
‘field2′ => $value2,
->expression(‘field1′, ‘field1 + :inc’, array(‘:inc’ => 1))

Note that expression() can be used multiple times, 1 time for each field.

Field updates can also be limited, if the row already exists. In this case, if the “name” already exists, only “field2” will be updated, and “field1” will be ignored:

->key(array(‘name’ => $name))
‘field1′ => $value1,
‘field2′ => $value2,

This is the end of my quick guide into the new Drupal 7 database layer. Hope you’ve enjoyed it. For more detailed information about this system, I would like to refere to the official drupal database API:http://drupal.org/developing/api/database

Posted in Drupal With Mysql | 5 Comments »

How to upgrade PHP version in XAMPP

Posted by drupallovers on May 16, 2012

Having been unable to find a definitive guide to upgrading the XAMPP PHP version to PHP 5.3.0rc2, I decided to improvise on a guide for installing the PHP 5.3 alpha.
My guide will describe how to upgrade the current XAMPP PHP version to the second release candidate of version 5.3. It is expected that this method will also work for the third release candidate when it is released later this month.

Step 1: Make backups

Before starting, make sure to backup any settings, custom modules and most importantly the htdocs directory, which contains your scripts and page resources. This directory is normally located atC:\xampp\htdocs\
Step 2: Preparation
  1. Download PHP 5.3.0rc2. I use the VC6 build in order to minimise any potential compatibility issues.
  2. It is also recommended that you download the latest Windows version of XAMPP. While this is an upgrade guide that shouldwork with previous versions of XAMPP, it is recommended that a fresh copy of the core files is used.
  3. Stop any instances of the Apache service that might be running.
Step 3: The upgrade
This guide will assume your XAMPP directory is C:\xampp\
  1. Extract the XAMPP archive to a directory of your choosing, I would recommend using the default C:\xampp\
  2. Extract the contents of the PHP archive to C:\xampp\php\, overwriting the contents of this directory with the new files.
  3. Open the file C:\xampp\apache\conf\extra\httpd-xampp.conf and ensure the following lines are present in this order:
    LoadFile "/xampp/php/php5ts.dll"
    LoadModule php5_module "/xampp/apache/bin/php5apache2_2.dll"
  4. Replace C:\xampp\php\php.ini with C:\xampp\php\php.ini-dist
    Uncomment the lines:

    Replace the line
    magic_quotes_gpc = On
    magic_quotes_gpc = Off
  5. Copy all files in the C:\xampp\php\ to C:\xampp\apache\bin\ (do not copy the subdirectories or their contents).
After following the above steps, restart your Apache service (this can be done using C:\xampp\xampp-control.exe or manually through the control panel/command prompt). Your PHPinfo should indicate that the upgrade has been successful.
I will update this post if I discover any problems from using this method, or a cleaner (automated) means of performing the upgrade.

Posted in Apache, Php | 25 Comments »

Drupal Site Configuration: Site Information, Triggers and File

Posted by drupallovers on May 14, 2012

People often assume that the basics are easy to master and therefore, don’t require much thought. Things are not quite so simple in reality because while a site’s basic setup is, more often than not, easy to implement, the more subtle problem is in knowing what to implement, and how to implement it in the first place. Precisely understanding what you need from a site is particularly important for this reason.

Does this mean that you should not start working directly on the site unless you know exactly what is required? Not really; like most things, it’s a bit of a trade-off when it comes to starting out with the development of a Drupal website. This is because it is almost impossible to determine exactly what the site will need and how its functionality should be provided until you have been working with it for some time. Often, you will find yourself modifying the behavior of a site based on feedback from the users.

In this article by David Mercer, author of the book Drupal 7, we are going to talk about the following Drupal site configuration topics:

  • Site information
  • Actions and Triggers
  • Shortcuts
  • File system

(For more resources on Drupal, see here.)

Not everything that is available in Drupal’s Configuration section is discussed in this article. Some settings are very straightforward and really don’t warrant more than perhaps a brief mention.

Before we start

It is sensible to make note of a few important things before getting our hands dirty. Make it second nature to check how the changes made to the settings affect the site. Quite often settings you modify, or features you add, will not behave precisely as expected and without ensuring that you use a prudent approach to making changes, you can sometimes end up with a bit of a mess.

Changes to the site’s structure (for example, adding new modules) can affect what is and isn’t available for configuration so be aware that it may be necessary to revisit this section.

Click on Configuration in the toolbar menu. You should see something like the following screenshot:

A quick point to mention is that we aren’t giving over much space to the final option—Regional and Language. This is because the settings here are very basic and should give you no trouble at all. There is also an online exercise available to help you with date types and formats if you are interested in customizing these.

Let’s begin!

Site information

This page contains a mixed bag of settings, some of which are pretty self-explanatory, while others will require us to think quite carefully about what we need to do. To start with, we are presented with a few text boxes that control things like the name of the site and the site slogan.

Nothing too earth shattering, although I should point out that different themes implement these settings differently, while some don’t implement them at all.

For example, adding a slogan in the default Garland theme prints it after the site name as shown in the following screenshot:

Whereas, the Stark theme places the slogan beneath the site name:

Let’s assume that there is a page of content that should be displayed by default—before anyone views any of the other content. For example, if you wanted to display some sort of promotional information or an introduction page, you could tell Drupal to display that using this setting. Remember that you have to create the content for this post first, and then determine its path before you tell Drupal to use it. For example, we could reference a specific node with its node ID, but equally, a site’s blogs could be displayed if you substitute node/x (in node/ID format) for the blog.

Once you are looking at the content intended for the front page, take note of the relative URL path and simply enter that into the text box provided.

Recall that the relative URL path is that part of the page’s address that comes after the standard domain, which is shared by the whole site. For example, setting node/2 works because Drupal maps this relative path to http://localhost/drupal/node/2

The first part of this address, http://localhost/drupal/ is the base URL, and everything after that is the relative URL path.

Sometimes, the front page is a slightly more complex beast and it is likely that you will want to consider Panels to create a unique front page. In this case, Panels settings can override this setting to make a specific panel page as the front page.

The following settings allow you to broadly deal with the problem of two common site errors that may crop up during a site’s normal course of operation—from the perspective of a site visitor. In particular, you may wish to create a couple of customized error pages that will be displayed to the users in the event of a “page not found” or “access denied” problem.

Remember that there are already pretty concise pages, which are supplied by default. However, if you wish to make any changes, then the process for creating an error page is exactly the same as creating any other normal page.

Let’s make a change very quickly. Click on Add new content in the Shortcuts menu and select Basic page. Add whatever content you want for, say the Page not found! error:

Don’t worry about the host of options available on this page—we will talk about all of this later on. For now, simply click on the Save button and make note of the URL of the page when it is displayed. Then head back to the Site information page, add this URL to the Default 404 (not found) page dialog, and then click on the Save configuration button:

If you navigate to a page that doesn’t exist, for example, node/3333, you should receive the new error message as follows:

In this example, we asked Drupal to find a node that does not exist yet and so it displayed the Page not found! error message. Since Drupal can also provide content that is private or available to only certain users, it also needs the access denied error to explain to the would-be users that they do not have sufficient permissions to view the requested page. This is not the same as not finding a page, of course, but you can create your own access denied page in exactly the same way.

Finally, you will need to specify how often cron should run in the Automatically run cron drop-down at the bottom of the Site information page. Cronjobs are automated tasks (of any type—they could be search indexing, feed aggregation, and so on) that should run at specified intervals. Drupal uses them to keep itself up-to-date and ensure optimal operation.

Drupal uses web page requests to initiate new cron runs once the specified interval has elapsed. If your website does not get visited regularly, cron itself cannot run regularly.

Running cron every few hours is reasonable for the vast majority of sites. Setting it to run too quickly can create a huge load on the server because each time the cron is run, all sorts of scripts are updating data, performing tasks, and consuming server resources. By the same token, run cron too infrequently and your site’s content can become outdated, or worse, important module, theme, and core updates can go unnoticed, among other things.

Actions and triggers

Quite often, it happens that for specific events, it is useful to have Drupal automatically perform a specified task or action. An action, in the Drupal sense, is one of a number of tasks that the system can perform, and these usually relate to e-mailing people or acting upon user accounts or content. There are a number of simple actions that are available as well as a few more advanced ones that can be set up by anyone with sufficient permissions.

To configure actions, navigate to Actions in SYSTEM under the Configuration menu in the toolbar:

Default simple actions cannot be modified, so we will ignore these for the moment and focus on creating a new, advanced action. Set up a new Send e-mail action by selecting it from the drop-down list and click on the Create button, as shown in the preceding screenshot. This brings up the following page that can be set according to how this specific action will be used:

It should be clear that the intention of this e-mail is to notify the staff/administration of any new site members. The Label field is important in this respect because this is how you will distinguish this action from the other ones that you may create in the future. Make the description as accurate, meaningful, and concise as possible to avoid any potential confusion.

Also notice that there are several placeholder variables that can be inserted into the Recipient, Subject, and Message fields. In this instance, one has been used to inform the e-mail recipient of the new user name, as part of the message.

A click on the Save button adds this new action to the list where it can be modified or deleted, accordingly:

So far so good—we have set the action, but this in itself does absolutely nothing. An action cannot do anything unless there is a specific system event that can be triggered to set it off. These system events are, perspicaciously enough, called triggers and Drupal can look for any number of triggers, and perform the actions that are associated with it—this is how actions and triggers work together.

Triggers are not part of the topic of Drupal configuration. However, we will discuss them here for completeness, since actions and triggers are integrally linked.

Triggers are not enabled by default, so head on over to the Modules section and enable the Triggers module. With the module enabled, there will now be a new Triggers link from the Actions page. Clicking on this brings up the following page:

Triggers are divided into five different categories, each providing a range of triggers to which actions can be attached. Assigning a trigger is basically selecting an action to apply from the drop-down list of the relevant trigger and clicking on the Assign button.

To continue with our example, select the USER tab from the top of the Triggers overlay and, in the TRIGGER: AFTER CREATING A NEW USER ACCOUNT box, select the newly defined action, as shown in the following screenshot:

Click on the Assign button, and the newly assigned action will show up in the relevant trigger box:

In the same way, a large number of actions can be automated depending on the system event (or trigger) that fires. To test this out, log off and register a new account—you will find that the New User Alert e-mail is dutifully sent out once the account has been registered (assuming your web server is able to send e-mail).

Drupal 7

Drupal 7 Create and operate any type of Drupal 7 website quickly and efficiently

Read more about this book

(For more resources on Drupal, see here.)


Shortcuts are a new feature of Drupal 7 and allow administrators (or anyone with sufficient permissions) to create sets of links that can be accessed by others using the shortcuts bar—directly below the toolbar menu. By default, Add content and Find content are the only two links that are provided, but you may change these regularly depending on what you are working on at any given time.

For example, it may be useful to create a set of shortcuts that involve theme-related links for quick access when it’s time to theme the site. By the same token, adding links to views and displays might be more useful when working on content.

The overlay system is integrated with shortcuts, making it easy for the administrators to add links to their shortcuts. For example, let’s say we wanted a set of configuration shortcuts so that all the main configuration tasks are readily accessible at a moment’s notice.

To do this, we need to first add a new shortcut set. Go to Shortcuts in USER INTERFACE under Configuration, and click on the Add shortcut set link, to bring up the following page:

Now go to your account, and select the Shortcut tab. Select the new Configuration option and save the changes by clicking Change set to ensure that you are viewing the correct shortcut set. Now click on Edit shortcuts in the shortcuts bar to bring up the list of links contained in this set:

Nothing too exciting yet. In fact, this is exactly the same as the default shortcut set. We can add new shortcuts to this list manually by clicking on the Add shortcut link and providing a name and path manually:

Clicking on the Save button shows the new link added to the list and it is also now available in the shortcuts bar on the top of the page.

The other, easier way to add links is simple; click on the plus icon next to the overlay name. A small popup appears to the right of the icon while hovering over it. Take note of this because it indicates which shortcut set the link will be added to.

The new shortcut will appear along the top of the page with the rest of the links.

Anyone with sufficient permissions can create their own set of shortcuts and use them as they choose. The shortcuts system also provides a block that can be added to the site like any other block. Making effective use of shortcuts can help you cut down the wasted navigation time—just remember to select the most relevant set from your account because it is only possible to view one at a time.

File system

How you deal with the file system settings really depends on what type of content you visualize your site using. If you know that most files should be available for anyone to download, then leave the Default download method as Public. By the same token, if you want some control over who can access the files then use the Private method.

Public files can be accessed directly through a browser without having to go through your Drupal website. So, if someone liked a video you posted, they could reference it from their own website, allowing their visitors to see the video using your bandwidth to serve it—obviously not ideal.

You need to keep an eye on this and find out if your host service provides some sort of hotlinking protection to combat this.

Assuming you want to make your download method private, you will need to specify a directory that is not directly available over the web—in other words, it is outside the document root folder.

The same technique is used for the temporary files folder that Drupal requires in order to properly handle any files you or the site users might deal with.

On your development machine, you might end up with something like the following screenshot (Public file downloads):

To make this private, create a folder outside of the web root (but still within the web server folder), add it to the Private file system path option, and click on the Save configuration button, as shown in the following screenshot:

With the new absolute path to the private folder specified (in this case, privatedrupalfiles) there will now be an additional Default download method available for selection, entitled Private local files served by Drupal.

The Default download method is the default behavior. Individual download methods can be set on each file type field added to any content type.

Before continuing, let’s confirm that we can specify a download method for any file without problems. Go to Content types under Structure, and click on the manage fields link next to one of the content types, say blog entry. Add a new field of the File type and save the changes. You will then be able to select Public files or Private files in the Upload destination section on the following configuration page, as shown in the next screenshot:

The important point here is that each file uploaded to the site can be controlled on a field level basis, and more importantly on a field level per content type basis. This is a vast improvement over Drupal 6 which forced either all files to be public or all to be private.

How Drupal controls what type and the size of the files that can be uploaded is a matter for the content type specific configuration page shown in the preceding screenshot. It is not really sensible to allow any type of file to be uploaded to the site. The first thing that will happen if you do this, is that someone will upload a malicious executable file that does something nasty when it runs on the users’ machines, in turn, causing them to say or do something nasty to you.

For example, you might know that for a particular content type, the only type of file that should be uploaded is a small text or .txt file. In this case, you would have something like the following settings:

In this case, we have specified that only ‘txt files’ of less than 50 KB can be uploaded to the blogtext sub-directory. The decisions you ultimately make should be dictated by the needs of the individual site. When in doubt, follow the tenet:

Provide only what is absolutely necessary, and no more!

The actual settings themselves are easy enough to implement, but I suggest you do not add any file extensions that you know the site will not need. Remember that it is possible to cloak nasty software within other file types, so the more variety you allow, the less secure things become.

We can test all of this out by posting a new blog and trying to upload files. Try a range of files, not just ‘txt’ files to see the results. For example, attempting to upload an image file gives the following result:

However, uploading a new file that does meet the criteria set, meets with success and we can check to ensure that the file is present in the proper sub-directory of the file system, as shown next:

As you can see, the site has correctly uploaded the blogtextfile.txt file in the blogtext subdirectory, as specified earlier. The field-based system for file handling in Drupal 7 represents a huge improvement over previous Drupal milestones.


This article has covered a fair amount of ground in terms of setting up the site. We began by looking at some general configuration settings, like Site information, that are important in terms of getting the nuts and bolts in working order. Many of these settings will need to be revisited as the site develops.

While triggers aren’t necessarily part of a discussion on configuration, we learned that they are inextricably linked to actions that can be configured to automate many common site tasks or chores. Again, coming back to actions and triggers every once and a while can help reduce the number of repetitive tasks that have to be completed manually.

Next, we gained the ability to control file uploads and file handling using Drupal 7’s new field-based paradigm. Having fine grained control over how various files are accessed is a great improvement over past incarnations of Drupal.

Posted in Drupal7, Modules | Tagged: , | Leave a Comment »

Workbench: Managing Content Management-1

Posted by drupallovers on April 25, 2012

This screencast is a part of the Workbench learning series. You can find more at the following links:
* NodeOne Drupal Learning Library: nodeone.se/learn-drupal
* The Workbench overview series: nodeone.se/node/1021
* The Workbench main project page: drupal.org/project/workbench

Posted in Drupal7, Modules, Videos | Tagged: | Leave a Comment »