Grid View Fetches all records in Yii - php

I am new to Yii. I have did a normal query operation by fixing a criteria in my action. My Grid view fetches particular records from the criteria query, but if I click on second page, it displays all the records again. Please help me in this. I have been stuck here so long. Thanks in advance.
My View:
<div class="form">
<?php $form=$this->beginWidget('CActiveForm', array(
'id'=>'nimsoft-alerts-form',
'enableAjaxValidation'=>false,
)); ?>
<h1>Missing Hosts List</h1>
<?php //echo $form->errorSummary($model); ?>
<div style="float:left;">
<div class="row">
<?php echo $form->labelEx($model,'host_start_date'); ?>
<?php
Yii::import('application.extensions.CJuiDateTimePicker.CJuiDateTimePicker');
$this->widget('CJuiDateTimePicker', array(
'attribute' => 'host_start_date',
'language' => '',
'model' => $model,
'options' => array(
'mode' => 'focus',
'dateFormat' => 'yy-mm-dd',
//'minDate'=>'0',
'showAnim' => 'slideDown',
),
'htmlOptions' => array(
'style'=>'height:20px;',
'value' => $model->host_start_date,
),
));
?>
<?php echo $form->error($model,'host_start_date'); ?>
</div>
</div><div style="float:left;"> </div>
<div style="float:left;">
<div class="row">
<?php echo $form->labelEx($model,'host_end_date'); ?>
<?php
Yii::import('application.extensions.CJuiDateTimePicker.CJuiDateTimePicker');
$this->widget('CJuiDateTimePicker', array(
'attribute' => 'host_end_date',
'language' => '',
'model' => $model,
'options' => array(
'mode' => 'focus',
'dateFormat' => 'yy-mm-dd',
//'minDate'=>'0',
'showAnim' => 'slideDown',
),
'htmlOptions' => array(
'style'=>'height:20px;',
'value' => $model->host_end_date,
),
));
?>
<?php echo $form->error($model,'host_end_date'); ?>
</div>
</div>
<div class="row buttons">
<?php echo CHtml::button('Search',array('submit' => array('Site/index')));?>
</div>
<?php $this->endWidget(); ?>
<?php //zii.widgets.grid.CGridView
$this->widget('zii.widgets.grid.CGridView', array(
'dataProvider'=>$dataProvider,
'enableSorting' => false,
'columns'=>array(
array( // display 'create_time' using an expression
'name'=>'alert_device',
'value'=>'$data->alert_device',
),
array( // display 'create_time' using an expression
'name'=>'alert_event_time',
'value'=>'$data->alert_event_time',
),
array( // display 'create_time' using an expression
'name'=>'alert_datetime',
'value'=>'$data->alert_datetime',
),
),
//'itemView'=>'_view',
));
?>
</div>
My Action:
public function actionIndex()
{
$model=new NimsoftAlerts;
if(isset($_POST['NimsoftAlerts']))
{
$model->attributes=$_POST['NimsoftAlerts'];
$params=array(
'host_start_date'=>$model->host_start_date,
'host_end_date'=>$model->host_end_date,
);
if($model->validate())
{
$criteria = new CDbCriteria();
$criteria->condition = "alert_datetime >= '$model->host_start_date' and alert_datetime <= '$model->host_end_date' and alert_itsm_ack_status IS NULL";
$details = NimsoftAlerts::model()->findAll($criteria);
$dataProvider=new CActiveDataProvider('NimsoftAlerts',array(
'criteria' => $criteria,
'pagination'=>array(
'params'=>$params,
),
'sort'=>array(
'params'=>$params,
'attributes'=>array('host_start_date','host_end_date'),
),
));
}
else
$dataProvider=new CActiveDataProvider('NimsoftAlerts');
}
else
$dataProvider=new CActiveDataProvider('NimsoftAlerts',array(
'pagination'=>array(
'params'=>$params,
),
'sort'=>array(
'params'=>$params,
'attributes'=>array('host_start_date','host_end_date'),
),
));
if($_REQUEST['isXLSDownload']=='1')
{
$xlsName='Missing_Host_Details_'.date('YmdHis').'.xls';
$sheetName='Missing Host Details';
$headerTxt='Host Details';
$arrTh=array(
'alert_device'=>array('label'=>'Alert Device'),
'alert_event_time'=>array('label'=>'Alert Event Time'),
'alert_datetime'=>array('label'=>'Alert Datetime'),
);
$this->generateCXLS($xlsName,$sheetName,$criteria,$model,$headerTxt,$arrTh);
}
$viewNimsoftTktSts = $model->dispNimsoftTktSts();
$this->render('index',array(
'viewNimsoftTktSts'=>$viewNimsoftTktSts,
'dataProvider'=>$dataProvider,
'model'=>$model,
));
}
My model:
<?php
/**
* This is the model class for table "mst_nimsoft_alerts".
*
* The followings are the available columns in table 'mst_nimsoft_alerts':
* #property string $alert_id
* #property string $alert_id_nimsoft
* #property string $alert_subject
* #property string $alert_message
* #property string $alert_severity
* #property string $alert_device
* #property string $alert_ip_address
* #property string $alert_status
* #property string $alert_monitor_type
* #property string $alert_instance
* #property string $alert_attribute
* #property string $alert_value
* #property string $alert_event_time
* #property string $alert_probe
* #property string $alert_datetime
* #property string $alert_itsm_ack
* #property string $alert_itsm_ack_status
* #property string $alert_itsm_ack_datetime
* #property string $alert_itsm_ticketnumber
*/
class NimsoftAlerts extends CActiveRecord
{
public $host_start_date;
public $host_end_date;
/**
* #return string the associated database table name
*/
public function tableName()
{
return 'mst_nimsoft_alerts';
}
/**
* #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('host_start_date,host_end_date', 'required'),
array('host_end_date','compare','compareAttribute'=>'host_start_date','operator'=>'>', 'allowEmpty'=>false,'message'=>'{attribute} must be greater than "{compareValue}".'),
array('alert_id_nimsoft, alert_ip_address, alert_probe', 'length', 'max'=>220),
array('alert_device, alert_status, alert_monitor_type, alert_instance, alert_attribute, alert_value, alert_event_time', 'length', 'max'=>250),
array('alert_itsm_ack', 'length', 'max'=>1),
array('alert_itsm_ack_status', 'length', 'max'=>4),
array('alert_itsm_ticketnumber', 'length', 'max'=>255),
//array('alert_subject, alert_message, alert_severity, alert_datetime, alert_itsm_ack_datetime,host_start_date,host_end_date', 'safe'),
// The following rule is used by search().
// #todo Please remove those attributes that should not be searched.
array('alert_id, alert_id_nimsoft, alert_subject, alert_message, alert_severity, alert_device, alert_ip_address, alert_status, alert_monitor_type, alert_instance, alert_attribute, alert_value, alert_event_time, alert_probe, alert_datetime, alert_itsm_ack, alert_itsm_ack_status, alert_itsm_ack_datetime, alert_itsm_ticketnumber,host_start_date,host_end_date', 'safe', 'on'=>'search'),
);
}
/**
* #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(
'alert_id' => 'Alert',
'alert_id_nimsoft' => 'Alert Id Nimsoft',
'alert_subject' => 'Alert Subject',
'alert_message' => 'Alert Message',
'alert_severity' => 'Alert Severity',
'alert_device' => 'Alert Device',
'alert_ip_address' => 'Alert Ip Address',
'alert_status' => 'Alert Status',
'alert_monitor_type' => 'Alert Monitor Type',
'alert_instance' => 'Alert Instance',
'alert_attribute' => 'Alert Attribute',
'alert_value' => 'Alert Value',
'alert_event_time' => 'Alert Event Time',
'alert_probe' => 'Alert Probe',
'alert_datetime' => 'Alert Datetime',
'alert_itsm_ack' => 'Alert Itsm Ack',
'alert_itsm_ack_status' => 'Alert Itsm Ack Status',
'alert_itsm_ack_datetime' => 'Alert Itsm Ack Datetime',
'alert_itsm_ticketnumber' => 'Alert Itsm Ticketnumber',
'host_start_date'=>'Start date',
'host_end_date'=>'End Date',
);
}
/**
* 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 dispNimsoftTktSts()
{
$criteria = new CDbCriteria;
$criteria->select='alert_datetime,alert_itsm_ack_status,alert_itsm_ticketnumber,alert_itsm_ack_datetime';
$criteria->limit = 3;
$criteria->order='alert_datetime DESC';
$dispLimit=$this->findAll($criteria);
return $dispLimit;
}
public function searchForAutoTickets()
{
// #todo Please modify the following code to remove attributes that should not be searched.
$criteria=new CDbCriteria;
$criteria->compare('alert_id',$this->alert_id,true);
$criteria->compare('alert_id_nimsoft',$this->alert_id_nimsoft,true);
$criteria->compare('alert_subject',$this->alert_subject,true);
$criteria->compare('alert_message',$this->alert_message,true);
$criteria->compare('alert_severity',$this->alert_severity,true);
$criteria->compare('alert_device',$this->alert_device,true);
$criteria->compare('alert_ip_address',$this->alert_ip_address,true);
$criteria->compare('alert_status',$this->alert_status,true);
$criteria->compare('alert_monitor_type',$this->alert_monitor_type,true);
$criteria->compare('alert_instance',$this->alert_instance,true);
$criteria->compare('alert_attribute',$this->alert_attribute,true);
$criteria->compare('alert_value',$this->alert_value,true);
$criteria->compare('alert_event_time',$this->alert_event_time,true);
$criteria->compare('alert_probe',$this->alert_probe,true);
$criteria->compare('alert_datetime',$this->alert_datetime,true);
$criteria->compare('alert_itsm_ack',$this->alert_itsm_ack,true);
$criteria->compare('alert_itsm_ack_status',$this->alert_itsm_ack_status,true);
$criteria->compare('alert_itsm_ack_datetime',$this->alert_itsm_ack_datetime,true);
$criteria->compare('alert_itsm_ticketnumber',$this->alert_itsm_ticketnumber,true);
$criteria->limit = 10;
$criteria->order='alert_datetime DESC';
return new CActiveDataProvider($this, array(
'criteria'=>$criteria,
"pagination" => false
));
}
public function search()
{
// #todo Please modify the following code to remove attributes that should not be searched.
$criteria=new CDbCriteria;
$criteria->compare('alert_id',$this->alert_id,true);
$criteria->compare('alert_id_nimsoft',$this->alert_id_nimsoft,true);
$criteria->compare('alert_subject',$this->alert_subject,true);
$criteria->compare('alert_message',$this->alert_message,true);
$criteria->compare('alert_severity',$this->alert_severity,true);
$criteria->compare('alert_device',$this->alert_device,true);
$criteria->compare('alert_ip_address',$this->alert_ip_address,true);
$criteria->compare('alert_status',$this->alert_status,true);
$criteria->compare('alert_monitor_type',$this->alert_monitor_type,true);
$criteria->compare('alert_instance',$this->alert_instance,true);
$criteria->compare('alert_attribute',$this->alert_attribute,true);
$criteria->compare('alert_value',$this->alert_value,true);
$criteria->compare('alert_event_time',$this->alert_event_time,true);
$criteria->compare('alert_probe',$this->alert_probe,true);
$criteria->compare('alert_datetime',$this->alert_datetime,true);
$criteria->compare('alert_itsm_ack',$this->alert_itsm_ack,true);
$criteria->compare('alert_itsm_ack_status',$this->alert_itsm_ack_status,true);
$criteria->compare('alert_itsm_ack_datetime',$this->alert_itsm_ack_datetime,true);
$criteria->compare('alert_itsm_ticketnumber',$this->alert_itsm_ticketnumber,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 NimsoftAlerts the static model class
*/
public static function model($className=__CLASS__)
{
return parent::model($className);
}
}

