Sunday, December 4, 2011

Setup for Linux Memcached (daemon) with PHP PECL Memcache and Drupal Memcache Module - with localized UNIX sockets

This information enhances some documentation for the Drupal Project Memcache -> http://drupal.org/project/memcache
Revision Notes PHP: I have tested both PECL Memcache and PECL Memcached versions, and for the moment see less 'bugs' with the use of PECL memcache.
Suggested 'priority' - is to get the latest [memcache] release at http://svn.php.net/viewvc/pecl/memcache/
It has several improved 'features' - including the option to use faster 'localized' Unix 'sockets'

Memcache - Guidelines: see items 1) to 3)

1) A typical Drupal / Pressflow 6.2x use of memcache - via settings.php is: (copied form my own Linux server + based on fast [local] sockets for memcache)
<?php/**
* Memcache:
*/
$conf += array(
 
'memcache_extension'           => 'memcache',
 
'show_memcache_statistics'     => 0,
 
'memcache_persistent'          => TRUE,
 
'memcache_stampede_protection' => TRUE,
 
'memcache_stampede_semaphore'  => 15,
 
'memcache_stampede_wait_time'  => 5,
 
'memcache_stampede_wait_limit' => 3,
 
'memcache_key_prefix'          => basename(realpath(conf_path())),
);
// We don't use chained memcached caching for sites cron, php-cli and install!if (isset($_SERVER['HTTP_USER_AGENT']) && !preg_match("/(?:cron\.php|install\.php)/", $_SERVER['REQUEST_URI'])) {
  if (isset(
$_SERVER['HTTP_HOST'])) {
   
$conf += array(
     
'cache_inc'        => './sites/all/modules/memcache/memcache.inc',
     
'session_inc'      => './sites/all/modules/memcache/memcache-session.inc',
     
'lock_inc'         => './sites/all/modules/memcache/memcache-lock.inc',
     
'memcache_servers' => array(
        
'unix:///tmp/memcached.socket0:0'  => 'default',
        
'unix:///tmp/memcached.socket1:0'  => 'block',
        
'unix:///tmp/memcached.socket2:0'  => 'content',
        
'unix:///tmp/memcached.socket3:0'  => 'filter',
        
'unix:///tmp/memcached.socket4:0'  => 'form',
        
'unix:///tmp/memcached.socket5:0'  => 'menu',
        
'unix:///tmp/memcached.socket6:0'  => 'page',
        
'unix:///tmp/memcached.socket7:0'  => 'update',
        
'unix:///tmp/memcached.socket8:0'  => 'views',
        
'unix:///tmp/memcached.socket9:0'  => 'session',
        
'unix:///tmp/memcached.socket10:0' => 'users'
     
),
     
'memcache_bins'    => array(
        
'cache'         => 'default',
        
'cache_block'   => 'block',
        
'cache_content' => 'content',
        
'cache_filter'  => 'filter',
        
'cache_form'    => 'form',
        
'cache_menu'    => 'menu',
        
'cache_page'    => 'page',
        
'cache_update'  => 'update',
        
'cache_views'   => 'views',
        
'session'       => 'session',
        
'users'         => 'users'
     
),
    );
  }
}
?>
2) Sample 'memcache php.ini' settings:
[memcache]
; Data will be transferred in chunks of this size
memcache.chunk_size = 32768
memcache.hash_strategy = consistent
memcache.default_port = 0
session.save_handler = memcache
session.save_path = "unix:///tmp/memcached.socket11:0?persistent=1&weight=1&timeout=1&retry_interval=15"
3) Sample Linux memcached daemon /etc/init.d/memcached script:
#! /bin/sh
#
# chkconfig: - 55 45
# description:  The memcached-multi daemon is a network memory cache service.
# processname: memcached-multi
# config: /etc/sysconfig/memcached
# pidfile: /var/run/memcached/memcached.*.pid


# Standard LSB functions
#. /lib/lsb/init-functions

# Source function library.
. /etc/init.d/functions

PORT=11211
UDP=0
SOCKET=/tmp/memcached.socket
VAR=0
USER=memcached
MAXCONN=300
CACHESIZE=64
OPTIONS=""

if [ -f /etc/sysconfig/memcached ];then
        . /etc/sysconfig/memcached
fi

# Check that networking is up.
. /etc/sysconfig/network

if [ "$NETWORKING" = "no" ]
then
        exit 0
fi

RETVAL=0
prog="memcached"

start_instance() {
        echo -n $"Starting $prog ($1): "
#       daemon --pidfile /var/run/memcached/memcached.$1.pid memcached -d -p $PORT           -u $USER -m $2 -c $MAXCONN -P /var/run/memcached/memcached.$1.pid $OPTIONS
        daemon --pidfile /var/run/memcached/memcached.$1.pid memcached -d -s $3 -a 766 -L -t 8 -u $USER -m $2 -c $MAXCONN -P /var/run/memcached/memcached.$1.pid $OPTIONS
        RETVAL=$?
        echo
        [ $RETVAL -eq 0 ] && touch /var/lock/subsys/memcached.$1
}

stop_instance() {
        echo -n $"Stopping $prog ($1): "
        killproc -p /var/run/memcached/memcached.$1.pid /usr/bin/memcached
        RETVAL=$?
        echo
        if [ $RETVAL -eq 0 ] ; then
            rm -f /var/lock/subsys/memcached.$1
            rm -f /var/run/memcached.$1.pid
        fi
}


