Yii2 execute controller and show view from package in vendor - yii2

In my case I am trying to execute slide(controller)/index(action) and render the corresponding view ( index ). They are both in my vendor folder like this way:
vendor/
tomaivanovtomov/
yii2-revolution/
controllers/
models/
views/
slide/
index.php
How should I construct my url to reach them ? Before this it was simply www.example.com\backend\web\slide\index. Now it gave me an expected error but I realized that I don't know how to reach them. Is there any way or I should override the controller at least in my backend\controllers\ directory and the call it ? Thank you in advance!
EDIT Now I did it this way:
1. Override the `SlideController.php` to my `backend\controllers\` directroy
2. Extend the `vendor/tomaivanovtomov/revolution/controllers/SlideController.php`
3. In action index set the layout to `$this->layout = '#vendor/tomaivanovtomov/yii2-revolution/views/slide/index';`
4. And the return to `return $this->render('#vendor/tomaivanovtomov/yii2-revolution/views/slide/index', [
'dataProvider' => $dataProvider,
'hidden' => $hidden
]);`
This is my slide/index action:
public function actionIndex()
{
$this->layout = '#vendor/tomaivanovtomov/yii2-revolution/views/slide/index';
$searchModel = new SlideSearch();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
$hidden = new Slide();
return $this->render('#vendor/tomaivanovtomov/yii2-revolution/views/slide/index', [
'dataProvider' => $dataProvider,
'hidden' => $hidden
]);
}
This way it properly renders the view but error Undefined variable: hidden occures. Any sugestions why is that ? Thank you!
EDIT
Index file:
<?php
use yii\widgets\ListView;
use yii\widgets\ActiveForm;
use yii\helpers\Html;
use backend\components\BackendPrefix;
\kartik\file\FileInputAsset::register($this);
/* #var $this yii\web\View */
/* #var $searchModel backend\models\SlideSearch */
/* #var $dataProvider yii\data\ActiveDataProvider */
$this->title = Yii::t('app', 'Slides');
$this->params['breadcrumbs'][] = $this->title;
?>
<div class="row">
<div class="col-sm-12">
<div class="form-group">
<button type="button" class="btn btn-primary" onclick="addSlideModel('<?= BackendPrefix::PREFIX ?>')"><?= Yii::t('app', 'Add slide') ?></button>
</div>
</div>
<?php
$form = ActiveForm::begin([
'options' => [
'multipart/form-data'
],
'action' => [
'slide/create'
],
'id' => 'slides'
]);
//Hidden model to enable UploadFile class
echo $form->field($hidden, 'image[]')->fileInput(['class' => 'display-n'])->label(false);
echo ListView::widget([
'dataProvider' => $dataProvider,
'layout' => "{items}",
'itemView' => function( $model, $key, $index, $widget ){
return $this->render("_slideImage", [
'model' => $model,
'index' => $index
]);
},
]);
?>
<div class="col-sm-12">
<div class="form-group mt20">
<?= Html::submitButton(Yii::t('app', 'Save'), ['class' => 'btn btn-success']) ?>
</div>
</div>
<?php
ActiveForm::end();
?>
</div>

Related

Yii2 Basic call action from different controller

Is it possible to call action from a controller in different view ?
example
I have 2 controllers : Post and Blog , so I want to call actionCreate from post but inside blog view not in post view. I have 2 views and 2 controllers :
view :
1. views/blog/view
2. views/post/view
controller
1. controllers/blogController.php
2. controllers/postController.php
controllers/PostController.php :
public function actionCreate()
{
$model_Post = new Post();
if ($model_Post->load(Yii::$app->request->post()) && $model_Post->save()) {
return $this->redirect(['view', 'id' => $model_Post->Post_id]);
} else {
return $this->render('/blog/view', [
'model_Post' => $model_Post,
]);
}
}
views/blog/view.php
<?php
use yii\helpers\Html;
use yii\widgets\DetailView;
/* #var $this yii\web\View */
/* #var $model app\models\Likectt */
$this->title = $model->Blog_id;
?>
<div class="blog-view">
<h1><?= Html::encode($this->title) ?></h1>
<p>
<?= Html::a('Update', ['update', 'id' => $model->Blog_id], ['class' => 'btn btn-primary']) ?>
<?= Html::a('Delete', ['delete', 'id' => $model->Blog_id], [
'class' => 'btn btn-danger',
'data' => [
'confirm' => 'Are you sure you want to delete this item?',
'method' => 'post',
],
]) ?>
</p>
<?= DetailView::widget([
'model' => $model,
'attributes' => [
'Blog_id',
'Blog_title',
'Blog_text',
'User_id',
'Category_id',
],
]) ?>
<?= Yii::$app->runAction('PostController/actionCreate', ['model_Post'=>$model_Post]);?>
</div>
Yes you can do that :
In you blog view :
Yii::$app->runAction('postController/actionCreate', ['param1'=>'value1', 'param2'=>'value2']);

Yii2 Basic sql query in view

I'm trying to get the user profile image of the author of the content inside the view , my view is channel I created but I get this error on my view
Undefined variable: queryAvatar
on my view I did
//Yii2 View code
use yii\helpers\Html;
use yii\widgets\DetailView;
/* #var $this yii\web\View */
/* #var $model app\models\Channel */
$this->title = $model->Channel_name;
?>
<div class="channel-view">
<h1><?= Html::encode($this->title) ?></h1>
<div><?php echo $queryAvatar; ?></div> // THE LINE I ADD
<?php if($model->uid == Yii::$app->user->id):?>
<p>
<?= Html::a('Update', ['update', 'id' => $model->Channel_id], ['class' => 'btn btn-primary']) ?>
<?= Html::a('Delete', ['delete', 'id' => $model->Channel_id], [
'class' => 'btn btn-danger',
'data' => [
'confirm' => 'Are you sure you want to delete this item?',
'method' => 'post',
],
]) ?>
</p>
<?php endif;?>
</div>
and on my controller I created this function
//function on my controller
public function actionChannel($id)
{
$cchannel = new Channel();
$queryAvatar = (new \yii\db\Query())
->select(['uavatar'])
->from('userlogin')
->where(['uid' => $cchannel->uid])
->All();
return $this->render('channel', [
'model' => $this->findModel($id),
'queryAvatar '=> $queryAvatar ,
]);
}
in your controller you define an empty model so your $cchannel->uid is empty.
You must define first your model like this
public function actionChannel($id)
{
$cchannel = $this->findModel($id);
$queryAvatar = (new \yii\db\Query())
->select(['uavatar'])
->from('userlogin')
->where(['uid' => $cchannel->uid])
->All();
return $this->render('channel', [
'model' => $cchannel ,
'queryAvatar '=> $queryAvatar ,
]);
}
The problem can be caused by space when you created array of variable before giving to view.
return $this->render('channel', [
'model' => $this->findModel($id),
'queryAvatar '=> $queryAvatar ,
]);
remove space from 'queryAvatar '
Like this:
return $this->render('channel', [
'model' => $this->findModel($id),
'queryAvatar'=> $queryAvatar ,
]);
Another problem can be caused by partial view in side view. For example when you call view:channel from controller inside it may be you view called like this.
<?=$this->render('your_view')?>
So, you should pass your variable to this view also like this.
<?=$this->render('your_view',['queryAvatar'=>$queryAvatar])?>
And finally you cannot echo the varable $queryAvatar beacuse it is array of objects. Therefore use the function print_r();
Like this.
<div><?php print_r($queryAvatar); ?></div> // THE LINE I ADD

How to send model id to ActiveFrom field

I have a view team/view where I have details for the team (from the model Team).
views/team/view.php:
<?php
use yii\helpers\Html;
use yii\widgets\DetailView;
use yii\grid\GridView;
use yii\data\ActiveDataProvider;
use app\models\Pt;
/* #var $this yii\web\View */
/* #var $model app\models\Team */
$this->title = $model->name;
$this->params['breadcrumbs'][] = ['label' => 'Teams', 'url' => ['index']];
$this->params['breadcrumbs'][] = $this->title;
?>
<div class="team-view">
<h1><?= Html::encode($this->title) ?></h1>
<p>
<?= Html::a('Update', ['update', 'id' => $model->id], ['class' => 'btn btn-primary']) ?>
<?= Html::a('Delete', ['delete', 'id' => $model->id], [
'class' => 'btn btn-danger',
'data' => [
'confirm' => 'Are you sure you want to delete this item?',
'method' => 'post',
],
]) ?>
</p>
<?= DetailView::widget([
'model' => $model,
'attributes' => [
'tournament.name',
'teamindex',
'region.name',
'rank',
],
]) ?>
<?= Html::a('add players to the team', ['pt/create'], ['class'=> 'btn btn-success']) ?>
</div>
Last link is a link button to add players to the team: <?= Html::a('add players to the team', ['pt/create'], ['class'=> 'btn btn-success']) ?>
In views/pt/create I have an ActiveForm with fields: team (dropdown list), player (dropdown list). So, if I want to add a player to the team I should choose the team's name from a looong dropdown list and then choose a player (and some player options..).
Here is views/pt/create.php:
<?php
use yii\helpers\Html;
use yii\helpers\ArrayHelper;
/* #var $this yii\web\View */
/* #var $model app\models\Pt */
$this->title = 'Add players to the team';
$this->params['breadcrumbs'][] = ['label' => 'Players in teams', 'url' => ['index']];
$this->params['breadcrumbs'][] = $this->title;
?>
<div class="pt-create">
<h1><?= Html::encode($this->title) ?></h1>
<?= $this->render('_form', [
'model' => $model,
]) ?>
</div>
Here is views/pt/_form.php:
<?php
use yii\helpers\Html;
use yii\bootstrap\ActiveForm;
use app\models\Player;
use yii\helpers\ArrayHelper;
/* #var $this yii\web\View */
/* #var $model app\models\Pt */
/* #var $form yii\widgets\ActiveForm */
?>
<div class="pt-form">
<?php $form = ActiveForm::begin(['id'=>'owner-form']); ?>
<?= $form->field($model, 'team_id')->dropDownList($model->teamList) ?>
<?= $form->field($model, 'player_id')
->dropDownList(ArrayHelper::map(Player::find()->joinWith('category')
->orderBy(['lastname'=>SORT_ASC])->all(), 'id', 'lastname'));
?>
<div class="form-group">
<?= Html::submitButton($model->isNewRecord ? 'Add' : 'Update', ['class' => $model
->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
</div>
<?php ActiveForm::end(); ?>
</div>
I want like this: when I am on http://localhost/myproject/web/team/100 I click on that button <?= Html::a('add players to the team', ['pt/create'], ['class'=> 'btn btn-success']) ?>
and go to pt/create where in the field team already defined team_id =100 and so I need to input only player.
How can I do that? I know this is simple but I'm still learning.
PS: Models Team and Pt have relations,
models/Team.php
public function getPt()
{
return $this->hasMany(Pt::className(), ['team_id' => 'id']);
}
You should create a proper cation for create the player with the id_team already assigned (or you can modify the original create)
/**
* Creates a new Palyer model assigning the id_team.
* If creation is successful, the browser will be redirected to the 'view' page.
* #return mixed
*/
public function actionCreateForTeam(id_team)
{
$model = new Player();
if ($model->load(Yii::$app->request->post()) && $model->save()) {
return $this->redirect(['view', 'id' => $model->id]);
} else {
$model->id_team = $id_team
return $this->render('create', [
'model' => $model,
]);
}
}
Then send the proper id_team
Html::a('add players to the team', ['pt/create-for-teaam', 'id_team'=> $model->team_id],
['class'=> 'btn btn-success']) ?>

Get data from select2 and pass it to controller in yii2

I've one select2 form field, two datepickers and a search button in productnames index file. It is only to search data I'm unable to get the data selected in the select2 widget and pass it to controller which in turn can search other models.
index.php
<?php
use yii\helpers\Html;
use yii\grid\GridView;
use kartik\select2\Select2;
use dosamigos\datepicker\DatePicker;
use yii\helpers\ArrayHelper;
use frontend\modules\sbbtdtproduct\models\Productnames;
use yii\helpers\Json;
/* #var $this yii\web\View */
/* #var $searchModel frontend\modules\sbbtdtproduct\models\ProductnamesSearch */
/* #var $dataProvider yii\data\ActiveDataProvider */
$this->title = 'Productnames';
$this->params['breadcrumbs'][] = $this->title;
?>
<div class="productnames-index">
<h1><?= Html::encode($this->title) ?></h1>
<?php // echo $this->render('_search', ['model' => $searchModel]); ?>
<div class="row">
<div class="form-group">
<div class="col-xs-5 col-sm-5 col-lg-5" >
<?php
echo Select2::widget([
'model' => $model,
'attribute' => 'productnames_productname',
'data' => ArrayHelper::map(Productnames::find()->all(),'productnames_productname','productnames_productname'),
'options' => ['placeholder' => 'Select Product'],
'pluginOptions' => [
'allowClear' => true
],
//'productname' => $productname,
]);
?>
</div>
<div class="col-xs-3 col-sm-3 col-lg-3">
<?= DatePicker::widget([
'name' => 'Start Date',
'attribute' => 'from_date',
'value' => '2014-01-31',
'template' => '{addon}{input}',
'clientOptions' => [
'autoclose' => true,
'format' => 'yyyy-mm-dd'
]
]);?>
</div>
<div class="col-xs-3 col-sm-3 col-lg-3">
<?= DatePicker::widget([
'name' => 'End Date',
'attribute' => 'to_date',
'value' => '2014-01-31',
'template' => '{addon}{input}',
'clientOptions' => [
'autoclose' => true,
'format' => 'yyyy-mm-dd'
]
]);?>
</div>
<div class="col-xs-1 col-sm-1 col-lg-1" >
<?= Html::a('Search', ['/sbbtdtproduct/production/index','productname' => $model['productnames_productname']], ['class'=>'btn btn-primary']) ?>
</div>
</div>
</div>
</div>
production controller action
public function actionIndex($productname)
{
$productname = yii::$app->request->get('productnames_productname');
$searchModel = new ProductionSearch();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams, $productname);
return $this->render('index', [
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
]);
}
productionsearch model
public function search($params,$productname)
{
$query = Production::find()
->where(['productname' => $productname]);
// add conditions that should always apply here
$dataProvider = new ActiveDataProvider([
'query' => $query,
]);
$this->load($params);
if (!$this->validate()) {
// uncomment the following line if you do not want to return any records when validation fails
// $query->where('0=1');
return $dataProvider;
}
// grid filtering conditions
$query->andFilterWhere([
'productionid' => $this->productionid,
'productiondate' => $this->productiondate,
'itemid' => $this->itemid,
'prodqty' => $this->prodqty,
]);
$query->andFilterWhere(['like', 'productname', $this->productname])
->andFilterWhere(['like', 'batchno', $this->batchno]);
return $dataProvider;
}
error -
update -
Database Log
The data base Log shows that no value has been passed from search model.
I can see the value selected in select2 or datepicker as below, but it's not passing to the controller.
1.on your view page
You have not added form tag, so other parameters will not get posted, you must add everything inside form tag and submit that form, as follows
<?php
use yii\helpers\Html;
use yii\grid\GridView;
use kartik\select2\Select2;
use dosamigos\datepicker\DatePicker;
use yii\helpers\ArrayHelper;
use frontend\modules\sbbtdtproduct\models\Productnames;
use yii\helpers\Json;
use yii\widgets\ActiveForm;
/* #var $this yii\web\View */
/* #var $searchModel frontend\modules\sbbtdtproduct\models\ProductnamesSearch */
/* #var $dataProvider yii\data\ActiveDataProvider */
$this->title = 'Productnames';
$this->params['breadcrumbs'][] = $this->title;
?>
<div class="productnames-index">
<h1><?= Html::encode($this->title) ?></h1>
<?php // echo $this->render('_search', ['model' => $searchModel]);
$form = ActiveForm::begin([
'action' => ['/sbbtdtproduct/production/index'],
'method' => 'post',
'options' => ['data-pjax' => true],
'enableClientValidation' => FALSE
]);
?>
<div class="row">
<div class="form-group">
<div class="col-xs-5 col-sm-5 col-lg-5" >
<?php
echo Select2::widget([
'model' => $model,
'attribute' => 'productnames_productname',
'data' => ArrayHelper::map(Productnames::find()->all(),'productnames_productname','productnames_productname'),
'options' => ['placeholder' => 'Select Product'],
'pluginOptions' => [
'allowClear' => true
],
//'productname' => $productname,
]);
?>
</div>
<div class="col-xs-3 col-sm-3 col-lg-3">
<?= DatePicker::widget([
'name' => 'Start Date',
'attribute' => 'from_date',
'value' => '2014-01-31',
'template' => '{addon}{input}',
'clientOptions' => [
'autoclose' => true,
'format' => 'yyyy-mm-dd'
]
]);?>
</div>
<div class="col-xs-3 col-sm-3 col-lg-3">
<?= DatePicker::widget([
'name' => 'End Date',
'attribute' => 'to_date',
'value' => '2014-01-31',
'template' => '{addon}{input}',
'clientOptions' => [
'autoclose' => true,
'format' => 'yyyy-mm-dd'
]
]);?>
</div>
<div class="col-xs-1 col-sm-1 col-lg-1" >
<?= Html::submitButton('Search', ['class'=>'btn btn-primary']) ?>
<?php ActiveForm::end(); ?>
</div>
</div>
</div>
</div>
2.Controller
now inside your controller you can access parametes as follows
public function actionIndex()
{
$productname = Yii::$app->request->post('productnames_productname');
$searchModel = new ProductionSearch();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams, $productname);
return $this->render('index', [
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
]);
}

Yii2 - Search exact value and return result in detailview

I need to put on the page to search by protocol number, and display only one result when the entered protocol number is exactly the same. If possible the results to be shown, it is a DetailView
My model OccurrenceSearch:
public function searchprotocol($params)
{
$query = Occurrence::find();
$dataProvider = new ActiveDataProvider([
'query' => $query,
]);
$this->load($params);
if (!$this->validate()) {
return $dataProvider;
}
$query->andFilterWhere([
'protocol' => $this->protocol,
]);
return $dataProvider;
}
}
My view search:
<?php
use yii\helpers\Html;
use yii\widgets\ActiveForm;
?>
<div class="occurrence-search">
<?php $form = ActiveForm::begin([
'action' => ['search'],
'method' => 'get',
]); ?>
<?= $form->field($model, 'protocol') ?>
<div class="form-group">
<?= Html::submitButton('Search', ['class' => 'btn btn-primary']) ?>
</div>
<?php ActiveForm::end(); ?>
</div>
My controller actionSearch() :
public function actionSearch()
{
$searchModel = new OccurrenceSearch();
$dataProvider = $searchModel->searchprotocol(Yii::$app->request->queryParams);
return $this->render('search', [
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
]);
}
The guest user can see only the record for its protocol number
The a detailView use model (and not dataProvider) for show the data instance ..
then in you controller you should obtain the model
public function actionSearch()
{
$searchModel = new OccurrenceSearch();
$dataProvider = $searchModel->searchprotocol(Yii::$app->request->queryParams);
$model = $dataProvider->query->one();
return $this->render('search', [
'searchModel' => $searchModel,
//'dataProvider' => $dataProvider,
'model' => $model,
]);
}
But in you view the code proposed don't show a detailView widget .. you should probably add
I decided to use the GRIDVIEW, and so changed the MymodelSearch
if (isset($_GET['AuthorSearch']) && !($this->load($params) && $this->validate())) {
return $dataProvider;
}