How can I pass parameter/dropdown value to model function - php

I am using yii2 advanced template improved
Not sure if relevant to problem/a solution but to get to the category I have a form with some javascript which on change redirects the user to the category selected.
I have the following code which allows me to access the posts within that category id I go to localhost:8888/advanced/article/category?id=1
The problem at the minute is that if I call getCategoryName function in my model from my category view the id parameter isn't being passed to the model function therefore when using getCategoryName defaults to sport.
public function actionCategory($id)
{
$model = new Article();
$searchModel = new ArticleSearch();
$query = Article::find()
->where(['category' => $id]);
$dataProvider = new ActiveDataProvider([
'query' => $query,
]);
return $this->render('category', [
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
'model'=>$model,
]);
}
Then within my view I use the following which works to an extent in terms of executing the model function, however I am unsure on how to pass the parameter/current category id to the model function. The below code work for the _index & in the single article view.
<?= $model->CategoryName ?>
This is my model function
public function getCategoryName($category = null)
{
$category = (empty($category)) ? $this->category : $category ;
if ($category === self::CATEGORY_ECONOMY)
{
return Yii::t('app', 'Economy');
}
elseif ($category === self::CATEGORY_SOCIETY)
{
return Yii::t('app', 'Society');
}
else
{
return Yii::t('app', 'Sport');
}
}

Use something like this, in your view
$request = Yii::$app->request;
$id = $request->get('id');//get id from request or change according to your requirement
echo $model->getCategoryName($id);//full method name here

Try to use this. change === to ==:
public function getCategoryName($category = null)
{
$category = (empty($category)) ? $this->category : $category ;
if ($category == self::CATEGORY_ECONOMY)
{
return Yii::t('app', 'Economy');
}
elseif ($category == self::CATEGORY_SOCIETY)
{
return Yii::t('app', 'Society');
}
else
{
return Yii::t('app', 'Sport');
}
}

Related

ArgumentCountError Too few arguments to function App\Controllers\Blog::view()