start() {
    # insure that /var/run/memcached has proper permissions
    if [ "`stat -c %U /var/run/memcached`" != "$USER" ]; then
        chown $USER /var/run/memcached
    fi
    # we start 12 socket streams for memcached
    start_instance default 64 /tmp/memcached.socket0;
    start_instance block 64 /tmp/memcached.socket1;
    start_instance content 64 /tmp/memcached.socket2;
    start_instance filter 64 /tmp/memcached.socket3;
    start_instance form 64 /tmp/memcached.socket4;
    start_instance menu 64 /tmp/memcached.socket5;
    start_instance page 64 /tmp/memcached.socket6;
    start_instance update 64 /tmp/memcached.socket7;
    start_instance views 64 /tmp/memcached.socket8;
    start_instance session 64 /tmp/memcached.socket9;
    start_instance users 64 /tmp/memcached.socket10;
    start_instance pbold 64 /tmp/memcached.socket11;
}

stop () {
    stop_instance default;
    stop_instance block;
    stop_instance content;
    stop_instance filter;
    stop_instance form;
    stop_instance menu;
    stop_instance page;
    stop_instance update;
    stop_instance views;
    stop_instance session;
    stop_instance users;
    stop_instance pbold;
}

restart () {
        stop
        start
}


# See how we were called.
case "$1" in
  start)
        start
        ;;
  stop)
        stop
        ;;
  status)
        status memcached
        ;;
  restart|reload|force-reload)
        restart
        ;;
  *)
        echo $"Usage: $0 {start|stop|status|restart|reload|force-reload}"
        exit 1
esac

exit $?
Notes: Above examples taken from my own working Linux server (multi-hosts).
For the last option (Linux), I used "yum install memcached"
eg:
yum search memcached
>
memcached.x86_64 : High Performance, Distributed Memory Object Cache



Additional Notes: The PHP Memcache PECL can also be compiled fully 'static' into the php-5.3.x binary-by moving the [memcache - PECL] source into the php /ext folder and rebuilding the PHP 'buildconf' - then compile PHP 5.3.x with --enable-memcache (it is *not* essential to use PECL if you are after the best speed - and understand *static* PHP compile builds).
PHP 5.3.x Static Compile guidelines:

In the PHP source root folder, issue the following (Linux);
rm configure
PHP_AUTOCONF=autoconf-2.13 PHP_AUTOHEADER=autoheader-2.13 ./buildconf --force


Then compile PHP manually (or use rpmbuild or similar). I usually work direct with Fedora RPM sources, hence I used; rpmbuild -bb php.spec >> php.checklist 2>&1

Using Unix Sockets with the Drupal Memcache Project:

To use Linux sockets with the Drupal memcache module - please refer to: http://drupal.org/node/538426
This method works well for me on my multi-hosted Linux dedicated server.

Current Changelog for PHP PECL memcache

: from http://pecl.php.net/package-changelog.php?package=memcache&release=3.0.6
3.0.6 - Fixed PECL Bug #16672 (memcache.php doesn't support unix socket)
- Fixed PECL Bug #19374 (memcache.php throws Notice: Undefined index: VALUE when viewing expired items)
- Fixed PECL Bug #17518 (Strange behavior in increment on non integer and after)
- Fixed potential segfault in memcache queue.
- Fixed various tests




Revison #1 Doc's by peter bowey http://drupal.org/user/564804

Peter Bowey Computer Solutions
http://www.pbcomp.com.au/

Memcache in Drupal

The Memcache contributed project provides memcache integration, and support for Drupal's caching, session, and lock backends.

Requirements

There are two different PECL packages supported by the 1.5+ release of the memcache module. If using the older memcache PECL package, 2.2.1 or higher is required to avoid a deletion bug. If using the more modern memcached PECL package, version 1.0 or higher is required.

Installation


These are the broad steps you need to take in order to use this software on Drupal 6.x.Information pertaining to the Drupal 7.x version is also found in the README.txt file from the module distribution.
For 6.x (order is important):
  1. Install the memcached binaries on your server. See How to install Memcache on Debian Etch or How to install Memcache on OSX
  2. Install the PECL memcache extension for PHP.
  3. In php.ini set memcache.hash_strategy="consistent".
  4. Put your site into offline mode.
  5. Download and install the memcache module.
  6. If you have previously been running the memcache module, run update.php.
  7. Start at least one instance of memcached on your server.
  8. Edit settings.php to configure the servers, clusters and bins that memcache is supposed to use. (see code snippet below)
  9. Edit settings.php to include memcache.inc. For example, $conf['cache_inc'] ='sites/all/modules/memcache/memcache.inc';
  10. Bring your site back online.
For 7.x (order is important):
  1. Install the memcached binaries on your server. See How to install Memcache on Debian Etch or How to install Memcache on OSX
  2. Install the PECL memcache extension for PHP. This must be version 2.2.1 or

    higher or you will experience errors.
  3. Put your site into offline mode.
  4. Download and install the memcache module.
  5. If you have previously been running the memcache module, run update.php.
  6. Start at least one instance of memcached on your server.
  7. Edit settings.php to mke memcache the default cache class, for example:
         $conf['cache_backends'][] = 'sites/all/modules/memcache/memcache.inc';
         $conf['cache_default_class'] = 'MemCacheDrupal';
  8. Bring your site back online.
