Insert rows in other tables on creation in yii - php

For the following database:
TABLES:
user: [id,username]
project: [id,name]
project_user_assignment: [user_id,project_id,role]
When a new project is being created I'd like to show a dropdown with the available users to manage the project and when saving it insert into project_user_assignment the row
[user_id,project_id,'manager']
I'm starter with yii and don't know where (class,method) I must do the insert and how to return an error if in the moment of the insert the query fails

To display a drop down list in the you can use the foliowing code:
<?php echo CHtml::dropDownList(null,
'type',
CHtml::listData(
User::model()->findAll(),
'id',
'username',
),
array('empty' => 'Select a manager from the list ... ', 'id'=>'manager_list')
);?>
to update the corresponding field of the project_user_assignment model use the following:
<?php
<div class="row">
<?php echo $form->labelEx($model,'user_id'); ?> // Here I assume you have the $model variable set to Project_user_assignemenet ... if not (which probably is the case since you are creating a new project, set a new $model2 variable in the controller and use $model2 instead of $model)
<?php echo $form->textArea($model,'user_id'); ?>
<?php echo $form->error($model,'user_id'); ?>
</div>
?>
<script>
$('#manager_list').on('change', function(e) {
$('#Project_user_assignemenet_user_id').val($(this).val()); // Here id maybe wrong! Check them.
return true;
});
</script>
and finally in the controller you just save the model.

Related

creating a multi_models signup page for Yii2 and saving that info in session

I am working on a personal Yii2 project and I am stuck! I don't know how to :
create a sing up page which has a form to create two related models (Organization & Employee ) and use a third one (Employee_Role)
Store these info in a session and use that session later.
General Scenario :
Admin signups by filling :
an Organization name
and username & password & email (for the Admin employee)
if the values are valid then the system creates "Organization" with an auto_generated organization_id.
Then, System creates "Employee" (which will need organization_id and assign this user to Admin "Employee_Role")
Then, the system keeps the following info in session: (organization_id, employee_id, role_id, timestamp ) and takes the user to admin home page.
Note, I am keeping the Models in the Common folder and the Controllers in the front-end and so should be the Views.
I appreciate your help,
This is a general outline of what you can do to solve your problem. You will need to add the actual fields to the form for both Organization and Employee.
The controller action:
public function actionSignup() {
$post = Yii::$app->request->post();
$organization = new Organization();
$employee = new Employee();
// we try to load both models with the info we get from post
if($organization->load($organization) && $employee->load($organization)) {
// we begin a db transaction
$transaction = $organization->db->beginTransaction();
try {
// Try to save the organization
if(!$organization->save()) {
throw new \Exception( 'Saving Organization Error' );
}
// Assign the organization id and other values to the employee
$employee->organization_id = $organization->id;
...
// Try to save the employee
if(!$employee->save()) {
throw new \Exception( 'Saving Employee Error' );
}
// We use setFlash to set values in the session.
// Important to add a 3rd param as false if you want to access these values without deleting them.
// But then you need to manually delete them using removeFlash('organization_id')
// You can use getFlash('organization_id'); somewhere else to get the value saved in the session.
Yii::$app->session->setFlash('organization_id', $organization->id)
Yii::$app->session->setFlash('employee_id', $employee->id)
...
// we finally commit the db transaction
$transaction->commit();
return $this->redirect(['somewhere_else']);
}
catch(\Exception e) {
// If we get any exception we do a rollback on the db transaction
$transaction->rollback();
}
}
return $this->render('the_view', [
'organization' => $organization,
'employee' => $employee,
]);
}
The view file:
<?php
use yii\helpers\Html;
use yii\widgets\ActiveForm;
?>
<?php $form = ActiveForm::begin() ?>
<?= $form->field($organization, 'some_organization_field') ?>
<!-- More Fields -->
<?= $form->field($employee, 'some_employee_field') ?>
<!-- More Fields -->
<?= Html::submitButton('Save', ['class' => 'btn btn-primary']) ?>
<?php ActiveForm::end() ?>

Create survey form in Yii2 with multiple choice answers

