[Frage] extbase: Dateiupload im Frontend OHNE FAL [Gelöst]

  • jenses jenses
    Flash Gordon
    0 x
    3087 Beiträge
    106 Hilfreiche Beiträge
    28. 02. 2014, 10:15

    Gibt es dafür irgendeine "saubere" extbase-Lösung?
    Mit dem, was der extension_builder zusammenbastelt,
    wird lediglich der Dateiname in das entsprechende Feld geschrieben, ein Upload erfolgt aber nicht.

    Bei der Suche nach Infos heißt es: muß man komplett selber bauen.
    Wie?

    Die Code-Schnipsel im Netz, bei denen man per

    1. if ($_FILES['tx_myExtension_myPlugin']['name']['formObject']['formFieldName']) {
    2. ...

    arbeitet, funktionieren nicht unter 6.1.x, da $_FILES immer leer ist.

    Wo versteckt extbase die hochgeladene Datei? Wie kann ich darauf zugreifen?
    Oder muß man wirklich den Upload und das Speichern komplett selber lösen,
    wie z.B. im femanager per jquery.fineuploader ?

  • jenses jenses
    Flash Gordon
    0 x
    3087 Beiträge
    106 Hilfreiche Beiträge
    28. 02. 2014, 14:19 - Lösung

    Zitiert von: vince

    Ich habe eine Extbase extension unter TYPO3 6.1.7 laufen, und da kann man auf $_FILES zugreifen.
    Ich schätze mal, dass da woanders etwas nicht stimmt.

    Jupp, hat eine Weile gedauert, aber jetzt hab ich es (Danke auch an Alex Kellner für die Hilfe und Inspiration)

    1. Damit $_FILES existiert, sollte man seinem Formular auch mitteilen, daß es doch bitteschön den [b]enctype "multipart/form-data"[/b] benutzt :-p

    2. Im jeweiligen Controller in der initializeAction muß dem Property Manager gesagt werden,
    welchen Konvertierer er für die Eigenschaft Model->Bilddatei benutzen soll,
    ansonsten gibt es eine nette Fehlermeldung
    (Erklärung dazu gibt es hier: http://www.typo3lexikon.de/typo3-tutorials/extensions/extbase/property-mapper.html)

    Das sieht dann so aus:

    1. /**
    2.   * initialize action
    3.   */
    4. public function initializeAction() {
    5. if ($this->arguments->hasArgument('events')) {
    6. $this->arguments->getArgument('events')->getPropertyMappingConfiguration()->setTargetTypeForSubProperty('image', 'array');
    7. }
    8. }

    Dann benötigt man die Funktionen, die das hochgeladene Bild auf Zulässigkeit(mime type) überprüfen, korrekten Dateinamen erzeugen (z.B. bei Dubletten) und das Bild letztendlich in den konfigurierten Ordner verschieben.
    ( alles innerhalb einer Utility-Klasse, hier habe ich mich bei Alex's femanager bedient und das Ganze entsprechend angepaßt für 6.1, namespaces usw.)

    1. <?php
    2. namespace smedjadotcom\Wsevents\Utility;
    3.  
    4. /**
    5.  *
    6.  * Misc Functions
    7.  *
    8.  * @package wsevents
    9.  * @license http://www.gnu.org/licenses/gpl.html GNU General Public License, version 3 or later
    10.  *
    11.  */
    12.  
    13. class Div {
    14.  
    15. /**
    16.   * objectManager
    17.   *
    18.   * @var \TYPO3\CMS\Extbase\Object\ObjectManager
    19.   * @inject
    20.   */
    21. protected $objectManager;
    22.  
    23. /**
    24.   * Upload file
    25.   *
    26.   * @param \string $filename
    27.   * @return mixed false or file.png
    28.   */
    29. public function uploadFile($imageField) {
    30. // Check file extension
    31. if (empty($imageField['name']) || !self::checkExtension($imageField['name'])) {
    32. return FALSE;
    33. }
    34. // create new filename and upload it
    35. $basicFileFunctions = $this->objectManager->get('TYPO3\CMS\Core\Utility\File\BasicFileUtility');
    36. $newFile = $basicFileFunctions->getUniqueName(
    37. $imageField['name'],
    38. \TYPO3\CMS\Core\Utility\GeneralUtility::getFileAbsFileName( self::getUploadFolderFromTca() )
    39. );
    40. #\TYPO3\CMS\Extbase\Utility\DebuggerUtility::var_dump($newFile,'$newFile in uploadFile()');
    41. if (\TYPO3\CMS\Core\Utility\GeneralUtility::upload_copy_move($imageField['tmp_name'], $newFile)) {
    42. $fileInfo = pathinfo($newFile);
    43. return $fileInfo['basename'];
    44. }
    45. return FALSE;
    46. }
    47.  
    48. /**
    49.   * Check extension of given filename
    50.   *
    51.   * @param \string Filename like (upload.png)
    52.   * @return \bool If Extension is allowed
    53.   */
    54. public static function checkExtension($filename) {
    55. $extensionList = $GLOBALS['TCA']['tx_wsevents_domain_model_events']['columns']['image']['config']['allowed'];
    56. $fileInfo = pathinfo($filename);
    57. if (!empty($fileInfo['extension']) && \TYPO3\CMS\Core\Utility\GeneralUtility::inList($extensionList, strtolower($fileInfo['extension']))) {
    58. return TRUE;
    59. }
    60. return FALSE;
    61. }
    62.  
    63. /**
    64.   * Read image uploadfolder from TCA
    65.   *
    66.   * @return \string path - standard "uploads/pics"
    67.   */
    68. public static function getUploadFolderFromTca() {
    69. $path = $GLOBALS['TCA']['tx_wsevents_domain_model_events']['columns']['image']['config']['uploadfolder'];
    70. if (empty($path)) {
    71. $path = 'uploads/pics';
    72. }
    73. return $path;
    74. }
    75.  
    76.  
    77. }

    Im Controller in der jeweiligen Action (hier updateAction) wird diese Funktion dann aufgerufen,
    die Eigenschaft "image des Objects event mit dem neuen Dateinamen überschrieben (da sie ja bis jetzt noch das Array mit tmp_name, absolutem Pfad usw. enthält, das macht sich ja nicht so gut beim nachfolgendn SQL-Insert).
    Anschließend wird das Object geupdatet, Erfolgsmeldung ausgegeben und zur vorherigen Action zurückgekehrt:

    1. /**
    2.  * action update
    3.  *
    4.  * @param \smedjadotcom\Wsevents\Domain\Model\Events $events
    5.  * @return void
    6.  */
    7. public function updateAction(\smedjadotcom\Wsevents\Domain\Model\Events $events) {
    8. $formData = $this->request->getArgument('events');
    9. $imageField = $formData['image'];
    10. $fileName = $this->div->uploadFile($imageField);
    11. $events->setImage($fileName);
    12. $this->eventsRepository->update($events);
    13. $this->flashMessageContainer->add('Your Events was updated.');
    14. $this->redirect( 'list' );
    15. }

    So funktioniert nun endlich der Bildupload,
    arbeitet man mit FAL, würde das noch wieder etwas anders aussehen


  • 1
  • vince vince
    Sternenflotten-Admiral
    0 x
    180 Beiträge
    6 Hilfreiche Beiträge
    28. 02. 2014, 13:29

    Zitiert von: jenses
    funktionieren nicht unter 6.1.x, da $_FILES immer leer ist.

    Ich habe eine Extbase extension unter TYPO3 6.1.7 laufen, und da kann man auf $_FILES zugreifen.
    (im Controller, in der update-Action)

    1. $_FILES['tx_myExtension_myPlugin']['name']['formObject']['formFieldName']

    im Formular hab ich das Feld so eingebunden:

    1. <f:form.upload property="formFieldName" />

    Ich schätze mal, dass da woanders etwas nicht stimmt.

  • jenses jenses
    Flash Gordon
    0 x
    3087 Beiträge
    106 Hilfreiche Beiträge
    28. 02. 2014, 14:19

    Zitiert von: vince

    Ich habe eine Extbase extension unter TYPO3 6.1.7 laufen, und da kann man auf $_FILES zugreifen.
    Ich schätze mal, dass da woanders etwas nicht stimmt.

    Jupp, hat eine Weile gedauert, aber jetzt hab ich es (Danke auch an Alex Kellner für die Hilfe und Inspiration)

    1. Damit $_FILES existiert, sollte man seinem Formular auch mitteilen, daß es doch bitteschön den [b]enctype "multipart/form-data"[/b] benutzt :-p

    2. Im jeweiligen Controller in der initializeAction muß dem Property Manager gesagt werden,
    welchen Konvertierer er für die Eigenschaft Model->Bilddatei benutzen soll,
    ansonsten gibt es eine nette Fehlermeldung
    (Erklärung dazu gibt es hier: http://www.typo3lexikon.de/typo3-tutorials/extensions/extbase/property-mapper.html)

    Das sieht dann so aus:

    1. /**
    2.   * initialize action
    3.   */
    4. public function initializeAction() {
    5. if ($this->arguments->hasArgument('events')) {
    6. $this->arguments->getArgument('events')->getPropertyMappingConfiguration()->setTargetTypeForSubProperty('image', 'array');
    7. }
    8. }

    Dann benötigt man die Funktionen, die das hochgeladene Bild auf Zulässigkeit(mime type) überprüfen, korrekten Dateinamen erzeugen (z.B. bei Dubletten) und das Bild letztendlich in den konfigurierten Ordner verschieben.
    ( alles innerhalb einer Utility-Klasse, hier habe ich mich bei Alex's femanager bedient und das Ganze entsprechend angepaßt für 6.1, namespaces usw.)

    1. <?php
    2. namespace smedjadotcom\Wsevents\Utility;
    3.  
    4. /**
    5.  *
    6.  * Misc Functions
    7.  *
    8.  * @package wsevents
    9.  * @license http://www.gnu.org/licenses/gpl.html GNU General Public License, version 3 or later
    10.  *
    11.  */
    12.  
    13. class Div {
    14.  
    15. /**
    16.   * objectManager
    17.   *
    18.   * @var \TYPO3\CMS\Extbase\Object\ObjectManager
    19.   * @inject
    20.   */
    21. protected $objectManager;
    22.  
    23. /**
    24.   * Upload file
    25.   *
    26.   * @param \string $filename
    27.   * @return mixed false or file.png
    28.   */
    29. public function uploadFile($imageField) {
    30. // Check file extension
    31. if (empty($imageField['name']) || !self::checkExtension($imageField['name'])) {
    32. return FALSE;
    33. }
    34. // create new filename and upload it
    35. $basicFileFunctions = $this->objectManager->get('TYPO3\CMS\Core\Utility\File\BasicFileUtility');
    36. $newFile = $basicFileFunctions->getUniqueName(
    37. $imageField['name'],
    38. \TYPO3\CMS\Core\Utility\GeneralUtility::getFileAbsFileName( self::getUploadFolderFromTca() )
    39. );
    40. #\TYPO3\CMS\Extbase\Utility\DebuggerUtility::var_dump($newFile,'$newFile in uploadFile()');
    41. if (\TYPO3\CMS\Core\Utility\GeneralUtility::upload_copy_move($imageField['tmp_name'], $newFile)) {
    42. $fileInfo = pathinfo($newFile);
    43. return $fileInfo['basename'];
    44. }
    45. return FALSE;
    46. }
    47.  
    48. /**
    49.   * Check extension of given filename
    50.   *
    51.   * @param \string Filename like (upload.png)
    52.   * @return \bool If Extension is allowed
    53.   */
    54. public static function checkExtension($filename) {
    55. $extensionList = $GLOBALS['TCA']['tx_wsevents_domain_model_events']['columns']['image']['config']['allowed'];
    56. $fileInfo = pathinfo($filename);
    57. if (!empty($fileInfo['extension']) && \TYPO3\CMS\Core\Utility\GeneralUtility::inList($extensionList, strtolower($fileInfo['extension']))) {
    58. return TRUE;
    59. }
    60. return FALSE;
    61. }
    62.  
    63. /**
    64.   * Read image uploadfolder from TCA
    65.   *
    66.   * @return \string path - standard "uploads/pics"
    67.   */
    68. public static function getUploadFolderFromTca() {
    69. $path = $GLOBALS['TCA']['tx_wsevents_domain_model_events']['columns']['image']['config']['uploadfolder'];
    70. if (empty($path)) {
    71. $path = 'uploads/pics';
    72. }
    73. return $path;
    74. }
    75.  
    76.  
    77. }

    Im Controller in der jeweiligen Action (hier updateAction) wird diese Funktion dann aufgerufen,
    die Eigenschaft "image des Objects event mit dem neuen Dateinamen überschrieben (da sie ja bis jetzt noch das Array mit tmp_name, absolutem Pfad usw. enthält, das macht sich ja nicht so gut beim nachfolgendn SQL-Insert).
    Anschließend wird das Object geupdatet, Erfolgsmeldung ausgegeben und zur vorherigen Action zurückgekehrt:

    1. /**
    2.  * action update
    3.  *
    4.  * @param \smedjadotcom\Wsevents\Domain\Model\Events $events
    5.  * @return void
    6.  */
    7. public function updateAction(\smedjadotcom\Wsevents\Domain\Model\Events $events) {
    8. $formData = $this->request->getArgument('events');
    9. $imageField = $formData['image'];
    10. $fileName = $this->div->uploadFile($imageField);
    11. $events->setImage($fileName);
    12. $this->eventsRepository->update($events);
    13. $this->flashMessageContainer->add('Your Events was updated.');
    14. $this->redirect( 'list' );
    15. }

    So funktioniert nun endlich der Bildupload,
    arbeitet man mit FAL, würde das noch wieder etwas anders aussehen

  • 1