For instructions on 1 and 2 above, please see the INSTALLATION.txt file that comes with the memcache module download.

Servers

NOTE: As of 6.15, it is possible to efficiently run memcache in one daemon, shared by all bins. You can safely ignore advice found elsewhere on the internet that advises one memcached daemon per bin. In terms of reporting, there are still some advantages to having more daemons.
If you want the simple version, you can start one default memcache instance on your web server like this: memcached -m 24 -p 11211 -d If that is enough to meet your needs, there is no more configuration needed. If you want to utilize this module's sophisticated clustering feature and spread your cache over several machines, or if your cache is found on a machine other than your web server, read on.
You should probably lock down the memcache server so that it only listens for connections from the hosts that need to be served, as the default is that memcache listens to connections from all addresses. So, to close that hole, edit /etc/sysconfig/memcached with:
OPTIONS="-l ${HOSTIP}"
For example:
OPTIONS="-l 127.0.0.1"
The available memcached servers are specified in $conf in settings.php. If you do not specify any servers, memcache.inc assumes that you have a memcached instance running on 127.0.0.1:11211. If this is true, and it is the only memcached instance you wish to use, no further configuration is required.
If you have more than one memcached instance running, you need to add two arrays to $conf; memcache_servers and memcache_bins. The arrays follow this pattern:
<?php'memcache_servers' => array(host1:port => cluster, host2:port => cluster, hostN:port => cluster)'memcache_bins' => array(bin1 => cluster, bin2 => cluster, binN => cluster)?>
WARNING: Avoid the use of "localhost" and instead use real IP addresses or hostnames that will remain consistent across the network.
The bin/cluster/server model can be described as follows:
  • Servers are memcached instances identified by host:port.
  • Bins are groups of data that get cached together and map 1:1 to the $table param in cache_set(). Examples from Drupal core are cache_filter, cache_menu. The default is 'cache'.
  • Clusters are groups of servers that act as a memory pool.
  • Many bins can be assigned to a cluster.
  • The default cluster is 'default'.
Here is a simple setup that has two memcached instances, both running on 10.1.1.1. The 11212 instance belongs to the 'pages' cluster and the table cache_page is mapped to the 'pages' cluster. Thus everything that gets cached, with the exception of the page cache (cache_page), will be put into 'default', or the 11211 instance. The page cache will be in 11212.
<?php
$conf
= array(
 
'memcache_servers' => array('10.1.1.1:11211' => 'default',
                             
'10.1.1.1:11212' => 'pages'),
 
'memcache_bins' => array('cache_page' => 'pages'),
);
?>
?>
Here is an example configuration that has two clusters, 'default' and 'cluster2'. Five memcached instances are divided up between the two clusters. 'cache_filter' and 'cache_menu' bins go to 'cluster2'. All other bins go to 'default'.
D6:
<?php
$conf
= array(
 
'cache_inc' => './sites/all/modules/memcache/memcache.inc',
 
'memcache_servers' => array('10.1.1.1:11211' => 'default',
                             
'10.1.1.1:11212' => 'default',
                             
'10.1.1.2:11211' => 'default',
                             
'10.1.1.3:11211' => 'cluster2',
                             
'10.1.1.4:11211' => 'cluster2'),

 
'memcache_bins' => array('cache' => 'default',
                          
'cache_filter' => 'cluster2',
                          
'cache_menu' => 'cluster2'),
);
?>


?>
D7:
<?php
$conf
['cache_backends'][] = 'sites/all/modules/memcache/memcache.inc';$conf['cache_default_class'] = 'MemCacheDrupal';$conf = array(
 
'cache_default_class' = 'MemCacheDrupal',
 
'memcache_servers' => array('10.1.1.1:11211' => 'default',
                             
'10.1.1.1:11212' => 'default',
                             
'10.1.1.2:11211' => 'default',
                             
'10.1.1.3:11211' => 'cluster2',
                             
'10.1.1.4:11211' => 'cluster2'),

 
'memcache_bins' => array('cache' => 'default',
                          
'cache_filter' => 'cluster2',
                          
'cache_menu' => 'cluster2'),
);
?>

Prefixing

If you want to have multiple Drupal installations share memcached instances, you need to include a unique prefix for each Drupal installation in the $conf array of settings.php:
<?php
$conf
= array(
 
'memcache_key_prefix' => 'something_unique',
);
?>

Sessions

NOTE: Session.inc is not yet ported to Drupal 7.
Here is a sample config that uses memcache for sessions. Note you MUST have

a session and a users server set up for memcached sessions to work.
<?phpinclude_once('./includes/cache.inc');
include_once(
'./sites/all/modules/memcache/memcache.inc');$conf = array(
 
'cache_default_class' = 'MemCacheDrupal',
 
'session_inc' => './sites/all/modules/memcache/memcache-session.inc',
 
'memcache_servers' => array(
   
'localhost:11211' => 'default',
   
'localhost:11212' => 'filter',
   
'localhost:11213' => 'menu',
   
'localhost:11214' => 'page',
   
'localhost:11215' => 'session',
   
'localhost:11216' => 'users',
  ),
 
'memcache_bins' => array(
   
'cache' => 'default',
   
'cache_filter' => 'filter',
   
'cache_menu' => 'menu',
   
'cache_page' => 'page',
   
'session' => 'session',
   
'users' => 'users',
  ),
);
?>

