Kategorien
Wochenbericht

Wochenbericht 2017.43

  1. Airbnb lässt die Umsetzung von Designskizzen nun von einer KI machen. Stellt sich heraus: Das gab’s vor ca. einem halben Jahr in ähnlicher Form schon: This app uses artificial intelligence to turn design mockups into source code
  2. On the Effectiveness of Visible Watermarks zeigt auf, wie gut die Wasserzeichen von Diensten wie Fotolia, Adobe Stock Images und Co. in Zeiten von Machine Learning funktionieren – nämlich gar nicht.
  3. Ein neues Botnetz infiziert IoT-Geräte. Diesmal keine nicht geänderten Passwörter, sondern Patchlevel-Attacken. Hätte uns doch jemand vor ungepatchten IoT-Geräten gewarnt.
  4. Visual Studio Code hatte mit der letzten Version das Icon geändert, von Blau auf Orange. Hat mich auch erst verwundert, ist aber letztendlich auch ziemlich egal. Das sieht aber nicht jeder so. Es gab eine Beschwerdewelle von Usern und in der nächsten Version haben wir dann wieder ein blaues Icon.
  5. Critical CSS mit PHP und Twig. Das sieht ziemlich interessant aus, insbesondere, da ich aktuell mit GRAV arbeite, welches auf PHP und Twig basiert. Allerdings gilt das ganze natürlich auch für jedes andere Projekt was PHP und Symfony einsetzt.
  6. 100 Punkte Pagespeed? Kein Thema.

Was zum Lachen: Design Pattern: Bureaucracy

Kategorien
Webentwicklung Werkzeuge

“To fix this issue you can simply rename your file to api2.php”

Ich bin ja auch Nutzer von InfiniteWP. Das ist eigentlich ein sehr gutes Tool zum Verwalten von mehreren WordPress-Instanzen.

Nun hatte ich in einem Kundenprojekt eine API entwickelt, die zur Authentifizierung ein WordPress mit einer Nutzerdatenbank verwendet. Dazu habe ich von einem externen Projekt die wp-load.php inkludiert. Das funktionierte auch eine zeitlang auch sehr gut, bis die Agentur, die die Seite betreut, ein paar Änderungen vornahm. Sie installierten unter anderem InfiniteWP. In der datei “api.php” von InfiniteWP ist folgender Code:

if(basename($_SERVER['SCRIPT_FILENAME']) == "api.php"):
    exit;
endif;

Das Ziel dieses Codes ist relativ offensichtlich: Die Datei sollte nicht direkt geladen werden können. Blöd ist: Es wird nur auf den Dateinamen geprüft. Da meine externe Datei, auch api.php heisst, wird aber, sobald ich die wp-load.php include, das exit; ausgeführt.

Ich regte also an, vielleicht nicht nur den Filename zu überprüfen, sondern vielleicht auch den Pfad des aufgerufenen Scripts oder – wie unter WP auch nicht unüblich – auf eine gesetzte Konstante. Auf meine Anfrage beim Support bekam ich folgende Antwort:

Thanks for taking the time to reach out to us on your query. Your patience is greatly appreciated.

We are using api.php in our client plugin to use call back functions for our addons.
To fix this issue you can simply rename your file to api2.php

Are you experiencing any conflict issues with IWP client plugin and other plugins?
Please give us more information so that I can assist you accordingly.

Ich habe dann etwas möglicherweise etwas unhöflich reagiert und gefragt, wie sich das verhält, wenn der nächste dann das gleiche mit proxy.php und jemand anderes dann die index.php seines Plugins so schützt. Und dass ein HTTP Status 200 und eine weiße Seite in dem Fall auch nicht sinnvoll debugbar sind und dass mich das einige Tage Projektverzögerung gekostet hat und ziemlich beschissen ist. Zumal es in WordPress ja auch Beispiele gibt, wie es besser geht.

Erst darauf hin habe ich die Antwort bekommen, dass ein “scope of improvement on our end” vorhanden sei. Da geben sich dann Codequalität und Servicequalität dann echt nichts.

Ich habe mal ein Beispiel geschickt, wie man das sinnvoller lösen kann. Mal sehen, wann ein Update dafür kommt.

Kategorien
Changelog Releases Webentwicklung Werkzeuge

pimcore 4.4.x

Ich hatte ja schon vor einer Weile mal Artikel zum Thema pimcore veröffentlicht. Damals habe ich, ganz besonders unter “Was ist pimcore und wofür brauche ich das?” an einigen Stellen kein gutes Haar gelassen.