Im new to Yii, and would appreciate any help.
I need to create a page with multiple choice poll. My models look like this:
PollQuestion:
id int
title varchar
PollAnswer
id char //one letter - answer option
title
question_id //FK pool_question(id)
PollResult
user_id int
question_id int //FK poll_question(id)
answers //will be stored like A,B,C
indicated_answer //alternaive answer specified by user
Sample question looks like:
What do you think about us?
(checkbox)A. Good
(checkbox)B.Bad
(checkbox)C.Other (indicate) (textbox goes here)
Im not sure if Im doing it right, my controller:
public function actionSurvey($user_id)
{
$model = [new PollResult];
foreach($model as $model_item){
$model_item->user_id= $user_id;
if ($model_item->load(Yii::$app->request->post())) {
//only one item received, why??
}
}
return $this->render('survey', ['model' => $model]);
}
View:
<?php $form = ActiveForm::begin(); ?>
<?php foreach(PollQuestion::find()->all() as $question) {?>
<?php foreach($model as $model_item) { ?>
<p><?=$question->title?></p>
<?= Html::activeHiddenInput($model_item , "user_id"); ?>
<?= $form->field($model_item, 'answers')->checkboxList(ArrayHelper::map($question->pollAnswers, 'id', 'title')?>
<?= $form->field($model_item, 'indicated_answer') ->textInput()?>
<?php } }?>
<div class="form-group">
<?= Html::submitButton(Yii::t('app', 'Send'), ['class' => 'btn btn-success' ]) ?> </div>
<?php ActiveForm::end(); ?>
The problem is that in controller i receive only one item in array. Im not sure what am I doing wrong.
My suggestion, you need an extra form model to do that.
You can see how to create form model on http://www.yiiframework.com/doc-2.0/guide-input-forms.html.
The form model you create at least has this attributes:
answers[]
indicated_answer[]
and you can save input from user to that attributes and save them into your ActiveRecord model.
It is correct that one model entry is returned. In your form, you are creating a single model and passing that to the form.
public function actionSurvey($user_id)
{
$model = [new PollResult];
// ...
return $this->render('survey', ['model' => $model]);
}
You can then expect a single model back.
Have a look at this related issue on how you can solve this.
Utilising Yii2.0 checkboxlist for Parent-child relation models

CakePHP why is associated null?

I have several tables and corresponding models, that is to say, Staffs, Dpmembers, Subjects and Positions tables.
In my Staff model I create hasOne on Department because I want to retrieve data from Department table which is working.
But I have also created more associations of hasMany on Dpmember, Subject and Position models because I want to save the corresponding staff records.
The view newstaff.ctp looks like this
<div class="staff form">
<?php echo $this->Form->create('Staff');?>
<h3><?php echo __('Add a new staff member'); ?></h3>
<?php
echo $this->Form->input('name');
echo $this->Form->input('marital',array('label'=>'Marital status','options'=>array('empty'=>'Choose status','Single'=>'Single','Divorced'=>'Divorced','Married'=>'Married')));
echo $this->Form->input('Children');
echo $this->Form->input('nationality');
echo $this->Form->input('location');
echo $this->Form->input('email');
echo $this->Form->input('phone',array('label'=>'Phone number'));
echo $this->Form->input('nextofkeen',array('label'=>'Next of keen'));
echo $this->Form->input('keenrelation',array('label'=>'Next of keen relationship','options'=>array('Choose option'=>'Choose option','Husband'=>'Husband','Wife'=>'Wife','Guardian'=>'Gaurdian','Child'=>'Child')));
echo $this->Form->input('school');
echo $this->Form->input('award');
echo $this->Form->input('schoolperiod');
echo $this->Form->input('workplace',array('label'=>'Workplace'));
echo $this->Form->input('workposition');
echo $this->Form->input('workperiod');
echo $this->Form->input('dpmember.department.',array('options'=>$department,'empty'=>'Choose Department','label'=>'Department'));
echo $this->Form->input('subject.subjcet',array('options'=>array('Choose option'=>'Choose option','Science'=>'Science','Social Studies'=>'Social studies','English'=>'English','Mathematics'=>'Mathematics'),'label'=>'Subject'));
echo $this->Form->input('position.role',array('options'=>array('Choose option'=>'Choose option','Class teacher'=>'Class teacher','Bursar'=>'Bursar','Cook'=>'Cook'),'label'=>'Position'));
echo $this->Form->submit('Save staff', array('class' => 'btn btn-success', 'title' => 'Click here to add the user') );
?>
<?php echo $this->Form->end(); ?>
</div>
My Staff Model Staff.php like this
<?php
class Staff extends AppModel{
public $hasOne = array(
'Department'=>array(
'className'=>'Department'
));
public $hasMany = array(
'Dpmember'=>array(
'className'=>'Dpmember',
'foreign_key'=>'Dpmember.staff_id'
),
'Subject'=>array(
'className'=>'Subject',
'foreign_key'=>'Subject.staff_id'
),
'Position'=>array(
'className'=>'Position',
'foreign_key'=>'Position.staff_id'
)
);
}
?>
In my StaffsController.php I have a function newstaff() with the code below
public function newstaff() {
/*Create a select form field for departments */
$department = $this->Staff->Department->find('list',array('fields'=>array('Department.title','Department.title')));
$this->set('department', $department);
/*End creation of a select form field for departments */
if (!empty($this->request->data)) {
debug($this->request->data); // returns all data
debug($this->Staff->Subject->subject); // has returned null
debug($this->Staff->Position->position); // has returned null
debug($this->Staff->Dpmember->departement); // has returned null
}
}
I don't know why but for some reason, I have not been able to found out. Running debug($this->request->data) returns expected data.
But accessing individual associated form fields returns null values not the expected data. Please help me.
Thank you
You seem to be using CakePHP 3.0 syntax, while using CakePHP 2.3. The data returned is an array in Cake 2, not an object. So the data is under array keys, like:
$this->request->data['Staff']['Subject']['subject'];
$this->request->data['Staff']['Position']['position'];
$this->request->data['Staff']['Dpmember']['departement'];
Well I think finally I have got the values which are not null. Since I created relationships or rather associations among the models and am using CakePHP 2.3 the right way is
$this->request->data['associateModel']['FormField'];
Therefore I was supposed to do.
$this->request['Subject']['subject'];
$this->request['Subject']['position'];
$this->request['Subject']['department'];
Thank you very much #Oldskool

How to add functions to a MVC Joomla component to access data from a different table?

I have a custom joomla MVC component created by http://component-creator.com with 4 tables:
#__mycomponent_items 27 Fields
#__mycomponent_bids 12 Fields
#__mycomponent_journeys 9 Fields
#__mycomponent_users 8 Fields
I am trying to set the relationships between these tables, but in the absence of documentation and experience I am struggling.
The basic relationships between the tables need to allow USERS to make BIDS to deliver ITEMS.
So I have created fields for items like this:
#__mycomponent_items
id
created
updated
ordering
state
checked_out
checked_out_time
created_by
deliverydestination
itemtitle
status
requiredby
listprice
deliveredprice
commission
points_reward
accepted_bid
accepted_bidder
accepted_journey
And for bid like this:
#__mycomponent_bids
id
state
created_by
item_id
buyer
bid
created
updated
bid_status
bid_expires
journey
arrival_date
I am working in templates/mytemplate/html/com_mycomponent/item/default.php and trying to add to that view a list of the current bids on that item. To do that I assume I need to add a custom function to /components/com_mycomponent/models/item.php and the function I have created is follows:
function itemBids() {
// Get a db connection.
$db = JFactory::getDbo();
// Create a new query object.
$query = $db->getQuery(true);
// Select item record matching the $orderID
$query
//->select('*')
->select($db->quoteName(array('id', 'created_by', 'created', 'bid', 'bid_status', 'arrival_date')))
->from($db->quoteName('#__mycomponent_bids'))
->where('item_id = item.id');
// Reset the query using our newly populated query object.
// Load the results as a list of stdClass objects (see later for more options on retrieving data).
$db->setQuery($query);
$itemBids = $db->loadObjectList();
//print_r($itemBids);
}
How do I then access the data in the view /mytemplate/html/com_mycomponent/item/default.php?
I have tried this and it returns nothing:
<ul>
<?php foreach ($itemBids as $itemBid) :?>
<?php $arrivalDate = $itemBid->arrival_date; ?>
<li><strong><?php echo $itemBid->created_by; ?></strong> <small>can deliver for</small> $<?php echo $itemBid->bid;?> <small>
<?php /*?><abbr class="timeago" title="<?php echo $itemBid->created; ?>"></abbr><?php */?>
in <strong><abbr class="timeago" title="<?php echo $arrivalDate; ?>"></abbr></strong></small><div class="uk-badge uk-float-right"><?php echo $itemBid->bid_status; ?></div></li>
<?php endforeach; ?>
</ul>
You wouldn't be putting it in your template like that. the template just holds the layouts that generate the html. Also you need to have a default layout in your views/myview/tmpl folder.
You don't seem to be returning anything from your itemBids() function. You would want to add return $itemBids; or possibly return $this->itemBids; depending on what you are doing elsewhere.
YOu want to get $this->itemBids in your view.html.php class so that it is then available to your layout. THen instead of referring to $itemBids you can refer to $this->itemBids in your loop in the layout.
Have you been through the Creating an MVC Cmponent tutorial? It would probably help you get a sense of how MVC works in Joomla.
OK , as far as I understand you have a method in yourmodel.php and you are trying to access it from the view I did notice that you are not returning any values in your method
return $db->loadObjectList();
let me just make it simple by the below code
//com_component/models/yourmodel.php
class componentModelYourmodel extends JModelLegacy
{
function yourMethod()
{
//code
return $value;
}
}
And then in view file
//com_component/views/yourview/tmpl/default.php
//get the model first
$model=$this->getModel();
//call the method
$items=$model->yourMethod();
//print
print_r($items);

How to send the request through POST and how to access attributes of the model?

I am a bit new to the Yii Framework. I am making a product selling website, which has 3 basic models
1. Users model containing the primary key id
2. Products model containing the primary key id
3. Orders model which is basically a mapping between the products and orders. It contains the fields product_id and user_id as foreign keys.
I have made a page where all the products are populated and the logged in user can click on a button on product box to order a particular product.
the code of the link is like this
<?php echo CHtml::link('Order Now',array('order',
'product_id'=>$model->id,
'user_id'=>Yii::app()->user->id)); ?>
(Q1) This is sending a GET request but I want to sent the details as post request. How to do this?
My default controller is the site controller. I have made an actionOrder method in this controller.
The code is:
if(Yii::app()->user->isGuest){
$this->redirect('login');
}else{
$model=new Orders;
if(isset($_POST['products_id']))
{
$model->attributes->products_id=$_POST['product_id'];
$model->attributes->users_id=Yii::app()->user->id;
if($model->save())
$this->redirect(array('index'));
}
$this->render('index');
}
But this code is showing bunch of errors. Also, (Q2) how can I put both products_id and users_id in a single array Orders so that I just have to write $_POST['orders']
Also, (Q3) how can I display a flash message after the save is successful?
Kindly help me to solve my 3 problems and sorry if you feel that the questions are too stupid.
Q1: If you want to use POST request, you're going to have to use a form of sorts, in this case the CActiveForm.
Controller:
public function actionOrder()
{
if(Yii::app()->user->isGuest)
$this->redirect('login');
else
{
$model=new Orders;
if(isset($_POST['Orders']))
{
$model->product_id=$_POST['Orders']['products_id'];
$model->users_id = Yii::app()->user->id;
if($model->save())
{
// Q3: set the flashmessage
Yii::app()->user->setFlash('ordered','The product has been ordered!');
$this->redirect(array('index'));
}
}
$this->render('index', array('model'=>$model)); //send the orders model to the view
}
}
View:
<!-- Q3: show the flash message if it's set -->
<?php if (Yii::app()->user->hasFlash('ordered')): ?>
<?php echo Yii::app()->user->getFlash('ordered'); ?>
<?php endif ?>
...
<?php $form=$this->beginWidget('CActiveForm', array('id'=>'order-form')); ?>
<?php echo $form->hiddenField($model,'products_id',array('value'=>$product->id)); ?> // please note the change of variable name
<?php echo CHtml::submitButton('Order Now'); ?>
<?php $this->endWidget(); ?>
Please note that I have changed the name of the product model variable $model to $product, because we will be using $model for the Orders model for the form.
Q2: In this case I set the users_id value in the controller, so $_POST['Orders'] only contains the value for products_id. In yii you can also mass assign your attributes with:
$model->attributes = $_POST['Orders']
Which basicly means $_POST['Orders'] is already an associative array containing the attribute names and values that are in your form.
Q3: The code shows you how to set and show a flash message after an order is succesfull.
First you have to declare forms send method, if you're using bootsrap it'll be like mine:
<?php $form = $this->beginWidget('bootstrap.widgets.TbActiveForm', array(
'action' => Yii::app()->createUrl($this->route),
'method' => 'post',
'id' => 'activity_timeRpt',
));
?>
Second if you want to send custom inputs, you have to specify, otherwise it'll be like
i'll be back to finish this
For your questions 1 and 2 I'd recomend you to use a CActiveForm class. For example
<?php $form = $this->beginWidget('CActiveForm', array(
'action' => 'you_action_here'
'method'=>'post' // this is optinal parameter, as 'post' is default value
)); ?>
<?php echo $form->textField($model,'product_id'); ?>
<?php echo $form->hiddenField($model,'user_id', array('value'=>Yii::app()->user->id)); ?>
<?php $this->endWidget(); ?>
where $model is instance of Orders class, passed by variables thru controller, or set in view file. After that you can use it in way you wanted $model->attributes = $_POST['orders'] in your action method.
For flash message you can use Yii->app()->user->setFlash('orderStatus', 'Successful'), before redirect( or render ) in your actionOrder. To show it:
<?php if(Yii::app()->user->hasFlash('orderStatus')):?>
<div class="info">
<?php echo Yii::app()->user->getFlash('orderStatus'); ?>
</div>
<?php endif; ?>

Categories