Posts By: Jason Glisson

The Drupal Commerce Address Duplication Issue

Recently I was working on a very large Drupal Commerce website that required many addresses for shipping (not billing) per customer.

The setup of the site was rather unique and required us to create many custom modules utilizing. We also needed a way to create orders on the front end of the site (the shopping cart side) and the back end of the site (the administrators side).

One thing that we noticed was that the checkout process on the front end and back end were very different. As a front end user, it’s the pretty typical shopping cart experience, but the backend was very different.

Going through the order creation process, we noticed there wasn’t a good way to search for a user. But even if we did manage to reference the user correctly using their email address, we couldn’t select one of their previously user addresses for an order.

Enter in the Commerce Admin Order Advanced module.

This module was exactly what we needed to search for customers and pick a previously used address that is stored as a Customer Profile in Commerce (and the address book if you’re using the AddressBook module).

But right off the bat, we noticed that ever single time we placed and order for a user, their address profile was duplicated. So one customer would have dozens of the same addresses entered into the system. You can see from he screenshot above, the same address is showing in the dropdown twice.

In one test, I had at least 20 of the same addresses in the system for one user. So if a manager went to go create an order, the same address was showing up over and over again. This didn’t seem like a very good user experience.

The strange thing is that, after we did some research, we realized that the address duplication was default commerce behavior.

Customer Profiles seem to endlessly duplicate!

Our solution was to allow the duplicate address to be created, but if the address is being referenced from an already existing customer profile, the new profile that is created when the order is saved would be set to deactivated.

// Load the current shipping profile
  $profile_dedup = commerce_customer_profile_load($form_state['values']['shipping_profile']);

  // If the profile is set and has an ID
  if(isset($profile_dedup->profile_id)) {
     
      // Load the referenced customer profile into the order
      $profile = commerce_customer_profile_load($profile_dedup->profile_id);

      // Set the status to deactivated so the shipping profile doesn't show up in the select box
    $profile->status = 0;
   
    // Save the profile as deactivated
    commerce_customer_profile_save($profile);    
  }

Twitter Lite Drupal Module

A while back, I was working on a Drupal website that needed to be lightweight and flexible. One of the requirements was a Twitter feed.

Now, don’t get me wrong, the official Twitter Drupal module is nice and has some great features. I have always felt like it’s a little bloated and not as easy as it should be to make a Twitter feed.

I decided to make a quick an easy to use module to solve my problem.

I’m naming it Twitter Lite since it is the lite version of the Twitter module. It doesn’t have all of the features that the Twitter module has.

This module creates two Twitter feed blocks. You can also choose how many tweets to show per block.

Eventually I’ll extend this to show hashtag searches as well as usernames. For now, it only uses usernames.

There are some fallbacks that need to be made also.

Feel free to try it out on your own Drupal 7 site.

Please feel free to let me know if you have any bug reports or issues with the module. I’d like to actively maintain this and prep it for Drupal 8.

Drupal Sandbox Project Page: https://www.drupal.org/sandbox/tk421jag/2451325

Github repo: https://github.com/jasonglisson/twitter_lite

Being a successful Drupal Developer

I’m a web developer. I enjoy what I do. A lot.

About 7 years ago, I discovered what it was that I was missing in web development. Drupal.

Drupal is open source software maintained and developed by a community of over 1,000,000 users and developers. (That’s taken directly from Drupal’s website.)

The first Drupal website I put together was a combination of downloading modules, hacking themes, and generally having no idea what I was doing. But it was fun and I was learning what Drupal was. I recall it was just after Drupal 6 was launched. Seems like it was eons ago.

I wish I could go back and yell at the developer I was then for not doing things a better way. Knowing what I know now, my development skills have dramatically improved and I try very hard to stay within the Drupal Best Practices documentation.

Here are some of my tips for being a successful Drupal developer.

Don’t hack core!

This is basically one of the cardinal rules of Drupal development. Hacking core files of Drupal means updating the site will likely break everything. Also hacking modules means that you won’t be able to update them for bug fixes and troubleshooting.