Troubleshooting

PROBLEM: Error: Failed to set key: Failed to set key: cache_page-......

SOLUTION: Upgrade your PECL library to PECL package (2.2.1) (or higher).
PROBLEM: WARNING: Zlib compression at the php.ini level and Memcache conflict.

SOLUTION: See http://drupal.org/node/273824

Memcache Admin

A module offering a UI for memcache is included. It provides stats, a

way to clear the cache, and an interface to organize servers, bins, and clusters.

Memcached PECL Extension Support

We also now support the Memcached PECL extension. If you install this extension,

it will be used by default. This new extension backends to libmemcached and

allows you to use some of the newer advanced features in memcached 1.4.
NOTE: It is important to realize that the memcache php.ini options do not impact

the memcached extension, this new extension doesn't read in options that way.

Instead, it takes options directly from Drupal. Because of this, you must

configure memcached in settings.php. Please look here for possible options:
http://us2.php.net/manual/en/memcached.constants.php
An example configuration block is below, this block also illustrates our

default options. These will be set unless overridden in settings.php.
<?php
$conf
['memcache_options'] = array(
 
Memcached::OPT_COMPRESSION => FALSE,
 
Memcached::OPT_DISTRIBUTION => Memcached::DISTRIBUTION_CONSISTENT,
);
?>
These are as follows:
  • Turn off compression, as this takes more CPU cycles than its worth for most

    users
  • Turn on consistent distribution, which allows you to add/remove servers

    easily
If you are using memcached 1.4 or above, you should enable the binary protocol,

which is more advanced and faster, by adding the following to settings.php:
<?php
$conf
['memcache_options'] = array(
 
Memcached::OPT_BINARY_PROTOCOL => TRUE,
);
?>


Setup for Linux Memcached (daemon) with PHP PECL Memcache and Drupal Memcache Module - with localized UNIX sockets

ICANN using Drupal

ICANN (Internet Committee for Assigned Names and Numbers), the non-profit organization that oversees the use of Internet domains is using Drupal at http://public.icann.org. They are using Mollom too!

Wednesday, November 30, 2011

Setup of /sites directory for multi-site

Drupal's multi-site hosting capability is built in with any installation. This is great news for users who run numerous web sites from a single hosting account. A single Drupal installation can be used to run multiple domains, which makes it much easier to manage and maintain the code base. Even if you are dealing with only one domain, the multi-site capability may be valuable by providing the ability to run a separate domain or sub-domain for a development version.
This page describes the set-up of the /sites directory for multi-sites.
With version 5.x, the intended location for all non-core elements of a Drupal installation is in a separate /sites directory inside the Drupal installation.
Directory Contents
/drupal/sites/all


(used by all sites)
/modules
/themes
/drupal/sites/default


(used when there is no /sites/example.com directory)
/files
settings.php
/drupal/sites/example1.com    /files
/modules
/themes
/tmp
settings.php
/drupal/sites/example2.com    /files
/modules
/themes
/tmp
settings.php
The intended best practice configuration is to create a /sites/example.com directory for each domain. It should contain a site-specific settings.php file and /files directory. Configure Drupal site settings to specify 'File System Directory' of 'sites/example.com/files' instead of the default 'files'. It's possible to do this with an existing web site, but moving file uploads around can cause a lot of confusion if there are already URLs pointing to the old locations.
Domain specific modules and themes should also be placed in /sites/example.com/modules and /sites/example.com/themes respectively.
Contributed modules and additional themes which are for use by all domains in a multi-site installation should be placed in /sites/all/modules and /sites/all/themes. Note that there shouldn't be a /sites/all/files or /sites/all/settings.php.
The /sites/default directory should contain /files and settings.php, for use if the /sites/example.com directory doesn't exist for a domain.
In addition to multiple sites, such as example1.com and example2.com, sub domains are also easily set up. Adding sub3.example2.com and sub3.example2.com/site4, the directory structure for these four sites would be:
/drupal/sites/all/modules
/drupal/sites/all/themes
/drupal/sites/default/files
/drupal/sites/default/settings.php
/drupal/sites/example1.com/files
/drupal/sites/example1.com/modules
/drupal/sites/example1.com/settings.php
/drupal/sites/example1.com/themes
/drupal/sites/example1.com/tmp
/drupal/sites/example2.com/files
/drupal/sites/example2.com/modules
/drupal/sites/example2.com/themes
/drupal/sites/example2.com/tmp
/drupal/sites/example2.com/settings.php
/drupal/sites/sub3.example2.com/files
/drupal/sites/sub3.example2.com/modules
/drupal/sites/sub3.example2.com/settings.php
/drupal/sites/sub3.example2.com/themes
/drupal/sites/sub3.example2.com/tmp
/drupal/sites/sub3.example2.com.site4/files
/drupal/sites/sub3.example2.com.site4/modules
/drupal/sites/sub3.example2.com.site4/settings.php
/drupal/sites/sub3.example2.com.site4/themes
/drupal/sites/sub3.example2.com.site4/tmp
Note that Drupal reconizes www.example.com as a sub-domain of example.com.

If you wish to point both of them to the same site, use /drupal/sites/example.com/ as your directory, and uncomment the corresponding option in your .htaccess

