Cakephp : display data in a table with other table's data - cakephp

I'm displaying my users in a table, and I am retrieving the company name and city with company_id
users :
id lastname firstname company_id role
1 doe john 2 author
2 deo jenne 2 admin
3 deus Joe 1 admin
4 Stewart Rob 1 author
companies :
id name city
1 New-York Company New-York
2 Paris Company Paris
user display :
<?php
foreach($users as $user):?>
<tr>
<td><?= $user->lastname?></td>
<td><?= $user->firstname?></td>
<td><?= $user->companies->name ?></td>
<td><?= $user->companies->city?></td>
<td><?= $user->role?></td>
</tr>
<?php endforeach;?>
usersTable.php :
<?php
namespace App\Model\Table;
use Cake\ORM\Table;
use Cake\Validation\Validator;
class UsersTable extends Table
{
public function initialize(array $config){
$this->belongsToMany('Companies');
$this->belongsTo('Companies', [
'foreignKey' => 'company_id',
]);
}
}
?>
So in my company display, I would like to retrieve admin and author names, like so :
<?php
foreach($companies as $company):?>
<tr>
<td><?= $company->name?></td>
<td><?= $company->city?></td>
<td><?= $company->users-> *adminlastname* ?></td>
<td><?= $company->users-> *adminfirstname* ?></td>
<td><?= $company->users-> *authorlastname* ?></td>
<td><?= $company->users-> *authorfirstname* ?></td>
</tr>
<?php endforeach;?>
I have tried getting company id to reference company_id in users for starters to get on track, without success(trying to get property of non-object)
Furthermore, would it work if I have several authors and admins ? Less likely to several admins per companies, but can happen, and several authors is definetely possible
companiesTable :
<?php
namespace App\Model\Table;
use Cake\ORM\Table;
use Cake\Validation\Validator;
class companiesTable extends Table
{
public function initialize(array $config){
//$this->addBehavior('Timestamp');
$this->hasMany('Users');
$this->hasMany('companies', [
'foreignKey' => 'identite',
]);
$this->hasMany('Admins', [
'className' => 'Users',
'conditions' => [
'Admins.role' => 'admin'
]
]);
$this->hasMany('Authors', [
'className' => 'Users',
'conditions' => [
'Admins.role' => 'author'
]
]);
}
public function isOwnedBy($companyId, $userId){
$company = $this
->find('all',['conditions' => ['companies.id'=>$companyId]])
->matching('Users', function ($q) use ($userId) {
return $q->where(['Users.id' => $userId]);
})
->first();
if ($company) return true;
return false;
}
}
Edit : adding Companies/index.ctp, still too new, I do not see at all what's wrong... :
<div class="row">
<div class="medium-4 small-12 columns">
<div style="padding: 22px;">
<h2>companies</h2>
</div>
<div id="customAdd" style="clear:both;padding: 22px;">
add
<div style="clear:both;height:0px;"></div>
</div>
<div id="customSearch" style="clear: both;padding: 22px">
<p style="font-size:36px; display: inline-block;">search for a company</p><input type="text" id="searchBox">
</div>
</div>
<div class="medium-8 small-12 columns">
<div>
<table id="companies" class="cell-border dataTable no-footer">
<thead>
<tr>
<th>name</th>
<th>city</th>
<th>last name</th>
<th>first name</th>
</tr>
</thead>
<tbody>
<?php foreach ($company->users as $user):?>
<tr class='clickable-row' data-href="/companies/edit/<?= $company->id?>">
<td><?= $company->name?></td>
<td><?= $company->city?></td>
<td><?= $company->users[0]->lastname?></td>
<td><?= $company->users[0]->firstname?></td>
</tr>
<?php endforeach;?>
</tbody>
</table>
</div>
</div>
</div>
I am getting these errors :
Notice (8): Undefined variable: company [APP/Template/Companies/index.ctp, line 36]
Notice (8): Trying to get property of non-object [APP/Template/Companies/index.ctp, line 36]
Warning (2): Invalid argument supplied for foreach() [APP/Template/Companies/index.ctp, line 36]
which corresponds to this :
<?php foreach ($company->users as $user):?>
CompaniesController :
<?php
namespace App\Controller;
use Cake\ORM\TableRegistry;
class CompaniesController extends AppController{
public function index(){
$companies = $this->Companies
->find('all',['order' => ['Companies.name' => 'ASC']]);
$this->set(compact('companies'));
$this->loadModel('Users');
$users = $this->Users->find('all')
->contain(['companies']);
$this->set(compact('users'));
}
public function view($id = null){
$company = $this->Companies->get($id);
$this->set(compact('company'));
}
public function add(){
$company = $this->Companies->newEntity();
if ($this->request->is('post')) {
if ($this->Companies->save($company)) {
$this->Flash->success(__('Your company has been saved.'));
return $this->redirect(['action' => 'index']);
}
$this->Flash->error(__('Unable to add your company.'));
}
$this->set('company', $company);
$this->set(compact('companies'));
}
public function edit($id = null){
$company = $this->Companies->get($id);
if ($this->request->is(['post', 'put'])) {
$company = $this->Companies->patchEntity($company, $this->request->data,['associated' => ['Users']]);
if ($this->Companies->save($company)) {
$this->Flash->success(__('Your company has been updated.'));
return $this->redirect(['action' => 'index']);
}
$this->Flash->error(__('Unable to update your company.'));
}
$this->set('company', $company);
$this->set(compact('companies'));
}
public function delete($id){
$this->request->allowMethod(['post', 'delete']);
$company = $this->Companies->get($id);
if ($this->Companies->delete($company)) {
$this->Flash->success(__('The company with id: {0} has been deleted.', h($id)));
return $this->redirect(['action' => 'index']);
}
}
public function isAuthorized($user){
if ($this->request->action === 'logout') {
return true;
}
if ($this->request->action === 'settings') {
return true;
}
return parent::isAuthorized($user);
}
}
thanks in advance

