New Plogger version
So, now I have worked some more on my Blogging engine Plogger (and I have just realized that there’s a web photo gallery named Plogger, so I will try to come up with a new name). I’ve added a few new features:
- RSS feed generation
Now we can subscribe to a latest entries feed as well as to a latest comments feed. The feeds are made in that way that I first generate an arbitrary XML tree that only contain the items and some meta information. I then pass this XML tree through and XSL template that generates the actual RSS feed. In this way it’s really simple to generate what version of RSS you want, and there would be no problems generating RDFs or what not. - Individual templating
Now we can also assign different XSL-templates to individual entries. These temlplates must reside in thedynamic-templatesdirectory. If there are templates in here they will occur in a drop down list in the “entry form”. - Enable/disable commenting
If we don’t want a given entry to be commentable we just check a checkbox in the “entry form” and that’s that.
I set the version to 0.2 for this release.
The desktop client
I also added the desktop client to the SVN repository, and added the above functionality – individual templating and enableing/disableing of comments – to the client, wich means the SOAP class and the WSDL file got their share of more code.
Entry form with template selection and comment enableing/disableing

What’s next?
Next step is adding some preview functionality, which wouldn’t be too difficult!
I’ve been thinking of adding support for TrackBacking and I will implement support for OpenID.
It seems like I have good fun ahead of me!
Handy functions
How many times don’t you write code like this: $var = isset($_GET['var']) ? $_GET['var'] : 'default';? I read an article in Linux Format (the paper issue) about the up and comming PHP6 (well, it will probably take some time until it gets stable but you can already download it) and some of its new functions and stuff and learned that there will be a function called $var = isset($_GET['var']) ? $_GET['var'] : 'default';. This function will work like this:
$var = isset($_GET['var']) ? $_GET['var'] : 'default';. Pretty much nicer than the old way!
So I though: How hard can it be to implement the same kind of functionality in a user defined function. Well, it’s not hard att all, and here’s how simple it is:
- /**
- * issetor
- *
- * @param mixed &$what Assoc array key
- * @param mixed $else Default value
- * @return mixed
- */
- function issetor(&$what, $else)
- {
- return isset($what) ? $what : $else;
- }
- #=================================================
- $arr = array('key1' => 'value1', 'key2' => 1);
- $var1 = issetor($arr['key1'], 'some value');
- echo $var1; # will echo: value1
- $var2 = issetor($arr['key5'], 'default for key 5');
- # will echo: default for key 5
- echo $var2;
The only thing noticable here is that the first argument needs to be passed by reference or PHP will throw a warning (depending on the error/warning level set).
Of cource you can escape this issue all together just by choking PHP errors/warnings – $var = isset($_GET['var']) ? $_GET['var'] : 'default'; – but that’s just pure ugly in my opinion.
Just by modifying the function above slightly we also get a nice way for writing:
$var = isset($_GET['var']) ? $_GET['var'] : 'default';
- /**
- * isemptyor
- *
- * @param mixed &$what Assoc array key
- * @param mixed $else
- * @return mixed
- */
- function isemptyor(&$what, $else)
- {
- return empty($what) ? $else : $what;
- }
- #=================================================
- $var1 = "Hello";
- $var2 = "";
- $myvar = isemptyor($var1, 'Default');
- echo $myvar; # will echo: Hello
- $myvar = isemptyor($var2, 'Default');
- # will echo: Default
- echo $myvar;
And that’s it. I use them all the time!
Database abstraction layer
I can’t remember the last time I made a web site that wasn’t hooked up to a database in one way or another! There’s nothing wrong with using the database functions that PHP provide directly but if you work with different types of databases – MySQL, Postgres, Oracle, SQL Server, SQLite and so on – you need to remeber how the functions for these databases work, in what order to pass arguments and what not. And maybe you write an application that teoretically could use an abritrary database and not MySQL that you developed the application for, and then it would be nice to use the same function calls no matter what database is being used.
This is where the database abstraction layer comes in handy. There already exist many of them so, again and as always, why bother writing another one? Well, it’s fun and you always learn new stuff and, for good and bad, third party APIs tend to be packed with features that you never use so it get quite tedious learning the API.
So I wrote my own database abstraction layer that only contain the functionality I mostly use. If I need more functionaly it’s easy to implement. When I wrote the abstraction layer I tried to evolve my OOP (object orientated programming) skills (which isn’t too great) so that in it self was I goal.
The abstraction layer contains of two interfaces and two master classes: A connection interface and class and a result interface and class. To create a driver for a new type of database you inherit the master classes and implement the interfaces. This is how the skelleton looks like:
- interface IDB
The connection interface - interface IDBResult
The query result interface - abstract class DB
The connection master class - abstract class DBResult
The query result master class
So a database driver should have two classes: One that extends the DB class and implements the IDB interface and one class that extends the DBResult class and implements the IDBResult interface.
Example
Here’s a simple example of usage:
- <?php
- require_once 'Database.php';
- //! MySQL example
- try {
- $category = $_GET['category'];
- $db = DB::Create('MySQL', 'localhost', 'uname', 'pw0rd', 'mydatabase');
- $db->Connect();
- $res = $db->Query("SELECT * FROM table WHERE cat_id = '%d'", $category);
- if ($res->NumRows() > 0) {
- while ($row = $res->Fetch()) {
- echo "Title: " . $row->title . "<br/>";
- }
- }
- }
- //! Could be DBDriverNotFound, DBConnectionFail, DBNotFound, DBQueryFail
- catch (Exception $e) {
- die("Error: " . $e->getMessage();
- }
- //! SQLite example
- try {
- $category = $_GET['category'];
- $db = DB::Create('SQLite', 'mysqlitedb');
- $db->Connect();
- $res = $db->Query("SELECT * FROM table WHERE cat_id = '%d'", $category);
- if ($res->NumRows() > 0) {
- while ($row = $res->Fetch()) {
- echo "Title: " . $row->title . "<br/>";
- }
- }
- }
- //! Could be DBDriverNotFound, DBConnectionFail, DBNotFound, DBQueryFail
- catch (Exception $e) {
- die("Error: " . $e->getMessage();
- }
- ?>
As you can see here we’re using exactly the same code, except for the instantiation of the database object, wether we’re using MySQL or SQLite, and that’s the meaning of the database abstraction layer.
Sources
I currently have two implementations for MySQL and SQLite. The MySQL implementation is what I’m using for this blog and the SQLite implementation is not very well tested yet.
The classes are pretty well documented and the documentation is bundled in the package below.
Database abstraction layer 17:31, Sat 17 October 2009 :: 42.1 kB
Get mimetype for a file
Sometimes you need/want to find out what mimetype a particular file has. If you have access to the PEAR “Fileinfo Functions” you can use them, but if you don’t here’s a simple solution that might be helpful.
NOTE! This is not as reliable as the Fileinfo Functions but it works in most cases.
In most GNU/Linux systems (if not all) there’s a file called mime.types (in /etc/) which is mapping of mimetype -> extension. The file looks like this:
- application/x-gnumeric gnumeric
- application/x-go-sgf sgf
- application/x-graphing-calculator gcf
- application/x-gtar gtar tgz taz
- application/x-hdf hdf
- application/x-httpd-php phtml pht php
Quite obvious you could build an array from this file where the mimetype could be the key and the extension(s) the value as an array:
- $_MIMETYPES = array(
- "mime/type" => array("ext1", "ext2", "ext3")
- );
When we’ve got this array populated we can easily look up a mimetype for an extention (and vice versa) by these two functions:
- /**
- * Find mimetype for extension
- * @global array $_MIMETYPES
- * @param string $ext
- * @return string|bool
- */
- function find_mimetype($ext)
- {
- global $_MIMETYPES;
- foreach ($_MIMETYPES as $mime => $exts)
- if (in_array($ext, $exts))
- return $mime;
- return false;
- }
- /**
- * Get extension(s) for a given mimetype
- * @global array $_MIMETYPES
- * @param string $mimetype
- * @return array
- */
- function findextensionfor_mimetype($mimetype)
- {
- global $_MIMETYPES;
- return isset($MIMETYPES[$mimetype]) ? $MIMETYPES[$mimetype] : array();
- }
The script to convert the mime.types database into an array an auto generate the two functions above looks like this (note that this PHP script is intended to run as a command line (cli) script, thus the shebang (#!/usr/bin/php), since we don’t need to do this conversion run time but only once):
- #!/usr/bin/php
- <?php
- /**
- * mimetyper.php
- * Turn the /etc/mime.types database into a PHP array
- * @author Pontus Ostlund <spam@poppa.se>
- */
- //! Mimetype file
- $mime_db = '/etc/mime.types';
- //! Resulting file for the PHP array
- $php_file = 'mimetypes.php';
- fileexists($mimedb) or die("No mimetype database ($mime_db) found\\n");
- $lines = @file($mimedb) or die("Couldn't read $mimedb");
- $fh = @fopen($phpfile, "w+") or die("Couldn't create $phpfile");
- $date = strftime("%A %B %d %Y", time());
- //! Write the PHP header to the file.
- @fwrite($fh,
- "<?php
- /
- * Find mimetype for file extension
- * Generated $date by " . basename(<strong>FILE</strong>) . "
- */
- $_MIMETYPES = array(n"
- );
- //! Loop through the lines array
- while ($line = array_shift($lines))
- {
- //! Match a comment or a blank line
- if ($line{0} == "#" || $line{0} == "\\n")
- continue;
- //! A line looks like:
- //! mime.type extention[ extension[ extension]]
- //! so lets grab the mimetype and extensions
- preg_match('/^(.?)\\s+(.?)$/', trim($line), $match);
- list(, $mime, $ext) = $match;
- if (empty($mime)) continue;
- //! This converts "ext ext ext" to "ext','ext','ext"
- $ext = join("', '", explode(' ', $ext));
- //! And lets write the new array index to the file
- fwrite($fh, sprintf(
- "\\t'%s' => array('%s')%s\\n",
- $mime, $ext, (empty($lines) ? "" : ","))
- );
- }
- //! Close the array, add a nifty search function, and close the PHP block
- //! and we're done!
- fwrite($fh, ");
- /**
- * Find mimetype for extension
- * @global array $_MIMETYPES
- * @param string $ext
- * @return string|bool
- */
- function find_mimetype($ext)
- {
- global $_MIMETYPES;
- foreach ($_MIMETYPES as $mime => $exts)
- if (in_array($ext, $exts))
- return $mime;
- return false;
- }
- /**
- * Get extension(s) for a given mimetype
- * @global array $_MIMETYPES
- * @param string $mimetype
- * @return array
- */
- function findextensionfor_mimetype($mimetype)
- {
- global $_MIMETYPES;
- return isset($MIMETYPES[$mimetype]) ? $MIMETYPES[$mimetype] : array();
- }
- ?>");
- fclose($fh);
- ?>
And this should result in a file called mimetypes.php that you just can include in you PHP scripts.
New site, new blog
Plogger, the badly named blogging system
So, I’ve been working on this blogging system for a while and now it’s completed enough to run. One can wonder why one would write a blogging system when there already exist a zillion of them? Well I guess it’s the callenge that make it worth the effort, or that it’s just great fun programming! And there’s always new things to learn, or new methods for how to do things and so on.
Anyhow, the system is still a bit rough around the edges so I wont share it just yet, but as soon as I’m satisfied I will release it under the GPL license.
Here’s a little summary of the project:
- -----------------------------------------------
- Plogger PROJECT SUMMARY
- -----------------------------------------------
- ent: 3 st
- xml: 1 st
- jpg: 3 st
- stx: 25 st
- swp: 1 st
- cache: 1 st
- text: 1 st
- php: 51 st
- css: 10 st
- ini: 1 st
- gif: 3 st
- txt: 3 st
- xsl: 20 st
- pdf: 1 st
- gz: 1 st
- wsdl: 1 st
- odt: 1 st
- dtd: 2 st
- js: 8 st
- png: 206 st
- unknown: 10 st
- -----------------------------------------------
- Number of files: 353 st
- Directories: 39 st
- Lines of code: 19030 st
- -----------------------------------------------
SOAP enabled
During the last months I have begun looking into C# so I thought a good project to start off with was to write a desktopk client for my blogging system. I also wanted to explore the SOAP protocol a little bit more, I’m up to some SOAP stuff at work soon, so I developed a SOAP API for the blogging system that I could use for the client.
So far the client is starting to work pretty well and you can create new blog post, edit blog post, delete blog posts and handle comments. Since I mostly use GNU/Linux at home the client runs on the Mono platform and uses GTK# for the GUI. My goal is also to port the client to Windows and Mac when I’m satisfied with the GNU/Linux version.
Here’s some screen dumps of the client (click on the images for larger versions):
Don’t be hassled by the mix of Swedish and English in the interface. GTK Stock buttons get their text from the surrounding environment and thus gets translated automatically.
The client is pretty stable but there’s some exception handling – and function implemetation – left to do, but that will come with time and along with using the client.
Templating
Since I really love XSL that’s what I’m using for the templating system for the blog system. I will give you a short example of why I love XSL. All external links on this site has a little icon appended to the link text. That little feature is handled by this code:
- <xsl:template match="a[contains(@href, 'http://')]">
- <a>
- <xsl:copy-of select="@*" />
- <xsl:copy-of select="node()"/>
- <img src="{$tmpl.path}/img/a-external.png" width="12" height="9"
- alt="External URL"
- />
- </a>
- </xsl:template>
This template matches all <a> tags where the arrtibute href contains http:// and append the <img> tag after the link text. Now isn’t that lovely so say!
That’s that for now. When I’ve cleaned up the code a little bit I will release it for those curious.






