<?php | |
namespace Craft; | |
class Plugin_FileController extends BaseController | |
{ | |
protected $valid_extensions = array('jpg', 'jpeg', 'png', 'pdf'); | |
protected $assetSourceId = 1; | |
public function actionUpload() | |
{ | |
$this->requireAjaxRequest(); | |
$errors = array(); | |
$success = array(); | |
foreach ($_FILES['files']['error'] as $key => $error) | |
{ | |
if (!$error) | |
{ | |
$filename = $_FILES['files']['name'][$key]; | |
$file = $_FILES['files']['tmp_name'][$key]; | |
$extension = end(explode('.', $filename)); | |
if (!in_array($extension, $this->valid_extensions)) | |
{ | |
$errors[] = "$filename has an invalid extension."; | |
continue; | |
} | |
$uploadDir = craft()->assetSources->getSourceById($this->assetSourceId)->settings['path']; | |
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')); | |
} | |
} |
<form method="post" action="" accept-charset="UTF-8" enctype="multipart/form-data"> | |
<input type="hidden" name="action" value="plugin/file/upload" /> | |
<input type="hidden" name="redirect" value="" /> | |
<p><input type="file" name="file" multiple></p> | |
<input type="submit" class="btn submit" value="Upload"> | |
</form> | |
<div style="margin-top:20px" id="output" /> | |
{% set js %} | |
$(function() { | |
$("form").submit(function() { | |
var url = '/admin/actions/' + $(this).children("[name=action]").attr('value'), | |
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 %} |
This comment has been minimized.
This comment has been minimized.
Thanks a lot for this! Great starting point to get things going. |
This comment has been minimized.
This comment has been minimized.
Great..!!! |
This comment has been minimized.
This comment has been minimized.
In the HTML, I ran into one problem: I had to use square brackets in the name attribute of the file upload input element, like:
In the PHP, there are three things that were causing issues for me: The $_FILES superglobal was not indexed by 'files', but rather 'file', even with multi-uploads: Additional, the end() function only accepts an argument passed by reference. It has to be a real variable and cannot be the return of a function. Simply assign the output of explode() to a variable then pass the variable, like this:
Lastly, the function to grab the asset base path was returning the literal "{basePath}/path/to/assets" string with the curly braces and all. The placeholder was not replaced. Having set up my config environment variables exactly according to the docs, to fix this, I used this code:
Hopefully, this helps someone down the road! |
This comment has been minimized.
This comment has been minimized.
@MFFunmaker I tried to implement it according to your changes, however i am running into this is the form (it throws a syntax error if i change the name to file[]):
this is the controller:
|
This comment has been minimized.
This comment has been minimized.
Hello, $this->requireAjaxRequest(); This is defined any where or It is Craft by default function. How I can use in Craft 3. Can you please guide me for this? |
This comment has been minimized.
$this->assetFolderId
...assetFolderId
is not being defined like you have definedassetSourceId