Skip to content

VulnerabilitiesBundle for Symfony2

Only two days after I pushed the first version of my VersionEyeBundle for Symfony2 to GitHub, Fabien Potencier announced SensioLab's new Security Advisories Checker. This service work quite similar to VersionEye, but instead of uploading your composer.json file your composer.lock file is required to figure out which dependencies are really installed - and if there are any known security issues.

VulnerabilitiesBundle for Symfony2 in Web Debug Toolbar
This is what it looks like in the toolbar

SensioLabs have an upload form in the browser, but conveniently offer an API, too. And, of course, the code of their security-checker is on GitHub. So what could be more natural than to add the results of the security check to the Web Profiler Toolbar right next to all the other useful information? Right. I wrote a second bundle, called VulnerabilitiesBundle, that displays security advisories in the toolbar and the profiler view.

VulnerabilitiesBundle for Symfony2 in Profiler
And this is the Profiler page.

Please keep in mind that this is an early development version that is only intended for use in DEV environments (even if it will be stable someday). It just doesn't make sense on production servers. Feel free to fork, test, and report any issues you encounter. Of course, contributions in the form of pull requests, are more than welcome :-)

VersionEyeBundle for Symfony2

At last week's Webmontag Frankfurt (?), Robert Reiz talked about continuous updating of dependencies with VersionEye. VersionEye, in its own words, is a

cross-platform search engine and crowdsourcing app for open source software libraries.

Essentially, the service tracks more than 170.000 libraries in languages like Java, Ruby, PHP, Python, and many more, and monitors any updates to those libs. Registered users can keep track of their projects and the libraries used in these projects. If any updates occur upstream, VersionEye sends out a mail. As a developer, you don't have to manually check on all the GitHub repositories anymore, VersionEye does that for you.

VersionEye also allows you to create beautiful graphs like this one here on the right. It also lists all the licenses of all the libraries used in your project, an let's you see which libraries you use most often.

Using it with PHP

Adding a PHP project to the service couldn't be simpler (if you use Composer, which you should!): Just upload your composer.json to VersionEye, and you're all set up. The same goes for project files like package.json (node.js), requirement.txt (Python Package Index), pom.xml (Maven) or Ruby Gemfiles. You can also connect VersionEye to your GitHub account, and it will notify you of outdated dependencies in your repositories.

Robert also said that there already is a VersionEye module for ZF2 and the ZendDeveloperTools that calls the VersionEye JSON API to track dependencies. However, I could not find a Symfony2 bundle with this functionality. So I wrote one.

"VersionEyeBundle for Symfony2" vollständig lesen

Zeit Online Content API und xkcd - Mein Hack vom Wochenende

Vor elf Tagen hat die Zeit Online mit einem kleinen Hackday ihr Content-API gelauncht. Die Zeit Online ist damit wohl die erste deutsche (Wochen-)Zeitung, die eine solche Programmierschnittstelle anbietet. International bieten z. B. der britische Guardian, die New York Times und USA Today einen ähnlichen Zugang zu ihren Inhalten an. Eine ausführliche Liste findet sich hier.

Da ich a) leider nicht beim Hackday in Berlin dabei sein konnnte und b) keine Idee für einen "Hack" hatte, hatte ich zunächst nur etwas mit dem API Explorer herumexperimentiert. Mein erster Eindruck war durchaus positiv, und bereits in den ersten Tagen wurden die ersten Apps geschrieben, die auf die Inhalte der Zeit zugreifen. Gelungene Beispiele sind etwa diese Visualisierung von Zeit-Artikeln auf einer Weltkarte oder diese Autorensuche in Sozialen Netzwerken.

xkcd-Comic
Der Original-Comic, cc by-nc Randall Munroe

Kurze Zeit später spülte mein Feedreader dann diesen Comicstrip herein, gezeichnet von Randall Munroe für seinen populären und genialen Webcomic xkcd. Im "Calendar of Meaningful Dates" zeigt die Größe eines Datums an, wie häufig es in englischsprachigen Büchern seit dem Jahr 2000 genannt wurde. Als Quelle gibt Munroe den Google Books Ngram Viewer an, mit dessen Hilfe sich übrigens auch Abfragen über deutschsprachige Bücher durchführen lassen.

Mir war sofort klar, dass sich ein solcher Kalender mit dem Zeit API nachbauen lassen müsste - und das sogar mit "Live-Daten". Also habe ich mich in den letzten Tagen zwischendurch daran gemacht, diese Idee umzusetzen. Die Anwendung, die auf Symfony2 basiert, fragt im Hintergrund (per Cronjob) bei der Zeit nach Artikeln, die ein Datum - z. B. "23. Mai" - enthalten, und speichert die Anzahl der Treffer. Anhand dieser wird nun die Kalenderdarstellung berechnet. Natürlich werden die Resultate gecachet, um die Server der Zeit zu schonen ;-) Und so sieht das Ergebnis aus, das unter http://calendarofmeaningfuldates.sperrobjekt.de/ zu finden ist:

Screenshot

Das ist natürlich nicht ganz so hübsch wie der handgezeichnete xkcd-Comic, dafür aber aktueller. Fährt man mit der Maus über ein Datum, wird rot die zugehörige Anzahl der Treffer angezeigt. Ein Klick leitet auf die Suchergebnisse bei Zeit Online weiter. Warum dort dann jeweils etwas mehr Treffer erzielt werden, kann ich nicht nachvollziehen; das Verhältnis der Daten untereinander scheint aber zu stimmen. Weil die Anwendung eben ein schneller "Hack" ist, sind solche Kleinigkeiten IMHO zu verschmerzen.

