All Posts in drupal

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

June 28, 2012 - Comments Off on Drupal 7 Commerce Coupons: Unlimited redemptions

Drupal 7 Commerce Coupons: Unlimited redemptions

The Commerce module and its add-ons are very powerful. The coupon module has recently undergone a major rewrite and its one we're using for one of our sites. In this post we'll talk about making a modification to one of the coupon rules to allow for unlimited coupon redemptions if you enter '0' (zero) in the Number of uses field when editing a coupon.

In Workflow > Rules edit the rule Coupon Validation: Check the number of redemptions.
Add an AND condition
Then, add a Data Comparison condition
For the data to compare choose: coupon:commerce-coupon-number-of-uses
Choose the equals operator, and 0 as the value.
Next, we want to negate this condition. See the post on Drupal Rule(s)! for an explanation of this option.
Lastly, save the new condition and drag it and the Entity has field condition under the And operator.

Coupon conditions

Coupon conditions

That's it. Now you can redeem a coupon as many times as you want.

Drupal's well thought-out and structured framework allows for changes to functionality to be done at a high level instead of always needing to dig into code and/or write Tarzan-like, custom PHP. This in turn, saves other developers and designers a lot of time. Thanks Drupal!

Links:

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

June 26, 2012 - Comments Off on Drush de Jour: Painless database backups for your Drupal site

Drush de Jour: Painless database backups for your Drupal site

Proceed directly to drush.
Do not pass Go.
Do not enter your site name.

When you first set up your Drupal site- install drush, the command line shell for Drupal. With drush, you can backup your db, create users, reset passwords, re-index search, start/stop migration, check logs, etc. etc. etc.

From the root of your Drupal install: (e.g., /var/www/<sitename>).

% drush archive-backup --destination=sitebackup.sql

That's it. Your entire drupal database is written to a file.

% drush sql-dump > sitebackup.sql

This method uses drush's Mysql command line interface to do a mysqldump of the site database

And if you want to be stubborn and not install drush:

mysqldump -u -p <sitedatabase> > sitebackup.sql

Links

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

June 21, 2012 - Comments Off on Drupal Rule(s)!

Drupal Rule(s)!

 Fitness Tips To Help You See Impressive Results

MARCH 23, 2020

Being fit has many physical and mental benefits for your health. However, many people may not understand what it fully requires to fully reach their goals. Follow these 5 fitness tips to help you see impressive results. Check these profit singularity reviews.

1. Stay Consistent

Consistency will lead you on the road to success the quickest. It doesn’t matter what your goals are. If you have consistency and develop a routine that you know that you can rely on, it will lead to you reaching your goals quicker.

For example, if you want to lose weight, you should be consistent in your cardio exercise regimen. This consistency cannot just stop at your physical exercise, though. This consistency has to extend into another important part of your routine, which is your diet.

2. Watch Your Diet

Maintain a good diet to reach your fitness goals.

Many people only focus on the gym and exercise component of attaining fitness goals. As mentioned before, your diet is one of the most important parts of your fitness regimen, but having a great diet, regardless of your fitness goals, will impact whether or not you are successful in your goals as much or more than actual exercise. This is because your body will reflect what you eat and your diet can either progress your goals further or set you back.

It may be helpful for you to keep a log of what you eat and determine which foods you need to eliminate and which foods you need to add. In addition, you also want to be mindful of when you are eating, because it can also affect your performance in the gym.

For those who are bodybuilding or looking to build muscle, it’s recommended to incorporate some kind of carbohydrates before a workout session, and then have a protein-heavy meal once you are finished to speed up the recovery process. Protein shakes are a popular commodity in this regard. However, different protein powders can have different vitamins, minerals, and ingredients that can be more effective for men or women.

Ladies can check out a variety of protein powders to see what’s available for their needs. There tend to be more protein powders available for men that already have the extra minerals and vitamins included to help them get gains. So when guys are searching for the best protein powder, it’s better to decide if they’re trying to get lean or gain weight.

3. Have Realistic Expectations

Having the right mindset is imperative to achieve the fitness goals of any kind, and it starts by having realistic expectations. If you don’t like what you see in the mirror, then you have to work hard to see a change. However, if you are looking to shed some pounds and reduce your waistline, you can’t expect it to be done within a week.

Realistic expectations directly correlate with being consistent. Gaining weight means you will need to take the time to increase the amount of food in your diet and the number of weight-bearing activities that you engage in.

Losing weight will take a gradual amount of time with you engaging in vigorous cardio and making healthy choices. Your body cannot adapt to the changes that you plan to make overnight.

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

May 11, 2012 - Comments Off on Building new sites… with some old data

Building new sites… with some old data

The files are IN the computer!

When building a new site for a client, migrating data from an old site or system can be a daunting task. There are several excellent modules such as feeds_import which can help move data that is already online in one form or another via rss/xml and so on. Sometimes there is content which needs to get onto the site that lives off-line or for other reasons isn't compatible with an existing import module- for that you can write some code to help out.

For one project we had to import a list of users which came from a CSV export from a spreadsheet. We really just needed users in the system to be able to assign them as authors of content. The following code is what we used to read in the CSV file and create the users. Any CCK field can be populated with this, here we are adding First, Middle and Last name fields before submitting.
This script relies on Drush and the Forms API to bootstrap drupal and feed it the form submission.

As with all things Drupal, there are more ways to accomplish a task than there are tasks to accomplish.

/**
* Import users via a CSV
*
*/
// Initialize a counter to track the number of users processed
$i = 0;
// Check for the .csv file in the particular directory. We create a <site>_util directory
// to put these sorts of scripts.
if (($handle = fopen("./sites/all/modules/custom/site_util/new-users.csv", "r")) !== FALSE) {
// While there are rows of data in the file, keep looping through.
while (($data = fgetcsv($handle, 0, "," )) !== FALSE) {
// Read in and sanitize data from the CSV file.
// Here we assign each column to a variable.
$fname = utf8_encode(trim($data[0]));
$mname = utf8_encode(trim($data[1]));
$lname = utf8_encode(trim($data[2]));
$email = trim($data[3]);
// Create random 8 character password.
$pass = user_password();

// Initialize the $form_state array which will be passed to drupal_form_submit.
$form_state = array();

// Tell drupal_form_submit what operation this form is performing
$form_state['values']['op'] = t('Create new account');

// Drupal 7 requires this second password field to create users.
$form_state['values']['pass']['pass1'] = $pass;
$form_state['values']['pass']['pass2'] = $pass;

// Populate the name and email elements of $form_state.
$form_state['values']['field_profile_fname']['und'][0]['value'] = $fname;
$form_state['values']['field_profile_mname']['und'][0]['value'] = $mname;
$form_state['values']['field_profile_lname']['und'][0]['value'] = $lname;
$form_state['values']['mail'] = $email;

// Build a human readable Username. We are using email as the primary login.
// Since the users do not always have a middle name we will use a
// a ternary operation to prevent adding a second space between the
// first and last name.
$form_state['values']['name'] = $fname . ' ' . ($mname ? $mname . ' ' : '') . $lname;

// Since we're running on the command line, we'll add some status information.
print('Adding: ' . $form_state['values']['name']. "n");

// Finally, we submit the built $form_state array to Drupal's user_register_form.
drupal_form_submit('user_register_form', $form_state);

// Increment the counter.
$i++;
}
}
print("Processed: " . $i . " users.");

Save this code to a file and then run execute it with drush:
% drush scr script.php

Thats it. It should import your users and report at the end.
You'll need to make sure the data going in is sensible, valid emails, names etc.

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