Datei-Presenter

Die Presenter für Dateien \Alvine\Application\Web\Presenter\File, \Alvine\Application\Web\Presenter\File\Upload und \Alvine\Application\Web\Presenter\File\Collection stellen Methoden für die Arbeit mit Dateien bereit.
Die Standardpresenter können Dateien empfangen und lokal speichern, eine Dateiliste übertragen und Dateien löschen.

In den Beispielen wird beschrieben wie ein Benutzer Dateinen auf dem Server speichern und wieder laden kann.

Pattern

Das Pattern einer Route wird mit einem Regex definiert, hier muss der Schrägstrich / nicht maskiert werden, es wird ein anderes Trennzeichen verwendent.

Platzhalter in der Route

Für den Pfad und die URL können unterschiedliche Platzhalter verwendet werden.
Alle Parameter stehen über ${PARAMETER:xxx} zur Verfügung (xxx ist der Name des Parameters).

Es können hier auch die Standardplatzhalter der Anwendung verwendet werden

Hinweis

Die verwendeten Parameter müssen im Abschnitt Parameter definiert werden. Bei Integer-Parametern ist darauf zu achten, dass diese einen Default-Wert haben. Parameter

Datei laden

Wenn die Dateien über den File Presenter geladen werden, wird der Mimetype der Datei mitgesendet.
Die Datei wird im Browser entsprechend angezeigt.

Hinweis

Die Server Konfiguration muss so eingestellt sein, das die Files nicht direkt vom Server ausgeliefert werden. Die Anfrage muss von Alvine verabeitet werden. location ~* api/user/files/([0-9]+)/.*.(?:avi|bin|css|js|bmp|dmg|doc|docx|dpkg|exe|flv|gif|htm|html|ico|ics|img|jpeg|jpg|m2a|m2v|mov|mp3|mp4|mpeg|mpg|msi|pdf|pkg|png|ppt|pptx|ps|rar|rss|rtf|swf|tif|tiff|txt|wmv|xhtml|xls|xml|zip)$ { try_files $uri @alvine; }

Konfiguration der Route

In der Konfiguration ist nur die Angabe des Server Pfad notwendig, wo die Dateien abgelegt sind.

<route id="ROUTE-ID-FILELOAD">
     <method>GET</method> 
     <pattern><![CDATA[^/api/user/files/(?<uid>[0-9]+)/(?<file>[a-z0-9.\-_]+\.(svg|jpg|gif|png|pdf))$]]></pattern>
     <template><![CDATA[/api/user/files/${uid}/${file}]]></template>
     <presenter>\Alvine\Application\Web\Presenter\File</presenter>
     <configuration>
         <source>
             <path>{CUSTOMISATIONPATH}upload/user/files/${PARAMETER:uid}</path>
         </source>
     </configuration>
     <parameters>
         <parameter name="uid" type="Integer" >0</parameter>
         <parameter name="file" type="StringType" />
     </parameters>
</route>

Dateien auflisten

Über die GET Anfrage kann eine Dateiliste abgerufen werden. Im folgenden Beispiel wird eine Liste für die UID 10 abgerufen

curl --request GET \
  --url 'http://example.com/api/user/files/10' \
  --header 'accept: application/json'

Konfiguration der Route

In der Route muss sowohl der Pfad als auch die gewünschte URL konfiguriert werden mit der die Datei wieder geladen werden kann.

Über den Filter-Tag werden die Dateien aufgeführt, die auszugeben sind. hierzu muss ein Regex, der auf den Dateinamen angewendet wird, angegeben werden. Nur Dateien die für den Regex gültig sind, werden im Ergebnis aufgeführt.

Wird der filter weggelassen, so werden alle Dateien in das Ergebnis aufgenommen.
In diesem Beispiel ist der Filter so eingestellt, wie auch der Upload oder das Laden erlaubt wird.

Die Dateien liegen hier im Beispiel auf dem Server {CUSTOMISATIONPATH}upload/user/files/10

<route id="ROUTE-ID-FILELIST">
    <method>GET</method>
    <pattern><![CDATA[^/api/user/files/(?<uid>[0-9]+)$]]></pattern>
    <template><![CDATA[/api/user/files/${uid}]]></template>
    <presenter>\Alvine\Application\Web\Presenter\File\Collection</presenter>
    <configuration>
        <source>
            <path>{CUSTOMISATIONPATH}upload/user/files/${PARAMETER:uid}</path>
            <uri>/api/user/files/${PARAMETER:uid}/</uri>
            <filter><![CDATA[/^[a-z0-9.\-_]+\.(svg|jpg|gif|png|pdf)$/]]></filter>
        </source>
    </configuration>
    <parameters>
        <parameter name="uid" type="Integer" >0</parameter>
    </parameters>
</route>

ein Beispiel für ein Ergebnis

{
    dataset: {
        9f18cb8f8d698e3a8c5090ec36a807a3: {
            name: "test.jpg",
            url: "/api/user/files/10/test.jpg",
            bytes: 366985,
            sha1: "ae2a20bfa00f916882d4cfd07da11d298985d802",
            lastAccessTime: "2019-08-25T06:21:36",
            lastModifiedTime: "2019-08-20T09:55:29"
    }
    },
    sys: {
        pagination: {
        total: 1
    },
        message: "200 OK",
        code: 200
    }
}