Once you've done this, the file structure of your site will be cleanly organized:
  • The main Drupal directory will contain only the standard 'core' files.
  • Themes and modules that are shared among all sites are properly placed in /sites/all
  • Site-specific themes, modules, and files are compartmentalized and properly placed in /sites/example.com, /sites/example1.com, /sites/sub3.example2.com and /sites/sub3.example2.com.site4 .
  • /sites/default/settings.php and /sites/default/files will be used if /sites/example.com directory does not exist.
  • Backing up the /sites directory and your Drupal database will give you everything you need to restore the site in the event of a crash, or to move to a new server.
  • Adding a domain is easy: just copy the /sites/default directory to /sites/example5.com
To help keep files organized you may choose to use shortcuts to point relevant files and directories that are stored elsewhere in your Drupal installation. These short-cuts (like a desktop "alias") are referred to as "symbolic links" on a Web server. Symbolic links can be used for several purposes:

  • Even if using default settings, a good option is to use links from /sites/example.com directory to point to the /sites/default directory. That way, if the settings and /files are ever changed from the default and actually placed in /sites/example.com, their location does not 'move' and no links are broken.
  • Links could also be used to point the /sites/default directory to your primary site.
  • A /files directory could easily be shared across two domains without being shared across the remaining domains.
  • A non-domain-name path for /files can be setup. If it is possible that the domain name might change (say, from a development name), then you can set up a link from /drupal/sites/moniker to /drupal/sites/example.com, where 'moniker' is a short version of the site name that will remain constant even if /example.com changes.
If you are working from the command line on a Linux, Unix or OSX server you can create a symbolic link using the following command:

$ ln -s /path/to/actual/file/or/directory name_of_shortcut
Although the /sites/default directory could contain a /modules and /themes directory, these elements should usually be placed in /sites/all or /sites/example.com. Similarly, although contributed modules could be placed in /drupal/modules as was the practice in version 4.7, this is not recommended.
Multi-site directory setup for sub-domains, including non-standard ports, is described in the installation instructions found in INSTALL.txt.
See multidomain for a contributed module that allows spanning one site across multiple domains, so that specific content types appear on specific domains or sub-domains.
Version 4.6 and 4.7: Best practice for multi-site set-up under version 4.6 and 4.7 is similar to 5.x. The primary difference is that there is no /sites/all directory. Instead, /modules and /themes that are available for all domains are kept in /drupal/modules and /drupal/themes.
Files Directory

The following user-submitted code may be useful in redirecting URLs for the /files directory to the /sites/example.com/files directory. The following code is added to the [drupal_root]/files/.htaccess file:


<IfModule mod_rewrite.c>
  RewriteEngine on

  # Note: this will redirect to the /sites subfolder which is identical to
  # the domain accessed by the browser.  If you use partial domain names as
  # the /sites subfolder (e.g. /sites/domain.com vs /sites/www.domain.com)
  # you will need to modify the Drupal root .htaccess to remove the leading www
  # or modify the following to use the protion of %{HTTP_HOST} that mirrors
  # your /sites subfolders

  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteCond %{REQUEST_FILENAME} ^(.*)\/files\/
  RewriteCond %1/sites/%{HTTP_HOST}/files -d
  # To redirect the URI to the actual location of the file /sites/<domain>/files/<filesname>
  # change the [L] to [L,R]
  RewriteRule ^(.*)$ /sites/%{HTTP_HOST}/files/$1 [L]

  # If the domain does not have a dedicated /sites/<domain>/files folder allow the
  # default folder to catch it.
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  # To redirect the URI to the actual location of the file /sites/default/files/<filename>
  # change the [L] to [L,R]
  RewriteRule ^(.*)$ /sites/default/files/$1 [L]

</IfModule>
If the .htaccess method doesn't work, try this user-contributed code for use in settings.php, instead of .htaccess.
In settings.php, put this code:


<?php
$conf
['file_directory_temp'] = 'sites/' .substr(strrchr(dirname(__FILE__), '/'), 1) .'tmp';$conf['file_directory_path'] = 'sites/' .substr(strrchr(dirname(__FILE__), '/'), 1) .'/files';?>

Running multi site

Run multiple sites from the same code base (multi-site)

If you are running more than one Drupal site, you can simplify management and upgrading of your sites by using the multi-site feature. Multi-site allows you to share a single Drupal installation (including core code, contributed modules, and themes) among several sites.

This is particularly useful for managing the code since each upgrade only needs to be done once. Each site will have its own database and its own configuration settings, so each site will have its own content, settings, enabled modules, and enabled theme. However, the sites are sharing a code base and web document root, so there may be security concerns (see section below for more information).

Overview of the Process

To create a new site using a shared Drupal code base you must complete the following steps:

  1. Create a new database for the site.
  2. Create a new subdirectory of the 'sites' directory with the name of your new site (see below for information on how to name the subdirectory).
  3. Copy the file sites/default/default.settings.php into the subdirectory you created in the previous step. Rename the new file to settings.php.
  4. Adjust the permissions of the new site directory, and grant write permissions on the configuration file
  5. Make symbolic links if you are using a subdirectory such as example.com/subdir and not a subdomain such as subd.example.com (see the subdirectory multi-site section below for details).
  6. In a Web browser, navigate to the URL of the new site and continue with the standard Drupal installation procedure.

It may also be necessary to modify your Web server's configuration file (often named httpd.conf for Apache) to allow Drupal to override Apache's settings. This is true for all installations of Drupal and is not specific to the multi-site install. Additional information is available in the Best Practices: Configuring Apache and PHP for Drupal in a Shared Environment section of the Install Guide.