Sorry for my bad english but i have a problem when i try to open localhost:8080/blog this message show up
Too few arguments to function App\Controllers\Blog::view(), 0 passed in C:\xampp\htdocs\baru\vendor\codeigniter4\framework\system\CodeIgniter.php on line 896 and exactly 1 expected
so this is the controller:
use CodeIgniter\Controller;
use App\Models\ModelsBlog;
class Blog extends BaseController
{
public function index()
{$data = [
'title' => 'artikel'
];
$model = new ModelsBlog();
if (!$this->validate([]))
{
$data['validation'] = $this->validator;
$data['artikel'] = $model->getArtikel();
return view('view_list',$data);
}
}
public function form(){
$data = [
'title' => 'Edit Form'
];
helper('form');
return view('view_form', $data);
}
public function view($id){
$data = [
'title' => 'artikel'
];
$model = new ModelsBlog();
$data['artikel'] = $model->PilihBlog($id)->getRow();
return view('view',$data);
}
public function simpan(){
$model = new ModelsBlog();
if ($this->request->getMethod() !== 'post') {
return redirect()->to('blog');
}
$validation = $this->validate([
'file_upload' => 'uploaded[file_upload]|mime_in[file_upload,image/jpg,image/jpeg,image/gif,image/png]|max_size[file_upload,4096]'
]);
if ($validation == FALSE) {
$data = array(
'judul' => $this->request->getPost('judul'),
'isi' => $this->request->getPost('isi')
);
} else {
$upload = $this->request->getFile('file_upload');
$upload->move(WRITEPATH . '../public/assets/blog/images/');
$data = array(
'judul' => $this->request->getPost('judul'),
'isi' => $this->request->getPost('isi'),
'gambar' => $upload->getName()
);
}
$model->SimpanBlog($data);
return redirect()->to('./blog')->with('berhasil', 'Data Berhasil di Simpan');
}
public function form_edit($id){
$data = [
'title' => 'edit artikel'
];
$model = new ModelsBlog();
helper('form');
$data['artikel'] = $model->PilihBlog($id)->getRow();
return view('form_edit',$data);
}
public function edit(){
$model = new ModelsBlog();
if ($this->request->getMethod() !== 'post') {
return redirect()->to('blog');
}
$id = $this->request->getPost('id');
$validation = $this->validate([
'file_upload' => 'uploaded[file_upload]|mime_in[file_upload,image/jpg,image/jpeg,image/gif,image/png]|max_size[file_upload,4096]'
]);
if ($validation == FALSE) {
$data = array(
'judul' => $this->request->getPost('judul'),
'isi' => $this->request->getPost('isi')
);
} else {
$dt = $model->PilihBlog($id)->getRow();
$gambar = $dt->gambar;
$path = '../public/assets/blog/images/';
#unlink($path.$gambar);
$upload = $this->request->getFile('file_upload');
$upload->move(WRITEPATH . '../public/assets/blog/images/');
$data = array(
'judul' => $this->request->getPost('judul'),
'isi' => $this->request->getPost('isi'),
'gambar' => $upload->getName()
);
}
$model->edit_data($id,$data);
return redirect()->to('./blog')->with('berhasil', 'Data Berhasil di Ubah');
}
public function hapus($id){
$model = new ModelsBlog();
$dt = $model->PilihBlog($id)->getRow();
$model->HapusBlog($id);
$gambar = $dt->gambar;
$path = '../public/assets/blog/images/';
#unlink($path.$gambar);
return redirect()->to('./blog')->with('berhasil', 'Data Berhasil di Hapus');
}
}
ModelsBlog.php :
use CodeIgniter\Model;
class ModelsBlog extends Model
{
protected $table = 'artikel';
public function getArtikel()
{
return $this->findAll();
}
public function SimpanBlog($data)
{
$query = $this->db->table($this->table)->insert($data);
return $query;
}
public function PilihBlog($id)
{
$query = $this->getWhere(['id' => $id]);
return $query;
}
public function edit_data($id,$data)
{
$query = $this->db->table($this->table)->update($data, array('id' => $id));
return $query;
}
public function HapusBlog($id)
{
$query = $this->db->table($this->table)->delete(array('id' => $id));
return $query;
}
}
And this is the view.php:
<body style="width: 70%; margin: 0 auto; padding-top: 30px;">
<div class="row">
<div class="col-lg-12 margin-tb">
<div class="pull-left">
<h2><?php echo $artikel->judul; ?></h2>
</div>
</div>
</div>
<hr>
<div class="row">
<div class="col-lg-12">
<div class="row">
<?php
if (!empty($artikel->gambar)) {
echo '<img src="'.base_url("assets/blog/images/$artikel->gambar").'" width="30%">';
}
?>
<?php echo $artikel->isi; ?>
</div>
</div>
</div>
</body>
i cant find any solutions for this error, pls help thank you very much
Let's go over what you're telling the code to do.
First, you make a call to /blog. If you have auto-routing turned on this will put you forward to the controller named 'Blog'.
class Blog extends BaseController
And since you do not extend the URL with anything, the 'index' method will be called.
public function index()
{$data = [
'title' => 'artikel'
];
$model = new ModelsBlog();
if (!$this->validate([]))
{
$data['validation'] = $this->validator;
$data['artikel'] = $model->getArtikel();
return view('view_list',$data);
}
}
The index method sets $data to an array filled with 'title' => 'artikel'. And then fills $model with a new ModelsBlog.
class ModelsBlog extends Model
There is no __construct method defined in ModelsBlog so just the class is loaded and specific execution related to $model stops there, which is fine.
Then, the index() from Blog goes on and checks whether or not $this->validate([]) returns false. Since there's no else statement, if $this->validate([]) were to return true, code execution would stop there. So we'll assume $this->validate([]) returns false. So far so good, there's nothing weird going on with your code.
However, IF $this->validate([]) returns false, you tell the index() to return the function called view(). Normally CodeIgniter would serve you the view you set as the first parameter. But since you also have a Blog method named 'view', CodeIgniter will try to reroute te request to that method. So in other words, the actual request you're trying to make is:
Blog::view()
And since you've stated that view() receives 1 mandatory parameter, the requests triggers an error. You can solve the problem by either renaming the view() method of Blog to something like 'show()' or 'read()'. Anything else that does not conflict with the native CodeIgniter view() function would be good.
Honestly though, you are sending through two parameters in the index() function call so I'm slightly confused why the error generated states you provided 0, but I hope at least you gain some insight from my answer and you manage to fix the problem.
If anyone could provide more information regarding this, feel free to comment underneath and I'll add your information to the answer (if it gets accepted).

