2

I have been looking through answers here at stackexchange but somehow can't figure out what i am missing. I simply want to upload an asset to a specific asset folder in my plugin.

I do get an error: Call to a member function getTempName() on null

Thanks a lot, much appreciated this is my form:

<form method="POST" enctype="multipart/form-data">
    <input type="hidden" name="action" value="assetLinks/upload/UploadFile">
    {{ getCsrfInput() }}
  <input type="file" name="file[]">
  <button type="submit">Upload file</button>
</form>

this is my controller:

<?php
namespace Craft;

class AssetLinks_UploadController extends BaseController
{

    public function actionUploadFile()
    {
        // Get info about the uploaded file
        $file = UploadedFile::getInstanceByName('fileInputName');
        $tempFilePath = $file->getTempName();

        // Find the target folder
        $folder = craft()->assets->findFolder(array(
            'sourceId' => 1,
            'path' => 'uploads/documents/',
        ));

        // Turn the file into a managed asset within that folder
        craft()->assets->insertFileByLocalPath(
            $file->getTempName(),
            $file->getName(),
            $folder->id,
            AssetConflictResolution::KeepBoth
        );
    }
}

Update:

I have been reading through the docs and some other examples and decided to go for an AJAX File upload, which of course lead to new problems :-)

this is the controller:

    <?php
namespace Craft;

class AssetLinks_UploadController extends BaseController
{

  protected $valid_extensions = array('jpg', 'jpeg', 'png', 'pdf');
  protected $assetSourceId = 1;
  public function actionUploadFile()
  {
      $this->requireAjaxRequest();
      $errors = array();
      $success = array();
      foreach ($_FILES['files']['error'] as $key => $error)
      {
          if (!$error)
          {
              $filename = $_FILES['file']['name'][$key];
              $file = $_FILES['file']['tmp_name'][$key];
              $filenamePieces = explode('.', $filename);
              $extension = end($filenamePieces);
              if (!in_array($extension, $this->valid_extensions))
              {
                  $errors[] = "$filename has an invalid extension.";
                  continue;
              }

              $uploadDir = craft()->assetSources->getSourceById($this->uploadAssetSourceId)->settings['path'];
              $uploadDir = str_replace('{basePath}', craft()->config->get('environmentVariables')['basePath'], $uploadDir);
              if (move_uploaded_file($file, $uploadDir . $filename))
              {
                  IOHelper::deleteFile($file);
                  $file = $uploadDir . $filename;
                  $fileModel = new AssetFileModel();
                  $fileModel->sourceId = $this->assetSourceId;
                  $fileModel->folderId = $this->assetFolderId;
                  $fileModel->filename = IOHelper::getFileName($filename);
                  $fileModel->kind = IOHelper::getFileKind(IOHelper::getExtension($filename));
                  $fileModel->size = filesize($file);
                  $fileModel->dateModified = IOHelper::getLastTimeModified($file);
                  craft()->assets->storeFile($fileModel);
                  $success[] = "$filename was saved.";
              }
              else
              {
                  $errors[] = "$filename was unable to be saved.";
                  continue;
              }
          }
      }
      $this->returnJSON(compact('errors', 'success'));
  }
}

and this is the form and Ajax post:

{% extends "_layouts/cp" %}
{% set title = 'Asset Links' %}

{% set content %}


  <form class="upload"  method="POST" enctype="multipart/form-data">
    <input  type="hidden" name="action" value="assetLinks/upload/UploadFile">
    {{ getCsrfInput() }}
    <input class="file btn" type="file" name="file">
    <button data-icon="upload" class="uploadfile btn submit" type="submit">Upload file</button>
  </form>
  <div style="margin-top:20px" id="output" />


{% endset %}


{% set js %}
    $(function() {
      $("form").submit(function() {
        var url = '/actions/assetLinks/upload',
          files = $(this).find("[name=file]")[0].files,
          formdata = new FormData(),
          file,
          reader;

        for (var i = 0; i < files.length; i++) {
          file = files[i];
          if (window.FileReader) {
            reader = new FileReader();
            reader.readAsDataURL(file);
          }
          formdata.append("files[]", file);
        }

        $("#output").html("Uploading...");

      $.ajax({
        type: "POST",
        url: url,
        data: formdata,
        processData: false,
          contentType: false,
        success: function(json) {
          window.json = json;
          console.log(json);

          var errors = json['errors'],
              success = json['success'],
              html = "<p><b>" + errors.length + " errors, " + success.length + " successfully uploaded</b></p>";

              $("#output").html(html);
        },
        error: function (xhr, ajaxOptions, thrownError) {
          alert("ERROR: " + xhr.status + " " + thrownError);
        }
      });

        return false;
      });
    })
{% endset %}
{% includeJs js %}

in wich i run into a 404, http://test.test/actions/assetLinks/upload 404 (Not Found)

it seems like i am addressing the wrong controller url ?

  • Are you using the correct field name for $file = UploadedFile::getInstanceByName('fileInputName')? – Andris Sevcenko Mar 25 '18 at 16:07
  • I am not sure to be honest, i posted all the data that is used in the plugin so its basically just the form and the uploadController – HendrikEng Mar 25 '18 at 16:14
  • @AndrisSevcenko you were right was blind, i changed the input name to:file and $file = UploadedFile::getInstanceByName('file');. it doesn't throw an error but doesn't upload anything – HendrikEng Mar 25 '18 at 21:01
1

Cant you just do as described in the craft docs? -> https://craftcms.com/docs/assets-fields#uploading-files-from-front-end-entry-forms

  • I am using the same form, but i am using a custom controller that throws the error. – HendrikEng Mar 25 '18 at 15:51
0

use $allowAnonymous feature in your controller to allow your function to work if you are not logged in when uploading[just assuming you are trying to upload this as logged off user.]

  • thanks for the answer, its a cp-tab and only used when someone is logged in into the backend, i must have made a mistake somewhere else – HendrikEng Mar 25 '18 at 23:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.