Details of the Process

Domains, URLs, and sites subdirectory name

The new subdirectory of the sites directory has a name that is constructed from the site's URL. For example, the configuration for www.example.com would be in sites/example.com/settings.php. You do not need to include 'www' as part of the directory name.

Drupal will use the same sites/example.com directory for any subdomain of example.com, including www, unless there is an alternative, matching subdomain sites subdirectory. For instance, URL http://sub.example.com would be served from sites/sub.example.com, if it exists.

For a subdirectory URL, such as http://example.com/subdir, name the sites subdirectory as follows: sites/example.com.subdir -- and read the section below on getting subdirectory multi-site working.

If you are installing on a non-standard port, the port number is treated as the first part of the subdomain. For example, http://www.example.com:8080 could be loaded from sites/8080.example.com. If that directory doesn't exist, Drupal would then look for sites/example.com, just like a real subdomain.

Site-specific modules and themes

Each site configuration can have its own site-specific modules and themes in addition to those installed in the standard 'modules' and 'themes' directories. To use site-specific modules or themes, simply create a 'modules' or 'themes' directory within the site configuration directory. For example, if sub.example.com has a custom theme and a custom module that should not be accessible to other sites, the setup would look like this:

sites/sub.example.com/settings.php 
sites/sub.example.com/themes/custom_theme 
sites/sub.example.com/modules/custom_module

Document root

One area of frequent confusion is that in a Drupal multisite installation the webserver document root is the same for all sites. For example with the following three sites: example.com, sub.example.com and example.com/site3 there will be a single Drupal directory and all sites will be calling the same index.php file.

Some webhosts automatically create a new directory (i.e. example.com) when creating a new domain or subdomain. In this case it is necessary to make it into a symbolic link to the main Drupal directory, or better yet when creating the domain or subdomain, set it to use the same document root as the site where you have Drupal installed.

Subdirectory multi-site

If you are attempting to get Drupal multi-site working using subdirectory URLs rather than subdomain or different domain URLs, you may encounter problems. You'll start out by making a directory such as sites/example.com.subdir, and putting a settings.php file there. If this works for you, great! But it probably will not, until you make a symbolic link that tells your web server that the document root for http://example.com/subdir is the same as the document root for http://example.com. To do this, go to the example.com document root and type:

ln -s . subdir


If your codebase itself is in a subdirectory, then link your new site to the directory:

ln -s drupaldir subdir

This symbolic link is enough to resolve issues with subdirectory multi-site installations on at least some web hosts. If you still encounter problems with clean URLs and have access to edit the .htaccess file, try adding the following stanza immediately before the existing rewrite rule (for Drupal 7):

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !=/favicon.ico
RewriteCond %{REQUEST_URI} ^/subdir
RewriteRule ^ subdir/index.php [L]

