Skip to content

Komponenten erstellen

Till Uhlig edited this page Jun 21, 2017 · 3 revisions

Wir wollen nun eine neue Komponente enwickeln und nennen diese myNewComponent. Dabei werden wir diese mit PHP entwerfen und auf die Assistants/Model.php zurückgreifen. Zudem gibt es bereits ein fertiges Beispiel unter DB\DBBeispiel. Zudem kann auch die DB\CSystem als einfaches Beispiel genutzt werden (erlaubt lediglich die Abfrage eines Zeitstempels über GET /timestamp).

Die neue Komponente soll dabei unabhängig vom restlichen System entwickelt werden. Dazu legen wir uns zunächst ein neues Repository auf github.com unter dem Namen http://github.com/myname/mynewcomponent (Beispielname entspreechend Ihrem Account) an. Der Installationsassistent wird die Dateien der Komponente myNewComponent dann später von dort beziehen und die Kommentare der Commits als Changelog nutzen.

die Komponente registrieren

Damit unsere Komponente über den Installationsassisten installiert werden kann, müssen wir diese in einem Paket anmelden (weitere Informationen auf der zugehörigen Paketdefinitionen Seite). Dazu legen wir im Hauptprojekt unter install/packages/ die Datei mynewpackage.json an und kopieren das unten stehende Beispiel hinein.

❗ Achtung: Die Anmeldung als Paket erfolgt im Hauptprojekt ostepu-core. Für Ihre lokale Installation können Sie die Paketdefinition natürlich einfach direkt in den Ordner install/packages hinterlegen.

{
    "name": "MyNewComponent",
    "version": "0.1.0",
    "versionDate": "17.05.2017",
    "requirements": [],
    "description":{"de":"meine Beschreibung"},
    "descUrl":"http://github.com/myname/mynewcomponent",
    "files": [
        {
            "path": "vendor/myNewComponent/",
            "type": "git",
            "params": {
                "name": "myNewComponent",
                "branch": "master",
                "URL": "http://github.com/myname/myNewComponent.git",
                "path": "vendor/myNewComponent/"
            }
        }
    ],
    "components": [
        {"conf": "vendor/myNewComponent/Component.json"}
    ]
}

Der Installationsassistent wird unsere myNewComponent nun im Ordner vendor/myNewComponent& hinterlegen (über ein GIT-Repository) und aktualisieren. Dazu nutzt er den master Branch des Repository.

Die nachfolgenden Dateien werden in Ihrem Repository hinterlegt und befinden sich dann im installierten System unter vendor/myNewComponent/.

Aufbau der Komponente

Nach diesem Abschnitt wird Ihr Repository die Dateien Component.json, Commands.json, index.php, .htaccess und myNewComponent.php enthalten.

Component.json

Zunächst müssen wir unsere Komponente beschreiben. Dazu tragen Sie die unten stehenden Zeilen in Ihre Component.json ein. Sie finden weitere Informationen auf der entsprechenden Komponentendefinitionen Seite.

{
    "name": "myNewComponent",
    "version": "1.0",
    "classFile": "myNewComponent.php",
    "className": "myNewComponent",
    "files": [
        {"path": ".htaccess"},
        {"path": "myNewComponent.php"},
        {"path": "index.php"},
        {"path": "Commands.json"},
        {"path": "info/"},
        {"path": "help/"}
    ],
    "links": [
        {
            "name": "getUser",
            "target": "DBUser",
            "links": [{
                "method": "GET",
                "path": "/user/user/:userid"
            }]
        }
    ],
    "connector":[
        {"name": "request","target": "CLocalObjectRequest"},
        {"name": "postPlatform","target": "CInstall"},
        {
            "name": "getContent",
            "target": "UINavigation",
            "links": [
                {"path": "/view/button/help", "priority": "150"}
            ]
        },
        {
            "name": "request",
            "target": "CHelp",
            "links": [
                {"path": "/help/:language/extension/mynewcomponent/A.png"}
            ]
        }
    ]
}

Die Komponentendefinition enthält nun einen Ausgang getUser, welcher auf DBUser zeigt und das Abrufen einzelner Nutzerdaten ermöglichen soll. Zudem hängt sich unsere Komponente an die Ausgänge anderer existierender Komponenten.

{"name": "request","target": "CLocalObjectRequest"}

Dazu gehört der Eintrag unter connector mit dem Name request, welcher auf CLocalObjectRequest verweist. Damit erlauben wir der internen API unsere Komponente als PHP-Datei einzubinden, falls sich ein Aufrufer auf unserem Server befindet und auf unsere myNewComponent.php zugreifen kann.

{"name": "postPlatform","target": "CInstall"}

Dieser Eintrag hängt sich an den postPlatform Eintrag des Installationsassistenten (CInstall). Dieser wird uns nun aufrufen, wenn Plattform installieren aufgerufen wird. Dabei wird uns der Installationsassistent mittels POST /platform aufrufen und dabei globale Plattformdaten übermitteln, sodass wir allgemeine Installationsaufgaben durchführen können (wenn das benötigt wird).

{"name": "getContent","target": "UINavigation", ...}

Dieser Eintrag hängt sich an einen Einstiegspunkt der Benutzerschicht (genauer an das Template UINavigation). Dabei soll uns dieses Template aufrufen, wenn es seinen Ausgang getContent auswertet. Wir verlangen dabei mittels GET "/view/button/help aufgerufen zu werden.

{"name": "request","target": "CHelp", ...}

