но вот косяк - при обновлении другого поля (не с картинкой) ссыль на картинку удаляется. понятно что $_POST['Item']['document'] приходит пустой, но что из-за этого затирать существущее? как победить?
D:\open\OpenServer\domains\localhost\mining\protected\modules\product\models\Item.php
Код: Выделить всё
<?php
/**
* This is the model class for table "tbl_item".
*
* The followings are the available columns in table 'tbl_item':
* @property integer $id
* @property string $title
* @property string $document
*/
class Item extends CActiveRecord
{
/**
* @return string the associated database table name
*/
public function tableName()
{
return 'tbl_item';
}
/**
* @return array validation rules for model attributes.
*/
public function rules()
{
return array(
array('title', 'required', 'on' => 'insert,update'),
array('document', 'file', 'types' => 'doc,docx,xls,xlsx,odt,pdf',
'allowEmpty' => true, 'on' => 'insert,update'),
// array('document', 'unsafe'),
);
}
/**
* @return array relational rules.
*/
public function relations()
{
// NOTE: you may need to adjust the relation name and the related
// class name for the relations automatically generated below.
return array(
);
}
/**
* @return array customized attribute labels (name=>label)
*/
public function attributeLabels()
{
return array(
'id' => 'ID',
'title' => 'Title',
'document' => 'Document',
);
}
/**
* Retrieves a list of models based on the current search/filter conditions.
*
* Typical usecase:
* - Initialize the model fields with values from filter form.
* - Execute this method to get CActiveDataProvider instance which will filter
* models according to data in model fields.
* - Pass data provider to CGridView, CListView or any similar widget.
*
* @return CActiveDataProvider the data provider that can return the models
* based on the search/filter conditions.
*/
public function search()
{
// @todo Please modify the following code to remove attributes that should not be searched.
$criteria = new CDbCriteria;
$criteria->compare('id', $this->id);
$criteria->compare('title', $this->title, true);
$criteria->compare('document', $this->document, true);
return new CActiveDataProvider($this, array(
'criteria' => $criteria,
));
}
/**
* Returns the static model of the specified AR class.
* Please note that you should have this exact method in all your CActiveRecord descendants!
* @param string $className active record class name.
* @return Item the static model class
*/
public static function model($className = __CLASS__)
{
return parent::model($className);
}
public function beforeSave()
{
if (!parent::beforeSave())
return false;
// echo '<pre>';
// var_dump(CUploadedFile::getInstance($this, 'document'));
//if (!is_null(CUploadedFile::getInstance($this, 'document') ))
// {
if (($this->scenario == 'insert' || $this->scenario == 'update') &&
($document = CUploadedFile::getInstance($this, 'document')))
{
$this->deleteDocument(); // старый документ удалим, потому что загружаем новый
$this->document = $document;
$this->document->saveAs(
Yii::getPathOfAlias('webroot.media') . DIRECTORY_SEPARATOR . $this->document);
// }
}
return true;
}
protected function beforeDelete()
{
if (!parent::beforeDelete())
return false;
$this->deleteDocument(); // удалили модель? удаляем и файл
return true;
}
public function deleteDocument()
{
$documentPath = Yii::getPathOfAlias('webroot.media') . DIRECTORY_SEPARATOR .
$this->document;
if (is_file($documentPath))
unlink($documentPath);
}
public function afterFind()
{
parent::afterFind();
}
public function defaultScope()
{
/*
//Example Scope
return array(
'condition'=>"deleted IS NULL ",
'order'=>'create_time DESC',
'limit'=>5,
);
*/
$scope = array();
return $scope;
}
}
D:\open\OpenServer\domains\localhost\mining\protected\modules\product\controllers\ItemController.php
Код: Выделить всё
<?php
class ItemController extends Controller
{
/**
* @var string the default layout for the views. Defaults to '//layouts/column2', meaning
* using two-column layout. See 'protected/views/layouts/column2.php'.
*/
public $layout = '//layouts/column2';
/**
* @return array action filters
*/
public function filters()
{
return array(
'accessControl', // perform access control for CRUD operations
'postOnly + delete', // we only allow deletion via POST request
);
}
/**
* Specifies the access control rules.
* This method is used by the 'accessControl' filter.
* @return array access control rules
*/
public function accessRules()
{
return array(
array('allow', // allow all users to perform 'index' and 'view' actions
'actions' => array('index', 'view', 'getfile'),
'users' => array('*'),
),
array('allow', // allow authenticated user to perform 'create' and 'update' actions
'actions' => array('create', 'update'),
'users' => array('@'),
),
array('allow', // allow admin user to perform 'admin' and 'delete' actions
'actions' => array('admin', 'delete', 'export', 'import', 'editable', 'toggle',),
'users' => array('admin'),
),
array('deny', // deny all users
'users' => array('*'),
),
);
}
/**
* Displays a particular model.
* @param integer $id the ID of the model to be displayed
*/
public function actionView($id)
{
if (isset($_GET['asModal']))
{
$this->renderPartial('view', array(
'model' => $this->loadModel($id),
));
}
else
{
$this->render('view', array(
'model' => $this->loadModel($id),
));
}
}
/**
* Creates a new model.
* If creation is successful, the browser will be redirected to the 'view' page.
*/
public function actionCreate()
{
$model = new Item;
// Uncomment the following line if AJAX validation is needed
// $this->performAjaxValidation($model);
if (isset($_POST['Item']))
{
$transaction = Yii::app()->db->beginTransaction();
try
{
$messageType = 'warning';
$message = "There are some errors ";
$model->attributes = $_POST['Item'];
//$uploadFile=CUploadedFile::getInstance($model,'filename');
if ($model->save())
{
$messageType = 'success';
$message = "<strong>Well done!</strong> You successfully create data ";
/*
$model2 = Item::model()->findByPk($model->id);
if(!empty($uploadFile)) {
$extUploadFile = substr($uploadFile, strrpos($uploadFile, '.')+1);
if(!empty($uploadFile)) {
if($uploadFile->saveAs(Yii::app()->basePath.DIRECTORY_SEPARATOR.'files'.DIRECTORY_SEPARATOR.'item'.DIRECTORY_SEPARATOR.$model2->id.DIRECTORY_SEPARATOR.$model2->id.'.'.$extUploadFile)){
$model2->filename=$model2->id.'.'.$extUploadFile;
$model2->save();
$message .= 'and file uploded';
}
else{
$messageType = 'warning';
$message .= 'but file not uploded';
}
}
}
*/
$transaction->commit();
Yii::app()->user->setFlash($messageType, $message);
$this->redirect(array('view', 'id' => $model->id));
}
}
catch (Exception $e)
{
$transaction->rollBack();
Yii::app()->user->setFlash('error', "{$e->getMessage()}");
//$this->refresh();
}
}
$this->render('create', array(
'model' => $model,
));
}
/**
* Updates a particular model.
* If update is successful, the browser will be redirected to the 'view' page.
* @param integer $id the ID of the model to be updated
*/
public function actionUpdate($id)
{
/* $model=$this->loadModel($id);
// Uncomment the following line if AJAX validation is needed
// $this->performAjaxValidation($model);
if(isset($_POST['Item']))
{
$messageType='warning';
$message = "There are some errors ";
$transaction = Yii::app()->db->beginTransaction();
try{
$model->attributes=$_POST['Item'];
$messageType = 'success';
$message = "<strong>Well done!</strong> You successfully update data ";
if($model->save()){
$transaction->commit();
Yii::app()->user->setFlash($messageType, $message);
$this->redirect(array('view','id'=>$model->id));
}
}
catch (Exception $e){
$transaction->rollBack();
Yii::app()->user->setFlash('error', "{$e->getMessage()}");
// $this->refresh();
}
$model->attributes=$_POST['Item'];
if($model->save())
$this->redirect(array('view','id'=>$model->id));
}
$this->render('update',array(
'model'=>$model,
));
*/
// в зависимости от аргумента создаем модель или ищем уже существующую
if ($id === null)
$model = new Item();
else if (!$model = Item::model()->findByPk($id))
throw new CHttpException(404);
if (isset($_POST['Item']))
{
//var_dump($_POST['Item']);
$model->attributes = $_POST['Item'];
// echo '<pre>';
// var_dump($model);
if (empty($_POST['Item']['document'])) $model->document = Item::model()->findByPk($id)->document;
//echo '<pre>';
//var_dump(Item::model()->findByPk($id));
if ($model->save())
{
// отображаем успешное сообщение, обновляем страницу
// или перенаправляем куда-либо ещё
// $this->refresh();
$this->redirect(array('admin'));
}
}
$this->render('update', array('model' => $model));
}
public function actionGetFile($id)
{
if ($id !== NULL) {
// некоторая логика по обработке пути из url в путь до файла на сервере
$currentFile = Yii::getPathOfAlias('webroot.media') . DIRECTORY_SEPARATOR.$id ;
$str=strpos($id, ".");
$row=substr($row, 0, $str);
if (is_file($currentFile)) {
header("Content-Type: application/octet-stream");
header("Accept-Ranges: bytes");
header("Content-Length: " . filesize($currentFile));
header("Content-Disposition: attachment; filename=" . $row);
readfile($currentFile);
};
} else {
$this->redirect('admin');
};
}
/**
* Deletes a particular model.
* If deletion is successful, the browser will be redirected to the 'admin' page.
* @param integer $id the ID of the model to be deleted
*/
public function actionDelete($id)
{
if (Yii::app()->request->isPostRequest)
{
// we only allow deletion via POST request
$this->loadModel($id)->deleteByPk($id);
// if AJAX request (triggered by deletion via admin grid view), we should not redirect the browser
if (!isset($_GET['ajax']))
$this->redirect(isset($_POST['returnUrl']) ? $_POST['returnUrl'] : array('admin'));
}
else
throw new CHttpException(400, 'Invalid request. Please do not repeat this request again.');
}
/**
* Lists all models.
*/
public function actionIndex()
{
/*
$dataProvider=new CActiveDataProvider('Item');
$this->render('index',array(
'dataProvider'=>$dataProvider,
));
*/
$model = new Item('search');
$model->unsetAttributes(); // clear any default values
if (isset($_GET['Item']))
$model->attributes = $_GET['Item'];
$this->render('index', array(
'model' => $model,
));
}
/**
* Manages all models.
*/
public function actionAdmin()
{
$model = new Item('search');
$model->unsetAttributes(); // clear any default values
if (isset($_GET['Item']))
$model->attributes = $_GET['Item'];
$this->render('admin', array(
'model' => $model,
));
}
/**
* Returns the data model based on the primary key given in the GET variable.
* If the data model is not found, an HTTP exception will be raised.
* @param integer $id the ID of the model to be loaded
* @return Item the loaded model
* @throws CHttpException
*/
public function loadModel($id)
{
$model = Item::model()->findByPk($id);
if ($model === null)
throw new CHttpException(404, 'The requested page does not exist.');
return $model;
}
/**
* Performs the AJAX validation.
* @param Item $model the model to be validated
*/
protected function performAjaxValidation($model)
{
if (isset($_POST['ajax']) && $_POST['ajax'] === 'item-form')
{
echo CActiveForm::validate($model);
Yii::app()->end();
}
}
public function actionExport()
{
$model = new Item;
$model->unsetAttributes(); // clear any default values
if (isset($_POST['Item']))
$model->attributes = $_POST['Item'];
$exportType = $_POST['fileType'];
$this->widget('ext.heart.export.EHeartExport', array(
'title' => 'List of Item',
'dataProvider' => $model->search(),
'filter' => $model,
'grid_mode' => 'export',
'exportType' => $exportType,
'columns' => array(
'id',
'title',
'document',
),
));
}
/**
* Creates a new model.
* If creation is successful, the browser will be redirected to the 'view' page.
*/
public function actionImport()
{
$model = new Item;
// Uncomment the following line if AJAX validation is needed
// $this->performAjaxValidation($model);
if (isset($_POST['Item']))
{
if (!empty($_FILES))
{
$tempFile = $_FILES['Item']['tmp_name']['fileImport'];
$fileTypes = array('xls', 'xlsx'); // File extensions
$fileParts = pathinfo($_FILES['Item']['name']['fileImport']);
if (in_array(@$fileParts['extension'], $fileTypes))
{
Yii::import('ext.heart.excel.EHeartExcel', true);
EHeartExcel::init();
$inputFileType = PHPExcel_IOFactory::identify($tempFile);
$objReader = PHPExcel_IOFactory::createReader($inputFileType);
$objPHPExcel = $objReader->load($tempFile);
$sheetData = $objPHPExcel->getActiveSheet()->toArray(null, true, true, true);
$baseRow = 2;
$inserted = 0;
$read_status = false;
while (!empty($sheetData[$baseRow]['A']))
{
$read_status = true;
//$id= $sheetData[$baseRow]['A'];
$title = $sheetData[$baseRow]['B'];
$document = $sheetData[$baseRow]['C'];
$model2 = new Item;
//$model2->id= $id;
$model2->title = $title;
$model2->document = $document;
try
{
if ($model2->save())
{
$inserted++;
}
}
catch (Exception $e)
{
Yii::app()->user->setFlash('error', "{$e->getMessage()}");
//$this->refresh();
}
$baseRow++;
}
Yii::app()->user->setFlash('success', ($inserted) . ' row inserted');
}
else
{
Yii::app()->user->setFlash('warning', 'Wrong file type (xlsx, xls, and ods only)');
}
}
$this->render('admin', array(
'model' => $model,
));
}
else
{
$this->render('admin', array(
'model' => $model,
));
}
}
public function actionEditable()
{
Yii::import('bootstrap.widgets.TbEditableSaver');
$es = new TbEditableSaver('Item');
$es->update();
}
public function actions()
{
return array(
'toggle' => array(
'class' => 'bootstrap.actions.TbToggleAction',
'modelName' => 'Item',
)
);
}
}
Код: Выделить всё
<?php $form=$this->beginWidget('CActiveForm',array(
'htmlOptions'=>array('enctype'=>'multipart/form-data'),
)); ?>
<?php /* текстовое поле названия элемента */ ?>
<div class="field">
<?php echo $form->labelEx($model,'title'); ?>
<?php echo $form->textField($model,'title'); ?>
<?php echo $form->error($model,'title'); ?>
</div>
<?php /* поле для загрузки файла */ ?>
<div class="field">
<?php if($model->document): ?>
<p><?php echo CHtml::encode($model->document); ?></p>
<?php endif; ?>
<?php echo $form->labelEx($model,'document'); ?>
<?php echo $form->fileField($model,'document'); ?>
<?php echo $form->error($model,'document'); ?>
</div>
<?php /* кнопка отправки */ ?>
<div class="button">
<?php echo CHtml::submitButton($model->isNewRecord ? 'Создать' : 'Сохранить'); ?>
</div>
<?php $this->endWidget(); ?>