Https://github.com/jaradsee/faktharm/blob/master/controllers/photolibrarycontroller.php 要上传多个图像,但是当我尝试以更新表单删除所选图像时,它会显示这些错误 (Image1) (Image2)
对于图像2,为什么URL链接始终给出产品%252FDELETEFILE-AJAX(给出数字25)BELOW是我的代码,请帮助我检查出了什么问题,谢谢! uploads.php
class Uploads extends \yii\db\ActiveRecord
{
/**
* {@inheritdoc}
*/
public static function tableName()
{
return 'uploads';
}
/**
* {@inheritdoc}
*/
public function rules()
{
return [
[['file_name'], 'required'],
[['upload_id'], 'integer'],
[['create_date'], 'safe'],
[['ref'], 'string', 'max' => 100],
[['file_name', 'real_filename'], 'string', 'max' => 150],
];
}
/**
* {@inheritdoc}
*/
public function attributeLabels()
{
return [
'upload_id' => 'Upload ID',
'ref' => 'Ref',
'file_name' => 'File Name',
'real_filename' => 'Real Filename',
'create_date' => 'Create Date',
];
}
}
class Products extends \yii\db\ActiveRecord
{
/**
* {@inheritdoc}
*/
//public $file;
const UPLOAD_FOLDER='products';
public static function tableName()
{
return 'products';
}
/**
* {@inheritdoc}
*/
public function rules()
{
return [
[['productName', 'productDescription', 'productPrice', 'categoryId', 'brandId', 'productStatus'], 'required'],
[['productDescription', 'productStatus'], 'string'],
[['productPrice'], 'number'],
[['categoryId', 'brandId'], 'integer'],
[['productName','ref'], 'string', 'max' => 100],
[['brandId'], 'exist', 'skipOnError' => true, 'targetClass' => Brands::className(), 'targetAttribute' => ['brandId' => 'brandId']],
[['categoryId'], 'exist', 'skipOnError' => true, 'targetClass' => Categorys::className(), 'targetAttribute' => ['categoryId' => 'categoryId']],
[['ref'],'unique']
// ['productImage', 'file','maxFiles'=>5],
//[['file'],'productImage']
];
}
/**
* {@inheritdoc}
*/
public function attributeLabels()
{
return [
'productId' => 'Product ID',
'productName' => 'Product Name',
'productDescription' => 'Product Description',
'productPrice' => 'Product Price',
'ref' => 'Product Image',
'categoryId' => 'Category',
'brandId' => 'Brand',
'productStatus' => 'Product Status',
];
}
/**
* Gets query for [[Brand]].
*
* @return \yii\db\ActiveQuery
*/
public function getBrand()
{
return $this->hasOne(Brands::className(), ['brandId' => 'brandId']);
}
/**
* Gets query for [[Category]].
*
* @return \yii\db\ActiveQuery
*/
public function getCategory()
{
return $this->hasOne(Categorys::className(), ['categoryId' => 'categoryId']);
}
public function getImages()
{
return $this->hasMany(Images::className(), ['productId' => 'productId']);
}
public static function getUploadPath(){
return Yii::getAlias('@webroot').'/'.self::UPLOAD_FOLDER.'/';
}
public static function getUploadUrl(){
return Url::base(true).'/'.self::UPLOAD_FOLDER.'/';
}
public function getThumbnails($ref,$event_name){
$uploadFiles = Uploads::find()->where(['ref'=>$ref])->all();
$preview = [];
foreach ($uploadFiles as $file) {
$preview[] = [
'url'=>self::getUploadUrl(true).$ref.'/'.$file->real_filename,
'src'=>self::getUploadUrl(true).$ref.'/thumbnail/'.$file->real_filename,
'options' => ['title' => $event_name]
];
}
return $preview;
}
}
namespace backend\controllers;
use Yii;
use backend\models\Products;
use backend\models\Uploads;
use backend\models\ProductsSearch;
use yii\web\Controller;
use yii\web\NotFoundHttpException;
use yii\filters\VerbFilter;
use yii\filters\AccessControl;
use yii\helpers\Json;
use yii\widgets\ActiveForm;
use yii\web\UploadedFile;
use yii\helpers\Url;
use yii\helpers\html;
use yii\helpers\BaseFileHelper;
use yii\helpers\ArrayHelper;
/**
* ProductsController implements the CRUD actions for Products model.
*/
class ProductsController extends Controller
{
/**
* {@inheritdoc}
*/
public function behaviors()
{
return [
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'delete' => ['POST'],
],
],
// 'access' => [
// 'class' => AccessControl::className(),
// 'rules' => [
// [
// 'actions' => ['view','update','_form','index','_search','create','uploadAjax','createDir'],
// 'allow' => true,
// 'roles' => ['admin'],
// ],
// ],
// ],
];
}
/**
* Lists all Products models.
* @return mixed
*/
public function actionIndex($pageSize = 10)
{
$searchModel = new ProductsSearch();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams, $pageSize);
return $this->render('index', [
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
'pageSize' => $pageSize,
]);
}
/**
* Displays a single Products model.
* @param integer $id
* @return mixed
* @throws NotFoundHttpException if the model cannot be found
*/
public function actionView($id)
{
return $this->render('view', [
'model' => $this->findModel($id),
]);
}
/**
* Creates a new Products model.
* If creation is successful, the browser will be redirected to the 'view' page.
* @return mixed
*/
/*public function actionCreate()
{
$model = new Products();
if ($model->load(Yii::$app->request->post()) && $model->save()) {
$model->imageFiles = UploadedFile::getInstances($model, 'productImage');
return $this->redirect(['view', 'id' => $model->productId]);
}
return $this->render('create', [
'model' => $model,
]);
}*/
public function actionCreate()
{
$model = new Products();
if ($model->load(Yii::$app->request->post())) {
$this->Uploads(false);
if($model->save()){
return $this->redirect(['view', 'id' => $model->productId]);
}
}
else{
$model->ref = substr(Yii::$app->getSecurity()->generateRandomString(),10);
}
return $this->render('create', [
'model' => $model,
]);
}
/**
* Updates an existing Products model.
* If update is successful, the browser will be redirected to the 'view' page.
* @param integer $id
* @return mixed
* @throws NotFoundHttpException if the model cannot be found
*/
public function actionUpdate($id)
{
$model = $this->findModel($id);
list($initialPreview,$initialPreviewConfig) = $this->getInitialPreview($model->ref);
if ($model->load(Yii::$app->request->post())) {
$this->Uploads(false);
if($model->save()){
return $this->redirect(['view', 'id' => $model->productId]);
}
}
return $this->render('update', [
'model' => $model,
'initialPreview'=>$initialPreview,
'initialPreviewConfig'=>$initialPreviewConfig
]);
}
/**
* Deletes an existing Products model.
* If deletion is successful, the browser will be redirected to the 'index' page.
* @param integer $id
* @return mixed
* @throws NotFoundHttpException if the model cannot be found
*/
public function actionDelete($id)
{
//$model = new Products();
//$this->findModel($id)->delete();
$model->$this->findModel($id);
$this->removeUploadDir($model->ref);
Uploads::deleteAll(['ref'=>$model->ref]);
$model->delete();
return $this->redirect(['index']);
}
/**
* Finds the Products model based on its primary key value.
* If the model is not found, a 404 HTTP exception will be thrown.
* @param integer $id
* @return Products the loaded model
* @throws NotFoundHttpException if the model cannot be found
*/
protected function findModel($id)
{
if (($model = Products::findOne($id)) !== null) {
return $model;
}
throw new NotFoundHttpException('The requested page does not exist.');
}
/*|*********************************************************************************|
|================================ Upload Ajax ====================================|
|*********************************************************************************|*/
public function actionUploadAjax(){
$this->Uploads(true);
}
private function CreateDir($folderName){
if($folderName != NULL){
$basePath = Products::getUploadPath();
if(BaseFileHelper::createDirectory($basePath.$folderName,0777)){
BaseFileHelper::createDirectory($basePath.$folderName.'/thumbnail',0777);
}
}
return;
}
private function removeUploadDir($dir){
BaseFileHelper::removeDirectory(Products::getUploadPath().$dir);
}
private function Uploads($isAjax=false) {
if (Yii::$app->request->isPost) {
$images = UploadedFile::getInstancesByName('upload_ajax');
if ($images) {
if($isAjax===true){
$ref =Yii::$app->request->post('ref');
}else{
$Products = Yii::$app->request->post('Products');
$ref = $Products['ref'];
}
$this->CreateDir($ref);
foreach ($images as $file){
$fileName = $file->baseName . '.' . $file->extension;
$realFileName = md5($file->baseName.time()) . '.' . $file->extension;
$savePath = Products::UPLOAD_FOLDER.'/'.$ref.'/'. $realFileName;
if($file->saveAs($savePath)){
if($this->isImage(Url::base(true).'/'.$savePath)){
$this->createThumbnail($ref,$realFileName);
}
$model = new Uploads;
$model->ref = $ref;
$model->file_name = $fileName;
$model->real_filename = $realFileName;
$model->save();
if($isAjax===true){
echo json_encode(['success' => 'true']);
}
}else{
if($isAjax===true){
echo json_encode(['success'=>'false','eror'=>$file->error]);
}
}
}
}
}
}
private function getInitialPreview($ref) {
$datas = Uploads::find()->where(['ref'=>$ref])->all();
$initialPreview = [];
$initialPreviewConfig = [];
foreach ($datas as $key => $value) {
array_push($initialPreview, $this->getTemplatePreview($value));
array_push($initialPreviewConfig, [
'caption'=> $value->file_name,
'width' => '120px',
'url' => Url::to(['/products/deletefile-ajax']),
'key' => $value->upload_id
]);
}
return [$initialPreview,$initialPreviewConfig];
}
public function isImage($filePath){
return @is_array(getimagesize($filePath)) ? true : false;
}
private function getTemplatePreview(Uploads $model){
$filePath = Products::getUploadUrl().$model->ref.'/thumbnail/'.$model->real_filename;
$isImage = $this->isImage($filePath);
if($isImage){
$file = Html::img($filePath,['class'=>'file-preview-image', 'alt'=>$model->file_name, 'title'=>$model->file_name]);
}else{
$file = "<div class='file-preview-other'> " .
"<h2><i class='glyphicon glyphicon-file'></i></h2>" .
"</div>";
}
return $file;
}
private function createThumbnail($folderName,$fileName,$width=250){
$uploadPath = Products::getUploadPath().'/'.$folderName.'/';
$file = $uploadPath.$fileName;
$image = Yii::$app->image->load($file);
$image->resize($width);
$image->save($uploadPath.'thumbnail/'.$fileName);
return;
}
public function actionDeletefileAjax(){
$model = Uploads::findOne(Yii::$app->request->post('key'));
if($model!==NULL){
$filename = Products::getUploadPath().$model->ref.'/'.$model->real_filename;
$thumbnail = Products::getUploadPath().$model->ref.'/thumbnail/'.$model->real_filename;
if($model->delete()){
@unlink($filename);
@unlink($thumbnail);
echo json_encode(['success'=>true]);
}else{
echo json_encode(['success'=>false]);
}
}else{
echo json_encode(['success'=>false]);
}
}
}
<?php
//use kartik\file\FileInput;
use yii\helpers\Html;
use yii\widgets\ActiveForm;
use kartik\select2\Select2;
use yii\helpers\ArrayHelper;
use backend\models\Brands;
use backend\models\Categorys;
use yii\helpers\Url;
use kartik\file\FileInput;
/* @var $this yii\web\View */
/* @var $model backend\models\Products */
/* @var $form yii\widgets\ActiveForm */
?>
<div class="photo-library-form">
<?php $form = ActiveForm::begin(['options'=>['enctype'=>'multipart/form-data']]); ?>
<?php $form->errorSummary($model) ?>
<?= $form->field($model, 'ref')->hiddenInput(['maxlength' => 100])->label(false); ?>
<?= $form->field($model, 'productName')->textInput(['maxlength' => true]) ?>
<?= $form->field($model, 'productDescription')->textarea(['rows' => 6]) ?>
<?= $form->field($model, 'productPrice')->textInput() ?>
<?=
$form->field($model, 'brandId')->widget(Select2::classname(), [
'data' => ArrayHelper::map(Brands::find()->where(['brandStatus'=>'active'])->all(),'brandId','brandName'),
'language' => 'en',
'options' => ['placeholder' => 'Select a brand ...'],
'pluginOptions' => [
'allowClear' => true
],
]);
?>
<?=
$form->field($model, 'categoryId')->widget(Select2::classname(), [
'data' => ArrayHelper::map(Categorys::find()->where(['categoryStatus'=>'active'])->all(),'categoryId','categoryName'),
'language' => 'en',
'options' => ['placeholder' => 'Select a category ...'],
'pluginOptions' => [
'allowClear' => true
],
]);
?>
<?= $form->field($model, 'productStatus')->dropDownList([ 'active' => 'Active', 'inactive' => 'Inactive', ], ['prompt' => 'Status']) ?>
<div class="form-group field-upload_files">
<label class="control-label" for="upload_files[]"> Product Images </label>
<div>
<?=
FileInput::widget([
'name' => 'upload_ajax[]',
//'attribute'=>'productImage[]',
//'name'=>'productImage[]',
'options' => [
'multiple'=>true,
'accept' => 'image/*',
//'id'=>'imageId',
],
'pluginOptions' => [
'initialPreview'=> $initialPreview,
'initialPreviewConfig'=> $initialPreviewConfig,
'deleteUrl'=>Url::to(['/products/deletefile-ajax']),
'showPreview' => true,
'showCaption' => false,
'showRemove' => false,
'showUpload' => false,
'uploadAsync' => true,
'uploadUrl'=>Url::to(['/products/upload-ajax']),
'maxFileCount' => 5,
'allowedFileExtensions' => ['jpg', 'png','jpeg'],
'previewFileType' => ['jpg', 'png','jpeg'],
'overwriteInitial'=>false,
'uploadExtraData' => [
'ref'=>$model->ref
],
'msgUploadBegin' => Yii::t('app', 'Please wait, system is uploading the files'),
'validateInitailCount'=>true,
'layoutTemplates'=>[
'actionZoom'=>'<button type="button" class="kv-file-zoom">{zoomIcon}</button>',
'actionUpload'=>'',
//'actionDelete'=>'<a>jj</a>',
//'footer' => '<div class="file-thumbnail-footer"><div class="file-caption-name" style="width:{width}">{caption}{size}</div>
//{progress}{actions}',
//'footer' => '<div class="file-thumbnail-footer"> <div class="file-caption-caption" title="{caption}"</div>'
//'actionDelete'=>'<button type="button" class="kv-file-remove"> {dataKey}{deleteUrl} {removeIcon}</button>',
],
],
'pluginEvents' => [
'filebatchselected' => 'function(event, files) {
$(this).fileinput("/products/upload-ajax");
}',
],
]);
?>
<br>
<div class="form-group">
<?= Html::submitButton($model->isNewRecord? 'Save': 'Update', ['class' => 'btn btn-primary']) ?>
<?= Html::a(Yii::t('app', 'Cancel'), ['index', 'id' => $model->productId], ['class'=>'btn btn-danger']) ?>
</div>
<?php ActiveForm::end(); ?>
</div>
__form.php
<?php
//use kartik\file\FileInput;
use yii\helpers\Html;
use yii\widgets\ActiveForm;
use kartik\select2\Select2;
use yii\helpers\ArrayHelper;
use backend\models\Brands;
use backend\models\Categorys;
use yii\helpers\Url;
use kartik\file\FileInput;
/* @var $this yii\web\View */
/* @var $model backend\models\Products */
/* @var $form yii\widgets\ActiveForm */
?>
<div class="photo-library-form">
<?php $form = ActiveForm::begin(['options'=>['enctype'=>'multipart/form-data']]); ?>
<?php $form->errorSummary($model) ?>
<?= $form->field($model, 'ref')->hiddenInput(['maxlength' => 100])->label(false); ?>
<?= $form->field($model, 'productName')->textInput(['maxlength' => true]) ?>
<?= $form->field($model, 'productDescription')->textarea(['rows' => 6]) ?>
<?= $form->field($model, 'productPrice')->textInput() ?>
<?=
$form->field($model, 'brandId')->widget(Select2::classname(), [
'data' => ArrayHelper::map(Brands::find()->where(['brandStatus'=>'active'])->all(),'brandId','brandName'),
'language' => 'en',
'options' => ['placeholder' => 'Select a brand ...'],
'pluginOptions' => [
'allowClear' => true
],
]);
?>
<?=
$form->field($model, 'categoryId')->widget(Select2::classname(), [
'data' => ArrayHelper::map(Categorys::find()->where(['categoryStatus'=>'active'])->all(),'categoryId','categoryName'),
'language' => 'en',
'options' => ['placeholder' => 'Select a category ...'],
'pluginOptions' => [
'allowClear' => true
],
]);
?>
<?= $form->field($model, 'productStatus')->dropDownList([ 'active' => 'Active', 'inactive' => 'Inactive', ], ['prompt' => 'Status']) ?>
<label>Product Images</label>
<?=
FileInput::widget([
'name' => 'upload_ajax[]',
//'attribute'=>'productImage[]',
//'name'=>'productImage[]',
'options' => [
'multiple'=>true,
'accept' => 'image/*',
//'id'=>'imageId',
],
'pluginOptions' => [
'initialPreview'=> $initialPreview,
'initialPreviewConfig'=> $initialPreviewConfig,
'showPreview' => true,
'showCaption' => false,
'showRemove' => false,
'showUpload' => false,
'uploadAsync' => false,
'uploadUrl'=>Url::to('index.php?r=products/upload-ajax'),
'deleteUrl'=>Url::to('index.php?r=products/deletefile-ajax'),
'maxFileCount' => 5,
'allowedFileExtensions' => ['jpg', 'png','jpeg'],
'previewFileType' => ['jpg', 'png','jpeg'],
'overwriteInitial'=>false,
'enableResumableUpload'=>true,
'uploadExtraData' => [
'ref'=>$model->ref
],
'validateInitialCount'=>true,
'initialPreviewShowDelete' => true,
'layoutTemplates'=>[
'actionZoom'=>'<button type="button" class="kv-file-zoom">{zoomIcon}</button>',
'actionUpload'=>'',
'actionDelete' => '<button type="button" class="kv-file-remove" title="{removeTitle}" {dataKey}{dataUrl}><i class="glyphicon glyphicon-trash"></i></button>'
],
],
'pluginEvents' => [
// 'filebatchselected' => 'function(files) {
// $(this).fileinput("index.php?r=products/upload-ajax");
// }',
'filepredelete'=>'function(jqXHR){
var abort = true;
if (confirm("Are you sure you want to delete this image?")) {
abort = false;
}
return abort;
}'
],
]);
?>
<br>
<div class="form-group">
<?= Html::submitButton($model->isNewRecord? 'Save': 'Update', ['class' => 'btn btn-primary']) ?>
<?= Html::a(Yii::t('app', 'Cancel'), ['index', 'id' => $model->productId], ['class'=>'btn btn-danger']) ?>
</div>
<?php ActiveForm::end(); ?>
</div>
productuctscontroller
private function getInitialPreview($ref) {
$datas = Uploads::find()->where(['ref'=>$ref])->all();
$initialPreview = [];
$initialPreviewConfig = [];
foreach ($datas as $key => $value) {
array_push($initialPreview, $this->getTemplatePreview($value));
array_push($initialPreviewConfig, [
'caption'=> $value->file_name,
'width' => '120px',
'url' => Url::to('index.php?r=products/deletefile-ajax'),
'key' => $value->upload_id
]);
}
return [$initialPreview,$initialPreviewConfig];
}