Contao-Camp 2024
Ergebnis 1 bis 18 von 18

Thema: Datei Upload: Vor dem Speichern im Benutzerverzeichnis Datei umbenennen

  1. #1
    Contao-Nutzer
    Registriert seit
    16.12.2015.
    Beiträge
    17

    Standard Datei Upload: Vor dem Speichern im Benutzerverzeichnis Datei umbenennen

    Hallo,

    ich möchte Bilddateien per Formular im jeweiligen Benutzerverzeichnis speichern. Mit dem Formulargenerator ist das problemlos möglich. Allerdings möchte ich die Datei vor dem Ablegen im Benutzerverzeichnis umbenennen.

    Ich komme aber einfach nicht an die hochgeladene Datei heran, um sie dann per move_uploaded_file(...) unter anderem Namen abzuspeichern.
    Ich habe versucht ein Contao-Konstrukt nach dem Vorbild
    PHP-Code:
    move_uploaded_file($_FILES['datei']['tmp_name'], "foo/bar/neuername.jpg"); 
    zu stricken.

    Meine bislang erfolglosen Versuche gehen in Richtung
    PHP-Code:
    $upload $_SESSION['FILES'];
    $datei $upload['datei']['tmp_name'];

    $this->Files->move_uploaded_files($datei'foo/bar/neuername.jpg'); 
    Oder bin ich damit auf dem Holzweg?

    Suche schon seit zwei Tagen nach einer Lösung, aber das einzige, was ich in dieser Richtung bisher gefunden habe, ist dieser Thread:
    https://community.contao.org/de/show...ad-im-Frontend


    NACHTRAG:

    Ich habe noch diesen Thread hier gefunden
    https://community.contao.org/de/show...namen-anpassen

    Dort findet sich folgender Hinweis von cliffen:
    Das Widget für den File Upload speichert den Zielort nicht im Post oder der Session ... irgendwie verschwindet alles , was zum Uploadfeld gehört.
    Das bezog sich alles (inkl. der Lösung) aber leider noch auf Contao 2. Besteht das Problem bei Contao 3 immer noch?

    Gruß
    Marc
    Geändert von w00dchuck (16.12.2015 um 21:27 Uhr)

  2. #2
    Community-Moderator
    Wandelndes Contao-Lexikon
    Avatar von Spooky
    Registriert seit
    12.04.2012.
    Ort
    Scotland
    Beiträge
    33.893
    Partner-ID
    10107

    Standard

    Das FormFileUpload Widget bietet leider keine Hooks. Aber du könntest die Datei einfach in einem prepareFormData Hook umbenennen. zB so:
    PHP-Code:
    public function prepareFormData$arrSubmitted$arrLabels, \Form $form$arrFields )
    {
        if (!empty(
    $_SESSION['FILES']))
        {
            foreach (
    $_SESSION['FILES'] as &$file)
            {
                if (
    $file['uploaded'])
                {
                    
    $objFile = new \File$file['tmp_name'] );
                    
    $objFile->renameTo$objFile->dirname .'/'$objFile->filename .'-foo.'$objFile->extension );
                    
    $file['name'] = $objFile->name;
                }
            }
        }

    (ungetestet)

  3. #3
    Contao-Nutzer
    Registriert seit
    16.12.2015.
    Beiträge
    17

    Standard

    Oha! Mit Hooks hab ich bislang noch nix gemacht. Lese mich gerade ein.

    Trotzdem noch ein paar Fragen:

    1. Der neue Dateiname wird eigentlich erst in dem aufgerufenen PHP-Skript generiert. Die Funktion, die den Namen generiert, könnte ich aber auch in den Hook auslagern, oder?

    2. Wenn ich das Skript direkt aufrufe -- z.B. aus einer App heraus und damit ohne die Verwendung eines Contao-Formulars -- lässt sich das überhaupt triggern? Das Skript ist in einem Artikel per {{file::...}} eingebunden. Aufgerufen wird der Artikel.

    Nachtrag zu 2.
    In diesem Fall müsste es ja auf dem konventionellen Weg klappen. Hier müsste ich ja an den übermittelten Dateinamen auch direkt per $_FILES kommen, bzw. $_SESSION['FILES'].
    Geändert von w00dchuck (18.12.2015 um 14:55 Uhr)

  4. #4
    Community-Moderator
    Wandelndes Contao-Lexikon
    Avatar von Spooky
    Registriert seit
    12.04.2012.
    Ort
    Scotland
    Beiträge
    33.893
    Partner-ID
    10107

    Standard

    Zitat Zitat von w00dchuck Beitrag anzeigen
    1. Der neue Dateiname wird eigentlich erst in dem aufgerufenen PHP-Skript generiert. Die Funktion, die den Namen generiert, könnte ich aber auch in den Hook auslagern, oder?
    Ja, ich würde das einfach dort machen.

  5. #5
    Contao-Nutzer
    Registriert seit
    16.12.2015.
    Beiträge
    17

    Standard

    Ich habe endlich mal den Vorschlag von @Spooky ausprobiert, aber leider führt
    PHP-Code:
    $objFile = new \File$file['tmp_name'] ); 
    zu:

    PHP Fatal error: Uncaught exception 'RuntimeException' with message 'No file or folder name given' thrown in (...) system/modules/core/library/Contao/Files.php on line 272

  6. #6
    Community-Moderator
    Wandelndes Contao-Lexikon
    Avatar von Spooky
    Registriert seit
    12.04.2012.
    Ort
    Scotland
    Beiträge
    33.893
    Partner-ID
    10107

    Standard

    Naja, wie sieht der restliche Code aus?

  7. #7
    Contao-Nutzer
    Registriert seit
    16.12.2015.
    Beiträge
    17

    Standard

    //config.php

    PHP-Code:
    $GLOBALS['TL_HOOKS']['prepareFormData'][] = array('uploadRenameClass''renamePrepareFormData'); 
    //uploadRenameClass.php

    PHP-Code:
    class uploadRenameClass
    {
      public function 
    renamePrepareFormData$arrSubmitted$arrLabels, \Form $form$arrFields )
      {
          if (!empty(
    $_SESSION['FILES']))
          {
              foreach (
    $_SESSION['FILES'] as &$file)
              {
                  if (
    $file['uploaded'])
                  {
                      
    $objFile = new \File$file['tmp_name'] );
                      
    $objFile->renameTo$objFile->dirname '/' $objFile->filename '-foo.' $objFile->extension );
                      
    $file['name'] = $objFile->name;
                  }
              }
          }
      }


  8. #8
    Contao-Nutzer
    Registriert seit
    16.12.2015.
    Beiträge
    17

    Standard

    Wenn ich mir
    PHP-Code:
    print_r($file['tmp_name']);die; 
    ausgeben lasse, dann erhalte ich jedenfalls den korrekten Dateinamen inkl. Pfad. Erst bei der Zuweisung an 'objFile' geht irgendwas schief.

    Hab das ganze auch mit 'processFormData' probiert. Mit dem gleichen Ergebnis.

  9. #9
    Contao-Nutzer
    Registriert seit
    16.12.2015.
    Beiträge
    17

    Standard

    Ich verwende nun
    PHP-Code:
    $datei $file['tmp_name']; 
    statt
    PHP-Code:
    $objFile = new \File$file['tmp_name'] ); 
    und

    PHP-Code:
    rename($datei"/pfad/zur/datei/" $account "/banner.png"); 
    statt
    PHP-Code:
    $objFile->renameTo$objFile->dirname '/banner.' $objFile->extension ); 
    Die Variable $account wird dabei aus dem Array arrSubmitted['account'] befüllt.

  10. #10
    Contao-Nutzer
    Registriert seit
    08.11.2009.
    Beiträge
    191

    Standard

    Da habe ich auch noch eine Frage dazu.
    Mein Formular hat vier Uploadfelder. Die hochgeladenen Dateien sollen so umbenannt werden wie der Feldname des jeweiligen Uploadfeldes.
    Mit dem Hook prepareFormData wie beschrieben habe ich es leider nicht geschafft.

  11. #11
    Community-Moderator
    Wandelndes Contao-Lexikon
    Avatar von Spooky
    Registriert seit
    12.04.2012.
    Ort
    Scotland
    Beiträge
    33.893
    Partner-ID
    10107

    Standard

    Was genau funktioniert nicht, wenn du den prepareFormData Hook verwendest? Was genau macht dein code?

  12. #12
    Contao-Nutzer
    Registriert seit
    08.11.2009.
    Beiträge
    191

    Standard

    Also ich habe folgendes gemacht:
    neuer Ordner modules/uploadRenameClass, darin die Datei uploadRenameClass.php

    PHP-Code:
    <?php
    class uploadRenameClass 

      public function 
    renamePrepareFormData$arrSubmitted$arrLabels, \Form $form$arrFields 
      { 
          if (!empty(
    $_SESSION['FILES'])) 
          { 
              foreach (
    $_SESSION['FILES'] as &$file
              { 
                  if (
    $file['uploaded']) 
                  { 
                      
    $objFile = new \File$file['tmp_name'] ); 
                      
    $objFile->renameTo$objFile->dirname '/banner.' $objFile->extension );  
                      
    $file['name'] = $objFile->name
                  } 
              } 
          } 
      } 
    }
    und die modules/uploadRenameClass/config/config.php sieht so aus:
    PHP-Code:
    <?php
    $GLOBALS
    ['TL_HOOKS']['prepareFormData'][] = array('uploadRenameClass''renamePrepareFormData');
    Die Datei wird hochgeladen, aber sonst tut sich nichts. Muss zugeben ich kann den Code auch zu wenig interpretieren.
    Hätte gerne die von Mitgliedern hochgeladenen Dateien per Frontend Formular umbenannt.
    Optimalerweise soll er den Feldnamen aus dem Formulargenerator übernehmen (es gibt mehrere Uploadfelder).

    Vielen Dank!

  13. #13
    Community-Moderator
    Wandelndes Contao-Lexikon
    Avatar von Spooky
    Registriert seit
    12.04.2012.
    Ort
    Scotland
    Beiträge
    33.893
    Partner-ID
    10107

    Standard

    Siehe auch https://community.contao.org/de/show...l=1#post394926 Die renameTo Methode der File Klasse hatte bei w00dchuck nicht funktioniert (warum auch immer).

    Ohne PHP Kenntnisse wird dein Vorhaben aber schwierig, denke ich.

  14. #14
    Contao-Nutzer
    Registriert seit
    08.11.2009.
    Beiträge
    191

    Standard

    Danke für deine Antwort. Ich dachte das Script ist schon soweit einsatzbereit.
    Aber anscheinend hab ich mir das zu leicht vorgestellt...

  15. #15
    Contao-Nutzer
    Registriert seit
    16.12.2015.
    Beiträge
    17

    Standard

    Wird dein Modul denn auch tatsächlich ausgeführt bzw. überhaupt geladen? Hast du den Autoload-Creator drüber laufen lassen?

    Zum Umbenennen nimmst du den entsprechenden Namen aus dem Array $arrFields bzw. $arrLabels.
    (Weshalb die File-Klasse bei mir nicht funktioniert, habe ich noch nicht herausgefunden.)

    Ansonsten kann ich Spooky nur beipflichten. Einfach Code zu übernehmen, den du nicht verstehst, ist keine gute Lösung. Und für meinen Zweck ist das "Skript" übrigens einsatzbereit.

    Hier mal ein Einstieg zu den Hooks:
    https://docs.contao.org/books/cookbo...in-Contao.html

  16. #16
    Contao-Nutzer
    Registriert seit
    16.12.2015.
    Beiträge
    17

    Standard

    Zitat Zitat von Spooky Beitrag anzeigen
    Die renameTo Methode der File Klasse hatte bei w00dchuck nicht funktioniert (warum auch immer).
    Ich bin zufällig wieder über diesen Thread gestolpert. Ich vermute es lag daran, dass die File-Klasse einen relativen Pfad zur Datei erwartet. 'tmp_name' in $_SESSION['FILES'] enthält jedoch den absoluten Pfad (zumindest wenn die Datei über das Formular im Benutzerverzeichnis gespeichert wird). Hab allerdings nicht getestet, ob’s wirklich daran lag.

  17. #17
    Contao-Nutzer
    Registriert seit
    07.12.2019.
    Beiträge
    147

    Standard

    Zitat Zitat von Spooky Beitrag anzeigen
    Das FormFileUpload Widget bietet leider keine Hooks. Aber du könntest die Datei einfach in einem prepareFormData Hook umbenennen. zB so:
    PHP-Code:
    public function prepareFormData$arrSubmitted$arrLabels, \Form $form$arrFields )
    {
        if (!empty(
    $_SESSION['FILES']))
        {
            foreach (
    $_SESSION['FILES'] as &$file)
            {
                if (
    $file['uploaded'])
                {
                    
    $objFile = new \File$file['tmp_name'] );
                    
    $objFile->renameTo$objFile->dirname .'/'$objFile->filename .'-foo.'$objFile->extension );
                    
    $file['name'] = $objFile->name;
                }
            }
        }

    (ungetestet)
    Hey Spooky, ich muss hier mal einen alten Thread ausgraben.
    Ich habe meine Hook genauso wie du implementiert und erhalte dabei dann, sobald die "renameTo()" - Funktion ausgeführt wird, folgenden Fehler:
    [2021-05-27 21:28:06] app.CRITICAL: An exception occurred. {"exception":"[object] (RuntimeException(code: 0): No file or folder name given at serverpfad/contao44/vendor/contao/core-bundle/src/Resources/contao/library/Contao/Files.php:322)"} []
    Wenn ich mir den Pfad, welchen ich da zusammenstelle vor der renameTo-Funktionalität ausgeben lasse, so ist dieser genau das, was ich haben möchte.

    Hast du eine Idee, wieso die RenameTo bei mir nicht funktioniert und diesen Fehler wirft?

    Zur Vollständigkeit noch mein etwas abgewandelter-Code:
    Code:
        public function prepareFormData(array &$submittedData, array $labels, array $fields, Form $form): void
        {
            if(!empty($_SESSION['FILES'])) {
                foreach($_SESSION['FILES'] as &$file) {
                    if($file['uploaded']) {
                        $objFile = new File($file['tmp_name']);
                        $objFile->renameTo(sprintf('%s/%s--new.%s', $objFile->dirname, $objFile->filename, $objFile->extension));
                        $file['name'] = $objFile->name;
                    }
                }
            }
        }

  18. #18
    Contao-Nutzer
    Registriert seit
    07.12.2019.
    Beiträge
    147

    Standard

    Edit, für die, die es vielleicht mal lesen sollten.

    Das Problem hierbei ist, dass $_SESSION['FILES'] einen absoluten Pfad liefert.

    In der File.php wird über die renameTo() dann folgendes aufgerufen:

    Code:
    // Create the parent folder if it does not exist
    if (!is_dir(TL_ROOT . '/' . $strParent))
    {
        new \Folder($strParent);
    }
    Hier kommt es dann zum Fehler.
    Meiner Einschätzung nach müsste man hier dann nur den Pfad ab TL_ROOT verwenden und den Rest verwerfen.

Aktive Benutzer

Aktive Benutzer

Aktive Benutzer in diesem Thema: 1 (Registrierte Benutzer: 0, Gäste: 1)

Lesezeichen

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •