Archive

You are currently browsing the archives for the PHP category.

Mar

20

Tame the Burrito: the 5 layers of drupal

By mike@mike-miles.com

My first session of Drupalcon run by Jeff Eaton,  sadly was stripped of all burrito analogies. But, lucky it was not stripped of great information about how the “Drupal Stack” is layered. Along with his overview of the five layers of Drupal, Jeff covered some practices to follow to make sure any development you do towards a Drupal application does it’s best to keep the layers separate (when possible).

First a bit of history.  Jeff explained that in the past, when it was simpler times, Drupal was composed of three main layers:

-Themes

- Contrib Modules

- Drupal Core.

Simple, straight forward.  The core layer, contained all of Drupals default functionality.  Contrib Modules, the extra functionality you threw onto your Drupal application. And the theme layer, the display and HMTL generation .

Now, things are not as simple, things have become more complicated and the layers have become muddled and more complex. In the simplest terms Jeff broke down what the current five layers of Drupal are.

The Products layer:

This is the layer that the end user sees, what is handed over to clients.  It is the “Drupal Product” you hand over to your clients. In Jeffs burrito analogies, it is the tortilla, it wraps everything.

The Features Layer:

The end functionality, what your drupal users actually interact with.  This is the layer that your users/clients care about, the features are what tehy see and use.

The “Building Tools” layer:

This is the layer where a Drupal product is built. It’s composed of the different tools (modules) that developers/adminstrators use to build nodes, forum, image galleries, ect. “The Drupal Application”, this is the first layer in the stack that your site visitors/content maintainers do not care about (in fact they will not care about any of the other layers).  This is the first layer that is for devs only.

The “Building Blocks” layer:

The code and architecture layer. This is the individual modules layer, weather it is a contributed module or your own custom developed module. this is the most important layer to developers, it’s where their drupal code goes to be used in the building tools layer to build a Drupal application.

The “Web framework” layer:

The least “drupally”, this is the layer of code that is simply needed to get a web application running. HTTP requests, database calls, sessions, caching, ect…

Ok so there are five layers , who care? Well as Jeff pointed out, all Drupal developers should care about the layers and developing within there respected layers. “Complexity means collissions”.  the more muddled the work we produce, the harder it is to maintain, update and future proof.

If developers focus on writing there code/modules/applications with these five layers in mind it’ll make it easier to contribute, share, produce code of better quality.  How to accomplish this? Follow a few rules:

Generic is hard:  the more generic of a problem you are trying to solve, the harder it is to implement. To combat this, when developing keep problems simple.  If you have a large problem you need to solve, break it down into simpler problems and solve them separately (separate modules)

Examples beat assumptions:  Do not assume what your module is going to be used for, instead provide examples of what it can be used for.  when you assume, you are limiting what other can do with your module. So do not assume what your module will be used for, but keep it open and provide examples of what it can be used for. Others will comeback to you with uses for your module, add-on modules that you might never even thought of.

Blur to optimize, isolate to reuse: It’s true in the world that you will not always have time to develop a clean module that keeps the layers separate, there are times where you just need to get it done and built.  In these instances, build to optimize, get your code to run the best that it can.  But if you do have the time, build to isolate.  Keep the layers seperate, and build the best you can so that your code/module can be reused.

 

 

 

 

 

 

 

Mar

20

From the mouth of Dries: my recap of the drupalcon keynote

By mike@mike-miles.com

All this week I am in Denver attending the 2012 Drupalcon, and I am doing my best to blog about all that I learn.  The core of drupal is of course the open source of knowledge.

To start things off Dries (he who invented Drupal) gave his annual keynote, with a focus this year on “winning hearts and minds through innovation”.  Dries emphasiseed that in order for products/companies to thrive the need to continuously innovate, or face death in the market place.  A great insight that I totally agree with, in order to stay relevant and competitive, you cannot focus on what people want today, but look towards (and build) what they will want tomorrow.

Since Drupal is a single product how does it innovate? Well as Dries covered in his keynote it is through improving four key aspects of drupal (with focus on Drupal 8). the focus is on improving and working with Drupals  strengths, weaknesses, opportunities and threats.