Die Erfahrungen, die ich mit den frühen Versionen von pimcore gesammelt habe, was das Thema Anpassung des Datenmodells bei einer Weiterentwicklung eines Projekts in verschiedenen Entwicklungsstufen angeht, habe ich damals stark kritisiert.

Innerhalb dieser 1,5 Jahre seit Erscheinen des Artikels hat sich einiges verändert, eigentlich ziemlich konstant zum Guten hin.

Unter diesen Umständen habe ich pimcore neu evaluiert und bin zu dem Entschluss gekommen, dass das ganze durchaus eine neue Chance verdient hat und sicher bei dem einen oder anderen Projekt in Zukunft zum Einsatz kommen wird.

Kategorien
Allgemein

Was ist pimcore und wofür brauche ich das?

pimcore_logo_2013_big

Ich habe mich, wie ich neulich schon geschrieben habe, in der letzten Zeit ein wenig mit pimcore auseinander gesetzt. Aber was genau ist pimcore und wofür kann man es benutzen?

The Good & the Bad

Laut Eigenaussage kann/ist pimcore folgendes:

Natürlich ist da viel Marketing dabei. Primär kann man mit pimcore recht einfach und flexibel, Seiten erstellen, deren Inhaltsbasis Modularer, vernetzter Content ist. Die Einstiegshürde ist die Nutzung des Zend-Frameworks, der Rest ist im Beispielcode recht gut dargestellt und ermöglicht es auch unerfahreren PHP-Entwicklern, sich kurzfristig in die Funktionalität hineinzudenken.

Zu glauben, pimcore wäre ein fertiges CMS (im WordPress’schen Sinne), ist leicht vermessen: es gibt keine fertigen Templates, sondern ein eigenes Design. Die Templatesprache ist PHP. WordPress hat Templates ohne Ende, mit Plugins und Themes kann man sich da leicht einen funktionalen Overkill einfahren, Funktionalität für den Besucher muss man mit pimcore selbst bauen. Drupal kommt dem Denkprinzip von pimcore da schon recht nahe, aber hier legt das Neulings-CMF aus Österreich eine deutlich striktere Trennung vor: Adminbereich und Besucher-Frontend werden hier von Anfang an sauber getrennt.

Dazu kommt, dass pimcore die Schnittstellenorgel rauf und runter spielt. Die Daten der Objekte lassen sich unter anderem per XML und JSON-Schnittstellen abrufen und modifizieren. Das ist gut und praktisch, wenn man Websites und Apps aus der gleichen Datenbasis bespielen will.

The ugly

Leider gilt das nicht für die initiale Konfiguration des Systems. In den Templates fragt man Objekte und Klassen ab, die in der Datenbank und nicht auf Code-Ebene generiert werden. Die Klassendateien werden aus dem Admin-Backend gefüllt. Statische Routen werden in der Datenbank angelegt. Die Klassendefinitionen werden teils-teils abgebildet.

Aus Entwicklungssicht ist das relativ ungünstig, weil die Datenbank in der Regel nicht Teil des versionierten Codes von pimcore ist, und zentrale Dinge wie die statischen Routen, die z.b. in der $view->url()-Funktion benötigt werden, damit nicht im Webprojekt-Code vohanden sind. Das sind Dinge, die bei WordPress mittlerweile deutlich besser funktionieren. Mit diesem etwas komischen Gefühl stehe ich glücklicherweise aber nicht alleine da, denn hier kann ein einzelnder Nutzer mit Admin-Rechten (nicht Server-Zugang) mit ein wenig Ungeschick und unwissen, die Website kaputtmachen. Vielleicht wird sich das mit kommenden Versionen noch geben.

Aber nicht nur die Routen, auch die Klassenbibliothek lässt sich nicht rein aus dem Code erzeugen, ohne Gegenstück in der Datenbank sind die Klassendateien für das Aufsetzen eines Projekts eher zwecklos. Ein Import geht, soweit ich das sehe, nur, wenn ich die Datentypen vorher im Admin-Backend aus der Klasse exportiert habe, eine Übernahme der Daten auf Codebasis geht nicht.

Fazit

Wer mit den oben angesprochenen “häßlichen” Teilen leben kann, bekommt mit Pimcore ein flexibles Werkzeug an die Hand, mit dem sich datenbasierte Websites und Apps vergleichsweise einfach und schnell umsetzen lassen.

