Vine-Videos im eigenen Blog einbetten

Vorerst gibt es noch keine offizielle Möglichkeit, sich aus den eigenen (oder fremden) Vine-Videos einen Code-Snippet für das eigene Blog zu erstellen. Technisch ist das aber durchaus möglich.

Um das zu vereinfachen, habe ich ein kleines Bookmarklet geschrieben. Um es benutzen zu können, zieht folgenden Link einfach in eure Lesezeichenliste:
Vine-Bookmarklet: https://twitter.com/th1nk/status/295994006347857920

Auf dieser Seite klickt ihr nun auf das Bookmarklet in der Lesezeichenleiste und schon öffnet sich ein kleines Fenster mit dem Code, den ihr für euer Blog benutzen könnt. Hier noch mal standesgemäß als Vine-Video :)

Native SQL-Anfragen in Doctrine / Symfony2

Ich bin jetzt schon seit längerem ein großer Fan von Symfony 2 und verwende Doctrine als ORM. Das klappt alles super, manchmal muss man sich aber in die Grenzgebiete wagen.

Im vorliegenden Fall ging es um Statistikwerte in einer Tabelle. Im wesentlichen besteht die Tabelle (neben einer ID) noch aus einem Timestamp und um einen Wert, der im aktuelle Fall immer zwischen 1 und 3 liegt und eine Bewertung darstellt. Die Tabelle selbst wird auch in einer Entität abgebildet folgende einfache Query sollte aber nun umgesetzt werden:

SELECT DATE(created_at), rating, COUNT(rating) 
FROM ratings 
GROUP BY DATE(created_at), rating 
ORDER BY DATE(created_at) ASC, rating ASC;

Damit wollte ich also eine Zeitreihe erhalten, die neben dem Datum noch enthält, wie häufig die entsprechende Bewertung an dem Tag vorkam.

Hierzu musste ich auf die NativeQuery von Doctrine zurückgreifen. Die Ergebnisse werden aber trotzdem von Doctrine verwaltet und verlangen ein ResultSetMapping, damit Doctrine weiß, wie die Ergebnisdaten umgesetzt werden sollen. Damit lässt sich zum Beispiel bewerkstelligen, dass Doctrine automatisch passende Objekte zurückgibt, die die Daten enthalten.

In meinem Fall wollte ich aber nur die nackten Zahlen haben, da ich die Werte zur späteren Visualisierung in JS eh noch einmal umschreiben muss. Den Code habe ich in einem EntityRepository gekapselt, wer einen ähnlichen Code in einem Service oder einer Controller-Action verwenden will, muss sich ggf. anderweitig den EntityManager besorgen. So sieht der Code aus:

$rsm = new \Doctrine\ORM\Query\ResultSetMapping();
$rsm->addEntityResult('CfMainBundle:Rating', 'r');
$rsm->addScalarResult('dateCreatedAt', 'date');
$rsm->addScalarResult('rating', 'rating');
$rsm->addScalarResult('countRating', 'count');
$data = $this->getEntityManager()
    ->createNativeQuery(
        'SELECT DATE(r.created_at) AS dateCreatedAt, r.rating, COUNT(r.rating) AS countRating
          FROM ratings r
          GROUP BY DATE(r.created_at), r.rating
          ORDER BY DATE(r.created_at) ASC, rating ASC',
         $rsm
    )
    ->getResult();

Das Ergebnisarray sieht so aus:

Array
(
    [0] => Array
        (
            [date] => 2013-01-05
            [rating] => 1
            [count] => 8
        )

    [1] => Array
        (
            [date] => 2013-01-05
            [rating] => 2
            [count] => 4
        )

    [2] => Array
        (
            [date] => 2013-01-05
            [rating] => 3
            [count] => 1
        )

    [3] => Array
        (
            [date] => 2013-01-07
            [rating] => 1
            [count] => 22
        )
...
)

Damit kann man nun prima weiterarbeiten. Zu beachten ist, dass in der Query die Originalnamen der Spalten aus der Datenbank genutzt werden müssen und nicht die Namen der gemappten Attribute aus der Entität. Dazu gibt es auch eine Abhilfe, die in der Doctrine-Dokumentation zur NativeQuery erklärt wird.

Framework vs. Bibliothek

Das Zend Framework soll nun also im Oktober 2006 in der Version 1.0 erscheinen.

Ich finde den Namen Framework jedoch ziemlich irreführend, da es sich eigentlich nur um eine Sammlung von Klassen handelt, die teilweise miteinander verzahnt sind.

Wer sich wirklich für ein PHP Framework interessiert, sollte sich mal CakePHP anschauen. Es ist auch kein Problem, einzelne Klassen aus dem Zend-Framework innerhalb von CakePHP zu verwenden.

CakePHP setzt das MVC-Paradigma um und gibt dem Entwickler gleich noch eine Struktur für sein Projekt an die Hand. Das diszipliniert und führt zu wirklich strukturiertem Code, den man auch noch Wochen und Monate später ruhigen Gewissens überarbeiten kann.

jQuery & Google Maps: ein Beispiel

Unter olbertz.de/jquery/googlemap.html habe ich mal ein kleines Beispiel für das Zusammenspiel von jQuery und Google Maps zusammen gestellt.

Die HTML-Datei selbst enthält kein Javascript, die Zuordnung von Aktionen (z.B. Mausklick) zu Java Script-Funktionen findet nur in olbertz.de/jquery/googlemap.js statt.

Dabei muss ich eine Einschränkung zugeben: ich habe es nicht geschafft, den onclick-Event für die Links auf die Locations, die ich in der Funktion processLocations() erzeuge, mittel jQuery zu setzen. Damit hatte ich mich dann aber auch nicht mehr so lange auseinander gesetzt.

Die locations.php gibt, in JSON kodiert, die Daten aus der Datenbank zurück an die Website und nimmt auch neue Locations entgegen. Das ganze wird mit den jQuery AJAX-Methoden $.get() und $.post() realisiert. Nach dem Aufruf erhält die Callback-Funktion den Inhalt der Rückgabe (hier die Locations in JSON kodiert). Da es sich um JSOn handelt, werden die Daten durch ein einfach eval() von JS der Seite bekannt gemacht.

Die Funktionalität des Beispieles ist sehr einfach: Bei Klick auf die Locations in der Liste rechts, wird die Karte in der aktuellen Zoomstufe auf diese Location zentriert. Über New kann eine neue Location angelegt werden. Dazu klickt man einfach an der gewünschten Stelle auf die Map (erst New klicken!) und gibt ihr anschließend einen Namen, bevor man sie mit Save in der Datenbank abspeichert. Es werden immer nur die letzten 10 Locations angezeigt.

Die Quelltexte des Beispiel sind auf der Demo-Seite verlinkt.

Ein klein wenig Statistik: Die Demo besteht aus insgesamt 145 Zeilen Code, die ich schreiben musste. Dabei entfallen 34 Zeilen auf HTML, 86 auf das Java Script und 25 auf PHP.

(Warum die Demo-Seite nicht im Safari läuft, kann ich im Moment leider nicht beantworten. So, jetzt läuft’s auch mit Safari. Man sollte immer daran denken, ein &lt/script&gt zu setzen, sonst ignoriert Safari die Zeile einfach.)