Yii2 Custom validation on scenario not working - yii2

I am creating a function for validation data on given scenario but its not working.
Model code :
public function rules()
{
return [
// ['session_key','deal_id','required'],
['data', 'validateCart'],
[['session_key','deal_id'], 'safe'],
// [['cartfood','session_key'], 'required','on'=>'sessionapi'],
['cartfood', 'myvalidation', 'on' => 'sessionapi'],
];
}
public function myvalidation($attribute, $params){
if (!$this->hasErrors()) {
echo '<pre>'; print_r($params); die;
}
}
Controller : code
public function actionPayinapp(){
$data=Yii::$app->getRequest()->getBodyParams();
$cart=json_decode($data['cartfood']);
$model=new Cart();
$model->scenario = 'sessionapi';
$dataarr = array();
$model->data = $cart;
if($model->validate())
{
die(ok);
}
}
I want myvalidation run on sessionapi scenario but it's not working.

Change Your Controller Code As: -SkipOnEmpty
public function rules()
{
return [
// ['session_key','deal_id','required'],
['data', 'validateCart'],
[['session_key','deal_id'], 'safe'],
// [['cartfood','session_key'], 'required','on'=>'sessionapi'],
//you have to apply skipOnEmpty in your rules as
['cartfood', 'myvalidation', 'on' => 'sessionapi' ,'skipOnEmpty' => false],
];
}
public function myvalidation($attribute, $params){
if (!$this->hasErrors()) {
echo '<pre>'; print_r($params); die;
}
}

Related

How do I download a generated csv in magento 2.4.5

My files so far are:
system.xml
<field id="generate_csv" translate="label" type="button" sortOrder="2" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Generate Categories CSV</label>
<frontend_model>Vendor\Module\Block\Adminhtml\System\Config\Button</frontend_model>
</field>
button.php
<?php
namespace [Vendor]\[Module]\Block\Adminhtml\System\Config;
use Magento\Config\Block\System\Config\Form\Field;
use Magento\Backend\Block\Template\Context;
use Magento\Framework\Data\Form\Element\AbstractElement;
class Button extends Field
{
protected $_template = 'Vendor_Module::system/config/button.phtml';
public function __construct(
Context $context,
array $data = []
){
parent::__construct($context, $data);
}
public function render(AbstractElement $element)
{
$element->unsScope()->unsCanUseWebsiteValue()->unsCanUseDefaultValue();
return parent::render($element);
}
protected function _getElementHtml(AbstractElement $element)
{
return $this->_toHtml();
}
public function getAjaxUrl()
{
return $this->getUrl('[router]/Export/CategoryExport');
}
public function getButtonHtml()
{
$button = $this->getLayout()->createBlock(
'Magento\Backend\Block\Widget\Button'
)->setData(
[
'id' => 'generate_csv',
'label' => __('Generate CSV')
]
);
return $button->toHtml();
}
}
button.phtml
<script>
require([
'jquery',
'prototype'
], function ($) {
$('#generate_csv').click(function () {
var params = {};
new Ajax.Request('<?php echo $block->getAjaxUrl() ?>', {
parameters: params,
loaderArea: false,
asynchronous: true,
onCreate: function () {
$('#custom_button_response_message').text('');
},
onSuccess: function (transport) {
var resultText = '';
if (transport.status > 200) {
resultText = transport.statusText;
} else {
var response = JSON.parse(transport.responseText);
resultText = response.message
}
$('#generate_csv_response_message').text(resultText);
}
});
});
});
</script>
<?php echo $block->getButtonHtml(); ?>
<p>
<span id="generate_csv_response_message"></span>
</p>
controller
<?php
namespace [Vendor]\[Module]\Controller\Adminhtml\Export;
use Magento\Framework\App\Action\Action;
use Magento\Framework\App\Action\Context;
use Magento\Framework\Controller\Result\Json;
use Magento\Framework\Controller\Result\JsonFactory;
use Magento\Framework\Filesystem;
use Magento\Framework\App\Filesystem\DirectoryList;
use Magento\Catalog\Model\ResourceModel\Category\CollectionFactory;
use Magento\Catalog\Model\CategoryFactory;
class CategoryExport extends Action
{
protected $resultJsonFactory;
/**
* #param Context $context
* #param JsonFactory $resultJsonFactory
*/
public function __construct(
Context $context,
JsonFactory $resultJsonFactory,
Filesystem $filesystem,
DirectoryList $directoryList,
CollectionFactory $categoryCollectionFactory,
CategoryFactory $categoryFactory
){
$this->resultJsonFactory = $resultJsonFactory;
$this->filesystem = $filesystem;
$this->directory = $filesystem->getDirectoryWrite(DirectoryList::VAR_DIR);
$this->categoryCollectionFactory = $categoryCollectionFactory;
$this->categoryFactory = $categoryFactory;
parent::__construct($context);
}
/**
* #return Json
*/
public function execute()
{
$message = 'Success';
$data[] = [
'id' => __('Entity ID'),
'name' => __('Name'),
'level' => __('Level')
];
$categoryCollection = $this->categoryCollectionFactory->create();
$categoryCollection->addAttributeToSelect('*');
$filepath = 'export/customerlist.csv';
$this->directory->create('export');
$stream = $this->directory->openFile($filepath, 'w+');
$stream->lock();
$header = ['Id', 'Name', 'Level'];
$stream->writeCsv($header);
//$categoryArray = array();
foreach ($categoryCollection as $category) {
$data = [];
$data[] = $category->getId();
$data[] = $category->getName();
$data[] = $category->getLevel();
$stream->writeCsv($data);
}
/** #var Json $result */
$result = $this->resultJsonFactory->create();
return $result->setData(['message' => $message]);
}
}
This creates a csv file in var/export directory but I cannot download it
Can anyone help explain how to modify the code so that it will automatically create and down the csv.
I have tried following various examples on the web but none of them have worked.
Please help me out