First things first, you cannot define multiple associations with the same name. Given that you have a company_id field, that is a belongsTo association from the users point of view.
Given these prerequisites, it's naturally a hasMany association from the companies point of view. I assume that you've set that up already in your CompaniesTable class, if not, then that's what you need to do first.
The users property will then be an array of User entitiy objects, so you need to access it accordingly, that is either directly via an index:
$company->users[0]->firstname
or by iterating over it:
foreach ($company->users as $user) {
// $user->firstname
}
If you need to handle the users separated by their roles, then you could for example filter them accordingly:
$admins = collection($company->users)->filter(function ($user) {
return $user->role === 'admin';
});
or maybe better yet create separate associations using conditions:
$this->hasMany('Admins', [
'className' => 'Users',
'conditions' => [
'Admins.role' => 'admin'
]
]);
$this->hasMany('Authors', [
'className' => 'Users',
'conditions' => [
'Admins.role' => 'author'
]
]);
That way you could contain and access the different types of users separately:
$company->admins
$company->authors
See also
Cookbook > Database Access & ORM > Associations - Linking Tables Together
Cookbook > Database Access & ORM > Retrieving Data & Results Sets > Eager Loading Associations Via Contain

Related

Cakephp retrieving row data from a table

I'm attempting to insert data from a row in one table into another following a button click. I have a table containing class information. When the user clicks register, I need to take the id of that class and insert it into my timetable table.
So far I'm trying to obtain the id from the POST data. However, when I run the debugger, the id for the class in the array is empty.
My register function:
public function register(){
$classestimetable = $this->Classestimetable->newEntity();
if ($this->request->is('post')) {
$classestimetable->user_id = $this->Auth->user('id');
$classestimetable->unit_id = $this->request->getData(['id']);
debug($classestimetable);exit;
if ($this->Classestimetable->save($classestimetable)) {
$this->Flash->success(__('The class has been added to your schedule.'));
return $this->redirect(['action' => 'index']);
}
$this->Flash->error(__('The class could not be added. Please, try again.'));
}
}
Table code:
<tbody>
<?php foreach ($units as $unit): ?>
<tr>
<td hidden><?= h($unit->id) ?></td>
<td><?= h($unit->className) ?></td>
<td><?= h($unit->user->firstName), ' ', h($unit->user->lastName) ?></td>
<td><?= h($unit->classDate) ?></td>
<td><?= h($unit->classTime) ?></td>
<td class="actions">
<?= $this->Form->postLink(__('Register'), ['action' => 'register', $unit->id], ['confirm' => __('Are you sure you want to register for "{0}"?', $unit->className)]) ?>
</td>
</tr>
<?php endforeach; ?>
</tbody>
Debug output:
object(App\Model\Entity\Classestimetable) {
'user_id' => (int) 11,
'unit_id' => null,
'[new]' => true,
'[accessible]' => [
'unit_id' => true,
'user_id' => true,
'unit' => true,
'user' => true
],
'[dirty]' => [
'user_id' => true,
'unit_id' => true
],
'[original]' => [],
'[virtual]' => [],
'[hasErrors]' => false,
'[errors]' => [],
'[invalid]' => [],
'[repository]' => 'Classestimetable'
}
When working I'm hoping the unit_id field will contain the id of the class the user has chosen to register for.
You are using $this->request->getData(['id']) to get the id. But in the URL you're building, you haven't named that parameter. Either change to:
['action' => 'register', 'id' => $unit->id]
or else change the definition of your function to:
public function register($id)
and then use $classestimetable->unit_id = $id;