yii2 ajax validation error in widget, yii\web\Response

I'm getting error from yii\web\Response when I use ajax validation.
Object of class yii\web\Response could not be converted to string
widget:
public function run()
{
$model = new Participants();
if (Yii::$app->request->isAjax && $model->load(Yii::$app->request->post())) {
Yii::$app->response->format = Response::FORMAT_JSON;
return ActiveForm::validate($model);
}
if ($model->load(Yii::$app->request->post())) {
$list = implode( ", ",$model->sections);
$model->sections = $list;
$model->save();
Yii::$app->session->setFlash(Alert::TYPE_SUCCESS, [
[
'title' => 'Congratulations!',
'text' => 'You are registered on the forum. Check out your email to get news about forum.',
'confirmButtonText' => 'Done!',
]
]);
return Yii::$app->controller->redirect(Yii::$app->request->referrer ?: Yii::$app->homeUrl);
}
return $this->render('header', [
'model' => $model,
]);
}
view of widget:
<?php $form = ActiveForm::begin();?>
...
<?= $form->field($model, 'email', ['enableAjaxValidation' => true])->textInput(['placeholder' => 'Email']); ?>
how I can solve this error? P.S. yii version - 2.0.17-dev
\yii\base\Widget::run() must return a string (all widgets basically)
All you should do within method run() is output or render content and you're attempting to return a Response object by way of return ActiveForm::validate($model); and return Yii::$app->controller->redirect(..)
i suggest you move all the code that supposed to handle form submission to it's own action
SiteController extends controller {
public function actionRegisterParticipant {
$model = new Participants();
if (Yii::$app->request->isAjax && $model->load(Yii::$app->request->post())) {
Yii::$app->response->format = Response::FORMAT_JSON;
return ActiveForm::validate($model);
}
if ($model->load(Yii::$app->request->post())) {
$list = implode(", ", $model->sections);
$model->sections = $list;
$model->save();
Yii::$app->session->setFlash(Alert::TYPE_SUCCESS, [
[
'title' => 'Congratulations!',
'text' => 'You are registered on the forum. Check out your email to get news about forum.',
'confirmButtonText' => 'Done!',
]
]);
return Yii::$app->controller->redirect(Yii::$app->request->referrer ?: Yii::$app->homeUrl);
}
// ...
}
and the form in the widget view should always point to this action:
<?php $form = ActiveForm::begin(['action' => 'site/register-participant']);?>
...
<?= $form->field($model, 'email', ['enableAjaxValidation' => true])->textInput(['placeholder' => 'Email']); ?>
Widget should return string as a result, but return Yii::$app->controller->redirect() returns Response object with configured redirection. If you want to redirect inside of widget you should use something like that:
if (Yii::$app->request->isAjax && $model->load(Yii::$app->request->post())) {
Yii::$app->controller->asJson(ActiveForm::validate($model));
Yii::$app->end();
}
// ...
Yii::$app->session->setFlash(/* ... */);
Yii::$app->controller->redirect(Yii::$app->request->referrer ?: Yii::$app->homeUrl);
Yii::$app->end();
But this smells like a bad design - widget should not be responsible for controlling application flow. It is better to handle user input in regular action/controller.

Yii2; code running in "else" block first, and then running code before "if" block?

I'm completely lost as to why this is happening, and it happens about 50% of the time.
I have a check to see if a user exists by email and last name, and if they do, run some code. If the user doesn't exist, then create the user, and then run some code.
I've done various testing with dummy data, and even if a user doesn't exist, it first creates them, but then runs the code in the "if" block.
Here's what I have.
if (User::existsByEmailAndLastName($params->email, $params->lastName)) {
var_dump('user already exists');
} else {
User::createNew($params);
var_dump("Creating a new user...");
}
And here are the respective methods:
public static function existsByEmailAndLastName($email, $lastName) {
return User::find()->where([
'email' => $email,
])->andWhere([
'last_name' => $lastName
])->one();
}
public static function createNew($params) {
$user = new User;
$user->first_name = $params->firstName;
$user->last_name = $params->lastName;
$user->email = $params->email;
$user->address = $params->address;
$user->address_2 = $params->address_2;
$user->city = $params->city;
$user->province = $params->province;
$user->country = $params->country;
$user->phone = $params->phone;
$user->postal_code = $params->postal_code;
return $user->insert();
}
I've tried flushing the cache. I've tried it with raw SQL queries using Yii::$app->db->createCommand(), but nothing seems to be working. I'm totally stumped.
Does anyone know why it would first create the user, and then do the check in the if statement?
Editing with controller code:
public function actionComplete()
{
if (Yii::$app->basket->isEmpty()) {
return $this->redirect('basket', 302);
}
$guest = Yii::$app->request->get('guest');
$params = new CompletePaymentForm;
$post = Yii::$app->request->post();
if ($this->userInfo || $guest) {
if ($params->load($post) && $params->validate()) {
if (!User::isEmailValid($params->email)) {
throw new UserException('Please provide a valid email.');
}
if (!User::existsByEmailAndLastName($params->email, $params->lastName)) {
User::createNew($params);
echo "creating new user";
} else {
echo "user already exists";
}
}
return $this->render('complete', [
'model' => $completeDonationForm
]);
}
return $this->render('complete-login-or-guest');
}
Here's the answer after multiple tries:
Passing an 'ajaxParam' parameters with the ActiveForm widget to define the name of the GET parameter that will be sent if the request is an ajax request. I named my parameter "ajax".
Here's what the beginning of the ActiveForm looks like:
$form = ActiveForm::begin([
'id' => 'complete-form',
'ajaxParam' => 'ajax'
])
And then I added this check in my controller:
if (Yii::$app->request->get('ajax') || Yii::$app->request->isAjax) {
return false;
}
It was an ajax issue, so thanks a bunch to Yupik for pointing me towards it (accepting his answer since it lead me here).
You can put validation like below in your model:
public function rules() { return [ [['email'], 'functionName'], [['lastname'], 'functionforlastName'], ];}
public function functionName($attribute, $params) {
$usercheck=User::find()->where(['email' => $email])->one();
if($usercheck)
{
$this->addError($attribute, 'Email already exists!');
}
}
and create/apply same function for lastname.
put in form fields email and lastname => ['enableAjaxValidation' => true]
In Create function in controller
use yii\web\Response;
if (Yii::$app->request->isAjax && $model->load(Yii::$app->request->post())) {
Yii::$app->response->format = Response::FORMAT_JSON;
return ActiveForm::validate($model);
}
else if ($model->load(Yii::$app->request->post()))
{
//place your code here
}
Add 'enableAjaxValidation' => false to your ActiveForm params in view. It happens because yii sends request to your action to validate this model, but it's not handled before your if statement.

Yii2 : Managing Pagination in custom function

I'm using Yii2-advanced-app. I'm writing a function which takes 2 parameters using post method & displays result in a Gridview with pagination. The screen is like this -
The problem I'm facing with this is - When I click on the 'next page' button in pagination bar, it loads the function again & gives me the blank form again, instead of showing the 2nd page. It's like this - .
My function is this -
public function actionReportMisc()
{
$model = new BanksDetail();
if($model->load(Yii::$app->request->post())) {
if($model->Process_ID != '' && $model->Bank_ID != '') {
if($model->Process_ID == 1) {
$searchModel = new BanksDetailSearch();
$bank = Banks::find()->select('ID')->where(['Account_Number' => $model->Bank_ID])->one();
if(count($bank) == 1) {
$queryParams = array_merge(array(),Yii::$app->request->getQueryParams());
$queryParams["BanksDetailSearch"]["Bank_ID"] = $bank->ID;
$dataProvider = $searchModel->search($queryParams);
$dataProvider->pagination->pageSize = 3;
if(count($dataProvider) > 0) {
return $this->render('misc', ['model' => $model, 'searchModel' => $searchModel, 'dataProvider' => $dataProvider]);
}
} else {
throw new \yii\web\HttpException(404, 'The selected Account does not exist. Please ensure that you have entered right account no. for Bank/Cashbox.');
}
} else if($model->Process_ID == 2) {
$searchModel = new CashboxesDetailSearch();
$cbx = Cashboxes::find()->select('ID')->where(['Account_Code' => $model->Bank_ID])->one();
if(count($cbx) == 1) {
$queryParams = array_merge(array(),Yii::$app->request->getQueryParams());
$queryParams["CashboxesDetailSearch"]["CashBoxes_ID"] = $cbx->ID;
$dataProvider = $searchModel->search($queryParams);
if(count($dataProvider) > 0) {
return $this->render('misc', ['model' => $model, 'searchModel' => $searchModel, 'dataProvider' => $dataProvider]);
}
} else {
throw new \yii\web\HttpException(404, 'The selected Account does not exist. Please ensure that you have entered right account no. for Bank/Cashbox.');
}
}
}
} else {
return $this->render('misc', ['model' => $model]);
}
}
I understand that, when I click on 'next page button', the function again initializes the form with empty values & returns empty fom. But need a suggestion to get it done or an another way to do it easily. Thanks in advance.
I solved the resp. problem by using get() instead of post(). It was suitable for my scenario, because I get those parameters each time during pagination too. Thanks for your kind help.

Yii2: How to access _POST method data

Sending form data from one action to another
<?php $form = ActiveForm::begin(['action' =>'site/roomsearch','method' => 'post']); ?>
<?= $form->field($model, 'arrival')->label(false) ?>
<?= $form->field($model, 'departure')->label(false) ?>
<?= Html::submitButton('Send', ['class' => 'btn btn-white']) ?>
<?php ActiveForm::end(); ?>
index page has the above form from which sending data to actionRoomsearch()
actionindex():
public function actionIndex()
{
$model = new \yii\base\DynamicModel(['arrival','departure','adult','child']);
if($model->load(Yii::$app->request->post()))
{
$arrival = $model->arrival;
$departure = $model->departure;
return $this->redirect([
'roomsearch',
'arrival' => $arrival ,
'departure' => $departure
]);
}
return $this->render('index', ['model'=>$model]);
}
actionroomsearch():
{
$post = Yii::$app->request->post();
$arrival = $post['arrival'];
$departure = $post['departure'];
return $this->render('roomsearch',[
'arrival' =>$arrival,
'departure' => $departure,
]);
}
How to display arrival and departure in roomsearch page?
Created model using \yii\base\DynamicModel
Well as you are redirecting from one action to another , you cant access POST data in the second action. But you can pass it as get parameters
return $this->redirect(\yii\helpers\Url::to([
'/you_controller/your_action',
'arrival' => $arrival ,
'departure' => $departure
]));
In your Second Action
$arrival = yii::$app->request->get('arrival');
$departure = yii::$app->request->get('departure');
Used dynamic model as no data need to save in database
public function actionIndex()
{
$model = new \yii\base\DynamicModel(['arrival','departure']);
$model->addRule(['arrival', 'departure'], 'string', ['max' => 128]);
$arrival = $model->arrival;
if($model->load(Yii::$app->request->post()))
{
$arrival = $model->arrival;
$departure = $model->departure;
$model->save();
}
return $this->render('index', ['model'=>$model]);
}
To get the POST method data in actionRoomsearch
public function actionRoomsearch()
{
$data = yii::$app->request->post();
if(isset($data['DynamicModel']))
{
$arrival = $data['DynamicModel']['arrival'];
$departure = $data['DynamicModel']['departure'];
}
return $this->render('roomsearch',['arrival' =>$arrival,'departure' => $departure]);
}
To display data on page <?php echo $arrival; ?>
Since this is a communication between two request. I will prefer to use Flash
Note: Flash will be deleted automatically after the next request.
public function actionIndex()
{
$model = new \yii\base\DynamicModel(['arrival', 'departure', 'adult', 'child']);
if($model->load(Yii::$app->request->post()))
{
Yii::$app->session->setFlash('arrival', $model->arrival);
Yii::$app->session->setFlash('departure', $model->departure);
return $this->redirect(['roomsearch']);
}
return $this->render('index', ['model'=>$model]);
}
In the room-search page
public function actionRoomSearch()
{
$session = Yii::$app->session;
$arrival = $session->hasFlash('arrival') ? $session->getFlash('arrival') : null;
$departure = $session->hasFlash('departure') ? $session->getFlash('departure') :null;
//Do whatever you like with the data
}
The reason I prefer this method over $_GET is because there are times
where you have to send security sensitive data over pages and you don't
want it revealed in the browser's address bar.
E.g ID that is posted in an hidden field.

Categories