Drupal has many strengths, but the best is by far its community.  The Drupal community is huge (around 3,000 attendees at Drupalcon this year)  and by fostering growth and talent in Drupal it can thrive in the CMS/framework marketplace.

Like everything Drupal has some weakpoints, places where it could use some improvements.  Looking at the current weaknesses and addressing them with the development of Drupal 8, we can make drupal more innovative.

Rudimentary authoring.  More and more content editors (those who will be working with a drupal site day-to-day) are involved with choosing their CMS solution. By adding more powerful/easy to use authoring tools into drupal 8′s core it can be come an easier and better solution for authors.  Some of these improvements (that are being worked on for drupal 8) are inline editing, better media support and easier layout building t0ols.

An aging framework. Since Drupals inception it has been built on again and again, making it something that once was an easy platform for hobbiests and new developers to pickup and develop with. But now, it has become very complex that it can be a bit daunting for new comers to Drupal (as well as more experienced developers).  The solution, Symphony.  Drupal 8 is going to be adopting parts of the symphony framework into its core to make Drupal development easier, faster and more reusable.  Direes also talked about working on plans for developing drupal SDK’s and distributions to make it easier to develop/share.

A focus on mobile.  the mobile market is ever increasing (a stat stated by Dries is that mobile browsing experience is expected to grow 25x in the next 5 years).  to stay innovative and great for users Drupal needs a better focus on mobile. In all aspects, easier to developemobile drupal applications (both native and mobile browsers), easier for visitors to view drupal applications on mobile (Drupal 8 with use HTML5 and have a RESTful api within its core) and easier for content editors to maintain their aplication from a mobile stand point.

Finally Dires laid out a rough timeline for the next innovation of Drupal, Drupal 8.  an expected feature freeze in December and a code freeze in February. Drupal 8 is expected to be released by August of 2013.  Only 18 short months away!

The time for my first coffee break is up, onto my first session.  Based on the awesome opening keynote I’m looking forward to what Drupal has in store for me this year.

 

 

 

 

Dec

5

Reading Backbone.js POST variables from PHP

By mike@mike-miles.com

For a recent project, I had to read POST variables sent from Backbone.js to PHP. Now is turns out Backbone.js does not simply send normal POST variables (retrievable from $_POST). Instead it sends a json object of the variables.

So simply querying the global $_POST object for the variables you are looking for will not work, PHP will say that the $_POST is empty.Enter “php://input” .

“php://input” is the input stream that allows you to read raw data from the request bod. Basically you can read in the raw POST data this way. so for example if you called file_get_contents(“php://input”); it would return the POST data.

Now as I said before, Backbone.js sends the POST data as a json object. So reading in the contents of the php://input will get your the values that are posted. Let’s look at an example.

Let’s say that Backbone.js was sending us the following variables:
category_id: 1
sub_catagory_id: 34
title: “my saved data”

Say Backbone.js was sending the following through POST

{"catagory_id":1,"sub_catagory_id":34,"title":"my saved data"}

Notice, Backbone.js sends only a json string, not variable name to access. the POST is the string. so trying to view the $_POST with say a print_r would return false. But using “php://input” with file_get_contents, we can get the raw POST data and place it into a variable.

<?php
  $post_data = file_get_contents("php://input");
?>

and $post_data would then be a json string

<?php
  echo $post_data; //{"catagory_id":1,"sub_catagory_id":34,"title":"my saved data"}
?>

And now you can simply use json_decode($post_data) to retrieve a the json object of values. (passing a second argument returns an associative array instead of an object.)

<?php
  $post_data = file_get_contents("php://input");
  $post_data = json_decode($post_data,true);
/* $post_data returns the following
  array(
   "catagory_id":1,
   "sub_category_id":34,
   "title":"my saved data",
  );
*/

But wait, that may solve our problem if we know for sure that “php://input” contains data from Backbone.js (a json string). But what if it doesnt? wouldn’t it make sense to cover our bases. How about writing a function that can return the POST data no matter what?  Well then a function like the following might suffice.