Cakephp application form

I created an application form using cakephp 2.
Now I want to know, How can users view only their application details using their user id. Here is the Form controller, the application form and the table for displaying the form
//Form controller
public function index() {
$this->set('posts', $this->Post->find('all'));
}
public function view($id = null) {
if (!$id) {
throw new NotFoundException(__('Invalid post'));
}
$post = $this->Post->findById($id);
if (!$post) {
throw new NotFoundException(__('Invalid post'));
}
$this->set('post', $post);
}
public function add() {
if ($this->request->is('post')) {
$this->Post->create();
if ($this->Post->save($this->request->data)) {
$this->Flash->success(__('Your post has been saved.'));
return $this->redirect(array('action' => 'index'));
}
$this->Flash->error(__('Unable to add your post.'));
}
}
//Create form
echo $this->Form->create('Post');
echo $this->Form->input('esta',['label'=>'New or Estabilished']);
echo $this->Form->end('Save Post');
//Form display
<table>
<tr>
<th>Id</th>
<th>Title</th>
<th>Created</th>
</tr>
<?php foreach ($posts as $post): ?>
<tr>
<td><?php echo $post['Post']['id']; ?></td>
<td>
<?php echo $this->Html->link($post['Post']['describe_idea'],
array('controller' => 'posts', 'action' => 'view', $post['Post']['id'])); ?>
</td>
<td><?php echo $post['Post']['created']; ?></td>
</tr>
<?php endforeach; ?>
<?php unset($post); ?>
</table>
You said that you are using cakephp 2.x please find below code to find record
for Single Record
$posts = $this->Post->find('first', array(
'conditions' => array('id' => 1)
));
For Multiple record
$posts = $this->Post->find('all', array(
'conditions' => array('id' => 1)
));
Add filter in your action
CakePHP 3.x
$posts = $this->Posts->find()
->where([
'Posts.user_id' => $this->Auth->user('id')
]);
CakePHP 2.x
$posts = $this->Posts->find('all', [
'user_id' => $this->Auth->user('id')
]);
Note: Make sure to login user to set Auth data.

