I have create a action comment like this:
public function actionComment($id)
{
$text = CommentModel::find($id)->where(true)->all();
if (isset($_POST['name'])) {
$text = new CommentModel();
$text->name=$_POST['name'];
$text->comment=$_POST['comment'];
$text->i_post=$_POST['id_post'];
$text->save();
$this->redirect('comment',array('id'=>$text->id));
}
return $this->render('comment',array("text"=>$text));
}
and comment view is:
<h2>List of all comments:</h2>
<?php
foreach($text as $text[0]){
echo "name"." ".":"." ".$text[0]->name."<br>" ;
echo "comment"." ".":"." ".$text[0]->comment."<br>";
?>
my comment model is:
public function attributeLabels()
{
return [
'id' => 'ID',
'name' => 'Name',
'comment' => 'Comment',
'id-post' => 'Id Post',
];
}
how should i define id_pst in my project to each post has sepecific comment??
Related
I have a lot of fields generated from loops. I would like to validate them through validation rules (integer). I don't know how to throw so many fields with random names into the model to the rules () function. How can I validate fields without a model?
View:
<?= Html::input('number', 'file[' . $indexRow . ']' . '[' . $indexCell . ']', $cell, $options = ['class' => 'form-control', 'filter' => 'intval', 'integer']) ?>
Controller:
` public function actionEdit($fileName)
{
$siteHelper = new SiteHelper();
$editForm = new EditForm();
$preparedRows = $siteHelper->prepareRows($fileName);
$preparedHTML = '';
if (Yii::$app->request->isPost) {
$post = Yii::$app->request->post();
if (isset($post['file'])) {
$dataFile = $post['file'];
$preparedRows = $siteHelper->updateExcelFile($fileName, $dataFile);
Yii::$app->session->setFlash('success', 'Plik zostaĆ zaktualizowany!');
} else if (isset($post['EditForm'])) {
$events = $post['EditForm']['events'];
$preparedHTML = $siteHelper->prepareHTML($events, $preparedRows, $fileName);
Yii::$app->session->setFlash('success', 'Wygenerowano plik PDF!');
}
}
$viewParameters = [
'rows' => $preparedRows,
'editForm' => $editForm,
'scoreHTML' => $preparedHTML,
'downloadLink' => Url::toRoute(['site/download', 'fileName' => $fileName])
];
return $this->render('edit', $viewParameters);
}`
Model:
`
class EditForm extends Model
{
public $events;
public function rules()
{
return [
[['events'], 'required'],
['events', 'integer'],
];
}
}`
When you have an array you can use each validator:
https://www.yiiframework.com/doc/api/2.0/yii-validators-eachvalidator
The validation function should be:
public function rules()
{
return [
[['events'], 'each', 'rule' => ['required']],
[['events'], 'each', 'rule' => ['integer']],
];
}
You may need to avoid multidemnsional array in html and render the field like this:
<?= Html::input('number', 'file[' . $indexRow . '-' . $indexCell . ']', $cell, $options = ['class' => 'form-control', 'filter' => 'intval', 'integer']) ?>
later you can "explode" the row cell index (isn't it supposed to be col?) to identify the row and the column.
$rowCellIndecies = explode('-', $rowCellIndex);
explode function: https://www.php.net/manual/en/function.explode.php
I have these Model Classes
Model:Subject
public function attributeLabels()
{
return [
'subject_id' =>Yii::t('app', 'ID'),
'subject_title' => Yii::t('app', 'Subject Title'),
];
}
Model:Grouping
public function attributeLabels()
{
return [
'grouping_id' => Yii::t('app', 'Grouping ID'),
'grouping_name' => Yii::t('app', 'Grouping Name'),
];
}
Model:SubjectGrouping
public function attributeLabels()
{
return [
'subject_grouping_id' => 'Subject Grouping ID',
'subject_grouping_grouping_id' => 'Subject Grouping Grouping ID',
'subject_grouping_subject_id' => 'Subject Grouping Subject ID',
];
}
Model:Exam
public function attributeLabels()
{
return [
'exam_id' =>Yii::t('app', 'ID'),
'exam_name' => Yii::t('app', 'Exam Name'),
'exam_group_id' => Yii::t('app', 'Exam Group'),
];
}
Model:SubjectGrouping has Foreign Keys from Model: Grouping (subject_grouping_grouping_id) and Model:Subject (subject_grouping_subject_id)
In Model:Exam, exam_group_id relates to subject_grouping_grouping_id in Model:SubjectGrouping.
Controller
public function actionCreate()
{
$model = new Exam();
if (Yii::$app->request->isAjax && $model->load(Yii::$app->request->post())) {
\Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
return ActiveForm::validate($model);
}
if ($model->load(Yii::$app->request->post())) {
$model->attributes = $_POST['Exam'];
$model->save();
return $this->redirect(['index']);
} else {
return $this->render(
'create', [
'model' => $model
]
);
}
}
View
<div class="col-xs-12 col-sm-4 col-lg-4">
<?=$form->field($model, 'exam_name')->textInput(['maxlength' => 50, 'placeholder' => 'Enter Exam Name'])?>
</div>
<div class="col-xs-12 col-sm-4 col-lg-4">
<?=$form->field($model, 'exam_group_id')->widget(
Select2::classname(), [
'data' => ArrayHelper::map(app\models\Grouping::find()->all(), 'grouping_id', 'grouping_name'),
'language' => 'en',
'options' => ['placeholder' => '--- Select Grouping ---'],
'pluginOptions' => [
'allowClear' => true
]
]
);
?>
</div>
From the diagram, how do I achieve these?
when Dropdownlist for exam_group_id is onChange the list of subjects with respect to grouping is displayed using the relationship between Model: SubjectGrouping and Model: Subject.
Others fields such as exam_name (textInput) and exam_group_id (Dropdownlist) should be save into the Model: Exam. But the subject list should not be saved. It is only for display purpose.
How do I achieve these?
I am using kartik\widgets\Select2 for the dropdownlist
I have done similar code by Kartik extension for state and country data.
here is the code for that.
<?php
//in view use this
use kartik\widgets\DateTimePicker; // or kartik\select2\Select2
use kartik\widgets\DepDrop;
use kartik\widgets\Select2;
?>
<?php
echo
$form->field($model, 'country_id')->widget(
Select2::className(),
[
'data' => \yii\helpers\ArrayHelper::map(common\models\Country::find()->all(), 'id', 'name'),
'options' => [
'id' => 'country_id',
'prompt' => Yii::t('aspns', 'Select')
]
]
);
?>
<?php
echo
$form->field($model, 'state_id')->widget(
DepDrop::classname(),
[
'data' => !empty($model->state_id) ? \yii\helpers\ArrayHelper::map(common\models\State::find()->where(['country_id' => $model->country_id])->all(), 'id', 'name') : [],
'options' => ['id' => 'state_id', 'placeholder' => Yii::t('aspns', 'Select')],
'pluginOptions' => [
'depends' => ['country_id'],
'url' => Url::to(['//country/get-states'])
]
]
)->label(Yii::t('aspns', 'State'));
?>
// In Controller section you need to do this
public function actionGetStates() {
$out = [];
if (isset($_POST['depdrop_parents'])) {
$parents = $_POST['depdrop_parents'];
if ($parents != null) {
$country_id = (int)$parents[0];
$out = State::find()->where(['country_id'=>$country_id])->select(['id', 'name'=>'name'])->asArray()->all();
return Json::encode(['output'=>$out, 'selected'=>'']);
}
}
return Json::encode(['output'=>'', 'selected'=>'']);
}
Change the code according to your requirement.
Thanks
I am trying to add captcha validation based on scenario, for which I am first retrieving number of failed attempts from database. For which I am using checkattempts() function. Based on the result I am displaying captcha in view and adding scenario condition in controller as below.
In LoginForm model:
public function rules()
{
return [
[['username', 'password'], 'required', 'on'=>'loginpage'],
[['username', 'password'], 'required', 'on'=>'withCaptcha'],
[['reference_url'], 'safe'],
[['verifyCode'], 'captcha', 'skipOnEmpty' => true,'on'=>'withCaptcha'],
['username','email', 'on'=>'loginpage', 'message'=> 'Please enter a valid email address'],
['password', 'validatePassword', 'on'=>'loginpage'],
['password', 'validatePassword', 'on'=>'withCaptcha'],
];
}
public function checkattempts($uname)
{
$user = \frontend\models\User::findByEmail($uname);
$ip = $this->get_client_ip();
if($user){
$data = (new Query())->select('*')
->from('login_attempts')
->where(['ip' => $ip])->andWhere(['user_ref_id' => $user->id])
->one();
if($data["attempts"] >=3){
return true;
}else{
return false;
}
}
return false;
}
in SiteController.php controller
public function actionLogin() {
if (!\Yii::$app->user->isGuest) {
return $this->redirect(Yii::$app->getUrlManager()->getBaseUrl() . '/../../');
}
$model = new \common\models\LoginForm();
$model->scenario = 'loginpage';
$captcha = false;
if(Yii::$app->request->post()){
$post_variables =Yii::$app->request->post('LoginForm');
if ($model->checkattempts($post_variables['username'])) {
$model->scenario = 'withCaptcha';
$captcha = true;
}
}
if ($model->load(Yii::$app->request->post()) && $model->validate()) {
$model->login(); print_r($model->getErrors()); exit;
} else {
return $this->render('login', [
'model' => $model, 'captcha' => $captcha,
]);
}
In my login.php view:
<?php if($captcha) { ?>
<?= $form->field($model, 'verifyCode')->widget(Captcha::className(),
['template' => '<div class="captcha_img">{image}</div>'
. '<a class="refreshcaptcha" href="#">'
. Html::img('/images/imageName.png',[]).'</a>'
. 'Verification Code{input}',
])->label(FALSE); ?>
<?php } ?>
In my controller when I am tring to print model errors at $model->login() function it is giving below error everytime even though the verification code is correct.
Array ( [verifycode] => Array ( [0] => The verification code is incorrect. ) )
Why is it failing every time. Is there any mistake in the code written?
Thanks in advance
I'm trying to upload multiple images when I create a Post, but only one Image is stored in database, in server all images are saved but in my table only first image is saved but not all so I created function for upload
// Function to upload images
public function CreateGallery($model_Post, $model_Gallery)
{
$model_Post->Post_id = md5(microtime());
$model_Post->User_id = Yii::$app->user->id;
$GLRID = md5(uniqid());
// file
$GFolder = 'upload/images/'. $model_Post->Post_id .'/' ;
mkdir ($GFolder, 0777, true);
if ( $model_Post->save() ){
$model_Gallery->GalleryFile = UploadedFile::getInstances($model_Gallery, 'GalleryFile');
$ly_GalName = uniqid();
foreach ($model_Gallery->GalleryFile as $GalleryImage) {
++$ly_GalName;
$model_Gallery->Gallery_id = ++$GLRID;
$model_Gallery->User_id = $model_Post->User_id;
$model_Gallery->Post_id = $model_Post->Post_id;
$GalleryImage->saveAs($GFolder . $GalName . '.' . $GalleryImage->extension);
$model_Gallery->Gallery_image = $GFolder . $GalName . '.' . $GalleryImage->extension;
}
$model_Gallery->save(false);
}
}
and inside my controller I add the function I created
public function actionCreate()
{
$model_Post = new Post();
$model_Gallery = new Gallery;
$actions_UploadImages = new ActionsUploadImages();
if ($model->load(Yii::$app->request->post()) ) {
$actions_UploadImages->CreateGallery($model_Post, $model_Gallery)
return $this->redirect(['view', 'id' => $model_Post->Post_id]);
} else {
return $this->render('create', [
'model_Post' => $model_Post,
'model_Gallery' => $model_Gallery,
]);
}
}
and my views/create my code is
<?php $form = ActiveForm::begin(['options' => ['enctype' => 'multipart/form-data']]); ?>
<?= $form->field($model_Post, 'Post_title')->textInput(['maxlength' => true]) ?>
<?= $form->field($model_Gallery, 'GalleryFile[]')->fileInput(['multiple' => true, 'accept' => 'image/*']) ?>
<?= $form->field($model_Post, 'Post_text')->textarea(['rows' => 2]) ?>
<?= $form->field($model_Post, 'Permission_id')->dropdownList($model_Permission->PermissionList()) ?>
<div class="form-group">
<?= Html::submitButton($model_Post->isNewRecord ? 'Create' : 'Update', ['class' => $model_Post->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
</div>
<?php ActiveForm::end(); ?>
I tried to change gallery_id to AUTO_INCREMENT but still the same problem, I tried to remove if ( $model_Post->save() ), but I get error from database. Only like it's is now it's save all images on server but in table save only one image.
//// gallery model :
<?php
namespace app\models;
use Yii;
/**
* This is the model class for table "gallery".
*
* #property string $Gallery_id
* #property string $Gallery_image
* #property string $Post_id
* #property string $User_id
*
* #property Post $post
* #property Userlogin $user
*/
class Gallery extends \yii\db\ActiveRecord
{
public $GalleryFile;
/**
* #inheritdoc
*/
public static function tableName()
{
return 'gallery';
}
/**
* #inheritdoc
*/
public function rules()
{
return [
[['Gallery_id', 'Post_id', 'User_id'], 'required'],
[['Gallery_id'], 'string', 'max' => 200],
[['Gallery_image'], 'string', 'max' => 350],
[['Post_id', 'User_id'], 'string', 'max' => 300],
[['GalleryFile'], 'file', 'skipOnEmpty' => false, 'extensions' => 'png, jpg, jpeg, gif', 'maxFiles' => 5],
[['Post_id'], 'exist', 'skipOnError' => true, 'targetClass' => Post::className(), 'targetAttribute' => ['Post_id' => 'Post_id']],
[['User_id'], 'exist', 'skipOnError' => true, 'targetClass' => Userlogin::className(), 'targetAttribute' => ['User_id' => 'User_id']],
];
}
/**
* #inheritdoc
*/
public function attributeLabels()
{
return [
'Gallery_id' => 'Gallery ID',
'Gallery_image' => 'Gallery Image',
'Post_id' => 'Post ID',
'User_id' => 'User ID',
];
}
/**
* #return \yii\db\ActiveQuery
*/
public function getPost()
{
return $this->hasOne(Post::className(), ['Post_id' => 'Post_id']);
}
/**
* #return \yii\db\ActiveQuery
*/
public function getUser()
{
return $this->hasOne(Userlogin::className(), ['User_id' => 'User_id']);
}
/**
* #inheritdoc
* #return \app\queries\GalleryQuery the active query used by this AR class.
*/
public static function find()
{
return new \app\queries\GalleryQuery(get_called_class());
}
}
you need write a new model en the for each , like that
Function
Create a new model object in the for each .
Set the $model_Gallery->save(false); in inside the foreach
// Function to upload images
public function CreateGallery($model_Post, $model_Gallery)
{
$model_Post->Post_id = md5(microtime());
$model_Post->User_id = Yii::$app->user->id;
$GLRID = md5(uniqid());
// file
$GFolder = 'upload/images/' . $model_Post->Post_id . '/';
mkdir($GFolder, 0777, true);
if ($model_Post->save()) {
$model_Gallery->GalleryFile = UploadedFile::getInstances($model_Gallery, 'GalleryFile');
$ly_GalName = uniqid();
foreach ($model_Gallery->GalleryFile as $GalleryImage) {
$model_GalleryImage = new Gallery;
++$ly_GalName;
$model_GalleryImage->Gallery_id = ++$GLRID;
$model_GalleryImage->User_id = $model_Post->User_id;
$model_GalleryImage->Post_id = $model_Post->Post_id;
$GalleryImage->saveAs($GFolder . $GalName . '.' . $GalleryImage->extension);
$model_GalleryImage->Gallery_image = $GFolder . $GalName . '.' . $GalleryImage->extension;
$model_GalleryImage->save(false); //here , remove 'false' to work validations
}
}
}
Controller
when the action load the data ,it should not be like that ?
if ($model_Gallery->load(Yii::$app->request->post()) and $model_Post->load(Yii::$app->request->post())) {
//the rest of the code
}
Please note that we use save(false) to skip over validations inside the models as the user input data... with the user input
All you have to do is iterate $_FILES object using foreach loop and create new model every time. To validate code manage flag for that
I am trying to display thumbnail image on EDIT form in Admin custom module.
I am getting check box to delete image.
I am getting a square box where image supposed to display.
But it's not displaying image.
Please suggest me solution
my save() action in controller is
public function saveAction()
{
if ($data = $this->getRequest()->getPost())
{
if(isset($_FILES['shop_image']['name']) && $_FILES['shop_image']['name'] != '')
{
try {
/* Starting upload */
$uploader = new Varien_File_Uploader('shop_image');
// Any extention would work
$uploader->setAllowedExtensions(array('jpg','jpeg','gif','png'));
$uploader->setAllowRenameFiles(false);
$uploader->setFilesDispersion(false);
echo $path = Mage::getBaseDir('media').DS.'ud'.DS;
$uploader->save($path, $_FILES['shop_image']['name'] );
} catch (Exception $e) {
}
// echo $path;exit;
//this way the name is saved in DB
$data['shop_image'] = $path.$_FILES['shop_image']['name'];
}
else if((isset($data['shop_image']['delete']) && $data['shop_image']['delete'] == 1)){
.'ud'.DS.$data['shop_image']['value'];
unlink($data['shop_image']['value']);
//set path to null and save to database
$data['shop_image'] = '';
}
$model = Mage::getModel('shop/shop');
$id = $this->getRequest()->getParam('id');
if ($id) {
$model->load($id);
}
$model->setData($data);
Mage::getSingleton('adminhtml/session')->setFormData($data);
try {
if ($id) {
$model->setId($id);
}
$model->save();
if (!$model->getId()) {
Mage::throwException(Mage::helper('shop')->__('Error saving shop'));
}
Mage::getSingleton('adminhtml/session')->addSuccess(Mage::helper('shop')->__('Shop was successfully saved.'));
Mage::getSingleton('adminhtml/session')->setFormData(false);
// The following line decides if it is a "save" or "save and continue"
if ($this->getRequest()->getParam('back')) {
$this->_redirect('*/*/edit', array('id' => $model->getId()));
} else {
$this->_redirect('*/*/');
}
} catch (Exception $e) {
Mage::getSingleton('adminhtml/session')->addError($e->getMessage());
if ($model && $model->getId()) {
$this->_redirect('*/*/edit', array('id' => $model->getId()));
} else {
$this->_redirect('*/*/');
}
}
return;
}
Mage::getSingleton('adminhtml/session')->addError(Mage::helper('shop')->__('No data found to save'));
$this->_redirect('*/*/');
}
my form.php is
<?php
class Sample_Shop_Block_Adminhtml_Shop_Edit_Form extends Mage_Adminhtml_Block_Widget_Form
{
protected function _prepareForm()
{
if (Mage::getSingleton('adminhtml/session')->getExampleData())
{
$data = Mage::getSingleton('adminhtml/session')->getExamplelData();
Mage::getSingleton('adminhtml/session')->getExampleData(null);
}
elseif (Mage::registry('example_data'))
{
$data = Mage::registry('example_data')->getData();
}
else
{
$data = array();
}
$form = new Varien_Data_Form(array(
'id' => 'edit_form',
'action' => $this->getUrl('*/*/save', array('id' => $this->getRequest()->getParam('id'))),
'method' => 'post',
'enctype' => 'multipart/form-data',
));
$form->setUseContainer(true);
$this->setForm($form);
$fieldset = $form->addFieldset('example_form', array(
'legend' =>Mage::helper('shop')->__('Shop Information')
));
$fieldset->addField('shopname', 'text', array(
'label' => Mage::helper('shop')->__('Shop Name'),
'class' => 'required-entry',
'required' => true,
'name' => 'shopname',
'note' => Mage::helper('shop')->__('The name of the shop.'),
));
$fieldset->addField('logo', 'text', array(
'label' => Mage::helper('shop')->__('Logo'),
'class' => 'required-entry',
'required' => true,
'name' => 'logo',
));
$fieldset->addField('productimage', 'text', array(
'label' => Mage::helper('shop')->__('Product Image'),
'class' => 'required-entry',
'required' => true,
'name' => 'productimage',
));
$fieldset->addField('state', 'text', array(
'label' => Mage::helper('shop')->__('State'),
'class' => 'required-entry',
'required' => true,
'name' => 'state',
));
$fieldset->addField('shop_image','image', array(
'label' => Mage::helper('shop')->__('Shop Image'),
'required' => false,
'name' => 'shop_image',
));
$form->setValues($data);
return parent::_prepareForm();
}
}
Find the below easy steps to display the thumbnail image.
Add this below code in your edit ->tab->form file
ex: Package_Campaign_Block_Adminhtml_Campaign_Edit_Tab_Form
$fieldset->addType('image','Package_Campaign_Block_Adminhtml_Campaign_Helper_Image');
Create the below helper class file to display the thumbnail image.
class Package_Campaign_Block_Adminhtml_Campaign_Edit_Tab_Form extends Varien_Data_Form_Element_Abstract{
public function __construct($data) {
parent::__construct($data);
$this->setType('file');
}
public function getElementHtml() {
$html = '';
if ($this->getValue()) {
$media = Mage::getBaseUrl('media').'campaign/';
$html = '<a onclick="imagePreview(\''.$this->getHtmlId().'_image\'); return false;" href="'.$this->getValue().'"><img id="'.$this->getHtmlId().'_image" style="border: 1px solid #d6d6d6;" title="'.$this->getValue().'" src="'.$media.$this->getValue().'" alt="'.$this->getValue().'" width="30"></a> ';
}
$this->setClass('input-file');
$html.= parent::getElementHtml();
return $html;
}
}