How to use Yii2 Queue::EVENT_AFTER_ERROR event

I'm using Yii2 Queue extension.
I want to add error handler after triggering error event in job.
This is my model:
namespace app\models;
use Yii;
use yii\base\BaseObject;
use yii\queue\JobInterface;
use yii\queue\Queue;
class AddTransaction extends BaseObject implements JobInterface
{
public function execute($queue)
{
$test = new League();
$test->title_fa = 'تست';
$test->title_en = 'test';
$test->status = 1;
$test->country_id = 3;
$test->created = time();
$test->save();
}
}
This is my action:
public function actionTest()
{
if (Yii::$app->queue->delay(5)->push(new AddTransaction())) {
echo "ok";
} else {
echo "error";
}
}
Where use this code?
Yii::$app->queue->on(Queue::EVENT_AFTER_ERROR, function (ErrorEvent $event) {
if ($event->job instanceof SomeJob) {
$event->retry = ($event->attempt < 5) && ($event->error instanceof TemporaryException);
}
});
You may add this to queue config array:
'components' => [
// ...
'queue' => [
// ...
'on afterError' => function (ExecEvent $event) {
if ($event->job instanceof SomeJob) {
$event->retry = ($event->attempt < 5) && ($event->error instanceof TemporaryException);
}
},
],
],
In advanced template you have bootstrap.php config file there you may subscribe to events and so on.
This is one of adopted examples from docs
Event::on(Queue::className(), Queue::EVENT_AFTER_ERROR, function ($event) {
Yii::debug(get_class($event->sender) . ' is error');
});

Activerecord cant update a row