CakePHP 3, display entire record row if a field is empty, otherwise do not display it

I have just started using CakePHP this week (required for my internship), and I am not really that good with PHP to begin with.
Anyhow, I require help with the following:
How can you make a record to only be displayed if it has an empty field?
Sample reference
Based on the above image, I only want the row with an empty Title/date to be displayed, while hiding the other.
And on a different page I want the same records to be displayed but this time around, only show the ones with completely filled fields, while hiding the ones with empty fields.
EDIT:
View:
<?php foreach ($users as $user): ?>
<tr>
<td><?= $this->Number->format($user->id) ?></td>
<td><?= h($user->username) ?></td>
<td><?= h($user->name) ?></td>
<td><?= h($user->phone) ?></td>
<td><?= h($user->email) ?></td>
<td><?= h($user->role) ?></td>
<td><?= $this->Number->format($user->status) ?></td>
<td class="actions">
<?= $this->Html->link(__('View'), ['action' => 'view', $user->id]) ?>
<?= $this->Html->link(__('Edit'), ['action' => 'edit', $user->id]) ?>
<?= $this->Form->postLink(__('Delete'), ['action' => 'delete', $user->id], ['confirm' => __('Are you sure you want to delete # {0}?', $user->id)]) ?>
</td>
</tr>
<?php endforeach; ?>
Model:
public function initialize(array $config)
{
parent::initialize($config);
$this->table('users');
$this->displayField('name');
$this->primaryKey('id');
}
public function validationDefault(Validator $validator)
{
$validator
->integer('id')
->allowEmpty('id', 'create');
$validator
->notEmpty('username', 'A username is required');
$validator
->notEmpty('password', 'A password is required');
$validator
->allowEmpty('name');
$validator
->allowEmpty('phone');
$validator
->email('email')
->allowEmpty('email');
$validator
->add('role', 'inList', [
'rule' => ['inList', ['admin', 'editor', 'sales_user', 'field_user']],
'message' => 'Please select a role']);
$validator
->add('status', 'inList', [
'rule' => ['inList', ['1', '2', '3']],
'message' => 'Please select a status']);
return $validator;
}
Controller:
public function index()
{
$users = $this->paginate($this->Users);
$this->set(compact('users'));
$this->set('_serialize', ['users']);
}
This is the first time I am posting a question, so please let me know if I need to include any further details or such.
Thank you.
this code selects the users where the name field is null.
public function index() {
$users = $this->users->find('all', array("conditions" => array('name' => '')));
$this->set("users", $users);
}

Yii2 array elements to display in different rows in detail view