Sie können Hilfedateien (Erklärungen etc.) am globalen Hilfesystem CHelp anmelden, indem Sie in Ihrem Repository diese Dateien unter help/ hinterlegen und die Dateien entsprechend dem Schema FolderA_FolderB_Filename_language.extension benennen. Dabei würde als der Aufruf /help/:language/extension/mynewcomponent/A.png in unserem Repository auf eine Datei help/extension_mynewcomponent_A_de.png verweisen. Der Aufruf muss in der Commands.json nicht extra beschrieben werden, er wird durch die Model.php bereitgestellt.

Commands.json

Nun wollen wir die Befehle beschreiben, welche unsere Komponente myNewComponent dem restlichen System anbieten möchte. Dazu legen Sie die Datei Commands.json an und kopieren die Beispielbeschreibung hinein (weitere Informationen finden Sie auf der entsprechenden Aufrufdefinitionen Seite).

[
    {
        "name": "getHello",
        "outputType": "binary",
        "inputType": "",
        "method": "GET",
        "placeholder":[{"name":"uid","regex":"%^([0-9_]+)$%"}],
        "path": "/hello/user/:uid"
    },
    {
        "name": "addPlatform",
        "outputType": "Platform",
        "inputType": "Platform",
        "method": "POST",
        "path": "/platform"
    },
    {
        "name": "getHelpButton",
        "outputType": "binary",
        "inputType": "",
        "method": "GET",
        "path": "/view/button/help"
    }
]

Die Definition der aufrufbaren Befehle (Commands.json) enthält nun:

  • GET /hello/user/:uid Dieser Aufruf soll einen Nutzer begrüßen
  • POST /platform Dieser Aufruf wird aufgerufen, wenn sich unsere Komponente in der Plattform einrichten soll
  • GET /view/button/help wir wollen HTML-Code liefern, welcher in einem Template der Benutzerschicht eine Hilfe-Schaltfläche zeichnet.

❗ Achtung: Diese Aufrufe wurden hier nur beispielhaft verwendet, Sie müssen also keinen dieser Aufrufe später in Ihrer Komponente verwenden (bieten Sie keine Aufrufe an, die keinen Nutzen haben)

.htaccess

Die .htaccess sorgt hierbei lediglich dafür, dass generell nur Aufrufe vom eigenen Server durchgelassen werden (hier localhost) und darüber hinaus jede Anfrage auf die index.php umgeleitet wird.

RewriteEngine On
RewriteCond %{HTTP_HOST} !^localhost(:\d+)?$
RewriteRule ^ - [F]
RewriteRule ^ index.php [QSA,L]

index.php

In der .htaccess hatten wir definiert, dass alle Aufrufe auf die index.php umgeleitet werden. Diese soll nun unsere eigentliche Komponente aufrufen. Die hauptsächliche Inhalt befindet sich dabei in myNewComponent.php.

<?php
require_once ( dirname( __FILE__ ) . '/myNewComponent.php' );

new myNewComponent();

die Komponentendatei (.php)

Die eigentliche Funktionalität der Komponente tragen Sie nun in Ihre myNewComponent.php ein. Sie können den Quelltext natürlich auch in kleinere Dateien zerlegen und per include einbinden.

<?php
include_once ( dirname(__FILE__) . '/../../Assistants/Model.php' );

class myNewComponent
{
    public function __construct( )
    {
        // erzeugt aus der Commands.json und Component.json unsere Komponente und ruft diese auf
        $component = new Model('', dirname(__FILE__), $this);
        $component->run();
    }

    // die Namen der Methoden ergeben sich aus den 'name' Attributen der Commands.json
    public function getHello( $callName, $input, $params = array())
    {
        $uid = $params['uid'];
        $positive = function($input){
            $userData = json_decode($input, true);
            return Model::isOk('Hallo '.$userData['firstName']);
        };

        $negative = function(){
            return Model::isOk('Ich kenne Sie nicht!!!'); 
        };

        // Hier wird der Ausgang 'getUser' aufgerufen und in den callback Funktionen behandelt.
        // Das Ziel von 'getUser' wurde in der Component.json definiert.
        return Model::call('getUser', array('userid'=>$uid), '', 200, $positive, array(), $negative, array(), null);
    }

    // wird durch den Installationsassistenten beim Anlegen der Plattform aufgerufen
    public function addPlatform( $callName, $input, $params = array())
    {
        // schreibt den Zeitstempel in eine Datei
        file_put_contents('created.dat', microtime(true));
        return Model::isCreated(''); // Rückgabe '' mit Status 201
    }

    // erzeugt eine Hilfe-Schaltfläche
    public function getHelpButton( $callName, $input, $params = array())
    {   
        // gibt HTML-Code für eine Schaltfläche zurück (Status 200)
        $URL = 'https://github.com/ostepu/ostepu-core/wiki/Komponenten-erstellen';
        $content = "<li><a href='{$URL}' class='plain image-button exercise-sheet-images' target='popup' onclick=\"window.open('{$URL}', 'popup', 'width=700,height=600,scrollbars=yes,location=no,directories=no,menubar=no,toolbar=no,status=no,resizable=yes')\" title='info' target='_blank'>meineHilfe</a></li>";
        return Model::isOk($content);
    }
}

Nun führen Sie die Komponenteninstallation des Installationsassistenten aus. Danach können wir (lokal) aufrufen:

http://localhost/uebungsplattform/vendor/myNewComponent/hello/user/1

Wenn der Nutzer mit der ID=1 in unserer Plattform existiert, dann wird uns myNewComponent beispielweise sowas zurückmelden wie: Hallo Till

Clone this wiki locally