SemanticScuttle 0.95

Some days ago, I released your own social bookmark manager SemanticScuttle in version 0.95 as I promised earlier. Yesterday, the first bugfix release, 0.95.1, was made public.

Build script

The release of 0.95 has been delayed by a week because I wanted to rely on a build script only, and do as few tasks by hand as possible. After coming into the project, I made a release-TODO list containing all the things that need to be done when releasing a new version:

  1. Run unit tests and verify that all of them pass
  2. Update doc/ChangeLog
  3. Update version in data/templates/about.tpl.php
  4. Create a zip file with all contents, and make sure the zip file root directory is SemanticScuttle-$version/
  5. Make a test installation from your zip file with a fresh database, register, add bookmarks etc.
  6. Tag the release in svn: (svn copy command)
  7. Upload release to sourceforge
  8. Write announcement mail to the SemanticScuttle mailing list
  9. Announce the new release in the sourceforge project news

At least some of the tasks should be automated: Running unit tests, creating the zip file, tagging the release and uploading the release zip to sourceforge. The other things are better done by humans if you don't want to send out changelogs only in release mails.

So I started hacking on a Phing build script. Phing is a build system like ant, but written in PHP. It might not be as robust as ant yet, but is easily extendable with PHP classes, and the correct choice for a PHP project - I would not want to install a whole Java JRE or SDK just to build my PHP tool.

Actually, I had to extend the Phing zip creation task to support file name prefixes and make life easier for me, but that was done in some twenty minutes. After the build script had been tested thoroughly, releasing version 0.95 of SemanticScuttle was a matter of minutes.

New features in 0.95

Not much has changed in SemanticScuttle 0.95 when seen from the outside - the only thing one will notice is the voting system.

Voting system

Every registered user can vote for or against a bookmark. This data are saved in the database, and can be used to hide bookmarks that have a total voting below the threshold set in the configuration file. It is also possible to sort bookmarks by the total voting.

There are two voting layouts. Both work with and without JavaScript, and your config.php determines which of both is used - and if you want to enable the voting system at all.

Layout #1:
Voting system layout #1

Layout #2:
Voting system layout #2

As a sidenote: I made sure that the performance does not suffer when using the voting system. No separate SQL query needs to be made on bookmarks lists. Overall performance of SemanticScuttle leaves really much to optimize, though - loading a page can lead to several dozen - if not a hundred - SQL queries to be sent to the database. This is definitely on the TODO list and will hopefully be resolved in a future version.

File system layout

Up to version 0.94.1, SemanticScuttle had a very traditional file system layout. All files, regardless of the type, were located in one folder. The root folder contained index.php, bookmarks.php, tags.php as well as css and image files. Below it, there were several folders containing libraries, helper scripts and so on. Files that did not need to be and absolutely should not be accessible from your web server

SemanticScuttle 0.94
|-- ajax
|-- api
|-- cache
|-- gsearch
|-- images
|-- includes
|   |-- db
|   |-- js
|   |-- php-gettext
|   |   |-- bin
|   |   `-- examples
|   `-- player
|-- locales
|   |-- de_DE
|   |-- dk_DK
|   ...
|-- services
|-- templates
`-- tests

Several security problems of other web applications had their root cause in such a file layout. It was time to change that!

Using PEAR, one can distribute whole web applications in a single package easily. Due to the nature of PEAR packages, files have different roles, and files with different roles are installed in different locations. PEAR supports php (library) files, documentation files, data files, script files and www (web) files.

While this separation is needed for PEAR packages only, it makes sense for non-PEAR packaged projects, too. Only necessary files are visible to the world in your web server's document root directory. Further, your php (library) files are accessible via include path, which makes development of additional tools easier.

Last but not least, the file layout makes it dead easy to pack the application up in a PEAR package - which means that a software upgrade will be as easy as typing pear upgrade SemanticScuttle.

So after restructurization, SemanticScuttle's files are organized as follows:

SemanticScuttle 0.95
|-- cache
|-- data
|   |-- locales
|   |   |-- de_AT
|   |   |-- de_DE
|   |   |-- dk_DK
|   |   ...
|   `-- templates
|-- doc
|   `-- developers
|-- scripts
|-- src
|   |-- SemanticScuttle
|   |   |-- Model
|   |   |-- Service
|   |   `-- db
|   `-- php-gettext
|       `-- examples
|-- tests
`-- www
    |-- ajax
    |-- api
    |-- gsearch
    |-- images
    |-- js
    `-- player

As you see, unlike previously, script and example files are outside www/ directory, unaccessible for all attackers.


Some days after the release of 0.95, a bug has been discovered. The menu2 tags did not work anymore because I forgot to fix a JavaScript include. Thanks to the build script, the fix and release together just took half an hour. Release early, release often!

Sequel to 0.94.1

In my last post I wrote about the security issues that I discovered and fixed in version 0.94 and earlier versions.

They have now been verified by Secunia, leading to my first security report on their site .

Written by Christian Weiske.

Comments? Please send an e-mail.