Yii Framework Forum: [SOLVED !!] Upload file to database - Yii Framework Forum

Jump to content

  • (2 Pages)
  • +
  • 1
  • 2
  • You cannot start a new topic
  • You cannot reply to this topic

[SOLVED !!] Upload file to database no more desperate... Rate Topic: -----

#21 User is offline   rozniy 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 26
  • Joined: 18-February 11

Posted 08 March 2011 - 11:00 AM

Grrr.... I can't make it work. Following Wiki example, trying to save a Photo attribute of the model Samples:

	<div class="row">
		<?php echo $form->labelEx($model,'Photo'); ?>
		
		<?php echo $form->fileField($model, 'Photo'); ?>
		<?php echo $form->error($model,'Photo'); ?>
	</div>


	
class Samples extends CActiveRecord
{
       public function rules()
	{
		// NOTE: you should only define rules for those attributes that
		// will receive user inputs.
          array('Photo,PhotoFilename', 'file', 'types'=>'jpg'),
        }


This beforeSave() is in the Model (which is called Samples in my app) I think? Or should it be in the Controller?
	public function beforeSave()
	{
		if($file=CUploadedFile::getInstance($this,'Photo'))

		$this->file_name=$file->name;
		$this->file_type=$file->type;
		$this->file_size=$file->size;
		$this->file_content=file_get_contents($file->tempName);
	
	
	
		
		
		}


in the COntroller:

	public function actionCreate()
	{
		$model=new Samples;

		// Uncomment the following line if AJAX validation is needed
		$this->performAjaxValidation($model);
	
		if(isset($_POST['Samples']))
		{
			
			$model->attributes=$_POST['Samples'];
			$model->Photo = CUploadedFile::getInstance($model, 'Photo');
			$model->PhotoFilename = CUploadedFile::getInstance($model, 'PhotoFilename');
			
			if($model->save())
				{
				
				mkdir('uploadedfiles/SampleID_' . strval($model->SampleID));
				$model->Photo->saveAs('uploadedfiles/SampleID_' . strval($model->SampleID) . '/' . $model->Photo);
				$model->PhotoFilename->saveAs('uploadedfiles/sampleID_' . strval($model->SampleID) . '/' . $model->PhotoFilename);

				$this->redirect(array('id'=>$model->SampleID));
				
				}
				
		}


All I'm getting is "Property "Samples.file_name" is not defined." I can upload a Photo onto server OK (by omitting the beforeSave code), but not blobbing into a table ( putting in the beforeSave code)... I've tried "$this->Photo_name=$file->name;" too. There must be something I'm not getting.

I am truly puzzled. Sorry if the example is supposed to be clear... :(
0

#22 User is offline   jkofsky 

  • Advanced Member
  • PipPipPip
  • Yii
  • Group: Members
  • Posts: 536
  • Joined: 17-May 10
  • Location:Pensacola, Florida

Posted 08 March 2011 - 02:26 PM

I have been looking for information on uploading a file and this thread seems to come the closest to what I want to do. However quit often replies (here or in Wiki) seem to assume certain knowledge levels that us newbies don't have yet :( This is not a criticism, just an observation. Although I try not to, I do it to sometimes when replying to posts on here. With that in mind, could those of you who answered in this thread correct me if I am wrong?

Given a SQLite3 database table:
CREATE TABLE [tbl_podcasts] ( 
   [ID]             INTEGER        PRIMARY KEY AUTOINCREMENT
                                   NOT NULL,
   [file_name]      VARCHAR( 48 )  NOT NULL,
   [file_type]      VARCHAR( 32 )  NOT NULL,
   [file_size]      INTEGER        NOT NULL DEFAULT ( 0 ),
);


In the Podcasts model:
class Podcasts extends CActiveRecord
{
    /**
     * Property for receiving the file from the form
     * It should be different from any other field in the database
     */
    public $uploadedFile;
    private $_audioFile=null;   //used to pass CUploadedFile() to afterSave() 

    public function rules()
    {
        return array(
            array('uploadedFile', 'file', 'types'=>'mp3, wav'),
        );

    public function getAttributeLabel(...)
    {
       ...
       'uploadedFile'=>'What file?',      // <-- Do I need to add this?
       ...
    }
  /**
    * Saves the name, size, type and data of the uploaded file
    */
    public function beforeSave()
    {
        if($_file=CUploadedFile::getInstance($this,'uploadedFile'))
        {
            $this->file_name=$_file->name;
            $this->file_type=$_file->type;
            $this->file_size=$_file->size;
            //Save the contents to database blob OR use afterSave() to save 
            // to filesystem.
            $this->file_content=file_get_contents($_file->tempName);
        }
        return parent::beforeSave();
    }
  /**
    * Saves the uploaded file to file if wanted
    */
    public function afterSave()
    {
        if($_file!==null)
        {
            $_file->saveAs(...);
        }
        return parent::afterSave();
    }
}


and the form/view would be:
<?php echo CHtml::form('','post',array('enctype'=>'multipart/form-data')); ?>
...
<div class="row">
<?php echo $form->labelEx($model,'uploadedFile'); ?>
<?php echo $form->fileField($model,'uploadedFile'); ?>
<?php echo $form->error($model,'uploadedFile'); ?>
</div>
...
<?php echo CHtml::endForm(); ?>


The above is a translation of what I understand from the various posting in this thread.

It looks like I need a separate/temp field name for the actual file upload from the db field name.
If saving to the filesystem, would it be MVC correct to it in the afterSave() of the model?
If I want to display the db file_name on the update form as an indicator of a file is already assigns, How? I think it would just be a $form->???label().

Does any of this make sense? Thanks in advanced.
Do, or do not. There is no 'try.' Jedi Master Yoda
0

#23 User is offline   birdwing 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 11
  • Joined: 02-May 11

Posted 20 May 2011 - 02:21 PM

This works fine, however it doesn't display the "incorrect file type" error message.

I have been fighting with it for a while now :huh:
0

#24 User is offline   birdwing 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 11
  • Joined: 02-May 11

Posted 20 May 2011 - 04:10 PM

Nevermind, I figured it out.

Apparently if you try and upload a file that is larger than your upload_max_filesize (as set in php.ini) then the file validator will not return ANY error messages.
0

#25 User is offline   jkofsky 

  • Advanced Member
  • PipPipPip
  • Yii
  • Group: Members
  • Posts: 536
  • Joined: 17-May 10
  • Location:Pensacola, Florida

Posted 02 June 2011 - 11:31 AM

View Postbirdwing, on 20 May 2011 - 04:10 PM, said:

Nevermind, I figured it out.

Apparently if you try and upload a file that is larger than your upload_max_filesize (as set in php.ini) then the file validator will not return ANY error messages.

I also ran into this problem. I changed the upload_max_filesize but was still not getting any thing. Then I found that the max_postsize (or something like that) also had to be increased. Then all worked. Just a heads up to check both.
Do, or do not. There is no 'try.' Jedi Master Yoda
0

#26 User is offline   krslynx 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 4
  • Joined: 18-July 11

Posted 27 July 2011 - 08:54 AM

View Postpc131, on 03 November 2010 - 01:54 AM, said:

Hi,

I used your code and now I don't get error that trying to work on non-object, but now I get that my cv_file_name (input for file) is blank. No matter if I use:

echo $form->fileField($model,'cv_file_name'); ?>


or:

echo CHtml::activeFileField($model, 'cv_file_name'); ?>


If I comment rule in my model:

array('cv_file_name', 'file', 'allowEmpty'=>false),


I also added to my form definition enctype html option:

<?php $form=$this->beginWidget('CActiveForm', array(
	'id'=>'candidate-form',
	'htmlOptions'=>array('enctype' => 'multipart/form-data'),
..................


I don't get this error but file is not saved to database. What is goin' on? :unsure:


Hi,

I've followed your Wiki example, however now I am getting an error 'Uploaded File cannot be blank.'

Attached File  Chitter - Create AbstractImageDev.jpg (22.53K)
Number of downloads: 17

I'm really unsure as to why this is occurring; my model and view are near exact to yours - have you made any changes to the controller?

Many thanks in advance,

krslynx
0

#27 User is offline   jowen 

  • Standard Member
  • PipPip
  • Yii
  • Group: Members
  • Posts: 191
  • Joined: 13-July 11
  • Location:Malaysia

Posted 28 July 2011 - 11:11 PM

hi guy,

what i need to write inside controller site if i wan save into database.

view site
<div class="row">
<?php echo $form->labelEx($model,'uploadedFile'); ?>
<?php echo $form->fileField($model,'uploadedFile'); ?>
<?php echo $form->error($model,'uploadedFile'); ?>
</div>

Model Site
class Candidate extends CActiveRecord
{

/* PROPERTY FOR RECEIVING THE FILE FROM FORM*/
public $uploadedFile;
/* MUST BE THE SAME AS FORM INPUT FIELD NAME*/

/**
*saves the name, size ,type and data of the uploaded file
*/
public function beforeSave()
{
if($file=CUploadedFile::getInstance($this,'uploadedFile'))
{

$this->cv_file_name=$file->name;
$this->cv_file_type=$file->type;
$this->cv_file_size=$file->size;
$this->cv_file_content=file_get_contents($file->tempName);

}

return parent::beforeSave();;

}


pls help.. i find the wiki is save the image to file folder and to show saved image only.
0

#28 User is offline   krslynx 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 4
  • Joined: 18-July 11

Posted 29 July 2011 - 05:39 PM

You'll need to create a Database schema that holds information in BLOB type - this will be where the content is stored. I've attached my Model, Controller and View so you can compare the code etcetera and figure things out ..

The SQL:

CREATE TABLE `tbl_abstract_img` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `chit_id` int(11) DEFAULT NULL,
  `create_time` datetime DEFAULT NULL,
  `create_user_id` int(11) DEFAULT NULL,
  `update_time` datetime DEFAULT NULL,
  `update_user_id` int(11) DEFAULT NULL,
  `file_name` varchar(128) DEFAULT NULL,
  `file_type` varchar(128) DEFAULT NULL,
  `file_size` int(11) DEFAULT NULL,
  `file_content` blob,
  PRIMARY KEY (`id`),
  UNIQUE KEY `id` (`id`),
  KEY `FK_abstract_img_chit` (`chit_id`),
  KEY `FK_abstract_img_author` (`create_user_id`),
  CONSTRAINT `FK_abstract_img_author` FOREIGN KEY (`create_user_id`) REFERENCES `tbl_user` (`id`),
  CONSTRAINT `FK_abstract_img_chit` FOREIGN KEY (`chit_id`) REFERENCES `tbl_chit` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 |


The View:
 
<div class="form">

<?php $form=$this->beginWidget('CActiveForm', array(
	'id'=>'abstract-image-form',
	'enableAjaxValidation'=>false,
        'htmlOptions'=>array(
            'enctype' => 'multipart/form-data',
        )
)); ?>

	<p class="note">Fields with <span class="required">*</span> are required.</p>

	<?php echo $form->errorSummary($model); ?>

        <div class="row">
            <?php echo $form->labelEx($model,'uploadedFile'); ?>
            <?php echo $form->fileField($model,'uploadedFile'); ?>
            <?php echo $form->error($model,'uploadedFile'); ?>
        </div>
        
	<div class="row buttons">
		<?php echo CHtml::submitButton($model->isNewRecord ? 'Create' : 'Save'); ?>
	</div>

<?php $this->endWidget(); ?>

</div><!-- form -->



The Model:
class AbstractImage extends CActiveRecord
{
    
        public $uploadedFile;
    
	/**
	 * Returns the static model of the specified AR class.
	 * @return AbstractImage the static model class
	 */
	public static function model($className=__CLASS__)
	{
		return parent::model($className);
	}

	/**
	 * @return string the associated database table name
	 */
	public function tableName()
	{
		return 'tbl_abstract_img';
	}

	/**
	 * @return array validation rules for model attributes.
	 */
	public function rules()
	{
		// NOTE: you should only define rules for those attributes that
		// will receive user inputs.
		return array(
			//array('chit_id, create_user_id, update_user_id, file_size', 'numerical', 'integerOnly'=>true),
			//array('file_name, file_type', 'length', 'max'=>128),
			//array('create_time, update_time, file_content', 'safe'),
			// The following rule is used by search().
			// Please remove those attributes that should not be searched.
			//array('id, chit_id, create_time, create_user_id, update_time, update_user_id, file_name, file_type, file_size, file_content', 'safe', 'on'=>'search'),
                        array('uploadedFile', 'file', 'allowEmpty'=>false, 'on' => 'insert'),
                        array('uploadedFile', 'file', 'allowEmpty'=>true, 'on' => 'update'),                    
                );
	}

	/**
	 * @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(
                    'createUser' => array(self::BELONGS_TO, 'User', 'create_user_id'),
                    'chit' => array(self::BELONGS_TO, 'Chit', 'chit_id'),
                    'author' => array(self::BELONGS_TO, 'User', 'create_user_id'),
		);
	}

	/**
	 * @return array customized attribute labels (name=>label)
	 */
	public function attributeLabels()
	{
		return array(
			'id' => 'ID',
			'chit_id' => 'Chit',
			'create_time' => 'Create Time',
			'create_user_id' => 'Create User',
			'update_time' => 'Update Time',
			'update_user_id' => 'Update User',
			'file_name' => 'File Name',
			'file_type' => 'File Type',
			'file_size' => 'File Size',
			'file_content' => 'File Content',
		);
	}

	/**
	 * Retrieves a list of models based on the current search/filter conditions.
	 * @return CActiveDataProvider the data provider that can return the models based on the search/filter conditions.
	 */
	public function search()
	{
		// Warning: Please modify the following code to remove attributes that
		// should not be searched.

		$criteria=new CDbCriteria;

		$criteria->compare('id',$this->id);
		$criteria->compare('chit_id',$this->chit_id);
		$criteria->compare('create_time',$this->create_time,true);
		$criteria->compare('create_user_id',$this->create_user_id);
		$criteria->compare('update_time',$this->update_time,true);
		$criteria->compare('update_user_id',$this->update_user_id);
		$criteria->compare('file_name',$this->file_name,true);
		$criteria->compare('file_type',$this->file_type,true);
		$criteria->compare('file_size',$this->file_size);
		$criteria->compare('file_content',$this->file_content,true);

		return new CActiveDataProvider($this, array(
			'criteria'=>$criteria,
		));
	}
        
        public function beforeSave()
        {
            $file=CUploadedFile::getInstance($this,'uploadedFile');
                if($file)
                {
                        $this->file_name=$file->name;
                        $this->file_type=$file->type;
                        $this->file_size=$file->size;
                        $this->file_content=file_get_contents($file->tempName);
                }
                
                if(!empty ($this->create_user_id)) {
                        $this->update_user_id=Yii::app()->user->id;
                        $this->update_time=date('Y-m-d H:i:s');
                }
                
                if(empty($this->create_user_id)) {
                        $this->create_user_id=Yii::app()->user->id;
                        $this->create_time=date('Y-m-d H:i:s');
                }
         
                
        return parent::beforeSave();
        }
}



The Controller:
<?php

class AbstractImageController 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
		);
	}

	/**
	 * 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','displaysavedimage'),
				'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'),
				'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)
	{
		$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 AbstractImage;

		// Uncomment the following line if AJAX validation is needed
		// $this->performAjaxValidation($model);

		if(isset($_POST['AbstractImage']))
		{
			$model->attributes=$_POST['AbstractImage'];
			if($model->save())
				$this->redirect(array('view','id'=>$model->id));
		}

		$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['AbstractImage']))
		{
			$model->attributes=$_POST['AbstractImage'];
			if($model->save())
				$this->redirect(array('view','id'=>$model->id));
		}

		$this->render('update',array(
			'model'=>$model,
		));
	}

	/**
	 * 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)->delete();

			// 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('AbstractImage');
		$this->render('index',array(
			'dataProvider'=>$dataProvider,
		));
	}

	/**
	 * Manages all models.
	 */
	public function actionAdmin()
	{
		$model=new AbstractImage('search');
		$model->unsetAttributes();  // clear any default values
		if(isset($_GET['AbstractImage']))
			$model->attributes=$_GET['AbstractImage'];

		$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 the ID of the model to be loaded
	 */
	public function loadModel($id)
	{
		$model=AbstractImage::model()->findByPk($id);
		if($model===null)
			throw new CHttpException(404,'The requested page does not exist.');
		return $model;
	}

	/**
	 * Performs the AJAX validation.
	 * @param CModel the model to be validated
	 */
	protected function performAjaxValidation($model)
	{
		if(isset($_POST['ajax']) && $_POST['ajax']==='abstract-image-form')
		{
			echo CActiveForm::validate($model);
			Yii::app()->end();
		}
	}
        
        public function actionDisplaySavedImage()
        {
            $model=$this->loadModel($_GET['id']);

            header('Pragma: public');
            header('Expires: 0');
            header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
            header('Content-Transfer-Encoding: binary');
            header('Content-length: '.$model->file_size);
            header('Content-Type: '.$model->file_type);
            header('Content-Disposition: attachment; filename='.$model->file_name);

                echo $model->file_content;
        }
}



I hope this helps.
1

#29 User is offline   ytannus 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 4
  • Joined: 06-October 08

Posted 08 August 2011 - 11:02 AM

Hi!,
What is the size of the uploaded file?
Try to remove
'allowEmpty'=>false



I had the same issue, but solved using beforeSave() method:

Model

Class myModel extends CActiveRecord
{
     public $uploadedFile;
     ...
     public function rules()
     {
          ...
          return array(
              ...
              array('uploadedFile','file'); //Note: not allowEmpty condition
          );
    }
    ...
    public function beforeSave()
    {
        if($_file=CUploadedFile::getInstance($this,'uploadedFile'))
        {
            $this->file_name=$_file->name;
            $this->file_type=$_file->type;
            $this->file_size=$_file->size;
            $this->file_content=file_get_contents($_file->tempName);
        }
        return parent::beforeSave();
    }

}



Controller

class myController extends Controller
{
    ...
    public function actionMyAction()
    {
        $model=new myModel;
        ...
        if($model->validate())
        {
            ...
            $model->save();
            ...
        }
        ...
    }
    ...
}

0

#30 User is offline   jowen 

  • Standard Member
  • PipPip
  • Yii
  • Group: Members
  • Posts: 191
  • Joined: 13-July 11
  • Location:Malaysia

Posted 09 August 2011 - 01:11 AM

hi,

i already remove my post cos not really related to it, change blob to mediumblob. blob only allow file <=60kb.

thank.
0

#31 User is offline   nsg 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 2
  • Joined: 12-July 13

Posted 12 July 2013 - 02:42 AM

I followed the way you did. But when i try to upload it says that the file field cannot be blanked.I have included my model and view contents here.

this is the View
<div class="form">

$model=new Mytbl;

<?php $form=$this->beginWidget('CActiveForm', array(
'id'=>'mytbl-form',
'enableAjaxValidation'=>false,
)); ?>

<p class="note">Fields with <span class="required">*</span> are required.</p>

<?php echo $form->errorSummary($model); ?>

<div class="row">
<?php echo $form->labelEx($model,'preview'); ?>
<?php echo $form->fileField($model,'preview'); ?>
<?php echo $form->error($model,'preview'); ?>
</div>

<div class="row buttons">
<?php echo CHtml::submitButton($model->isNewRecord ? 'Create' : 'Save'); ?>
</div>

<?php $this->endWidget(); ?>

</div><!-- form -->


My Model

<?php

class Mytbl extends CActiveRecord {

public $preview;

public static function model($className = __CLASS__) {
return parent::model($className);
}

public function tableName() {
return 'mytbl';
}

public function rules() {
return array(
array('preview', 'file', 'types' => 'png,jpg,gif'),
array('id, image', 'safe', 'on' => 'search'),
);
}

public function beforeSave() {
$file = CUploadedFile::getInstance($this, 'preview');
if (!$file->getHasError()) {

$this->image = file_get_contents($file->tempName);
}

return parent::beforeSave();
;
}

public function relations() {
return array(
);
}

public function attributeLabels() {
return array(
'id' => 'ID',
'image' => 'Image',
);
}

public function search() {
$criteria = new CDbCriteria;

$criteria->compare('id', $this->id);
$criteria->compare('image', $this->image, true);

return new CActiveDataProvider($this, array(
'criteria' => $criteria,
));
}

}
0

Share this topic:


  • (2 Pages)
  • +
  • 1
  • 2
  • You cannot start a new topic
  • You cannot reply to this topic

1 User(s) are reading this topic
0 members, 1 guests, 0 anonymous users