That block should go right after the RewriteBase / line, and before the other RewriteCond lines. What that does is catch incoming URLs that contain the subdir prefix and route them to the symlinked file so that they find the right database. Note that if you have multiple subdirectory-based multi-sites, each one will need its own block as above. (Based on this forum thread: http://drupal.org/node/239583#comment-786932)

Note that these problems do not usually occur for multi-site installations using a subdomain, so you might want to try that if you cannot get subdirectory multi-site to work. (However, subdomains are not good for search engine rankings!)

Localhost alias for local workstation

On many systems it is possible to create entries in a "hosts" file to create aliases for the localhost name for a local workstation. By creating aliases for localhost it is possible to create names such as localdev1.example.com and localdev2.example.com, both for the local computer.

If on the other hand you use subdirectories in your local web root, create a symbolic link like this:

ln -s drupaldir subdir


and name your site folder localhost.subdir.

Domain name changes

Once a site is in production in a particular subdirectory under the sites directory, the subdirectory should not be renamed, even if the Web site URL changes. This is because several database tables (for example: system and files) include references to "sites/www.mydomain.com." Instead of renaming the sites directory, you can create a symlink to the new URL from the old one. Navigate to the sites directory and then use the following command:

$ ln -s /path/to/drupal/sites/old.domainname.com new.domainname.com

Security Concerns

You might want to reconsider using Drupal's multi-site configuration, in situations where the administrators for all of the sites being run from the same code base are not either the same person or a small group with a high level of mutual trust. The reason is that anyone with full administrative privileges on a Drupal site can execute arbitrary PHP code on that site through various means (even without FTP access to the site), and that arbitrary PHP code could be used from one site to affect another site, if the two sites are in the same HTTP document root and sharing the same Drupal code.

So, unless you completely trust all of the administrators of the sites you are considering running from the same Drupal code base to be knowledgeable, careful, and not malicious, you might want to consider installing their Drupal sites in completely separate areas of the web server that are not able to affect each other via PHP scripting.

Tuesday, November 29, 2011

drupal target _blank not working

A target="_blank" alternative for Drupal, or saving users' content by overriding the filter tips link
With a few lines of code in template.php and a small jQuery script, you can fix that by opening a new window when that link is clicked - without losing XHTML compliance (which you'd lose if you used target="_blank"). Additionally, you can re-use that trick elsewhere by adding a special class attribute to your anchor tags.

The first thing you need to do is add the following lines to your Drupal theme's template.php (replacing YOURTHEMENAME with your theme's name):

// Theming the filter tips more info link so users don't lose
// their stuff when visiting another page.
function phptemplate_filter_tips_more_info() {
  return '<p>'. l(t('More information about formatting options'), 'filter/tips', array('class' => 'target_blank')) .'</p>';
}

drupal_add_js(drupal_get_path('theme', 'YOURTHEMENAME') .'/target-blank.js', 'theme');



What that does is first override the theme function for the filter tips "more link" and add the "target_blank" class to that link. Our jQuery will use that class. Secondly, it tells Drupal to add a Javascript file called target-blank.js to every page. It's a really small script, and because of the potential for re-use, we might as well load it on every page, so we don't put any conditions on when we add it.
Next, create a file named target-blank.js in your theme's folder and add the following jQuery Javascript to it:

$(document).ready(function(){
  $("a.target_blank").click(function(){
    window.open(this.href);
    return false;
  });
});



This jQuery script waits until the document is ready, then on the click of any anchor tag with the class "target_blank" it opens that link in a new window.
That's it.
If you want to use this jQuery with any other anchor tags in your site, add class="target_blank" and you've got a link opening in a new window without compromising your XHTML compliance.
Hat tip to ejhildreth for the tip on using jQuery to maintain XHTML compliance.
Additionally, you can read about why this isn't in Drupal already. In short, opening new windows is considered bad UI. And I agree. My personal conviction, though, is losing users' data is worse.

Git GUI tools

Git can be integrated with your development environment using command-line tools, several 'front-ends' or GUIs, and integrated tools in some IDEs.

This section includes documentation to configure tools for use with Drupal.org and, where available, detailed directions for best-practice workflows using those tools.

Refer to Git interfaces, frontends, and tools for a comprehensive list maintained in the official Git Wiki, including graphical user interfaces (GUIs).

SmartGit


  1. Click "Edit" » "Preferences" » "Git" and choose "User Information"
  2. Enter your Full Name and E-mail address

EGit


  1. Click "Window" » "Preferences" » "Team" » "Git" » and choose "Configuration"
  2. Add your Full Name and E-mail address

Git Gui


  1. Click "Window" » "Edit" » "Options..."
  2. Add your Full Name and Email address

Giggle


Linux (gtk+/GNOME)

  1. Install giggle-personal-details-plugin from your distribution's repository
  2. Click "Edit" » "Personal Details"
  3. Add your Full Name and Email address

gitg


Linux (gtk+/GNOME)

  1. Click on "Edit" » "Preferences" and choose "Configuration"
  2. Add your Full Name and Email address



Installing Git

Unlike traditional version control systems like CVS or SVN, a Git repository can be a completely local undertaking. Consequently, to work with Git, you first install it on your local machine.

Wikipedia holds a list of available Git clients and (IDE) plugins.

Mac / Linux


Windows


Git graphical user interface (GUI) tools


Visit the Git GUI tools page for a list of Git tools with graphical user interfaces, if you prefer using those rather than working on the command line.






Sunday, November 27, 2011

Design for Drupal 8

Attracting more designers to Drupal is an important goal in our quest to create a well-rounded ecosystem and to attract more users to Drupal. While we made some great improvements in Drupal 7, we need to do more of the same with Drupal 8, and then some. After conversations with various Drupal designers and front-end developers, I decided that adding a new theme to Drupal 8 core is a great way to attract more designers, both as end-users of Drupal but hopefully also as contributors to the project.

I wanted to kick this off early in the Drupal 8 development cycle, and have asked Jeff Burnz to be the Initiative Owner for the Drupal 8 Design Initiative. This is the third official Drupal 8 initiative after the Configuration Management Initiative and the Web Services Initiative.

Jeff will guide the community through a design process with the goal of producing a beautiful theme that can be added to Drupal 8. The emphasis of this theme will be on design to show the world that Drupal can be used to create delightful experiences.

As important as a new theme for Drupal 8 is, so is the process of selecting the design and building the theme itself. Another goal of the the Design Initiative is to define and execute a new process for the selection and development of new core themes. Jeff has gathered a small team of Drupal UX-ers, designers and front-end developers to drive this process forward. You will be hearing a lot more about this in the coming weeks and months and your input will be sought -- this will be an entirely open process, with full community collaboration an important part of the process.

Last but not least, hopefully we can continue to improve Drupal's mark-up, CSS and theming capabilities along the way, as well as further educate the Drupal community about the importance of design.

Long story short, this should be a great initiative for Drupal 8. If all goes well, not only will we get a new theme for Drupal 8, but hopefully we'll raise the bar for design for Drupal in a significant way. If you want to learn more about this initiative, you can find additional information in Jeff's announcement blog post.

If you want to get involved please see this discussion on drupal.org.

Eclipse using Drupal

Eclipse, the Open Source IDE/framework originally from IBM, is using Drupal for Eclipse Live:

Eclipse Live is your source of multi-media material about Eclipse projects and Eclipse-based products. Register for a live webinar or browse and view webinars and podcasts from our extensive library.

Friday, November 25, 2011

PayPal developer community using Drupal

Drupal continues to rack up successes among large developer communities, with x.commerce joining Twitter, which made the move last month. X.commerce is a new division of PayPal that serves as an open, central meeting place for over 700,000 developers for eBay, PayPal, Magento, and other eBay properties.
These communities join those of Brightcove, Symantec, DivX -- and, of course, Drupal. All told, that's millions of developers relying on Drupal-run sites for coding tips, product info, and idea exchange.


x.commerce's communities were formerly run on Jive, a proprietary package. Through Acquia, eBay engaged VML to create the site, with additional consulting by Cyrve (now part of Acquia) to migrate data. Acquia provided a Technical Account Manager (TAM), who helped coordinate resources to put the site into production and will be on call as it grows.

Like many developer sites, x.commerce centers around its documentation and its communities. The latter are a model of social networking at its best, in the service of a question-and-answer format. Developers help each other by responding directly to questions, either publicly or through private email; vote on questions (and answers) to highlight those of importance; promote conversations through other social sites such as Facebook; and bookmark discussions to form personal collections. The results are evident in the enormous level of activity within the forums (which, by the way, are built on Organic Groups).

This project is an excellent example of how open-source software drives innovation. Under Jive, eBay wasn't able to develop features that it needed. If eBay needed to do something that wasn't in Jive's roadmap, that was just too bad. Drupal, of course, allows them to create whatever they need, or developers outside the company to do it. That jibes well with x.commerce's ethos of open development, as is demonstrated by the extensive APIs it provides for eBay and PayPal, and the freedom the company allows its developers. I believe that their openness is a key factor to their success -- there are over 4,500 apps on Magento alone -- and that their move to Drupal will allow them to grow at the speed of their community.

Mobile for Drupal 8

In my State of Drupal keynote in Chicago I said: "If I were to start Drupal from scratch today, I'd build it for mobile experiences first, and desktop experience second.". I believe in that more than ever.

We already have a number of initiatives under way that will make Drupal a great platform for building native mobile applications (e.g. the Web services initiative) as well for building mobile web experiences (e.g. the HTML5 initiative and the Design initiative).

However, there is more that needs to be done to make Drupal a go to platform in a mobile world. For example, a couple of weeks ago I talked to a number of big media companies, each employing hundreds of editorial staff. They all believed that in less than two years, most of their editors that report from the field will be using tablets instead of laptops. Applied to Drupal, this means we need to make the Drupal administration back-end and the editorial experience mobile-friendly, something that isn't covered by the existing Drupal 8 initiatives. Another example would be responsive web design.

The mobile internet is coming at us fast and furious. We need to move fast and we might only get one shot at this. I want to make mobile the big theme for Drupal 8. That is why I decided to launch another initiative related to mobile.

I've asked John Albin Wilkins to be the Initiative Owner for the Drupal 8 Mobile Initiative, and to work with the existing initiatives to fill the remaining gaps. To learn what that means, please consult John's announcement blog post, which includes an overview of the initiatives' goals. Like with any of these initiatives, they don't actually materialize unless people decide to help. To get involved, please join the discussions in the Mobile group on groups.drupal.org and help work on Mobile issues on drupal.org.

Zynga using Drupal

Drupal isn't only for work: it's also for play, as "FarmVille" creator Zynga proves. While their games usually appear as apps on social networks such as Facebook, its main site is on Drupal. It's a terrific example of how Drupal is used in the entertainment industry. After all, Zynga's annual revenue in 2010 was almost a billion US dollars, and is aiming for an initial public offering that values the company at $15-20 billion.

The Hang Up Ringer

The Hang Up “Ringer”

-So we are all familiar with the emergence of the unique ring tone. You call your friend and are treated to the latest single from Gwen Stefani or the gifted musician T-Pain (world’s most sarcastic comment). Gone is good old standby: ring….ring…ring…, replaced by “If I could be free…you know I’d be a real bad giiirrlll”. My idea: the Hang Up ringer!

Why do we need this you may be asking….well, let me elaborate. Back in “the day”, when you got PO’d at someone on the phone, you could take the handset and violently SLAM it down to hang up on them, and the idiot on the other end would have to pull the phone away from their ear to avoid having their ear drum burst (which they probably deserved). Now though, will these darn cell phones, all you can do is push end…unable to convey your anger, thereby allowing the other person to get away with their phone rudeness! In fact, they will often have no clue they have been hung up on and continue in their rudeness with no audience! Psh…punks!

Well, no more. What if every time you pushed END, the sound of a loud flushing toilet signaled the end of the call to the person on the other end? Whooo….sssssshhhhh!!! Yup, you’ve just been flushed like a piece of you know what!!! You could go anywhere with this idea. There could be different catagories: bathroom sounds (all KINDS of opportunity here), gangsta sign offs (“WHADJU SAY??? I’m comin over there!” or simply the sound of a gunshot), sports (an umpire screaming “Yeeerrr OUTTA HERE!!!”) and even songs (“Na na na…na na na…hey hey hey…goodbye” – I could sing it and be as famous as that operator lady!). You could even go old school and have it be a recording of someone loudly slamming a handset!!! How in your face would that be. The person hears the slam, and says to themselves “But he was on his cell phone!?!?!” and is confused for the remainder of the day.

The possibilities are endless! Suffice it to say, people would probably start calling people just to hang up on them. Prank calls would be a whole new ballgame. And in the off chance that you really can’t stand when someone calls you, you could make the hang up ringer be the regular ringer whenever they call! Every time they CALL they hear a man ask “Why are you calling me. I can’t stand you…don’t even leave a message, cuz I am not calling you back…EVER!”

***I ALREADY CALLED THE US PATENT OFFICE, so don’t even try it!!!***