In my project I have a function which returns an array of elements. these array of elements have converted into string using implode and has been called in the detail view. Here my detail view displays all the elements in 1 single row.
I want each and every array element to be displayed in different rowsof detail view.
My function which returns array elements.
public function getHazStatement(){
$codes = array();
$pLines = GhsHazStatements::find()->where(['haz_id' => $this->getHazID()])->all();
foreach ($pLines as $pLine){
$codes[] = $pLine->haz_statement;
//var_dump($codes); exit();
}
// var_dump(); exit();
return implode(', ', $codes);
}
public function getHazCode(){
$codes = array();
$pLines = GhsHazStatements::find()->where(['haz_id' => $this->getHazID()])->all();
foreach ($pLines as $pLine){
$codes[] = $pLine->haz_code;
//var_dump($codes); exit();
}
// var_dump(); exit();
return implode(', ', $codes);
}
My view file detail view.
[
'label' => $model->getHazCode(),
'value' => $model->getHazStatement(),
'options' => ['class' => 'table table-striped table-bordered detail-view','style'=> 'width:500px'],
],
My output is :
In my output you can see that there are two elements in the same row.. I want them to be in two different rows in detail view. How can I achieve this? Any possible solution?
Thank you
In your class:
public YourClass extends ActiveRecord
{
...
public function getHazStatemets()
{
return $this->hasMany(GhsHazStatements::className(), ['haz_id' => '<haz id column name in your class>']);
}
}
In your conroller:
$this->render('<your view file name>', [
'haz_statements' => $yourClassInstance->getHazStatements()->all(),
'options' => ... // try to avoid passing CSS classes to from view controller
])
In your view:
<?php foreach($haz_statement as $statement) ?>
<tr>
<td>
<?= $statement->haz_code ?>
</td>
<td>
<?= $statement->haz_statement ?>
</td>
</tr>
<?php endforeach; ?>
I have not exactly understood your question.
If you want to have two rows and info..: (for example)
[
'label' => $model->getHazCode(),
'value' => "detail",
'options' => ['class' => 'table table-striped table-bordered detail-view','style'=> 'width:500px'],
],
[
'label' => $model->getHazStatement(),
'value' => "detail",
'options' => ['class' => 'table table-striped table-bordered detail-view','style'=> 'width:500px'],
],
But if you want a list of ...
When you want a list of rows, this is the same GridView
Anyway, I hope the following code will help you.
Please disable Show Header (see below)
$query = GhsHazStatements::find()->where(['haz_id' => $this->getHazID()]);
$dataProvider = new \yii\data\ActiveDataProvider([
'query' => $query,
]);
echo yii\grid\GridView::widget([
'dataProvider' => $dataProvider,
'columns' => [
'haz_statement',
'haz_code',
],
'showHeader' => false,
]);

inserting multiple checkbox values using implode function in same column in cakephp 2.8.2

Hi i am tyring to insert multiple checkbox values in same column using cakephp but i have error "Trying to get property of non-object [APP\Model\Task.php, line 34]" that is at Model
if($this->request->data['Task']['Feel']!=0)
{
$this->data['Task']['Feel'] = implode(',', $this->data['Task']['Feel']);
}
My view
<?php
echo $this->Html->css('style');
echo $this->Form->create('task');
?>
<table align= "center">
<div class="checkbox">
<tr>
<td>Name 1</td>
<td>
<?php
$list = array('1' => 'Happy', '2' => 'Laugh', '3' => 'Sad', '4' => 'Angry','5'=>'Cry');
echo $this->Form->input('Feel',array('label' => false,'options' => $list,'multiple'=>'checkbox'));
?>
</td>
</tr>
<tr>
<td>Name 2</td>
<td>
<?php
$list = array('6' => 'Happy', '7' => 'Laugh', '8' => 'Sad', '9' => 'Angry','10'=>'Cry');
echo $this->Form->input('Feel',array('label' => false,'options' => $list,'multiple'=>'checkbox'));
?>
</td>
</tr>
</div>
</table>
<?php
echo $this->Form->input('id', array('type' => 'hidden'));
echo $this->Form->end('Submit');
?>
My Model
class Task extends AppModel
{
function beforeValidate()
{
if($this->request->data['Task']['Feel']!=0)
{
$this->data['Task']['Feel'] = implode(',', $this->data['Task']['Feel']);
}
}
}
My Controller
class TaskController extends AppController
{
public $uses = array();
public $helpers = array('Html','Form');
public $components =array('Flash');
public function task($id=null)
{
$this->Task->create();
if ($this->Task->save($this->request->data))
{
$this->Flash->success(__('Your task has been saved.'));
return $this->redirect(array('action' => 'task'));
}else
{
$this->Flash->error(__('Unable to add the task.'));
}
}
}
How can I remove this error and how can I solve it?
Please any body help me....
echo $this->Form->create('task');
This should be
echo $this->Form->create('Task');
Two problems:
echo $this->Form->create('task');
Should be:
echo $this->Form->create('Task');
And:
if($this->request->data['Task']['Feel']!=0)
Should be:
if($this->data['Task']['Feel']!=0)
Or even better:
if($this->data['Task']['Feel'])

Resources