July 20, 2012 - Comments Off on Drupal: Connecting to multiple databases in your module

Drupal: Connecting to multiple databases in your module

Have you ever needed your Drupal site to access data from a different database? from a different Drupal installation? The Drupal database abstraction layer has the ability to switch between databases! We are working on a project that requires a Drupal website to talk to another database on the same server. Updates to the website must also be made to the other database, in this case a membership directory.

By setting up multiple databases in the settings.php file for your site, you can load up your data from the website, then switch to the second database to make updates. If you are doing data migration from one Drupal site to another, this can be very handy.

First, in settings.php expand the default database declaration array:

[cce_php]
$databases['default']['default'] = array(
      'database' => 'drupalsite',
      'username' => 'drupalsite_user',
      'password' => 'drupalsite_pass',
      'host' => 'localhost',
      'port' => '3306',
      'driver' => 'mysql',
      'prefix' => '',
    );
$databases['external']['default'] = array(
      'database' => 'groucho_db',
      'username' => 'groucho',
      'password' => 'groucho',
      'host' => 'localhost',
      'port' => '3306',
      'driver' => 'mysql',
      'prefix' => '',
    );

Then in your new module you can load your data:

/**
 * Implements hook_user_save().
 */
function awesome_user_save(&$user) {
  $user_obj = user_load($user->uid);
  // Load the Users favorite Beatle (George, of course)
  if(isset($user->field_favorite_beatle['und']) {
    $favorite_beatle = $user_obj->field_favorite_beatle['und'][0]['value];
  } else {
    $favorite_beatle = 'George Harrison';
  }

  if(db_set_active('groucho')) {
    $result  = db_update('Users')
        ->fields(array('Fav_Beatle'=>$favorite_beatle))
        ->condition('user_id', $user->uid, '=')
        ->execute();
    // Check on success of query
    if(!$result) {
      // Error executing query
    }
    elseif($result->rowCount() > 0) {
      // Query succeeded- rowCount() will report number of rows affected
    }
    else {
      // Query ran, but no rows were affected
    }
    db_set_active();
  }
}
[/cce_php]

With some error checking in there, and ensuring that db_set_active() is called at the end, you have loaded data from your Drupal site and entered into an external database! This can be run in the other direction too. You can retrieve data from another database and populate Drupal objects like nodes and users directly. The things to watch out for with this method are that the database engines must be the same, i.e., mysql, postgres, etc., and to be sure you find more information of which database is active when you are accessing data.

Published by: chazcheadle in The Programming Mechanism
Tags: , , ,

July 17, 2012 - Comments Off on Drush de Jour: Reset user passwords and e-mail one-time login links

Drush de Jour: Reset user passwords and e-mail one-time login links

Do you have users that like to forget their passwords? Here are 2 methods for getting new ones (the passwords, not the users!)

% drush upwd username

And here is how to create a one-time login link for a user that has forgotten their password. (again?!)

% drush user-login username

The output will be something like this:

http://example.com/user/reset/17/13425300/c18Zh_dYH2XxHzBcJU9jU

Just email that link to your user and they can log in and reset their password.

If you know their email address you could be clever and do something like this:

drush uli username | mail -s 'Reset password request' useremail 
The Drush de Jour brings you the latest and possibly greatest bits of drush wisdom we use for developing and maintaining our Drupal sites.

Published by: chazcheadle in The Programming Mechanism
Tags: , ,

July 16, 2012 - Comments Off on Millimeters of Metropolis

Millimeters of Metropolis

I'll be the first to admit it: I have a problem--a media problem. It might be just my generation but I'm beginning to think it's really all of us. We've contracted what I call "screen-lookitis" and I suffer from a particularly acute case. I'll be with friends in a bar having a merry old time, but put a screen in the corner of the room and I can't help but look every few minutes or seconds even! Perhaps being raised in a world where anything and everything of worth appears in glowing pixels at some point or another has conditioned me to this extreme behavior. But even looking back to the birth of the moving image we see a similar devotion in those Vaudevillian days. Film is an extremely efficient and engaging communication tool and as such it has completely altered the human experience. As a confessed media junky, I can easily say it very much inspires.

 Of course all forms of media inspire us. Our ability to communicate and interpret ideas is what makes human so unique after all. But by simulating our real world experience in the lit rectangle of the screen, movies, television and now the web manage to hijack our senses completely and unlike anything before. The amount of television we now consume is quite startling at an average of 4 hours a day in the US. But the works of people like César Moreno tap the brakes on this depressing train of thought. His strong illustrative style echoes a comic book aesthetic while his downplayed colors and extreme contortions of scale and perspective serve to make his work truly unique. The subjects often involve film stars and characters alike, below are Heisenberg from Breaking Bad (which just returned this past Sunday!) and one of the most famous scenes in modern cinema from Pulp Fiction.

The interplay of film and the web was obvious at first glance to many. Web video has recently taken off on services like Youtube, Hulu, and Vimeo. But like so much else in our glorious digital revolution, progress has been slowed and stymied by entrenched parties. While some are coming around, many more remain obstinate in the course of progress. But that just leaves more opportunities for the small guys to swoop in and take over as the site for Media Arts Lawyers can attest. A small law practice, MAL provides legal support for small burgeoning artists in all forms of media and distribution. Their long horizontal site calls to mind film strips with its perforated menu design. The monochromatic palette mixed with splashes of red is like the darkrooms of old while slick design and interface rule all. Though the site doesn't work well on small screens it does work on mobile devices. However the static header fills the entire screen making it unclear that the content below has changed.

One often overlook downside of film is how invisible it makes the artistic process. Large amounts of work are required to bring any artistic vision to life, especially in film. If a film maker has done a good job of course, all this work should be invisible to the viewer. And no crew member is more overlooked than the Foley artist; the men and women who add all those subtle sounds that don't get picked up while recording but are vital to giving actions a sense of weight and reality.

Please tune in later this week for our podcast on the subject of digital media and privacy in the modern age. Till then, happy watching.

The Sketching Mechanism is a series of weekly posts, published on Mondays, containing the artistic musings of Mobile Designer/Developer Ben Chirlin from our Monday morning meeting at the NY Creative Bunker as well as his inspiring artistic finds of the week.

Published by: benchirlin in The Sketching Mechanism
Tags: , ,

July 13, 2012 - Comments Off on How to Force a Download in Drupal

How to Force a Download in Drupal

Drupal is a great CMS when it comes to managing files. The large variety of extant modules allow you to support pretty much any file type you can imagine in your back end. However, browser to browser, many file types are treated quite differently. The most problematic culprit being, of course, images as all browsers view them in the window by default. So how can you cause a link to force an image download to the user's computer when it comes to such finicky files? Try the following script I adapted from one found on eLouai.


// ** http://www.*MYSITE*.com/*path to this script*/force-download.php?file=*file path NB: must be in same directory or child directory as this script*

$filename = $_GET['file'];
$filename = preg_replace("/.*/files//", '', $filename);

// required for IE, otherwise Content-disposition is ignored
if(ini_get('zlib.output_compression'))
ini_set('zlib.output_compression', 'Off');

// addition by Jorg Weske
$file_extension = strtolower(substr(strrchr($filename,"."),1));

if( $filename == "" )
{
echo "ERROR: download file NOT SPECIFIED."; exit; } elseif ( ! file_exists( $filename ) ) { echo "ERROR: File not found, please go back and try another file.
$filename"; exit; }; switch( $file_extension ) { case "pdf": $ctype="application/pdf"; break; case "exe": $ctype="application/octet-stream"; break; case "zip": $ctype="application/zip"; break; case "doc": $ctype="application/msword"; break; case "xls": $ctype="application/vnd.ms-excel"; break; case "ppt": $ctype="application/vnd.ms-powerpoint"; break; case "gif": $ctype="image/gif"; break; case "png": $ctype="image/png"; break; case "jpeg": case "jpg": $ctype="image/jpg"; break; default: $ctype="application/force-download"; } header("Pragma: public"); // required header("Expires: 0"); header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); header("Cache-Control: private",false); // required for certain browsers header("Content-Type: $ctype"); // change, added quotes to allow spaces in filenames, by Rajkumar Singh header("Content-Disposition: attachment; filename="".basename($filename)."";" ); header("Content-Transfer-Encoding: binary"); header("Content-Length: ".filesize($filename)); readfile("$filename"); exit();

?>

Place the following script in your files directory of your Drupal installation (our default being "sites/theme/default/files"). The script needs to be in a common root of all the files you wish users to be able to download. This is due to the only major addition to the code I made, the preg_replace on line 9. This essentially deletes anything that comes before the "files" directory in the path leaving just the rest of the file path.

While you could remove this line and put the script in your root, this could be a serious security gap so I do not recommend doing so. Moreover, restricting downloads to specific directories is useful if you want to prevent users from using the script to easily download certain files outside of the script's parent directory. You can move the script to any folder that contains your expected targets and change line 9 as below with your chosen directory replacing "files" (or in this case "**YOUR FILE DIRECTORY**").

$filename = preg_replace("/.*/**YOUR FILE DIRECTORY**//", '', $filename);

While you're at it, feel free to replace the error messages with whatever you feel is appropriate. Note that this script currently supports pdf, exe, zip, doc, xls, ppt, gif, png, jpeg and jpg file types though you can easily add more exotic file types. I'd caution against including any web related extensions (especially php) to prevent users from potentially using the script to download your source files.

To then use this script simply make your links as follows:

Force Download

Or if you have your file's URI, which you should, do this:

Force Download

Remember, such a script gives even a semi-savvy user incredible access to your site's file structure so be careful how and where you use this. If placed in the incorrect directory, a user could potentially download your source files.

Published by: benchirlin in The Programming Mechanism
Tags: ,

July 12, 2012 - Comments Off on Adding CCK fields to Apachesolr documents in Drupal 7

Adding CCK fields to Apachesolr documents in Drupal 7

Drupal's core searching functionality is awesome in that it can be replaced by other search modules and even other search engines. We're using Apache Solr for its lightning fast response time and powerful indexing and faceting. In a nutshell, Solr is a standalone index/search engine to which Drupal sends its search queries. The real beauty is that the indexed results are all cached and served back to the Drupal site as XML documents ridiculously fast, much faster than Drupal's core search. The core search module has to hit the Database and fully load each node/entity for every matching result.

By default Apache Solr will index most of your content type's fields, however many CCK fields that you add will not be included in the default indexing. That is to say, if you add a checkbox, or text field to your content type you will have to explicitly direct Solr to add it to the index. Each piece of content that is indexed by Solr is processed and stored as a Solr document which holds all of the indexed fields as well as some Solr metadata. That is how Solr can return results so quickly, it is only sending the fields you require, not loading the entire object.
Here is some sample code showing how to add some custom fields to the Solr document. These two hooks are all you need to get started, just add them to a custom module and be sure to re-index afterwards to update the Solr index.


/**
* Implements hook_apachesolr_index_document_build().
*
* Add custom fields to the solr document
*/
function themech_solr_apachesolr_index_document_build(ApacheSolrDocument $document, $entity, $entity_type, $env_id) {
if($entity->type == 'publication') {
if (isset($entity->field_publication_author[$entity->language])) {
foreach($entity->field_publication_author[$entity->language] AS $id => $obj) {
if(isset($entity->field_publication_author[$entity->language][$id])) {
$document->setMultiValue('sm_field_publication_author', $entity->field_publication_author[$entity->language][$id]['entity']->name);
}
}
}
if(isset($entity->field_publication_attachment[$entity->language])) {
foreach($entity->field_publication_attachment[$entity->language] AS $id => $obj) {
$document->setMultiValue('sm_field_publication_attachment', $entity->field_publication_attachment[$entity->language][$id]['uri']);
}
}
if(isset($entity->field_publication_recommended[$entity->language])) {
$document->setMultiValue('is_field_publication_recommended', $entity->field_publication_recommended[$entity->language][0]['value']);
}
}
}

/**
* Implementation of hook_apachesolr_query_alter($query)
*
* Add the newly indexed fields from above to the query result.
*/
function themech_solr_apachesolr_query_alter($query) {
$query->addParams(array('fl' => array('sm_field_publication_author')));
$query->addParams(array('fl' => array('sm_field_publication_attachment')));
$query->addParams(array('fl' => array('sm_field_publication_recommended')));
}

In this example, we're adding any names that were selected in a selectlist of authors, a checkbox state, and a file attachment uri. The first function checks to see if the Publication node has data in certain fields then adds them to the $document object via SetMultiValue(). The fields are now stored in Solr, but as they were custom additions to the document, you have to specify them in the query to tell Solr to pull them back out with the rest of the document.

You can index anything you can put into a content type, and each content type can have specific fields indexed. With Solr you can create thumbnail gallery search results, or integrate with your commerce site to generate product category and price range searches, as well as tune the results based on custom weights and ratings. The possibilities are almost limitless. Maybe as many as a googol (1x10^100), or in Drupal terms... a Droogol. :+)

Links:
Apache Solr
Apachesolr Search Integration

Published by: chazcheadle in The Programming Mechanism
Tags: , ,

July 10, 2012 - Comments Off on Drush de Jour: Debugging Drupal modules

Drush de Jour: Debugging Drupal modules

Ever want to see what's happening behind the scenes on your Drupal site? With Drush you can do just that. Whether you are building, debugging or unintentionally breaking a Drupal site, the system logs are an invaluable way to see what is going on. Strange behavior of a module? Rules not working as expected? the logs can tell you a great deal. You can access the logs by browsing to Reports>Recent log messages (/admin/reports/dblog) and view and filter the messages. You can however get a realtime view of everything being written to the log with Drush.

% drush watchdog-show --tail

This command will let you all the messages as they come in. Keep that terminal window open and you can see users log in, rules being fired, module/php errors, and your own custom debug() and watchdog() messages. You will even see PHP warnings being thrown that may not break your site but indicate coding errors that won't be obvious by just using a browser to test.

Logic loops in modules can get complicated and sometimes you can't print out a standard debugging message to the browser with print or dpm depending on where in the rendering process your code occurs. You can however put in watchdog() statements inside your loops to let you see where your code is taking you. You could add logging to an existing module if you want to learn how it works and how you can hook into it. Just be sure to make backups if you're not working in a development environment.

All your log are belong to Drush!

The Drush de Jour brings you the latest and possibly greatest bits of drush wisdom we use for developing and maintaining our Drupal sites.

 

Published by: chazcheadle in The Programming Mechanism
Tags: ,

July 9, 2012 - Comments Off on Mutagens of Melanin

Mutagens of Melanin

We've already discussed the beauty and power of the human form in past entries. For a thing we see so often it's amazing how it never ceases to move us dating all the way back to the earliest cave paintings. Around that same time, some keen hunter-gatherer realized the body's potential as not only the subject but the canvas itself thereby inventing tattoos. Society has always had a strange relationship with such forms of body modification. They represent a more primal time. A time before we expressed ourselves through our brand of sneakers. Some may view such acts as desecration of the perfected human form but for many they are anything but. To be able to spark such an ultimate act of permanent self expression, tattoos must be terrifically inspiring and it is also recommended you take care of your skin using the best recommended anti wrinkle cream. 8Bit Ink

 I'll be the first to admit that often, tattoos simply don't appeal to me. Living in Brooklyn they're a bit difficult to avoid so when you see a piece of work that is not only good but matches its wearer (or canvas in this case) it can be quite stunning. Most tattoos rely on a well established iconography as pixelated upon above, however every so often one finds tattoo artists truly pushing the boundaries of the medium. Peter Aurisch does just this with his vivid line and color work. Many interplay gorgeously with their owner becoming one with the surface. The boundary between skin and ink is further blurred by the way he manages to make his work imitate watercolors, the hues bleeding past the lines that defines them. I can only imagine how much time and skill are required to simulate traditional mediums in the realm of female and male skin.

ElefantRose

Tattoos are often associated with the fringes of society as they can represent a passionate commitment to a specific subculture. Yet as seen above they can just as easily be about pure art and expression. The Family Affair tattoo studio seeks to remind us of this soft side with their friendly website emphasizing the family nature of their business in Italy. The site is simple and straight to the point clearly showing the studio's work and location while communicating their unique vision of the industry.

Family Affair

It's hard to think about tattoos nowadays without thinking about the hit books and film series The Girl with the Dragon Tattoo by Stieg Larsson. While the movies and books are still on my to watch/read list, the stunning opening credits for the film can be found below. Sit back and enjoy (no spoilers included).

http://vimeo.com/34699752

The Sketching Mechanism is a series of weekly posts, published on Mondays, containing the artistic musings of Mobile Designer/Developer Ben Chirlin during our Monday morning meeting at the NY Creative Bunker as well as his inspiring artistic finds of the week.

Published by: benchirlin in The Sketching Mechanism

July 5, 2012 - Comments Off on Digging into Drupal with node_load()

Digging into Drupal with node_load()

So, you've installed Drupal and created a custom content type. Now what?
Well, data goes in and (hopefully) data will come back out. Here are a few ways to see what data is being stored in your nodes and how it is structured. With this information you can manipulate and theme that information the Drupal way.

Every node in Drupal is stored in the backend indexed by its Node ID, or 'nid'. With the nid you can call up the node and make it dance for you. By dissecting the node as it is rendered by Drupal you can get access to the cck fields, referenced nodes, etc.

The quickest way to get node data is from the command line using our friend Drush.
% drush ev 'print_r(node_load(NID))'
This will bootstrap Drupal and evaluate the PHP expression you pass to it. The result will look something like this:

...
[field_gallery_category] => Array
(
  [und] => Array
  (
    [0] => Array
    (
      [tid] => 35
  )
    [1] => Array
    (
      [tid] => 36
    )
  )
)
[field_gallery_main_photo] => Array
(
  [und] => Array
  (
    [0] => Array
    (
      [fid] => 2072
      [alt] =>
      [title] => Antikythera Mechanim
      [width] => 515
      [height] => 438
      [filename] => antikythera-mechanism.png
      [uri] => public://images/antikythera-mechanism.png
      [filemime] => image/jpeg
      [filesize] => 43707
      [status] => 1
    )
  )
)
...

This is just a snippet of the entire node object that is returned. You can see how Taxonomy terms are associated with a node are stored in an array and how information for an attached imagefield file are stored. The parent [und] array is the language designation. An example of how you could use this is to use the image's title text as a div to be a captioned overlay at the bottom of the image. You could likewise, use the taxonomy term ID and get a list of other nodes that are tagged with that term and print out links to them. You could provide a direct download link via your template using the [uri] of the attached image. Understanding how data is presented to the theme layer of Drupal is the key to bending templates to your will.

If you have installed and enabled the Devel module you can evaluate that same php code:

print_r(node_load(...));

right from the webpage.

If you've already created a module and want to print out the node object in a nice collapsable viewer you can add this code:

/**
 * Implements hook_node_load().
 */
function custommodule_node_load($node) {
  if ($node->type == '<NODE_TYPE>') {
    dpm($node);
  }
}

and you will be rewarded with a very convenient display of the node elements.

When you get into creating and modifying custom theme templates for you site and I hope you do, being able to access the node object and its constituent elements will help in fine tuning the output as well as being a good way to see why data is or isn't appearing as expected.

Links:

devel module

node_load

 

Published by: chazcheadle in The Programming Mechanism
Tags:

July 3, 2012 - Comments Off on Drush de Jour: Getting your backup back up

Drush de Jour: Getting your backup back up

Last week we saw a couple of quick ways to get a database backup of your Drupal site with Drush and the command line. Here is a drushy way to restore that backup.

% drush vset --yes maintenance_mode 1
% drush sqlc < sitebackup.sql

Login as admin and check that everything is ok (www.yoursite.com/user).

% drush vset --yes maintenance_mode 0

We're using drush's sqlc command which is taking the sitebackup.sql file and dumping it back into your database. If you omit the < and backup file you will be taken to the mysql (or whatever database backend) cli, logged in as the drupal site sql user.

Taking your site offline ensures no one is making changes to the database and is a nice way to let people know that the site is not broken. You can additionally specify a maintenance mode:

% drush vset --yes maintenance_mode_message "The website is currently being updated. Please check back in a few minutes"

Drush vset (variable-set) and its partner in crime, vget (variable-get), allow you to access the variables table from your site's database. Wonderful things can be done with these two commands, like putting the site into maintenance mode. You can also check your site's current theme:

% drush vget theme

And yes, vget will pull all variables that match the substring you enter. so 'vget theme' will pull the admin_themedefault_theme, etc.

The Drush de Jour brings you the latest and possibly greatest bits of drush wisdom we use for developing and maintaining our Drupal sites.

Published by: chazcheadle in The Programming Mechanism
Tags: ,

July 2, 2012 - Comments Off on Malted Meteorites

Malted Meteorites

We take a lot for granted and there is one thing in particular we are all subjected to every waking moment. No human to this day has ever been truly free of its grasp though many may think otherwise. I am of course talking about gravity, the force that holds us all down and determines what's up and what's down. Most everything in our world is right side up, meaning heavy on bottom, light on top which is quite a limiting factor one would think. But artists love such established notions. The best art always comes out of breaking such expectations and precedents. And seeing how gravity is one of the strongest forces of all, it's opposite, inversion, must be quite the inspiration.

Artists have long experimented with themes of flight and weightlessness. Making things feel like they have weight at all can be quite a frustrating artistic process. Yet Li Wei seems to have mastered an ability to toy with preconceptions about physics in a startling way. His works are often self portraits with the artist performing death-defying feats like seeming to hover outside a window or hanging onto a car to stop from floating away. Yet his more recent pieces seem much lighter, focusing on the freedom of flight rather than the danger of falling. Most important to our theme however is his obsession with being upside down. Nearly every series he creates contains at least one portrait of the artist in an ostrich-like pose, head in ground.

Red Ribbon

The web promises a similarly liberating freedom from mass, yet unlike a piece of paper, a screen cannot be easily rotated. However the rise of tablets has given fostered a new breed of adaptive sites. Imagine a magazine that changes its layout depending on orientation to best highlight certain aspects of an article, for instance a chart in one orientation and the text describing it in the other. Or, as in this example for software development firm Ikayzo, the page seamless transitions to an inverted state as you scroll from top to bottom (though obviously the words stay right way up). Such designs could leverage mobile computing in the future to great effect.

Ikayzo

Yet can you imagine having to live life completely inverted every waking moment? What a strange and challenging existence that would be. Oh, well someone thought of just that and made a wonderful animation to tell the tale.

Have a great July 4th and enjoy the warm weather!

The Sketching Mechanism is a series of weekly posts, published on Mondays, containing the artistic musings of Mobile Designer/Developer Ben Chirlin during our Monday morning meeting at the NY Creative Bunker as well as his inspiring artistic finds of the week.

Published by: benchirlin in The Sketching Mechanism
Tags: , , ,