Die Ergebnisse sind übrigens auch ganz interessant: Am häufigsten genannt wird der 1. Januar, wie überhaupt der erste und letzte Tag jedes Monats häufiger auftaucht als die übrigen Tage. Drei Daten stellen eine Ausnahme dar: Der 17. Juni, der 20. Juli sowie der 11. September. Letzterer tritt auch im Original groß hervor. Der 17. Juni war bis zur Wende der Tag der Deutschen Einheit, und das Archiv der Zeit reicht ja zurück bis 1946. Aber was ist mit dem 20. Juli? Hat jemand für dieses Datum eine Erklärung? Mir ist bisher noch keine überragende Begebenheit für diesen Tag eingefallen.

Hier geht's direkt zum Calendar of Meaningful Dates - German ZEIT Edition.

Symfony2 Tipps und Tricks (2)

Alle Beiträge dieser Serie sind unter dem Tag sf2tt zu finden.

Weiter geht's also mit meiner kleinen Reihe "Symfony2 Tipps und Tricks". Heutiges Thema sind Formulare und Subformulare, auch bekannt als Embedded Forms, und insbesondere deren Validierung. Lest vorher am besten auch das Cookbook-Kapitel "How to Embed a Collection of Forms"(http://symfony.com/doc/current/cookbook/form/form_collections.html), um eine noch bessere Vorstellung von den ineinander geschachtelten Formularen zu bekommen.

Die Problemstellung

Häufig dienen Formulare der Bearbeitung von Daten, die aus der Datenbank kommen. Das geht auch sehr einfach, indem man eine Entity in ein entsprechendes Formular hineingibt. Allerdings muss die Entity ja nicht zwingend über ORM einer DB-Tabelle entsprechen. Entities können auch einfache Objekt sein, die Daten enhalten. Das kann schon mal sinnvoll sein, wenn man Werte aus vielen DB-Feldern zusammenziehen und anzeigen möchte.

Wie im Handbuch beispielhaft gezeigt, wird der Formtyp CategoryType ins Formular TaskType "eingebettet". Entsprechend ist Category ein Attribut von Task. Was aber, wenn statt Category ein Array von Kategorien möglich ist? Dann reicht der vorgeschlagene Constraint @Assert\Type(type="Acme\TaskBundle\Entity\Category") nicht aus bzw. die Validierung schlägt fehl, weil ja ein Array von Category-Objekten erwartet wird.

Die Lösung

Hier kommt der Valid Constraint ins Spiel. Denn sollen alle Entities Category im Array zusammen mit Task über das Formular TaskType (und das Subformular CategoryType) validiert werden, muss gewährleistet sein, dass die Validierung auch für diese greift. Das geschieht leider nicht automatisch, sondern erst, wenn das explizit verlangt wird.

namespace Sperrobjekt\Sf2ttBundle\Entity;

use Doctrine\ORM\Mapping as ORM,
    Sperrobjekt\Sf2ttBundle\Entity\Category;

/**
 * @ORM\Table(name="task")
 * @ORM\Entity
 */

class Task
{
    /**
     * Array mit Kategorien vom Typ Category
     *
     * @var Category[]
     *
     * @Assert\Valid()
     */

    protected $categories;
    /* ... */
}

Damit wird auch das Unterformular bzw. die entsprechende Entity ganz normal validiert. Idealerweise werden Validierungsfehler noch mittels error_bubbling an das "obere" Formular durchgereicht.

Ich hoffe, das war verständlich beschrieben, und meine Lösung ist auch korrekt. Jedenfalls funktioniert es für mich damit. Ich bin aber immer für Verbesserungsvorschläge in den Kommentaren offen; schließlich gibt es auch bei Symfony2 meistens nicht nur einen Weg zum Ziel ;-)

Symfony2 Tipps und Tricks (1)

Ende letzten Jahres habe ich mein erstes Projekt mit dem (immer noch) relativ jungen PHP-Framework Symfony2 begonnen und war schnell davon begeistert. Symfony2 bringt einige für die PHP-Welt sehr moderne Eigenschaften mit, etwa das Arbeiten mit Annotations, Dependency Injection, Scaffolding, Datenvalidierung über Constraints und ein eigenes Caching-System (vieles davon ähnelt nebenbei bemerkt Django). Weil Symfony2 heute schon produktiv einsetzbar ist, ist es den anderen beiden großen PHP-Frameworks, Zend2 und FLOW3, um eine Nasenlänge voraus.

Symfony2 Tipps und Tricks

Viele Features sind äußerst angenehm, und ich möchte sie nicht mehr missen. Anderes ist gewöhnungsbedürftig, und es dauerte jeweils seine Zeit, bis ich herausgefunden hatte, wie es zu realisieren ist - und mögen es auch nur Kleinigkeiten gewesen sein. Diese Aspekte möchte ich hier im Blog in einer kleinen Serie festhalten, die ich "Symfony2 Tipps und Tricks" (sf2tt) genannt habe; sei es, damit andere davon profitieren können, sei es, damit ich selbst meine Kniffe schnell wiederfinden kann. Wenn ich übrigens Symfony2 sage, meine ich manchmal auch Doctrine2 (das standardmäßige ORM-Layer), Twig (die standardmäßige Template-Engine) oder ähnliche enge verbandelte Komponenten.

Deshalb geht es jetzt auch los mit einem Tipp zu Doctrine2 ;-)

"Symfony2 Tipps und Tricks (1)" vollständig lesen
tweetbackcheck