<?php
function get_post_data(){
	if ($input = file_get_contents("php://input")){
		//test for json
		if ($json_post = json_decode($input,true)){
			return $json_post;
		}else{
			parse_str($input,$variables);
			return $variables;
		}
	}
	return false;
}
?>

One additional function to note I am using is “parse_str“. parse_str parses a string as if it were the query string passed via a URL and sets variables in the current scope. Passing the second argument sets the parsed data into a variable. So with this function, if the POST data is a json string, it gets parsed into an associate array, and if it is normal POST data, it gets parsed into an associative array. A win win for all cases.

Oct

19

Drupal like templating for your wordpress plugin

By mike@mike-miles.com

As part of my job, from time to time I am responsible for building custom WordPress plugins for client sites. One of the biggest pains of building a plugin (besides the miss-mash of resources/tutorials on how to build one) is theming the output. Weather it be output to the front end user, or an admin screen or a form, I have never been able to find a great way to separate back end code and front end code (not having HTML within the plugin itself). That is until the idea came to me to mimic the method Drupal uses to template output (I do a lot more Drupal development, than I do wordpress). On the latest wordpress plugin I had to develop, I decided to implement my idea and it worked quite well. so I thought I’d share the methods used so that any other wordpress plugin developer out there might use it.

A quick basic overview of how Drupal templates content for any of you who maybe unfamiliar. When a Drupal module (module is to Drupal, what plugin is to WordPress) want to output content it calls a theming function, an example:

<?php
//... other module code
return theme('my-template-file',$arg1,$arg2);
?>

So basically, you call a function ( called ‘theme’) and pass it the name of the template file you want to use along with the arguments to pass to that template. (This is a very basic overview of how the Drupal theme function works).

What Drupal then does is start an output buffer, render the content of the template (passing the arguments as variables in the local scope) captures the output, clears the output buffer and return the rendered content. here is the function that does it (from ‘theme.inc’ in the Drupal directory ‘includes’).

<?php
function theme_render_template($template_file, $variables) {
	extract($variables, EXTR_SKIP);  // Extract the variables to a local namespace
	ob_start();                      // Start output buffering
	include "./$template_file";      // Include the template file
	$contents = ob_get_contents();   // Get the contents of the buffer
	ob_end_clean();                  // End buffering and discard
	return $contents;                // Return the contents
}
?>

So we want to replicate this function in our WordPress plugin, all be it with a few additions. First, we’ll need to be able to get the location of our plugin, and thus the full location of the template file (Drupal does something similar with themes and modules in other functions to get the full $template_file path). Second, we’ll want to extend the functionality of this to allow multiple templates to be used. This is again, modeled after Drupal. What the Drupal theme engine allows you to do is have different versions of a template file. For instance, there will be a basic one with the module, but any theme can also have the same template file which will be used instead (This allows Drupal sites to customize output without needing to alter the modules core code).

So our WordPress plugin function will look something like this:

<?php
//... other module code
function myplugin_theme($template,$variables){
        //empty content to start
	$contents = '';
	//no template path to start
	$template_file = false;
	//get the path or the current active theme
	$theme_path = get_stylesheet_directory();
	//get the path to our plugin template directory
	$plugin_path = dirname(__FILE__).'/templates/';
	//assume the template name we are given does not have the extension
	$template.='.tpl.php';
	//see which template file we want to use
	//doe the theme have the template file?
	if (file_exists($theme_path.'/'.$template)){
		//it does, so use this as the path
		$template_file = $theme_path.'/'.$template;
		//does the plugin have the template file?
	}else if (file_exists($plugin_path.$template)){
		//it does, use that instead
		$template_file = $plugin_path.$template;
	} // else, there is no template file found.
	//do we have a template file to output?
	if ($template_file){
		extract($variables, EXTR_SKIP);  // Extract the variables to a local namespace
		ob_start();                      // Start output buffering
		include "./$template_file";      // Include the template file
		$contents = ob_get_contents();   // Get the contents of the buffer
		ob_end_clean();                  // End buffering and discard
	}
	return $contents;                // Return the contents
}
?>

