YQL is a pretty neat tool for web developers. Consider it an API for APIs. It really takes the pain out of mashing together several webservices by providing a unified interface to access these services. Go check it out, if you haven’t already.
When working with YQL to build RIAs you’d probably want to go with JavaScript using libraries such as YUI or jQuery. Recently, however, we had the urgent need to use YQL from CodeIgniter for collecting information from several webservices and cache them on our own servers. This is important to us, because in the app we’re currently building, we’ll need to compare different versions of information and query results. Therefore we decided to go server-side. Since we’re building on CodeIgniter anyway, we decided to write a little library. It’s nothing special, but still we wanted to share it with you. Hope you find it useful. If you have any improvement ideas or feature ideas, let us know!
<?php
_set_latest_query($query);
$url = "http://query.yahooapis.com/v1/public/yql?q=";
$url .= urlencode($query);
$url .= "&format=json&env=store://datatables.org/alltableswithkeys";
$response = $this->_query($url);
return $this->_decode_response($response);
}
private function _set_latest_query($value) {
$this->_latest_query = $value;
}
function get_latest_query() {
return $this->_latest_query;
}
private function _query($url) {
return file_get_contents($url);
}
private function _decode_response($response) {
$this->_dec_response = json_decode($response);
return $this->_dec_response->query->results;
}
}
If you haven’t seen Symphony CMS yet, be sure to check it out! It’s not a Content Management System in the traditional way. It is more like a Content Management Framework, that let’s you decide, how to shape your content, instead of forcing you into adapting their scheme. You can build anything you want, from small personal blog, to huge social network. Not even the sky is the limit.
Sounds great, you might say. The only thing, that is not perfect about Symphony is, that it’s not easy for beginners to wrap their head around Symphony’s concept. We felt the same, when building our first site using the Framework. But now, we’ve become seasoned “symphonists” and want to share some of our knowledge. So let’s jump right in.
To get started with Symphony, just download it, upload it to your server and let the installation magic happen. If you’re more into Git, they also have a git-reposority that you can clone.
When logging in for the first time, you might find yourself a little confused. Don’t worry, we’ll walk you through the basic concepts of the CMS in just a second. If you’re hovering the Blueprints rider, you’ll see a drop-down menu with different links. Let’s take a look at these three: Pages, Components, Sections.
Sections - That’s right, let’s start with seconds. I know it’s the last navigation entry, but let’s follow the way your data has to go rather than just the order of some programmer designing an interface. Sections are basically like the heart of your site. You can model whatever type of content you would like to have. If you plan to build a blog, you can add a section for posts, one for comments … Sections are basically just like the models of a MVP-development approach (Guess you’re somewhat familiar with webdevelopment, otherwise Symphony CMS isn’t that much a great idea for you). To add a section, simply click “Create New”. Now you can name your section, decide which navigation category it belongs to and add data fields. When we saw this for the first time, it somehow reminded us of SQL Interfaces like phpmyadmin.
Components - Sections being like the MVP-model, you can talk of components as controllers. This is where the raw data, delivered by the model (section) gets filtered, for whatever purpose you need it. If you need to display a list of all your posts, you would create a component and set it up to load all your posts from the posts-section. If you just need to display one post, you would set up another component, just fetching one post, specified by whatever parameter you want. This kind of reminded us of building MySQL-queries. If you’re familiar with that, using Symphony’s components will be easy.
Pages - Pages, this one is pretty self-explanatory. Pages are the views. On the page’s setting page you can decide which components shall deliver their content to this page. You can then use this delivered content in your templates. We’ll cover how to do that in next week’s episode.
If you would like more in-depth information on Symphony’s concept, make sure to read the official user guide. That’s it for now, stay tuned.
Useful links
Productivity is somehow like the holy grail to freelancers and creatives. Trying to solve a problem but not getting on sucks. It’s frustrating and sometimes even depressing. Here’s how we handle all the obstacles in the way to good productivity.
Destroy Distraction
Either way, if you have a strong will, just force yourself to not visiting youtube or whichever website distracts you. If you’re like us, you don’t have a will that strong. Simple problem, simple solution. Get an app like concentrate. This really boosted our productivity.
Get off your butt…
…from time to time. Define regular breaks and enjoy them. Get up, talk to colleagues or go for a walk.
Don’t take your work home
If you’re freelancing from home this should be: “Don’t take your work to your private life”. Work is work and life is life. Enjoy the time off work. It will help you boost new energy. For us cycling, playing guitar and reading good books works great.
Add some “distraction”
What the…? Didn’t you just tell me to eliminate all distractions? Yes, but here I’m talking about music. Plug in your iPod or crank up the radio. Just make sure it’s music you like. This will boost your productivity…
Don’t let it bother you!
Let’s face it, there will be days, when you just can’t get productive. You feel drained, tired and just can’t find the right motivation. Basically, that sucks. We hate this feeling, too! But here’s probably the most important item of this list: Don’t let such days or phases bother you! Guess what, that’s perfectly normal and just human! Don’t be frustrated or feel guilty about your lack of productivity. Being frustrated will just totally destroy your motivation. So just accept, that there are days, where you just don’t seem to get it right!
List incomplete? Total non-sense? Well I guess, there is no golden path to productivity. Just figure out, what works for you. If you think this list is incomplete, please share your ideas with us! We’d appreciate that!
Finally we got a fresh and nice domain for our kick-ass mixer. So say goodbye to mixer.91media.de and hello to 91mix.com
CodeIgniter sure is one kick-ass framework. The built-in cache functionality is great for scaling your app. Unfortunately you can’t manually expire your cache. Why would you want to do that? Let’s presume you have a pretty Read-heavy site delivering different articles to the public. Since every user, logged in or not, will see the same article this a good place to cache. But, if the author changes his article, you want to update the cache file as well. Otherwise the output will contain the old output until it automatically expires. In some cases this would be just fine, but let’s presume you’re building a news site and need your articles to be up to date immediately. This is where you’ll need to manually expire your cache. To do so, you’ll have to extend the CI_Output class. Create the file ‘system/application/libraries/MY_Output.php’
<?php class MY_Output extends CI_Output { function expire_cache($uri) { $this->_expire_cache($uri); } function _expire_cache($uri) { log_message('debug', 'Deleting cache for '.$uri); // Get the instance $CI =& get_instance(); // Load the cache directory from the config file $path = $CI->config->item('cache_path'); // If no value is specified, use the standard cache path $cache_path = ($path == '') ? BASEPATH.'cache/' : $path; // Generate the file name $file = $CI->config->item('base_url'). $CI->config->item('index_page').'/'. $uri; // md5 hash of the cache item $cache_path .= md5($file); // try to delete it if(@unlink($cache_path)) { log_message('debug', 'Deleted the cache for '.$uri); return; } else { log_message('error', 'Unable to delete the cache for '.$uri); return; } } }
CI’s built-in cache uses a hash of the page’s URI to name the cache file, so you’ll need to pass that URI to the expire function. Normally your URI will be ‘controller/method’.
To expire your cache you can now use the following code within your controllers:
$this->output->expire_cache('controller/method');
Do you know what sucks about most pieces of software? Developers tend to sit on them, like a bird on its eggs, thinking they have to protect their tiny bits of software against competitors. Screw them! The web is becoming a social place and so should software. This is why we decided to publish the Youtube DJ source code on github. We believe in the power of the social to make this app even greater! We’re looking forward to collaborate and discuss with you! So if you’re ready to make youtube dj-ing as easy as never before, take a look at the github repo and get coding!
This morning we finally released the browser-based version of our youtube-crossfader app. Check it out at mixer.91media.de and tell us what you think!
Despite the fact that today is April 1, this is not a joke. Today we opened the IllustrationBox beta. IllustrationBox helps you organizing your sermon illustrations, search for inspiration in other boxes and saving the good stuff to your bow. Sermon preparation has never been easier. If you’re not in the beta yet, be sure to join!

We all know the situation. You’re having a party and provide the music via youtube. Great! Only one thing sucks about youtube: You have these huge gap between two songs. Out of this problem, we came up with the solution! The YoutubeDJ App for Mac OS 10.5+ let’s you play songs from youtube in two different decks and provides a nifty cross-fader. It’s a pretty simple idea, but simple ideas maka all the difference, don’t they? We’ll soon be launching a browser-based version of the app. For now, go ahead and download the app for Mac OS 10.5+

Durch eine interessante Diskussion im CodeIgniter Forum, auf die ich durch Elliot Haughin’s Blog gestoßen bin (wo Elliot sich in Sachen Passwortdatensicherung zur gleichen Methode wie ich bekennt), habe ich mal wieder (dieses Thema lässt einen nie ganz los, wenn man täglich WebApps schreib darüber nachgedacht, wie man Passwörter am sinnvollsten mithilfe von PHP und MySQL speichert.
Ganz egal ob ihr eine große oder kleine App schreibt, die Passwörter in sicherer Form zu speichern ist immer sinnvoll. Gehen wir einmal davon aus, dass es einem Hacker tatsächlich gelungen sein sollte, an die Daten unserer Nutzertabelle zu gelangen. In der Regel sollte eure App natürlich gegen solch einen Angriff, wie z.B. SQL-Injektion vorbereitet sein, aber das ist ja hier nicht das Thema und außerdem hat doch jede App irgendwo eine Schwachstelle. Also gehen wir also von diesem worst-case einmal aus. Stellen wir uns also außerdem vor, ihr hättet die Passwörter einfach unverschlüsselt in der Datenbank hinterlegt. Ein Alptraum. Der Hacker bekommt also alle Login-relevanten Daten jedes Nutzers und kann damit Unfug treiben.
Natürlich speichert niemand die Passwörter in Klartext in der Datenbank ab. Zum Glück gibt es ja One-way Algorithmen, die euer Passwort in einen 16bit-String verschlüsseln. In PHP sind diese sogar von Haus aus eingebaut: md5() und sha1() lassen grüßen. Aber reicht eine einfache Verschlüsselung wirklich aus? Da es sich um One-way Verschlüsselungen handelt, dürfte man ja eigentlich meinen, dass md5 oder sha1 ausreichen sollten. Aber auch diese Methode der Passwortaufberahung hat eine drastische Schwachstelle: Directory-Attacks. Eine Directory-Attack lässt sich mit dem folgenden Code-Schnippsel am einfachsten erklären:
function find_password($password) {
// Ein Array bestehend aus unzähligen möglichen Passwörten
$directory = array();
foreach($directory as $item) {
if(md5($item) == $password) {
echo "Das Passwort lautet: ".$item;
break;
}
}
}
Diese Funktion lädt also ein Directory-Array, loopt dieses mithilfe von foreach und vergleicht den md5-Hash jedes Items mit dem zu knackenden Passwort. Wird eine Übereinstimmung gefunden, wird das Passwort ausgegeben und die Schleife abgebrochen. So einfach ist es also ein einfaches in md5 oder sha1 verschlüsseltest Passwort zu knacken. Was aber tun, um die Passwörter wirklich sicher zu speichern?
Die Antwort klingt erstmal lustig: “Salted sha1-hash”. Was hat das ganze denn mit Salz zu tun?
Beim “salten” von Passwörten geht es darum, dem zu verschlüsselnden String erst noch eine 32-Bit lange Zeichenfolge anzuhängen. Man salzt das Passwort also. Auch hier erklärt das Beispiel viel besser als jede Beschreibung:
var $encryption_key = 'APANtByIGI1BpVXZTJgcsAG8GZl8pdwwa84';
private function _prep_password($password) {
return sha1($password.$this->encryption_key);
}
Die Funktion _prep_password() heftet dem Passwort also noch einen vorher festgelegten String an und verschlüsselt den neu entstandenen String nach dem sha1 Algorithmus. Diesen Hash kann man nun in die Datenbank speichern. Natürlich muss man darauf auchten, alle Funktionen, die die Datenbank nach dem Passwort abfragen, das Passwort erst mit dieser Funktion vorbereiten:
// Hier noch ein Beispiel, wie man dies nun nutzen kann
// Beispiel Query aus einer Login Funktion
$query = 'SELECT * FROM user_table WHERE username = "$username" AND password = "$this->_prep_password($password)" LIMIT 1';
Diese Methode ist sicher gegen Directory-Attacks, da der Hacker die Variable encryption_key kennen müsste, um diese mit in seine Directory Funktion einzubauen. Ob dies nun letztendlich das Nonplusultra der Passwortsicherung ist, dafür möchte ich meine Hand nicht ins Feuer legen, da sich tagtäglich sowohl Hacker bemühen, Sicherheitslücken zu finden, als auch Entwickler, diese wieder zu schließen. In meinen Projekten hat diese Methode bis jetzt immer sehr gut funktioniert, so viel kann ich mich Sicherheit sagen. Sollte es neuere, sichere, bessere Methoden geben, würde ich mich über einen Kommentar freuen!