Kategorien
Webentwicklung Werkzeuge

Websites bauen mit pimcore

phpstorm

Ich bin ja als PHP-Entwickler nicht gerade erfahren, ich mach dann eher das mit dem Frontend. Neuerdings beschlich mich allerdings der dringende Wunsch, mal ein bisschen Abwechslung zu haben und ich habe mich auch mal auf der Entwicklungsseite mal ein bisschen mit pimcore auseinandergesetzt.

Dazu habe ich eine kleine Website gebaut, die über Energydrinks informieren kann. Die Website ist direkt zweisprachig und von Objekten getrieben. Ich will nur mal einen kleinen Einblick geben, wie das ganze anhand der Drink-Darstellung aussieht.

Der Drinks-Controller

<?php

use Website\Controller\Action;
use Pimcore\Model\Object;


class DrinksController extends Action
{

    public function defaultAction()
    {
        $this->enableLayout();

    }

    public function listDrinksByCaffeineAction()
    {
        $this->enableLayout();

        $drinkList = new Object\Drink\Listing();
        $drinkList->setOrderKey("Koffeingehalt");
        $drinkList->setOrder("DESC");

        $this->view->drinks = $drinkList;


    }

    public function drinkDetailAction(){
        $this->enableLayout();

        $drink = Object\Drink::getById($this->getParam('id'));

        $this->view->drink = $drink;

    }

    public function indexAction()
    {
        $this->enableLayout();
    }
}

Hier werden eigentlich nur zwei Views mit passenden Daten gefüllt, die dann z.B. in list-drinks-by-caffeine.php (man beachte die Benamung der Datei im Vergleich mit der Action) angezeigt werden:

<?php
$this->layout()->setLayout('standard');
$lang_prefix = $this->document->getProperty('mainNavStartNode')->getFullPath();
?>


<?php while ($this->block("contentblock")->loop()) { ?>
    <?= $this->wysiwyg("content"); ?>
<?php } ?>


<table class="table">
    <tr>
        <th><?= $this->translate("Bild"); ?></th>
        <th><?= $this->translate("Koffeingehalt"); ?> / 100ml</th>
        <th><?= $this->translate("Name"); ?></th>
        <th><?= $this->translate("Hersteller"); ?></th>
    </tr>



    <?php
    /** @var  \Pimcore\Model\Object\Drink $drink */
    foreach ($this->drinks as $drink) { ?>

        <tr>
            <td>
                <a href="<?= $this->url(array(
                    "prefix" => $lang_prefix,
                    'id' => $drink->getId()
                ), "drink") ?>">
                    <?php if ($drink->getBild()) { ?>
                        <?= $drink->getBild()->getThumbnail('list')->getHTML() ?>
                    <?php } ?>
                </a>

            </td>

            <td class="col-sm-4">
                <?= $drink->getKoffeingehalt(); ?>

            </td>
            <td class="col-sm-4">


                <a href="<?= $this->url(array(
                    "prefix" => $lang_prefix,
                    'id' => $drink->getId()
                ), "drink") ?>">
                    <?= $drink->getName(); ?>
                </a>
            </td>
            <td class="col-sm-4">

                <a href="<?= $this->url(array(
                    "prefix" => $lang_prefix,
                    'id' => $drink->getHersteller()->getId()
                ), "hersteller") ?>">
                    <?= $drink->getHersteller()->getName(); ?>

                </a>

            </td>
        </tr>

    <?php }; ?>

</table>

Das sieht dann so aus:

Drinks Übersicht
Drinks Übersicht

Für die Abbildung der Detail-Ansicht muss man sich dann ein bisschen mit statischen Routen befassen, die man in pimcore pflegen kann, die sieht dann so aus:

static_routes

Drinks Detail
Drinks Detail

Zusammenfassend kann ich sagen:

Mit dem CMS/PIM-System pimcore und dem Hilfsmittel PHPStorm bekomme ich (PHP nicht so erfahren) recht schnell brauchbare Ergebnisse und kann Seiten, die viele strukturierte Daten darstellen sollen, die untereinander verknüpft sind, schnell und einfach umsetzen.

Das ersetzt sicher keinen PHP-Profi, der 10 Jahre Zend-Erfahrung hat, kann aber ein guter erster Schritt sein, solche Modelle mal anzudenken. Wen das ganze interessiert, kann sich bei pimcore.org weitere Informationen holen, oder mich fragen.