This can be fixed using 'get' for form method instead of the 'post' method you seem to have used.
<div class="form">
<?php $form=$this->beginWidget('CActiveForm', array(
'method' => 'get',
'id'=>'nimsoft-alerts-form',
'enableAjaxValidation'=>false,
)); ?>
And in your action use the following instead of $_POST variables:
$_GET['NimsoftAlerts']

Related

Add a textinput which does not belong to the same model in yii2

I have a table production with 3 fields productname,batchno,qty. The data productname,batchno I get is from productbatch model. I can insert it clearly. Now I want to insert into table "bottle" with 3 fields bottlename, productname, qty. Productname has relation with bottlename. And the data comes from model productnames. I want to load bottlename whenever I select productname. I can populate the data and can see in firebug. What I want is to add a textinput in the production form and display the bottlename in the same form.
Production Controller
public function actionCreate()
{
$model = new Production();
$productname = new Productnames();
$bottle = new Bottle();
if ($model->load(Yii::$app->request->post()) && $productname->load(Yii::$app->request->post()))
{
$model->save();
//$bottle->attributes = $model->attributes;
$bottle->usedate = $model->productiondate;
$bottle->useqty = $model->prodqty;
$bottle->productname = $model->productname;
$bottle->bottlename = $productname->bottletype;
// $employee->emp_email = $model->emp_email;
// $employee->emp_mobile = $model->emp_mobile;
$bottle->save();
return $this->redirect(['create']);
} else {
return $this->render('create', [
'model' => $model,
'bottle' => $bottle,
]);
}
}
Production _form
<div class="production-form">
<?php $form = ActiveForm::begin(); ?>
<!--<?= Html::a('Select Product', ['/production/productbatch/index'], ['class'=>'btn btn-primary']) ?> -->
<?= $form->field($model, 'productiondate')->widget(
DatePicker::className(), [
// inline too, not bad
'inline' => false,
// modify template for custom rendering
//'template' => '<div class="well well-sm" style="background-color: #fff; width:250px">{input}</div>',
'clientOptions' => [
'autoclose' => true,
'format' => 'yyyy-mm-dd'
]
]);?>
<!-- echo CHtml::button("(+)",array('title'=>"Select Product",'onclick'=>'js:selectproductforproduction();')); -->
<?= $form->field($model, 'productname')->widget(Select2::classname(), [
'data' => ArrayHelper::map(Productnames::find()->all(),'productnames_productname','productnames_productname'),
'language' => 'en',
'options' => ['placeholder' => 'Select Product Name', 'id' => 'catid'],
'pluginOptions' => [
'allowClear' => true
],
]); ?>
<?= $form->field($model, 'batchno')->widget(DepDrop::classname(), [
'options'=>['id'=>'subcat-id'],
'pluginOptions'=>[
'depends'=>['catid'],
'placeholder'=>'Select BatchNo',
'url'=>Url::to(['/production/productbatch/subcat'])
]
]); ?>
<?= $form->field($model, 'prodqty')->textInput() ?>
<?= $form->field($productname, 'bottlename')->textInput() ?>
<div class="form-group">
<?= Html::submitButton($model->isNewRecord ? 'Create' : 'Update', ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
</div>
<?php ActiveForm::end(); ?>
</div>
The error I'm getting is -
Productnames Model -
<?php
namespace frontend\modules\production\models;
use Yii;
/**
* This is the model class for table "productnames".
*
* #property integer $productid
* #property string $company
* #property string $type
* #property string $productnames_productname
* #property integer $inventory
* #property string $unitrmcost
* #property string $unitlabelcost
* #property string $unitcartonecost
* #property string $productnames_labelname
* #property string $productnames_cartonename
* #property string $bottletype
* #property string $captype
*
* #property Productbatch[] $productbatches
* #property Production[] $productions
* #property Bottlename $bottletype0
* #property Capname $captype0
* #property Cartonename $productnamesCartonename
* #property Labelname $productnamesLabelname
* #property Productsales[] $productsales
*/
class Productnames extends \yii\db\ActiveRecord
{
/**
* #inheritdoc
*/
public static function tableName()
{
return 'productnames';
}
/**
* #inheritdoc
*/
public function rules()
{
return [
[['company', 'type', 'productnames_productname'], 'required'],
[['inventory'], 'integer'],
[['company'], 'string', 'max' => 40],
[['type', 'unitrmcost', 'unitlabelcost', 'unitcartonecost'], 'string', 'max' => 10],
[['productnames_productname', 'productnames_labelname', 'productnames_cartonename'], 'string', 'max' => 60],
[['bottletype', 'captype'], 'string', 'max' => 50],
[['productnames_productname'], 'unique']
];
}
/**
* #inheritdoc
*/
public function attributeLabels()
{
return [
'productid' => 'Productid',
'company' => 'Company',
'type' => 'Type',
'productnames_productname' => 'Productnames Productname',
'inventory' => 'Inventory',
'unitrmcost' => 'Unitrmcost',
'unitlabelcost' => 'Unitlabelcost',
'unitcartonecost' => 'Unitcartonecost',
'productnames_labelname' => 'Productnames Labelname',
'productnames_cartonename' => 'Productnames Cartonename',
'bottletype' => 'Bottletype',
'captype' => 'Captype',
];
}
/**
* #return \yii\db\ActiveQuery
*/
public function getProductbatches()
{
return $this->hasMany(Productbatch::className(), ['productname' => 'productnames_productname']);
}
/**
* #return \yii\db\ActiveQuery
*/
public function getProductions()
{
return $this->hasMany(Production::className(), ['productname' => 'productnames_productname']);
}
/**
* #return \yii\db\ActiveQuery
*/
public function getBottletype0()
{
return $this->hasOne(Bottlename::className(), ['bottlename' => 'bottletype']);
}
/**
* #return \yii\db\ActiveQuery
*/
public function getCaptype0()
{
return $this->hasOne(Capname::className(), ['capname' => 'captype']);
}
/**
* #return \yii\db\ActiveQuery
*/
public function getProductnamesCartonename()
{
return $this->hasOne(Cartonename::className(), ['cartone_name' => 'productnames_cartonename']);
}
/**
* #return \yii\db\ActiveQuery
*/
public function getProductnamesLabelname()
{
return $this->hasOne(Labelname::className(), ['label_name' => 'productnames_labelname']);
}
/**
* #return \yii\db\ActiveQuery
*/
public function getProductsales()
{
return $this->hasMany(Productsales::className(), ['productname' => 'productnames_productname']);
}
}
You forgot to render productname to create view, so pass it.
return $this->render('create', [
'model' => $model,
'bottle' => $bottle,
'productname' => $productname,
]);
Here's variants. Either you use two model instances(current and related) and pass them to view http://www.yiiframework.com/doc-2.0/guide-input-multiple-models.html or add virtual attribute to current model http://www.yiiframework.com/doc-2.0/guide-input-forms.html.
you have use $model = new Production(); in view ..so you have to define productname in production class .like--
public function attributeLabels()
{
return [
'productname' => 'Product Name',
];
}
then check it ...

Yii2 rest api join query with ActiveDataProvider

I have a custom action in ActiveController and need to fetch some data by joining two tables.
I have written following query .
$query = Item::find()->joinWith(['subcategory'])->select(['item.*', 'sub_category.name'])->where(['item.active' => 1])->addOrderBy(['item.id' => SORT_DESC]);
$pageSize = (isset($_GET["limit"]) ? $_GET["limit"] : 1) * 10;
$page = isset($_GET["page"]) ? $_GET["page"] : 1;
$dataProvider = new ActiveDataProvider(['query' => $query, 'pagination' => ['pageSize' => $pageSize, "page" => $page]]);
$formatter = new ResponseFormatter();
return $formatter->formatResponse("", $dataProvider->getTotalCount(), $dataProvider->getModels());
but it is throwing an exception
"message": "Setting unknown property: common\\models\\Item::name",
Here is the item Model with all the fields and relation.
<?php
namespace common\models;
use Yii;
use yii\behaviors\TimestampBehavior;
use yii\db\BaseActiveRecord;
use yii\db\Expression;
/**
* This is the model class for table "item".
*
* #property integer $id
* #property integer $subcategory_id
* #property string $title
* #property resource $description
* #property integer $created_by
* #property integer $updated_by
* #property string $created_at
* #property string $updated_at
* #property string $image
* #property integer $active
*
* #property SubCategory $subcategory
*/
class Item extends \yii\db\ActiveRecord
{
public $imageFile;
/**
* #inheritdoc
*/
public static function tableName()
{
return 'item';
}
/**
* #inheritdoc
*/
public function rules()
{
return [
[['created_by', 'updated_by'], 'required'],
[['subcategory_id', 'created_by', 'updated_by', 'active'], 'integer'],
[['description'], 'string'],
[['created_at', 'updated_at'], 'safe'],
[['title', 'image'], 'string', 'max' => 999],
[['title'], 'unique'],
[['imageFile'], 'file', 'skipOnEmpty' => true, 'extensions' => 'png, jpg'],
];
}
/**
* #inheritdoc
*/
public function attributeLabels()
{
return [
'id' => 'ID',
'subcategory_id' => 'Subcategory ID',
'title' => 'Title',
'description' => 'Description',
'created_by' => 'Created By',
'updated_by' => 'Updated By',
'created_at' => 'Created At',
'updated_at' => 'Updated At',
'image' => 'Image',
'active' => 'Active',
'imageFile' => 'Image',
];
}
/**
* #return \yii\db\ActiveQuery
*/
public function getSubcategory()
{
return $this->hasOne(SubCategory::className(), ['id' => 'subcategory_id']);
}
/**
* #return \yii\db\ActiveQuery
*/
public function getCreatedBy()
{
return $this->hasOne(User::className(), ['id' => 'created_by']);
}
/**
* #return \yii\db\ActiveQuery
*/
public function getUpdatedBy()
{
return $this->hasOne(User::className(), ['id' => 'updated_by']);
}
public function behaviors()
{
return [
'timestamp' => [
'class' => TimestampBehavior::className(),
'attributes' => [
BaseActiveRecord::EVENT_BEFORE_INSERT => ['created_at', 'updated_at'],
BaseActiveRecord::EVENT_BEFORE_UPDATE => 'updated_at',
],
'value' => new Expression('NOW()'),
],
];
}
}
The joinWith makes a query using the joins requested, but result data are mapped in source model (in this case Item).
Since you have select(['item.*', 'sub_category.name']) , the framework will try to fill 'name' field of Item model, that does not exist and this generates the error.
According with documentation (http://www.yiiframework.com/doc-2.0/guide-rest-resources.html#overriding-extra-fields) you should have db relation subcategory populated from db, by default, but I don't see subcategory relation in your model.
So you have only to create subcategory relation in your model, such as:
public function getSubcategory() { return $this->hasOne(Subcategory::className(), ['id' => 'subcategory_id']); }
So you should solve your problem.
Other solution to have custom fields from more models could be:
1) Create a sql View (and from that create the Model) with fields that you want and pass it to ActiveDataProvide
2) Override extraFields method of the model (http://www.yiiframework.com/doc-2.0/yii-base-arrayabletrait.html#extraFields%28%29-detail)
Again, I suggest you to read this good article:
http://www.yiiframework.com/wiki/834/relational-query-eager-loading-in-yii-2-0/

Yii Image Upload not working on action Update

I am using YII Framework but when i update my information excluding image , it throw error that image type is not valid , even i have valid iamge type .
it throw error that
Please fix the following input errors:
Image cannot be blank.
Please choose correct file format
public function actionUpdate($id) {
$model = $this->loadModel($id);
$oldImage = $model->image;
if (isset($_POST['Product'])) {
$model->attributes = $_POST['Product'];
$rnd = rand(0, 9999); // generate random number between 0-9999
$uploadedFile = CUploadedFile::getInstance($model, 'image');
if (!empty($uploadedFile)) {
$fileName = "{$rnd}" . time() . "{$uploadedFile}"; // random number + file name
$model->image = $fileName;
$uploadedFile->saveAs(Yii::app()->basePath . '/../images/product/' . $fileName);
#unlink(Yii::app()->basePath . "\\..\\images\\product\\" . $oldImage);
} else {
$model->image = $oldImage;
}
if ($model->save())
$this->redirect(array('view', 'id' => $model->id));
}
$this->render('update', array(
'model' => $model,
));
}
and my _form file is below
<div class="form">
<?php
$form = $this->beginWidget('CActiveForm', array(
'id' => 'product-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, 'title'); ?>
<?php echo $form->textField($model, 'title', array('size' => 60, 'maxlength' => 256)); ?>
<?php echo $form->error($model, 'title'); ?>
</div>
<div class="row">
<?php
echo $form->labelEx($model, 'slug');
echo $form->textField($model, 'slug', array('size' => 60, 'maxlength' => 256));
echo $form->error($model, 'slug');
?>
</div>
<div class="row">
<?php
echo $form->labelEx($model, 'image');
echo CHtml::activeFileField($model, 'image');
echo $form->error($model, 'image');
?>
</div>
<?php if ($model->isNewRecord != '1') {
?>
<div class="row">
<?php echo CHtml::image(Yii::app()->request->baseUrl . '/images/product/' . $model->image, "image", array("width" => 200)); ?>
</div>
<?php } ?>
<div class="row">
<?php
echo $form->labelEx($model, 'status');
echo $form->dropDownList($model, 'status', array('active' => 'Active', 'inactive' => 'InActive'), array('empty' => 'Select Status'));
echo $form->error($model, 'status');
?>
</div>
<div class="row buttons">
<?php echo CHtml::submitButton($model->isNewRecord ? 'Create' : 'Save'); ?>
</div>
<?php $this->endWidget(); ?>
and my model is below
<?php
class Product extends CActiveRecord {
public function tableName() {
return 'products';
}
public function rules() {
// NOTE: you should only define rules for those attributes that
// will receive user inputs.
return array(
array('title, image, status', 'required'),
array('image', 'file', 'types' => 'jpg, gif, png', 'message' => 'Please choose correct file format'),
array('created_by, modified_by', 'numerical', 'integerOnly' => true),
array('title', 'length', 'max' => 256),
array('slug', 'length', 'max' => 256),
array('status', 'length', 'max' => 8),
array('image, created_at, modified_at', 'safe'),
// The following rule is used by search().
// #todo Please remove those attributes that should not be searched.
array('id, title, slug, image, status, created_at, created_by, modified_at, modified_by', 'safe', 'on' => 'search'),
);
}
/**
* #return array relational rules.
*/
public function relations() {
return array(
'productitems' => array(self::HAS_MANY, 'Productitems', 'proid'),
);
}
/**
* #return array customized attribute labels (name=>label)
*/
public function attributeLabels() {
return array(
'id' => 'ID',
'title' => 'Title',
'slug' => 'Slug',
'image' => 'Image',
'status' => 'Status',
'created_at' => 'Created At',
'created_by' => 'Created By',
'modified_at' => 'Modified At',
'modified_by' => 'Modified By',
);
}
/**
* 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('slug', $this->slug, true);
$criteria->compare('image', $this->image, true);
$criteria->compare('status', $this->status, true);
$criteria->compare('created_at', $this->created_at, true);
$criteria->compare('created_by', $this->created_by);
$criteria->compare('modified_at', $this->modified_at, true);
$criteria->compare('modified_by', $this->modified_by);
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 Product the static model class
*/
public static function model($className = __CLASS__) {
return parent::model($className);
}
}
You are using a CFileValidator for the field image in your Product class, and you are restricting the formats that can be uploaded, as it is written in the following line:
array('image', 'file', 'types' => 'jpg, gif, png', 'message' => 'Please choose correct file format'),
The problem you are having is that CFileValidator does not allow file fields to be empty by default, so you have to explicitly set the allowEmpty attribute of the rule to true.
That said, your rule should be written as follows:
array('image', 'file', 'types' => 'jpg, gif, png', 'allowEmpty' => true, 'message' => 'Please choose correct file format'),
You can see more about Model Rules Validation in the following link:
http://www.yiiframework.com/wiki/56/#hh12
Hope it helps.

How to upload file in Yii along with form data?

I'm stuck at a problem where in I need to upload two different files (e.g. one of type jpg and the other of the type pdf/epub) along with the additional form data.
The form data should be uploaded to a database along with the path of the files and the files should be saved inside a directory.
Any help would be appreciated.
BooksController.php
<?php
namespace backend\controllers;
use backend\models\Books;
use Yii;
use yii\data\ActiveDataProvider;
use yii\filters\VerbFilter;
use yii\web\Controller;
use yii\web\NotFoundHttpException;
use yii\web\UploadedFile;
/**
* BooksController implements the CRUD actions for Books model.
*/
class BooksController extends Controller
{
public function behaviors()
{
return [
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'delete' => ['post'],
],
],
];
}
/**
* Lists all Books models.
* #return mixed
*/
public function actionIndex()
{
$dataProvider = new ActiveDataProvider([
'query' => Books::find(),
]);
return $this->render('index', [
'dataProvider' => $dataProvider,
]);
}
/**
* Displays a single Books model.
* #param integer $id
* #return mixed
*/
public function actionView($id)
{
return $this->render('view', [
'model' => $this->findModel($id),
]);
}
/**
* Creates a new Books model.
* If creation is successful, the browser will be redirected to the 'view' page.
* #return mixed
*/
public function actionCreate()
{
$model = new Books();
$path = Yii::$app->basePath . '../../uploads/';
if (!is_dir($path)) {
mkdir($path);
}
if (Yii::$app->request->post()) {
$book_file = UploadedFile::getInstance($model, 'book');
$cover_file = UploadedFile::getInstance($model, 'cover');
$book_file->saveAs($path . $book_file->baseName . '.' . $book_file->extension);
$cover_file->saveAs($path . $book_file->baseName . '_' . $cover_file->baseName . '.' . $cover_file->extension);
return $this->redirect(['view', 'id' => $model->id]);
}
return $this->render('create', ['model' => $model]);
}
/**
* Updates an existing Books model.
* If update is successful, the browser will be redirected to the 'view' page.
* #param integer $id
* #return mixed
*/
public function actionUpdate($id)
{
$model = $this->findModel($id);
if ($model->load(Yii::$app->request->post()) && $model->save()) {
return $this->redirect(['view', 'id' => $model->id]);
} else {
return $this->render('update', [
'model' => $model,
]);
}
}
/**
* Deletes an existing Books model.
* If deletion is successful, the browser will be redirected to the 'index' page.
* #param integer $id
* #return mixed
*/
public function actionDelete($id)
{
$this->findModel($id)->delete();
return $this->redirect(['index']);
}
/**
* Finds the Books model based on its primary key value.
* If the model is not found, a 404 HTTP exception will be thrown.
* #param integer $id
* #return Books the loaded model
* #throws NotFoundHttpException if the model cannot be found
*/
protected function findModel($id)
{
if (($model = Books::findOne($id)) !== null) {
return $model;
} else {
throw new NotFoundHttpException('The requested page does not exist.');
}
}
}
Books.php (Model)
<?php
namespace backend\models;
use Yii;
/**
* This is the model class for table "books".
*
* #property integer $id
* #property string $title
* #property string $subtitle
* #property string $description
* #property string $author
* #property string $isbn
* #property integer $page
* #property string $year
* #property string $publisher
* #property string $cover
* #property string $link
*/
class Books extends \yii\db\ActiveRecord
{
public $book;
public $cover;
/**
* #inheritdoc
*/
public static function tableName()
{
return 'books';
}
/**
* #inheritdoc
*/
public function rules()
{
return [
[['title', 'page', 'cover', 'book'], 'required'],
[['description'], 'string'],
[['isbn', 'page'], 'integer'],
['year', 'date'],
[['title', 'subtitle', 'author', 'publisher'], 'string', 'max' => 255],
['book', 'file', 'extensions' => 'pdf, epub', 'maxSize' => 1024 * 1024 * 1024],
['cover', 'file', 'extensions' => 'jpg, jpeg, png', 'maxSize' => 1024 * 1024 * 10]
];
}
/**
* #inheritdoc
*/
public function attributeLabels()
{
return [
'id' => 'ID',
'title' => 'Title',
'subtitle' => 'Subtitle',
'description' => 'Description',
'author' => 'Author',
'isbn' => 'Isbn',
'page' => 'Page',
'year' => 'Year',
'publisher' => 'Publisher',
'cover' => 'Cover',
'book' => 'Book'
];
}
}
_form.php (View)
<?php
use yii\helpers\Html;
use yii\widgets\ActiveForm;
/* #var $this yii\web\View */
/* #var $model backend\models\Books */
/* #var $form yii\widgets\ActiveForm */
?>
<div class="books-form">
<?php $form = ActiveForm::begin(['options' => ['enctype' => 'multipart/form-data']]); ?>
<?= $form->field($model, 'title')->textInput(['maxlength' => 255]) ?>
<?= $form->field($model, 'subtitle')->textInput(['maxlength' => 255]) ?>
<?= $form->field($model, 'description')->textarea(['rows' => 6]) ?>
<?= $form->field($model, 'author')->textInput(['maxlength' => 255]) ?>
<?= $form->field($model, 'isbn')->textInput(['maxlength' => 13]) ?>
<?= $form->field($model, 'page')->textInput() ?>
<?= $form->field($model, 'year')->textInput() ?>
<?= $form->field($model, 'publisher')->textInput(['maxlength' => 255]) ?>
<?= $form->field($model, 'book')->fileInput() ?>
<?= $form->field($model, 'cover')->fileInput() ?>
<div class="form-group">
<?= Html::submitButton($model->isNewRecord ? 'Create' : 'Update', ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
</div>
<?php ActiveForm::end(); ?>
</div>
What exactly doesn't work – saving file into filesystem, o saving model attribute? It looks like you are not calling $model->save() in your actionCreate. Also if model attribute is named file and it is used to handle uploaded file here will be a problem when saving model. Probably you want to save only file name / file path to DB. In this case you need additional attributes to handle those values.
You can use CMultiFileUpload widget. See example in docs. And do not forget to add multipart/form-data to your form:
$form = $this->beginWidget('CActiveForm', array(
'id'=>'user-form',
'htmlOptions' => array( 'enctype' => 'multipart/form-data' ),
));
And file can be processed „along with the additional form data“. Also see CUploadedFile.

yii CActiveDataProvider or TbGridView do not work with pagination

I'm using Yii Booster TbGridView to show a DataProvider from CActiveDataProvider. It is functioning but not completely. I do not know what is going on with the pagination because when I select the other pages from the Grid, it does not return any record. It is strange because the pagination by default is 10 records, and the data is for example 33 records, the pagination creates 4 pages but I only can see the first 10 records and the others are not shown after I click on the number of the page I want to see. I only can see the first ten records.
Here's my code:
Action (Controller)
public function actionIndex() {
//Verificamos si es la primera vez que se corre la accion y asignamos fechas iniciales
if (!isset($_POST['FormGestionInformacion']['fechaDesde'])
&& !isset($_POST['FormGestionInformacion']['fechaDesde']) ){
$fechaHasta = date('Y-m-d');
$fechaDesde = date('Y-m-d',time()-(60*60*24*15));//Quince dias atras
} else {
$fechaHasta = $_POST['FormGestionInformacion']['fechaHasta'];
$fechaDesde = $_POST['FormGestionInformacion']['fechaDesde'];
}
//Verificamos si el usuario mando filtro, y armamos el WHERE a ver si esa palabra esta en alguna parte
$criteria = new CDbCriteria();
$criteria->alias = 's';
$criteria->select = 'c.fecha_creacion,
c.fecha_cierre,
s.caso_sistema_info,
s.sistema_informacion,
s.documentacion,
s.fecha_documentacion,
s.usuario,
s.tipo_documentacion,
s.tipo_protocolo';
$criteria->join = "INNER JOIN ".DB_USUARIOS.".soporte_casos c ON s.caso_sistema_info=c.caso_sistema_info";
$criteria->condition = "s.caso_sistema_info=c.caso_sistema_info and fecha_cierre>='"
.$fechaDesde." 00:00:00' and fecha_cierre<='".$fechaHasta." 23:59:59'";
$criteria->group = "s.caso_sistema_info";
$criteria->order = " s.caso_sistema_info";
$criteria->offset = 0;
if (isset($_POST['FormGestionInformacion']['filtro'])
&& $_POST['FormGestionInformacion']['filtro']!='') {
$filtro = $_POST['FormGestionInformacion']['filtro'];
$criteria->addCondition ("s.caso_sistema_info like '%$filtro%'
or s.sistema_informacion like '%$filtro%'
or s.usuario like '%$filtro%' or
s.tipo_documentacion like '%$filtro%'
or s.tipo_protocolo LIKE '%$filtro%'");
}
$dataProvider = new CActiveDataProvider('SoporteCasosDocumentacion', array(
'criteria' => $criteria,
'pagination' => array(
'pageSize' => 5,
),
)
);
$model = new FormGestionInformacion ();
$this->render('index', array(
'dataProvider' => $dataProvider,
'model'=> $model,
'fechaDesde'=>$fechaDesde,
'fechaHasta'=>$fechaHasta,
'filtro'=>$filtro,
)
);
}
Model:
class SoporteCasosDocumentacion extends CActiveRecord {
/**
* #return string the associated database table name
*/
public function tableName() {
return 'soporte_casos_documentacion';
}
/**
* #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('caso_sistema_info, sistema_informacion, usuario', 'required'),
array('fecha_documentacion, caso_sistema_info, sistema_informacion, usuario', 'length', 'max' => 45),
array('email, celular', 'length', 'max' => 50),
array('informacion_cliente_une', 'length', 'max' => 1),
array('archivo_adjunto, pro_det, sol_dad, ubi_fal, causa, ser_afe, con_aut, cor_ele', 'length', 'max' => 100),
array('tipo_documentacion, tipo_protocolo, tie_sol, tel_con, cel_con', 'length', 'max' => 10),
array('documentacion, error_oci', 'safe'),
// The following rule is used by search().
// #todo Please remove those attributes that should not be searched.
array('id_doc, fecha_documentacion, caso_sistema_info, sistema_informacion, documentacion, email, celular, informacion_cliente_une, usuario, archivo_adjunto, tipo_documentacion, tipo_protocolo, error_oci, pro_det, sol_dad, ubi_fal, causa, ser_afe, tie_sol, con_aut, cor_ele, tel_con, cel_con', 'safe', 'on' => 'search'),
);
}
/**
* #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_doc' => 'Id Doc',
'fecha_documentacion' => 'Fecha Documentacion',
'caso_sistema_info' => 'Caso Sistema Info',
'sistema_informacion' => 'Sistema Informacion',
'documentacion' => 'Documentacion',
'email' => 'Email',
'celular' => 'Celular',
'informacion_cliente_une' => 'Informacion Cliente Une',
'usuario' => 'Usuario',
'archivo_adjunto' => 'Archivo Adjunto',
'tipo_documentacion' => 'Tipo Documentacion',
'tipo_protocolo' => 'Tipo Protocolo',
'error_oci' => 'Error Oci',
'pro_det' => 'Pro Det',
'sol_dad' => 'Sol Dad',
'ubi_fal' => 'Ubi Fal',
'causa' => 'Causa',
'ser_afe' => 'Ser Afe',
'tie_sol' => 'Tie Sol',
'con_aut' => 'Con Aut',
'cor_ele' => 'Cor Ele',
'tel_con' => 'Tel Con',
'cel_con' => 'Cel Con',
);
}
/**
* 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_doc', $this->id_doc, true);
$criteria->compare('fecha_documentacion', $this->fecha_documentacion, true);
$criteria->compare('caso_sistema_info', $this->caso_sistema_info, true);
$criteria->compare('sistema_informacion', $this->sistema_informacion, true);
$criteria->compare('documentacion', $this->documentacion, true);
$criteria->compare('email', $this->email, true);
$criteria->compare('celular', $this->celular, true);
$criteria->compare('informacion_cliente_une', $this->informacion_cliente_une, true);
$criteria->compare('usuario', $this->usuario, true);
$criteria->compare('archivo_adjunto', $this->archivo_adjunto, true);
$criteria->compare('tipo_documentacion', $this->tipo_documentacion, true);
$criteria->compare('tipo_protocolo', $this->tipo_protocolo, true);
$criteria->compare('error_oci', $this->error_oci, true);
$criteria->compare('pro_det', $this->pro_det, true);
$criteria->compare('sol_dad', $this->sol_dad, true);
$criteria->compare('ubi_fal', $this->ubi_fal, true);
$criteria->compare('causa', $this->causa, true);
$criteria->compare('ser_afe', $this->ser_afe, true);
$criteria->compare('tie_sol', $this->tie_sol, true);
$criteria->compare('con_aut', $this->con_aut, true);
$criteria->compare('cor_ele', $this->cor_ele, true);
$criteria->compare('tel_con', $this->tel_con, true);
$criteria->compare('cel_con', $this->cel_con, true);
return new CActiveDataProvider($this, array(
'criteria' => $criteria,
));
}
/**
* #return CDbConnection the database connection used for this class
*/
public function getDbConnection() {
return Yii::app()->Usuarios;
}
/**
* 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 SoporteCasosDocumentacion the static model class
*/
public static function model($className = __CLASS__) {
return parent::model($className);
}
}
The Widget:
$this->widget('bootstrap.widgets.TbButton', array(
'buttonType' => 'button',
'type' => 'primary',
'label' => 'Consultar',
'size' => 'large',
'htmlOptions' => array(
'onClick' => '{ValidacionDatos()}',
'class' => 'btn'
),
));

Categories