I want update just one column of table I'm getting this error when updating a table rows:
Call to a member function load() on null
This is my action:
public function actionAddNote(){
$id = \Yii::$app->request->post('id');
$model = MainRequest::findOne($id);
if ($model->load(\Yii::$app->request->post()) && $model->validate())
{
if($model->update()){
echo "1";
}else {
print_r($model->getErrors());
}
}
return $this->renderAjax('add-extra-note',['model' => $model]);
}
My model:
class MainRequest extends ActiveRecord {
public static function tableName()
{
return "main_request";
}
public function behaviors()
{
return [
DevNotificationBehavior::className(),
];
}
public function rules() {
return [
[
['who_req',
'req_description',
'req_date',
'extra_note'
], 'safe']
];
}
The form will render properly and I can see my text but when I submit this the error occur:
<div>
<?php $form = ActiveForm::begin(); ?>
<?= $form->field($model, 'extra_note')->textInput(); ?>
<div class="form-group">
<?= Html::submitButton('save', ['class' => 'btn green']) ?>
</div>
<?php ActiveForm::end(); ?>
</div>
Can anybody tell what is problem ? Thank you.
You should load the model and the use the model loaded for accessing attribute
and you should manage ythe initial situation where you d0n't have a model to update but need a model for invoke the update render form eg:
public function actionAddNote(){
$myModel = \Yii::$app->request->post();
$model = MainRequest::findOne($myModel->id);
if (isset($model)){
if ($model->load(\Yii::$app->request->post()) && $model->validate())
{
if($model->update()){
echo "1";
}else {
print_r($model->getErrors());
}
}
} else {
$model = new MainRequest();
}
return $this->renderAjax('add-extra-note',['model' => $model]);
}
Use Simple save function or updateAttributes of Yii2:
public function actionAddNote(){
$id = \Yii::$app->request->post('id');
$model = MainRequest::findOne($id);
if ($model->load(\Yii::$app->request->post()) && $model->validate())
{
if($model->**save**()){
echo "1";
}else {
print_r($model->getErrors());
}
}
return $this->renderAjax('add-extra-note',['model' => $model]);
}

Import Excel in Yii2

I have yii2 application using advanced template and database mySql, i already make function for import an excel file to one of the table,
I made the function in a controller named student that contains CRUD of students data.this is my code
public function actionImportExcel()
{
$inputFile = 'uploads/siswa_file.xlsx';
try{
$inputFileType = \PHPExcel_IOFactory::identify($inputFile);
$objReader = \PHPExcel_IOFactory::createReader($inputFileType);
$objPHPExcel = $objReader->load($inputFile);
} catch (Exception $e) {
die('Error');
}
$sheet = $objPHPExcel->getSheet(0);
$highestRow = $sheet->getHighestRow();
$highestColumn = $sheet->getHighestColumn();
for($row=1; $row <= $highestRow; $row++)
{
$rowData = $sheet->rangeToArray('A'.$row.':'.$highestColumn.$row,NULL,TRUE,FALSE);
if($row==1)
{
continue;
}
$siswa = new Siswa();
$siswa->nis = $rowData[0][0];
$siswa->nama_siswa = $rowData[0][1];
$siswa->jenis_kelamin = $rowData[0][2];
$siswa->ttl = $rowData[0][3];
$siswa->alamat = $rowData[0][4];
$siswa->telp = $rowData[0][5];
$siswa->agama = $rowData[0][6];
$siswa->nama_ortu = $rowData[0][7];
$siswa->telp_ortu = $rowData[0][8];
$siswa->pekerjaan_ortu = $rowData[0][9];
$siswa->tahun_masuk = $rowData[0][10];
$siswa->kelas = $rowData[0][11];
$siswa->save();
print_r($siswa->getErrors());
}
die('okay');
}
but i don't know how to make a button in a view to make this function work. i mean i want to make a button that when the user click the button and browse their excel file they can import that file and the data inside the excel can import to database
First you should upload the file
and then processing with your function
there are several parts of code you must produce ..
eg a view for the user to upload the file
View: #app/views/site/upload.php
<?php $form = ActiveForm::begin(['options' => ['enctype' => 'multipart/form-data']]) ?>
<?= $form->errorSummary($model); ?>
<?= $form->field($model, 'imageFile')->fileInput() ?>
<button>Submit</button>
<?php ActiveForm::end() ?>
Controller: #app/controllers/SiteController.php
namespace app\controllers;
use Yii;
use yii\web\Controller;
use app\models\UploadForm;
use yii\web\UploadedFile;
class SiteController extends Controller
{
public function actionUpload()
{
$model = new UploadForm();
if (Yii::$app->request->isPost) {
$model->imageFile = UploadedFile::getInstance($model, 'imageFile');
if ($model->upload()) {
// file is uploaded successfully
return;
}
}
return $this->render('upload', ['model' => $model]);
}
}
Model: #app/models/UploadForm.php
namespace app\models;
use yii\base\Model;
use yii\web\UploadedFile;
class UploadForm extends Model
{
/**
* #var UploadedFile
*/
public $imageFile;
public function rules()
{
return [
[['imageFile'], 'file', 'skipOnEmpty' => false, 'extensions' => 'png, jpg'],
];
}
public function upload()
{
if ($this->validate()) {
$this->imageFile->saveAs('uploads/' . $this->imageFile->baseName . '.' . $this->imageFile->extension);
return true;
} else {
return false;
}
}
}
the code is from this doc

Yii2:how to get return value in view from model?

I have a table name "staff".Staff table has one to many relation with attendance table.
In model Staff.php
public function getAttendances()
{
if(isset($_GET['startdat']))
$start_date=$_GET['startdat'];
if(isset($_GET['enddate']))
$end_date=$_GET['enddate'];
if(isset($_GET['startdat'])){
return $this->hasMany(Attendance::className(), ['staff_id' => 'id'])
->where('daytime >= "'.$start_date.'" and daytime<="'.$end_date.'"');
}
else{
return $this->hasMany(Attendance::className(), ['staff_id' => 'id'])
->andOnCondition(['daytime' => 'Absent'])
->orOnCondition(['status' => 'Present'])
->orOnCondition(['status' => 'leave']);
}
}
public function getPresent(){
$present=0;
foreach($this->attendances as $attendance){
if($attendance->status=='Present')
$present++;
}
return $present;
}
public function getAbsent(){
$Absent=0;
foreach($this->attendances as $attendance){
if($attendance->status=='Absent')
$Absent++;
}
return $Absent;
}
public function getLeave(){
$Leave=0;
foreach($this->attendances as $attendance){
if($attendance->status=='Leave')
$Leave++;
}
return $Leave;
}
in views report.php
<?=
GoogleChart::widget(['visualization' => 'PieChart',
'data' => [
['Task', 'Hours per Day'],
['Present', 5],
['Absent', 2],
['leave', 4],
],]);
?>
i want to get the returned value of $present ,$Absent and $leave. to make GoogleChart dynamic. How to echo the function returned value from model in view in yii2 ?
You can try this code for getting value from model's functions.
use path\to\model\Staff;
<?=
GoogleChart::widget(['visualization' => 'PieChart',
'data' => [
['Task', 'Hours per Day'],
['Present', Staff::getPresent()],
['Absent', Staff::getAbsent()],
['leave', Staff::getLeave()],
],]);
?>
I think you should use static function
public static function getAttendances()
{
.......
public static function getPresent(){
$present=0;
foreach(self::attendances() as $attendance){
if($attendance->status=='Present')
$present++;
}
return $present;
}
public static function getAbsent(){
$Absent=0;
foreach(self::attendances() as $attendance){
if($attendance->status=='Absent')
$Absent++;
}
return $Absent;
}
public static function getLeave(){
$Leave=0;
foreach(self::attendances() as $attendance){
if($attendance->status=='Leave')
$Leave++;
}
return $Leave;
}
and the use in your widget
use path\to\model\Staff;
<?php echo GoogleChart::widget(['visualization' => 'PieChart',
'data' => [
['Task', 'Hours per Day'],
['Present', Staff::getPresent()],
['Absent', Staff::getAbsent()],
['leave', Staff::getLeave()],
],]);
?>