Learn to use the Drupal API

Eventually, you’ll find the need to write functions and do crazy things with your code. The fun part of developing for Drupal is that the API rocks. I mean, really rocks. There are so many cool functions and code snippets for doing things that would otherwise take you forever to write/code yourself. Learn to use things like node_load(), path_to_theme(), node_save(). These three functions are simple but extremely useful. Use case: I recently wrote a module that went through 20,000 nodes for a Drupal website, retrieved data from another website using their API, brought that data back to my project site, then saved the data using node_save(). Doing that by hand, no. It would take weeks on top of weeks. The script I wrote took 90 seconds. Boom. Drupal Magic.

Contribute to the Drupal Community

Whether you contribute code, testing, or bug reports, Drupal thrives off the community. This is something that I failed at for a while. I simply felt that I wasn’t good enough to contribute to discussions or code. However, simply reporting a bug is useful to the community. If you’ve used a module and had an issue with it’s basic usage, report it. Search for the bug you’re reporting first. It could be that it’s a duplicate issue. Please please please search for the issue first. Don’t be a lazy Googler.

Learn Version Control

This may be one of the most valuable takeaways from this post. Version control isn’t just used by the Drupal community, it’s used by coders everywhere for a wide variety of things. Personally, I use Git for version control, but there are many other options. Some people find it very daunting to do things in Command Line or Terminal (that thing that looks like MS-Dos for those that don’t know). It’s really very simple though. If you learn version control, you’re value to a company will go up significantly. I promise. Here are a few sites that might help:

  • Easy Guide – http://rogerdudler.github.io/git-guide/
  • Try Git – https://try.github.io/levels/1/challenges/1
  • GitHub – https://github.com/

Learn helpful shortcuts

For a long long time, when I setup a Drupal website, there was a lot of downloading, decompressing files, placing modules and themes in the correct place, then finally starting to work on the project. Enter Drush. If you are using Command Line/Terminal, then Drush will be your best friend. Using Drush, you can download Drupal, setup themes and install them, download modules and install them, update Drupal, backup you site, and a slew of other things using very basic and easy commands. It’s cut down my setup time to just a few minutes. Read up on Drush here.

Setup local development environments

Gone are the days where you had to have a server to work on a website. There are some very easy to setup tools that you can use to setup your site on your desktop or laptop so you can work on it anywhere without the internet. I once worked on a local website for 2 hours while my train was stuck in a cellular dead zone in Virginia. Try using MAMP to setup your local environment so you can get coding and work on your sites from anywhere.

Attend conferences and meetups

Speaking for myself, I learned Drupal development from a hand full of very gifted developers over a long period of time. It never hurts to find a developer willing to share some knowledge with you. The best resource to learn Drupal is by going to conferences and meetups to hear people speak on a wide variety of topics. Maybe you can even take some training. Drupal Con is a big one. I’ve never had the opportunity to go, but something tells me that I will soon. My favorite conference was the 2011 Do It With Drupal (DIWD) conference by Lullabot. My mind was blown about every 60 seconds. I came back understanding more about development skills, Drupal development, and the future of the web. Here are some highlights from that conference.

Don’t be closed minded to other technologies

I love Drupal. We know this. But I also love WordPress. I can hear some developers now: What’s that you say! Traitor! Burn him!

Calm down people. Being a web developer doesn’t mean I only want to do things my way or I only want to use one technology to do things. You need to learn when and where specific software and tools will work best. If someone says to me “I want a website, but I’m not that good at computers, but I do want to write blog post” then I’m likely gonna recommend WordPress. But if someone comes to me and said, “I want a custom website where I can load in videos, pictures, and other content. I also want to sell things, etc etc” then I’d likely recommend Drupal.

Having said that, there are other options outside of Drupal and WordPress that I’ve also used from time to time. Flat-file CMS’ are popping up everywhere. they are lightweight and easy to setup. One of my favorites is GetSimple. Another one is Pico.