Dateien hochladen

Dateien können als Multipart-Mimetype hochgeladen werden. Dazu muss ein Feldname - in diesem Fall image definiert und im Request übergeben werden. Wird in der Route kein fester Dateiname bestimmt, so wird der übergebene Dateiname genommen.

POST http://example.com/api/file/myname/upload HTTP/1.1
Host: example.com
Content-Length: 3038
Accept: application/json
...
Cache-Control: no-cache
Content-Type: application/x-www-form-urlencoded

------WebKitFormBoundary5F4MlOdhad1hS9cu
Content-Disposition: form-data; name="image"; filename="test.gif"
Content-Type: image/gif
...

Konfiguration der Route

In der Route muss wie bei der Liste in destination/path der Pfad und in destination/uri die URL konfiguriert werden. Außerdem kann man optional einen Dateinamen und die Option zum Überschreiben angeben. Wird ein Dateiname definiert, so wird die Datei immer unter diesem Namen gespeichert. Ansonsten wird der Name aus der Übertragung genommen.

Im Tag name muss der Feldname der in der Übertragung verwendet wird definiert sein.

Wird die Option overwrite auf true gesetzt, so wird eine vorhandene Datei überschrieben. Andernfalls wird jeweils eine Zahl an den Dateinamen gehängt. Wird zum Beispiel der Dateiname bild.jpg übertragen, und gibt es im Zielordner bereits eine Datei mit diesem Namen, so wird die neue Datei unter bild-1.jpg, danach unter bild-2.jpg usw abgespeichert.

Ab 1000 Dateien mit dem gleichen Namen wird allerdings ein Fehler zurück gegeben. Damit sind datei-1.jpg bis datei-999.jpg möglich. Die maximale Anzahl kann über eine abgeleitete Klasse geändert werden.

Über die Einschränkung restriction/bytes kann die maximal erlaubte Dateigröße in Bytes angegeben werden. Über restriction/filter kann ein regulärer Ausdruck definiert werden. Der Dateiname wird gegen diesen Ausdruck geprüft. Schlägt eine Prüfung fehl, so wird eine Fehlermeldung zurück gegeben.

<route id="ROUTE-ID-FILEUPLOAD">
    <method>POST</method> 
    <pattern><![CDATA[^/api/user/files/(?<uid>[0-9]+)/upload$]]></pattern>
    <template><![CDATA[/api/user/files/${uid}/upload]]></template>
    <presenter>\Alvine\Application\Web\Presenter\File\Upload</presenter>
    <configuration>
        <name>file</name> <!-- Feldname im Post -->
        <destination>
            <path>{CUSTOMISATIONPATH}upload/user/files/${PARAMETER:uid}</path>
            <uri>/api/user/files/${PARAMETER:uid}/upload</uri>
            <filename>myImage.png</filename>  <!-- optional dann auch den filter entsprechend einstellen wegen der Dateiendung ".png" -->
            <overwrite>true</overwrite>  <!-- optional -->
        </destination>
        <restriction>
            <bytes>2000000</bytes>  <!-- optional 2Mb -->
            <filter><![CDATA[/^[a-z0-9.\-_]+\.(svg|jpg|gif|png|pdf)$/]]></filter>  <!-- optional -->
        </restriction>
    </configuration>
    <parameters>
        <parameter name="uid" type="Integer" >0</parameter>
    </parameters>
</route>

Datei löschen

Über den File-Presenter lassen sich Deteien über DELETE auch löschen. Aktuell kan nur eine Datei auf einmal gelöscht werden.

Konfiguration der Route

In der Route muss der Pfad der Datei konfiguriert sein. Optional kann - insbesondere wenn der Dateiname nicht als URL-Parameter - sondern als Query-Parameter definiert ist - ein Filter angegeben werden. Dieser schränkt dann den erlaubten Dateinamen der zu löschenden Dateien ein.

Hinweis

Aus Sicherheitsgründen sollte der Dateiname über die URL konfiguriert werden und nicht als Parameter übergeben werden.

<route id="ROUTE-ID-FILEDELETE">
    <method>DELETE</method>
    <pattern><![CDATA[^/api/user/files/(?<uid>[0-9]+)/(?<file>[a-z0-9.\-_]+\.(svg|jpg|gif|png|pdf))$]]></pattern>
    <template><![CDATA[/api/user/files/${uid}/${file}]]></template>
    <presenter>\Alvine\Application\Web\Presenter\File</presenter>
    <configuration>
        <destination>
            <path>{CUSTOMISATIONPATH}upload/user/files/${PARAMETER:uid}</path>
            <!-- Wichtig: Wenn der Dateiname nicht über die URL, sondern über einen Parameter übergeben wird -->
            <filter><![CDATA[/^[a-z0-9.\-_]+\.(svg|jpg|gif|png|pdf)$/]]></filter>  <!-- optional -->
        </destination>
    </configuration>
    <parameters>
        <parameter name="file" type="StringType" /> 
        <parameter name="uid" type="Integer" >0</parameter>
    </parameters>
</route>