A quick break down of our function and how it work. The function retrieves the current active theme path, as well as the path to our plugin. It first checks to see if the theme has the template file (indicates the theme creator has specialized the output of this template), else it sees if the plugin has a base template file (as it should). If there is a template file, then the function uses the PHP extract function to move the variables passed into the local namespace. It then does the same thing as the Drupal function, renders the content and returns it. Not that, if the template file is not found our function returns an empty string.

So how might one use this? Well here is an example, say our module displays a list of restaurants near a users location. We don’t know how many results are being returned, but we want to template how the list looks. so we might do something like this:

<?php
function mymodule_display_restaurants(){
	//User submitted their zipcode via a form
	$zipcode = $_POST['zipcode'];
	//we retrieve a list of restaurants near the users zipcode
	$restaurants = mymodule_get_restaurants($zipcode);
	//display restaurants to user
	echo mymodule_theme('restaurant-list',array('restaurants'=>$restaurants));
}
?>

What is happening here is the function ‘mymodule_display_restaurants’ is sending an array of restaurants to the template file ‘restaurant-list.tpl.php’. Here is an example of what that template file might look like:

<div id="restaurant-list">
<?php if (sizeof($restaurants)>0){ ?>
	<p>Here are the restaurants in your area</p>
	<ul>
	<?php foreach ($restaurants as $restaurant){ ?>
		<li><?php echo $restaurant->title; ?> - <?php echo $restaurant->address; ?></li>
	<?php } ?>
	</ul>
<?php }else{ ?>
	<p>It looks like there are no restaurants in your area.</p>
<?php } ?>
</div>

There is still PHP in our template file, but what is most important is that the HTML to display this list is separated from our plugin code. This means that a theme developer could create a custom template for our plugin to display this data differently (say in a table).

This system also allows you to build complex themed output, theming individual parts with separate template files and theming all the output in a template. Example, we might change our previous function to something like this to make it more flexible:

<?php
function mymodule_display_resturants(){
	//User submitted their zipcode via a form
	$zipcode = $_POST['zipcode'];
	//we retrieve a list of resturnats near the usrs zipcode
	$resturants = mymodule_get_resturants($zipcode);
	if (sizeof($resturants)>0){
		foreach ($resturants as &$resturant){
			$resturant = mymodule_theme('resturant',array('resturant'=>$resturant));
		}
	}
	//display resturants to user
	echo mymodule_theme('resturant-list',array('resturants'=>$resturants));
}
?>

The ‘restaurant.tpl.php’, might look something like this:

<div>
        <strong>Name:</strong><?php echo $resturant->title; ?><br />
	<strong>Address:</strong><?php echo $resturant->address; ?><br />
</div>

And our ‘restaurant-list.tpl.php’ will now look something like this:

<div id="restaurant-list">
<?php if (sizeof($restaurants)>0){ ?>
	<p>Here are the restaurants in your area</p>
	<?php
		foreach ($restaurants as $restaurant){
			echo $restaurant;
		}
	?>
<?php }else{ ?>
        <p>It looks like there are no restaurants in your area.</p>
<?php } ?>
</div>

So you can see, this gives themers much more control over the output of your plugins data without needing to alter your plugin.

 

I hope this post proves useful and your able to build upon and use this theming convention to make your plugin development much more flexible.

 

 

 

Mar

2

Drunken Stumble: a breakdown

By mike@mike-miles.com

So my last post, I mostly went through the process of how Drunken Stumble was built and competing in the boston hack day challenge.  So I thought I would follow up with  a more in depth post about Drunken Stumble itself.

Read more »

Dec

1

Semantics and Readability

By mike@mike-miles.com

When you write code there are two overlying important aspects to remember. First being that your code is semantically correct (else it wont work, duh) and readability. As in the ability for your code to be read and understood by other developers and yourself in the future (you WILL forget how your code works, trust me).

Read more »