Hopefully this will help someone figure out what they need to learn to be more successful at Drupal development. As always, feel free to contact me if you have any questions. Except for haters. You guys can jump in front of a bus.

Simple Fixed Header Javascript/CSS

I’ve done several post on fixed headers. I get a lot of emails about them and a lot of site traffic. Obviously, a lot of people find them useful. So I’m going to post the simplest way that I know to make one. Be it in Drupal or WordPress, or even flat-file sites; this is the easiest way that I do fixed headers.

Below you’ll see some javascript. Take a look at it and then I’ll explain.

$(function () {
	//store the element
	var $top = $('.navigation-wrap');

	//store the initial position of the element
	$(window).scroll(function(){
	    if($(document).scrollTop() > 200) {
		  // if so, add the fixed class
		  $top.addClass('fixed');
		} else {
		  // otherwise remove it
		  $top.removeClass('fixed');
		}
	});
});

The first line is the basic shorthand document ready jquery opening. So we’ll skip to the next few lines.

var $top = $('.navigation-wrap');

Where you see ‘.navigation-wrap’, you’ll want to replace this with your header wrapper selector or whatever selector you have that you want to fix to the top of the viewport. This is storing the selector as a variable called “$top”.

Next you’ll see a function that detects scroll events on the browser window.

$(window).scroll(function(){

Then the fun stuff…

if($(document).scrollTop() > 200) {
    // if so, add the fixed class
    $top.addClass('fixed');
} else {
    // otherwise remove it
    $top.removeClass('fixed');
}

This code basically tells your viewport “Hey, when I scroll down greater than 200px, I want to do something.” In this case, we are adding a class to the previously referenced variable called “$top”.

The fun part of this is that you can also remove the class by using an else statement, which you can see above.

Feel free to adjust the ‘200’ to whatever you’d like it to be. Or if you’re really brave, you can use the script that I posted about viewport size to calculate the size of your first div, and make the menu stick after you’ve scrolled that distance. Just like my homepage does. 🙂

Now, in your stylesheet, you’ll need to add some style to the selector that you’re fixing to the top. Pretty simple. Something like this..

.navigation-wrap.fixed {
    position:fixed;
}

Hope this helps someone!

Adjust div height based on viewport

Did you ever wonder how some sites scale their intro or top homepage area to be the size of the entire screen? It certainly looks good on larger screens with background images or large images.

This is accomplished with some pretty easy javascript or jquery.

Below you’ll see a function that targeting a div with the ID ‘top-header’. Since that div is given a width of 100%, the height is the only thing we need to worry about.

This code will set the div height to whatever the height of your viewport window is on page load.

function viewport_height() {
      var window_height = $(window).height();
      $('#top-header').height(window_height);
}

viewport_height();

$(window).resize(function() {
  viewport_height();
});

Convert Taxonomy Term ID (tid) to alias url path

While working on a tremendously large Drupal 7 project, I found myself needing to convert Taxonomy tid’s to full URLs. The easiest solution was to just print out the value of the field after the taxonomy path url, like this:

/taxonomy/term/$tid

A problem with this is that it’s not following the alias naming conventions that you may have setup for your site. In my case, I had hundreds of taxonomy terms that were setup with specific URLs.

Luckily, Drupal has it’s own function to link the terms to their alias URLs.

$url = drupal_lookup_path('alias', 'taxonomy/term/'. $known_tid);

So in my case, I was able to write a foreach statement to cycle through all of my terms that have been referenced through an entity reference field.

foreach ($node->field_related_issues['und'] as $val) {
    $tid = $val['taxonomy_term']->tid;
    $url = drupal_lookup_path('alias', 'taxonomy/term/'. $tid);
    echo '<li><a href="/' . $url . '">' . $val['taxonomy_term']->name . '</a></li>';			    
}

Twitter Feed Using Php

HAPPY NEW YEAR!

To start off the year, I’ll post something that I’ve been using a lot in the last month or so for a few sites that I’ve built.

A few years ago, Twitter ended support for their 1.0 API and all twitter feeds across the net began to crash if they weren’t updated to the new 1.1 API. I remember that day well because years past clients were calling wondering why their twitter feeds were no longer working. Naturally, if I were under a maintenance contract they would have been fixed prior to the API changes.

Below is a quick and easy snippet for getting your twitter feed to work using the 1.1 API and OAuth. To use this you’ll need to login to Twitter and create an app, then enter your app information in the token and key areas.


	$token = '[YOUR TOKEN FROM THE APP SETTINGS]';
	$token_secret = '[YOUR TOKEN SECRET FROM THE APP SETTINGS]';
	$consumer_key = '[YOUR CONSUMER KEY FROM THE APP SETTINGS]';
	$consumer_secret = '[YOUR CONSUMER SECRET FROM THE APP SETTINGS]';

	$host = 'api.twitter.com';
	$method = 'GET';
	$path = '/1.1/statuses/user_timeline.json'; // api call path

	$query = array( // query parameters
	    'screen_name' => '[ENTER YOUR TWITTER USERNAME HERE]',
	    'count' => '1' // How many tweets do you want to show?
	);

	$oauth = array(
	    'oauth_consumer_key' => $consumer_key,
	    'oauth_token' => $token,
	    'oauth_nonce' => (string)mt_rand(), // a stronger nonce is recommended
	    'oauth_timestamp' => time(),
	    'oauth_signature_method' => 'HMAC-SHA1',
	    'oauth_version' => '1.0'
	);

	$oauth = array_map("rawurlencode", $oauth); // must be encoded before sorting
	$query = array_map("rawurlencode", $query);

	$arr = array_merge($oauth, $query); // combine the values THEN sort

	asort($arr); // secondary sort (value)
	ksort($arr); // primary sort (key)

	// http_build_query automatically encodes, but our parameters
	// are already encoded, and must be by this point, so we undo
	// the encoding step
	$querystring = urldecode(http_build_query($arr, '', '&'));

	$url = "https://$host$path";

	// mash everything together for the text to hash
	$base_string = $method."&".rawurlencode($url)."&".rawurlencode($querystring);

	// same with the key
	$key = rawurlencode($consumer_secret)."&".rawurlencode($token_secret);

	// generate the hash
	$signature = rawurlencode(base64_encode(hash_hmac('sha1', $base_string, $key, true)));

	// this time we're using a normal GET query, and we're only encoding the query params
	// (without the oauth params)
	$url .= "?".http_build_query($query);

	$oauth['oauth_signature'] = $signature; // don't want to abandon all that work!
	ksort($oauth); // probably not necessary, but twitter's demo does it

	// also not necessary, but twitter's demo does this too
	function add_quotes($str) { return '"'.$str.'"'; }
	$oauth = array_map("add_quotes", $oauth);

	// this is the full value of the Authorization line
	$auth = "OAuth " . urldecode(http_build_query($oauth, '', ', '));

	// if you're doing post, you need to skip the GET building above
	// and instead supply query parameters to CURLOPT_POSTFIELDS
	$options = array( CURLOPT_HTTPHEADER => array("Authorization: $auth"),
	                  //CURLOPT_POSTFIELDS => $postfields,
	                  CURLOPT_HEADER => false,
	                  CURLOPT_URL => $url,
	                  CURLOPT_RETURNTRANSFER => true,
	                  CURLOPT_SSL_VERIFYPEER => false);

	// do our business
	$feed = curl_init();
	curl_setopt_array($feed, $options);
	$json = curl_exec($feed);
	curl_close($feed);

	$twitter_data = json_decode($json);

	function linkify_tweet($twitter_data) {

		//Convert urls to <a> links
		$twitter_data = preg_replace("/([\w]+\:\/\/[\w-?&;#~=\.\/\@]+[\w\/])/", "<a target=\"_blank\" href=\"$1\">$1</a>", $twitter_data);

		//Convert hashtags to twitter searches in <a> links
		$twitter_data = preg_replace("/#([A-Za-z0-9\/\.]*)/", "<a target=\"_new\" href=\"http://twitter.com/search?q=$1\">#$1</a>", $twitter_data);

		//Convert attags to twitter profiles in <a> links
		$twitter_data = preg_replace("/@([A-Za-z0-9\/\.]*)/", "<a target=\"_blank\" href=\"http://www.twitter.com/$1\">@$1</a>", $twitter_data);

		return $twitter_data;

	}

/* 	print_r($twitter_data); */

// Use the print_r above to view all of the twitter settings and data that you want to use

Below is a basic example of how you would parse the twitter data using the code above.

<div id="tweet">
	<div class="row">
		<div class="large-10 columns tweet-wrap">
			<span class="date"><?php 

						$date = new DateTime($twitter_data[0]->created_at);
						$date->setTimezone(new DateTimeZone('America/New_York'));
						$formatted_date = $date->format('M d, Y');
						echo $formatted_date;			

			?></span><br>
			<span class="tweet-text"><?php echo linkify_tweet($twitter_data[0]->text); ?></span>
			<div class="intents">
				<span class="reply"><a target="_blank" href="https://twitter.com/intent/tweet?in_reply_to=<?php echo $twitter_data[0]->id; ?>"><i class="fi-arrow-left small"></i> Reply</a></span>
				<span class="retweet"><a target="_blank" href="https://twitter.com/intent/retweet?tweet_id=<?php echo $twitter_data[0]->id; ?>"><i class="fi-loop small"></i> Retweet</a></span>					<span class="favorite"><a target="_blank" href="https://twitter.com/intent/favorite?tweet_id=<?php echo $twitter_data[0]->id; ?>"><i class="fi-star small"></i> Favorite</a></span>
			</div>
		</div>
	</div>
</div>

You may need to download the OAuth code from here: https://github.com/abraham/twitteroauth/tree/master/src

Display only the first menu link in Drupal 7

This is a useful Drupal 7 code snippet that can echo out the first (or whatever link you prefer) link in a menu. Recently, I used this to create a menu with one link used for a Donation button. I wanted to prevent any other items being echoed or inserted into a block area, so I used this so that the first menu item was always the only one that would be shown. It was useful since, on other pages, the full menu with other links under “Donate” was used in Block form.

<?php
$menu_depth = 1;
$menu_tree = menu_tree_output(menu_tree_all_data('menu-donate', null, $menu_depth));
print drupal_render($menu_tree);
?>	

Using Javascript to get a variable from a URL

Sometimes, within a website, you see variables that are passed through the URL. The variable part of the URL usually looks something like this:
“?tab=mo&authuser=0”

In the above example, ‘tab’ is equal to ‘mo’ and ‘authuser’ is equal to ‘0’.

This snippet below with let you extract the values of variables by parsing the URL. It specifically looks for the & and = symbols so you’ll need to make some changes to the regex part (/[?&]+([^=&]+)=([^&]*)/gi) if you’re using symbols other than that.

function getUrlVar() {
    var vars = {};
    var parts = window.location.href.replace(/[?&]+([^=&]+)=([^&]*)/gi, function(m,key,value) {
        vars[key] = value;
    });
    return vars; 
}
var tab = getUrlVar()["tab"];
var user = getUrlVar()["authuser"];

Delete all of a content type in Drupal 7

On a recent project, I had the need to delete thousands of a content type in order for me to correct some issues with the website, before re-adding them all. This is a useful script that I found to do just that. You fill in your content type, and all the nodes will be deleted. This works best in a custom module that you can turn on or off.

$node_types = array('content_type'); // add the machine names of node types you want to bulk delete

$query = new EntityFieldQuery();
$query->entityCondition('entity_type', 'node')
->propertyCondition('type', $node_types, 'IN');
$result = $query->execute();
foreach($result['node'] as $node){
node_delete($node->nid);
}