Archive for the ‘web development’ Category
My Bookshelf & openbook
Yesterday I installed the openbook plugin for wordpress on this site. My intentions was to build a “My bookshelf” page similar to what Mats Lindh and Trond Huso have on their sites.
I installed the plugin without any problems but the layout was a bit nasty. I don’t know if that was because of the theme I am running on this site or if the openbook markup was messed up. Anyway I rewrote the html and css for the openbooks template on its configuration page and added some custom css to the site to get it working.
This is my openbook template:
-
<li>
-
<div class="medium">[OB_COVER_MEDIUM]</div>
-
<div class="description">
-
<div class="title">[OB_TITLE]</div>
-
<div class="meta-1">Written by: [OB_AUTHORS]</div>
-
<div class="publisher-year">[OB_PUBLISHER] [OB_PUBLISHYEAR]</div>
-
<div class="category">[OB_LINK_WORLDCAT][OB_DOT][OB_READONLINE][OB_DOT][OB_LINK_LIBRARYTHING][OB_DOT][OB_LINK_GOOGLEBOOKS][OB_DOT][OB_LINK_BOOKFINDER]</div>[OB_COINS]
-
</div>
-
<div class="clearboth"></div>
-
</li>
This is the css I added:
-
ul.books {
-
list-style-type: none;
-
}
-
-
ul.books li {
-
border-bottom: 1px solid #ccc;
-
margin-bottom: 15px;
-
padding-bottom: 15px;
-
}
-
-
ul.books li div.medium {
-
float:left;
-
margin-right: 10px;
-
}
-
-
ul.books li div.medium img {
-
width:120px;
-
}
-
-
ul.books li div.description {
-
float: left;
-
width: 450px;
-
}
-
-
ul.books li div.description div {
-
font-size: 11px;
-
padding-top: 5px;
-
}
-
-
ul.books li div.clearboth {
-
clear: both;
-
}
At last I added this custom html in the “my bookshelf” page:
-
<ul class="books">
-
[Open Library Server Error]
-
-
[Open Library Server Error]
-
-
[Open Library Server Error]
-
-
</ul>
You can see the result here: My Bookshelf .
Merging code bases
Yesterday I had the “pleasure” of merging two code bases of the same application. The code bases had been developed in two different parts of the world, but shared a common foundation. I got access to a development version of the code base a few weeks ago, and the final delivery of the application was done late last week. No version control system was shared between myself and the contractor which made the merge a bit more cumbersome. Unfortunately I could not wait for the contractor to finish the development before I started to add features and bug fixes to the application; this eventually resulted in two separate versions of the code base.
I was aware that this merge would going to happen from the very start so some precautions were taken before I started my own branch of the source code.
1. I separated all new features out in separate directories and added symbolic links to these in the existing code base. This worked very well and we had no problem at all adding the new features to the final delivery.
2. I tried to be very careful and keep track of all the bug fixes and changes done to the original code.
Trouble
I realized that we would have trouble with the final merge not long after I received the first development version, it was cluttered with bugs and issues which made it impossible to even run it in my development version. To get the application up and running I had to make a bunch of changes to the code.
In addition to the initial bugs I soon realized that the front end of the application (read: html and css) was a complete mess. The site was not browser compliant, nothing validated and it was impossible to go through. These issues would not be resolved by the contractor and since the project was on the clock it needed resolving as quickly as possible. This ended up in a complete rebuild of the front end which modified 300+ files.
1st Attempt – Failure
1. Created a git branch of my development code
2. Added the final code from the contractor to the branch
This ended up in a complete mess, nothing working, a complete mess.
2nd Attempt – Success
When the final delivery from the contractor came through the two code bases was in completely different states, most of the bug fixes I had was still needed.
1. Created a git branch of my code base
3. Found the differences from the initial development version we got and the final delivery
-
diff -qr dev final | grep -v -e 'DS_Store' -e 'Thumbs' | sort > changes.txt
Where dev is the directory of the untouched development version we got access to, and final is the directory of the final delivery. This resulted in a complete list (changes.txt) of files which differed between the two original versions. It also identified files that was obsolete in and new files that was added. An example of the content in the changes.txt can be seen below.
-
Files dev/view/file-1.php and final/view/file-1.php differ
-
Files dev/view/file-2.php and final/view/file-2.php differ
-
Only in dev/css: css-1.css
-
Only in dev/css: css-2.css
-
Only in dev/css: css-3.css
-
Only in final/css: css.css
-
Only in final/: file-a.php
4. Once I had this overview I added all the new files from the final version into my git branch.
5. Updated all the files I knew had not been changed. I had a list of all the core files which had been changed.
6. I manually had to go through all the core files that had been changed and compare them with the files from the final delivery.
7. Remove all old files which only were present in the development delivery.
8. Manual comparison of all the front end files, updating and merging these files by hand. Diff can not be used here since the entire front end has changed, and it would only result in a complete difference, still there might have been changes that I needed to incorporate with the new front end.
I still have approx 150 front end files to compare, it is time consuming and frustrating labor, but it seems to be the only way to do it. I keep testing the application while doing the update and so far all of the changes and updates has been successful.
The positive flip of this is that I get a good overview of the code and understanding of the application when I have to go through much of the code from the final delivery.
I might not have chosen the best solution and I would love to hear your approach if you have done similar things or have an opinion about it.
Javascript snippets
Lately I have been doing some javascript development and I have written a couple of functions which I find really useful. I almost find the code snippets to be used on all sites I work on so I thought I would share them with you. Both the snippets are written using the jQuery library.
Opening urls in a separate window/tab in a xhtml strict environment
The target attribute is not a valid attribute in xhtml strict and your site will fail to validate if you use it, so to get around this you can use replace your target attribute with the rel attribute. Adding the rel=”external” attribute on your anchors that points to an external source and adding some javascript solves the problem.
-
<a href="http://www.klunde.net" rel="external" title="Klunde.net">Kristian Lunde</a>
-
function externalLinks() {
-
$("a[rel='external']").each(function() {
-
$(this).attr('target', '_blank');
-
});
-
};
The code here is pretty self explaining, but to describe it briefly, the javascript function must be invoked once the DOM is loaded (see code further down on the page). The function loops through all anchors that have the rel=”external” attribute and add the attribute target=”_blank”. I guess this is a bit of a hack, but it works and it keeps the clients happy
Creating spam proof mailto: anchors
It is a well known fact that if you add your email address on a site in a plain mailto anchor you will be flooded by spam after a while. You can easily avoid this by adding a little bit of javascript on your site.
It works simply by printing out the email address as plain text replacing the @ with a ” AT ” and add the email addresses in a div or which ever element you prefer and add a set class to that tag. Then you run a small snippet of javascript that find all the elements with that class, I have chosen the class name “email”. The script replaces the content in all the elements with the email class with the proper html anchor. This can not be picked up by web crawlers and it displays the links properly for the user. All browsers without javascript support / enabled will of course only see the post AT somesite.com.
-
<div class="email">post AT somesite.com</div>
-
function createMailTo() {
-
var c_email_field = $('.email');
-
if($(c_email_field).length > 0) {
-
$(c_email_field).each(function()
-
{
-
var email = $(this).html().replace(' AT ', '@');
-
$(this).html('<a href="mailto:' + email + '" rel="nofollow" title="' + email + '">' + email + '</a>');
-
});
-
};
-
};
Running this script would transform the code into:
-
<a href="mailto:post@somesite.com" rel="nofollow" title="post@somesite.com">post@somesite.com</a>
Putting it all together
I have but together a simple example to illustrate the functions in action with all code and functionality. You should be able to copy this code save it as a .html file and run it in your browser.
-
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-
<html>
-
<head>
-
<title>Javascript snippets</title>
-
</head>
-
<body>
-
-
<a href="http://www.klunde.net" rel="external" title="Klunde.net">Kristian Lunde</a>
-
<div class="email">post AT somesite.com</div>
-
-
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
-
<script type="text/javascript">
-
-
function externalLinks() {
-
$("a[rel='external']").each(function() {
-
$(this).attr('target', '_blank');
-
});
-
};
-
-
function createMailTo() {
-
var c_email_field = $('.email');
-
if($(c_email_field).length > 0) {
-
$(c_email_field).each(function()
-
{
-
var email = $(this).html().replace(' AT ', '@');
-
$(this).html('<a href="mailto:' + email + '" rel="nofollow" title="' + email + '">' + email + '</a>');
-
});
-
};
-
};
-
-
$(function() {
-
externalLinks();
-
createMailTo();
-
});
-
</script>
-
</body>
-
</html>
Flowplayer, https and the streamnotfound “problem”
Lately I have been working on a project which used Amazon S3 to provide videos to Flowplayer on a website. This was working superbly until we added a link to a video using the https protocol. This broke the Flowplayer on Internet explorer 6 and 7 and Safari, and we got a:
-
streamNotFound, clip: 'https://someurl'
Solution: Amazon S3 supports both http and https, so replacing https with http solved the problem. This problem probably occurs because the web browser is unable to cache the data from the https url and therefore the Flowplayer is unable to play the video.
Interestingly enough Firefox had no problem at all running Flowplayer and https urls.
All frameworks sucks…. ?
I’ve been hearing this a lot lately, that most framework sucks, well do they?
Mr. Paul M. Jones has a really good article about the subject, he says that when a developer has to do a major change in his mindset and development routines to get used to a new framework, the developer often think that the “framework sucks”.
Personally I’ve been the kind of developer who like to write my own frameworks from scratch, and yes that also mean that I’ve written a couple of frameworks for myself, and threw them away. Since I like to write things from the scratch I’ve also been a bit critical to other frameworks,and I do understand term “all frameworks sucks”. When you’ve written your own framework, you know how it works, and it works just the way you want it to, at least that was the goal of writing it in the first place. It also gives you the possibility to change or add functionality in the core of the framework rather easily.
The advantages with a “off the shelf” framework can sometimes be intriguing, with a little bit of effort you can become darn efficent with this kind of framework, that will of course require a bit from the developer to learn the framework. Another bonus about learning a new framework is that you pick up on some of the bright ideas the developers have implemented in their framework.
I do not think that all frameworks sucks but, there are some frameworks out there that do not match my mindset at all, there is no secret that I’m not a huge fan of large enterprise frameworks with a wide extent of xml files and structures (I’m not naming any names, but the Java world have a few of these). Why on earth would you need to define a new page in three different xml files to get it working?
I’ve heard a lot about Code Ignitor and it sounds like a promising framework, I have not had the time to have a look at it yet. I am familiar with the Zend framework and EZ components which probably are more of a set of building bricks than frameworks, both of these are quite good and comfortable to work with.
Recently I’ve started to look at the Drupal. I realize that Drupal is more of a content management system than a framework, but it has its similarities to a framework. So far I still think Drupal “sucks”
but I do however like the simplicity of writing modules. What I do not like at all is the “lack” of OOP, and yes I know Drupal have its own way of implementing OOP, but I still feels thats is a little bit awkward, I am a bit of a OOP junkie ![]()
Anyway I see the potential of Drupal and look forward to getting to know it better. I believe I eventually will like Drupal because it is easy to extend, you get a lot of stuff for free because someone has already written it for you and it is a big community around it with a lot of smart developers. There is probably a reason why Drupal is one of the largest PHP framework out there.
Templating with Eclipse
Today I came over a a post on dzone.com about Eclipse and templating. It turns out that you can write small templates of code snippets you use a lot and bind them to a keyword. When typing the keyword, press “ctrl” and “space” and a list of possible templates available will appear, select the prefered template, press “enter” and the code snippet is inserted into your working code. I works just the same way code completion. This actually means that you do not have to write the boring “for” loops or “if” tests anymore, just write a template and become a more efficient developer.
The original post explains how to set up templates, so I will not go into that in this post, but since I am primarily a PHP developer and the post describes templating for Java, I’ll just give a description of where to go if you use the PHPEclipse.
To edit and create templates for PHP, HTML or css, even javascript you have to use this path:
window -> preferences -> PHPeclipse Web Development -> PHP -> Templates.
To write and edit the templates, just follow the guidelines from Mr. Graversen, or have a look at the links below.
For further reading have a look these sites.
- http://firstclassthoughts.co.uk/java/eclipse_tip_templates_public_static_final.html
- http://www.phpeclipse.de/tiki-index.php?page=Howto+use+the+templates+system
- http://help.eclipse.org/help21/index.jsp?topic=/org.eclipse.jdt.doc.user/concepts/ctemplates.htm
I guess if I had read the PHPEclipse manual when I first started using Eclipse, I would probably been using it from the start
Good luck with your Eclipse templates, I know I will be using them extensively.
The View Helper pattern
Developing MVC (Model View Controller pattern) applications in PHP or any other language often require a lot from the view tier. The view needs to process data received from the model tier and form it into presentable data, it also has to manage user input and form that into data understandable for the model tier.
This might not be a big issue while working with small application, but when it comes to midscale and large applications the view helper pattern can be of great help. The view helper pattern is one of the J2EE core patterns and the documentation can be found on:
http://java.sun.com/blueprints/corej2eepatterns/Patterns/ViewHelper.html
What does the helper pattern do?
First of all the helper pattern adds an extra tier to the system, this tier can be seen as a mid tier which has some understanding of the logic of the system, it knows a little bit about the view and a little bit about the model. Another cool thing is that the view helper pattern makes your code more reusable. When moving complex structures from the view and into a view helper it can with ease be used by other views.
Example:
You are writing a web application where the user writes a review of some product, the application should do auto saving of the user input every 20 second using Ajax functionality. The application should of course also save the user input then the user submits the data. The ajax request and the user submit does almost the same thing but the when the user submits the data the view should also store a rating of the product. This require the ajax request and the user submit to be two different views, or one complex view.
In an ordinary MVC system you would have to implement two views with very much of the similar behavior or one complex view. Using the view helper pattern you extract the storage of the user review in a helper which can be reused by both the ajax request view and the user submit view.
I have written a very simple implementation of the example in PHP. The implementation is not complete at all, but it is meant as a proof of concept that the reusability of code in your application can increase using the view helper pattern.
-
<?php
-
-
class ProductReviewHelper
-
{
-
public function __construct(){}
-
-
/**
-
* save the review
-
**/
-
public function save($user_input)
-
{
-
//validate input
-
$input = $this->validate($user_input);
-
-
//saves the review and return the result of the save
-
return $review_manager->save($input['product_id'], $input['review']);
-
}
-
-
/**
-
* validate the input
-
**/
-
public function validate($user_input)
-
{
-
$filter_args = array('product_id' => FILTER_VALIDATE_INT,
-
'review' => FILTER_SANITIZE_STRING);
-
$input = filter_var_array($user_input, $filter_args);
-
-
//do validation
-
return $input;
-
}
-
}
-
<?php
-
-
//Ajax view
-
$review_helper = new ProductReviewHelper();
-
$result = $review_helper->save($_POST);
-
echo $result;
-
exit();
-
?>
-
<?php
-
-
//User submit view
-
$review_helper = new ProductReviewHelper();
-
$review_result = $review_helper->save($_POST);
-
-
$rating_helper = new ProductRatingHelper();
-
$rating_result = $rating_helper->save($_POST);
-
-
//manage the result from the helpers
-
?>
I am sure that the view helper pattern has helped me to write better and more organized code, which is easily understandable and very reusable.
If you do not use the view helper pattern, and still have solved the problem with reusability of code in the view tier please feel free to leave me a comment describing your solution.
Unsecure password practices
Dansnetwork has a short an simple article explaining the simplest way of securing user passwords on the web. If you are new to authorization on the web, this article will give you a quick introduction to hashing methods and what not to do when dealing with authorization information.
URL: http://blog.dansnetwork.com/2008/07/15/unsafe-password-storage-practices/
Still this article is a bit to basic, since it does not discuss rainbow table attacks, which could with ease break most of the passwords. My previous article discuss how to avoid rainbow table attacks.
Password encryption using PHP
A recent post on dzone.com linked to a article about “password encryption using PHP” written by Stefan Ashwell on total.php.com. In this article he illustrate a how to save user passwords and authenticating users using the sha1 hashing algorithm.
First of all lets all agree that hashing passwords are basics requirements for a secure web application, but is a simple hashing of the password enough? I do not think so.
Here is the scenario, Someone breaks into your system (not through the web application, but for instance through an ssh connection), they get access to your user database or file where you store user account information. The intruder is now in possession of the password and user name of all your users, but still the passwords are hashed with md5, sha1 or an similar hashing method. If the intruder is determined to get into your system and mess up, he may now try to decrypt the passwords using a dictionary word file and brute force (also known as rainbow tables). This method is quite common and is not advanced at all, all it does is looping through the dictionary file, which contains all words and common password phrases, do a md5 or sha1 hashing of these words and see if it matches up to the hashed password, if it does it has found a match, and the intruder is able to log into the account.
Even though this brute force method might take some time, he will eventually get the passwords and get full access to the users account. There are however methods to complicate this and even make it impossible for the intruder to get the password using brute force method and that is called salting your password.
Example:
-
-
$salt = '2glkpe895';
-
$password = $_POST['password'];
-
-
$encrypted_password = sha1($salt . $password . $salt);
As you can see the salt is an secret string which is only used by your application, it is prepended and appended to the password. You could of course also go the extra mile and split the password in two and add the salt in the middle of the password, but there might not be any point in doing that.
This makes the word not like any word you will find in an dictionary and therefore the brute force method will not find the password.
The point is that if the intruder get a partial access to some of your system, for instance the user database, it will not be enough to get access to the total system because the security system is layered, one layer in your code, and one layer in your user database.
I do not say that this method is a 100 percent secure but it is is way more secure than not using a salted password.
Writing SOA applications with PHP
Lately I’ve been working a lot with data integration between several web applications, and a natural choice for the integration was to use a Service Oriented Architecture (SOA). I’ve built both SOA servers and clients before using the SOAP approach, which is a superb way of transferring data when not knowing who the user of the service is, or when you are a client of such a service. However in this setting I knew who the user was, I knew what the service would be used for, also had the chance to write both the client and server.
The choice fell on a simple implementation using the JSON (JavaScript Object Notation) data structure. This is really easy using the built in json library in php. The server use the json_encode() function and the implemented sub class of the client use the json_decode() function.
To simplify this further I implemented two abstract classes, a ServiceServer class and a ServiceClient class. The service server class contained a very simple displayJSONResult function, which sets the correct header, encode the data as json data and echo the data.
The service client class has two main functions, doGetRequest and doPostRequest, both functions use the cURL library in PHP.
Server
-
<?php
-
-
abstract class ServiceServer
-
{
-
-
public function __construct(){}
-
-
protected function displayJSONResult($data)
-
{
-
header('Content-type: text/plain');
-
-
echo json_encode($data);
-
-
exit();
-
}
-
}
Client
-
<?php
-
-
/**
-
* ServiceClient
-
*
-
*
-
* @author Kristian Lunde
-
*
-
*/
-
-
class ServiceClient
-
{
-
-
public function __construct(){}
-
-
/**
-
* do a post request to a service
-
*
-
* the params parameter must be a string with the format:
-
* key=val&key2=val2&key3=val3
-
*
-
* @param string $url
-
* @param string $params
-
*/
-
protected function doPostRequest($url, $params)
-
{
-
$ch = curl_init($url);
-
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER , false);
-
curl_setopt($ch, CURLOPT_RETURNTRANSFER , true);
-
curl_setopt($ch, CURLOPT_POST , 1);
-
curl_setopt($ch, CURLOPT_POSTFIELDS , $params);
-
$result = curl_exec($ch);
-
curl_close($ch);
-
return $result;
-
}
-
-
/**
-
* do a get request to a service
-
*
-
* @param string $url
-
*
-
* @return mixed
-
*/
-
protected function doGetRequest($url)
-
{
-
$ch = curl_init($url);
-
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER , false);
-
curl_setopt($ch, CURLOPT_RETURNTRANSFER , true);
-
$result = curl_exec($ch);
-
curl_close($ch);
-
return $result;
-
}
-
-
}
Example
To illustrate the easiness and simplicity of this SOA approach I written a small example. In this example the server finds the country of a city using POST parameters or it can find cities using the country as a GET parameter.
Example server
-
<?php
-
-
/**
-
* Example of using the ServiceServer class
-
*
-
* Returns countries or cities
-
*
-
* @author Kristian Lunde
-
*/
-
-
require_once('ServiceServer.php');
-
-
class ExampleServer extends ServiceServer
-
{
-
-
-
-
public function __construct()
-
{
-
$this->countries = array('norway' => array('Oslo',
-
'Trondheim',
-
'Bergen',
-
'Halden',
-
'Sarpsborg',
-
'Hammerfest'),
-
'sweden' => array('Stockholm',
-
'Gothenburg',
-
'Karlstad'),
-
'england' => array('London',
-
'Newcastle',
-
'Bath',
-
'Liverpool'));
-
-
-
if(isset($_GET['country']))
-
{
-
$this->findCitiesByCountry(trim($_GET['country']));
-
}
-
-
if(isset($_POST['city']))
-
{
-
$this->findCountryByCity(trim($_GET['city']));
-
}
-
}
-
-
public function findCitiesByCountry($country)
-
{
-
$cities = 'Not found';
-
$country = strtolower($country);
-
-
if(isset($this->countries[$country]))
-
{
-
$cities = $this->countries[$country];
-
}
-
-
$this->displayJSONResult($cities);
-
}
-
-
public function findCountryByCity($city)
-
{
-
$country = 'Not found';
-
-
$break = false;
-
foreach($this->countries as $key => $val)
-
{
-
for($i = 0, $count = count($val); $i < $count; $i++)
-
{
-
if($city == $val[$i])
-
{
-
$country = $key;
-
$break = true;
-
break;
-
}
-
}
-
-
if($break)
-
{
-
break;
-
}
-
}
-
-
$this->displayJSONResult($country);
-
}
-
}
-
-
$obj = new ExampleServer();
-
?>
Example client
-
<?php
-
/**
-
* Example of using the ServiceClient class
-
*
-
* does a request to the ExampleServer
-
*
-
* @author Kristian Lunde
-
*/
-
-
require_once('ServiceClient.php');
-
-
class ExampleClient extends ServiceClient
-
{
-
public function __construct()
-
{
-
$this->getCities('Norway');
-
$this->getCounty('Bath');
-
}
-
-
public function getCities($country)
-
{
-
$url = 'http://files.klunde.net/files.klunde.net/ExampleServer.php?country=' . $country;
-
echo $this->doGetRequest($url);
-
}
-
-
public function getCountry($city)
-
{
-
$url = 'http://files.klunde.net/files.klunde.net/ExampleServer.php';
-
$params = 'city=' . $city;
-
-
echo $this->doPostRequest($url, $params);
-
}
-
}
-
$obj = new ExampleClient();
-
?>
I’m quite satisfied with this implementation because it is so easy to maintain and even more important, implementing new services and clients for the services is straight forward and supports rapid development.