cant edit data after using a find but needed a get - cakephp

I cant edit data from a table of rows from a find command as I get an unknown method 'isNew'. I understand I didnt use a get command to retrieve the data but I used a find instead. The data returned is correct (array given below) but it is in the wrong format . I used a query and need to convert to an entity but I dont know how to do this.
My question is how do I get data with a get command with where conditions if I need to use get for edit functions to make this work?
https://github.com/cakephp/cakephp/issues/5262
Argument 1 passed to Cake\ORM\Table::patchEntity() must be an instance of Cake\Datasource\EntityInterface, instance of Cake\ORM\Query given
public function edit2($id = null)
{
$a3 = '2016-05-28';
$a4 = '2016-06-01';
$lessons = $this->find()
->contain(['Tutors', 'Subjects', 'TutoringTypes', 'Terms', 'Students'])
->select([
'Lessons.id', 'Lessons.lesson_date', 'Lessons.lesson_plan',
'Tutors.id', 'Tutors.first_name', 'Tutors.last_name',
'Subjects.name', 'TutoringTypes.value'
])
->where([
'Lessons.lesson_date >' => $a3,
'Lessons.lesson_date <' => $a4,
'Lessons.tutor_id' => 12
])
->order(['Lessons.lesson_date' => 'ASC'])
->hydrate(true);
$lessons->matching('Students', function ($q) use ($a8) {
return $q
->select(['Students.id', 'Students.first_name', 'Students.last_name'])
->where(['Students.first_name like' => '%' . $a8 . '%']);
});
if ($this->request->is(['patch', 'post', 'put'])) {
debug($this->request->data);
$lessons = $this->Lessons->patchEntity($lessons, $this->request->data);
if ($this->Lessons->save($lesson)) {
$this->Flash->success(__('The lesson has been saved.'));
return $this->redirect(['action' => 'edit2']);
} else {
$this->Flash->error(__('The lesson could not be saved. Please, try again.'));
}
}
$this->set(compact('lessons'));
$this->set('_serialize', ['lessons']);
}
view
<?php foreach ($lessons as $key => $item):
//foreach ($query3 as $item):
?>
<tr>
<?php echo $this->Form->hidden($key . '.id', ['label' => '', 'value' => $item->id]) ?>
<td><?= $item->id ?></td>
<td><?= $item->lesson_date ?></td>
<td><?= $item->tutor->first_name . ' ' . $item->tutor->last_name ?></td>
<td><?= $item->students[0]->first_name . ' ' . $item->students[0]->last_name ?></td>
<td><?= $item->subject->name ?></td>
<td><?= $item->tutoring_type->value ?></td>
<td><?php echo $this->Form->input($key . '.lesson_plan', [
'label' => '',
'value' => $item->lesson_plan,
'style' => 'width: 300px; height:50px;'
]) ?></td>
</tr>
<?php endforeach; ?>
returned data
[
(int) 0 => [
'id' => '12397',
'lesson_plan' => 'hello'
],
(int) 1 => [
'id' => '12408',
'lesson_plan' => ''
],
(int) 2 => [
'id' => '14432',
'lesson_plan' => ''
],
(int) 3 => [
'id' => '12419',
'lesson_plan' => ''
],
(int) 4 => [
'id' => '12441',
'lesson_plan' => ''
]
]

The reason for the error is $lessons is a query returning 5 objects. It's illogical to call save on it as if it were one lesson.
Save one entity at a time
If the submitted data is the structure shown in the question, code similar to this will do what you expect:
if ($this->request->is(['patch', 'post', 'put'])) {
$patched = $this->Lessons->patchEntities($lessons, $this->request->data());
foreach ($patched as $entity) {
$this->Lessons->save($entity);
}
}
Note that how to patch multiple entries is covered in the docs

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 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,
]);

CakePHP Ajax search : Showing same data two times for pagination

Here ajax search working fine but the problem is same data is showing two times, because I have given pagination limit 2.If I make it 3, same result is showing 3 times.
Here is my index.ctp
$( "#search" ).keyup(function() {
var value=$('#search').val();
$.get("<?php echo Router::url(array('controller'=>'userTypes','action'=>'search'));?>",{search:value},function(data){
$('.search_data').html(data);
});
})
Here is my search action
public function search()
{
$search=$_GET['search'];
$request=$this->UserType->find('all', array(
'conditions' => array('UserType.name LIKE' => "%$search%")
));
$this->set('usertype',$request);
}
Here is the search.ctp
<?php foreach($usertype as $usertypes) { ?>
<tr>
<td><?php echo $usertypes['UserType']['id']; ?></td>
<td><?php echo $usertypes['UserType']['name']; ?></td>
<td><?php echo $usertypes['UserType']['description']; ?></td>
</tr>
<?php } ?>
Pagination limit In appcontroller
parent::beforeFilter();
$this->Paginator->settings = array(
'limit'=>2
);
Result is showing me like this
May anybody help me for solve it ?
If you want to use pagination, your search method should look like this:
public function search()
{
if(isset($this->request->query['search'])){
$search = $this->request->query['search'];
}else{
$search = '';
)
$this->Paginator->settings = array(
'conditions' => array('UserType.name LIKE' => "%$search%"),
'limit' => 2
);
));
$this->set('usertype',$this->Paginator->paginate());
}

How cakePHP build form data

i've created a form that loop in my table and give me some images:
id1: ->Image path, title etc
id2: -> Image path title etc
i've created my view in this way:
<div>
<?php echo $this->Form->create('Gallery',
array( 'action' => 'save')); ?>
<table cellpadding="0" cellspacing="0">
<?php foreach($images as $image): ?>
<tr>
<td>
<?php echo $this->PhpThumb->thumbnail($image['medias']['file'], array('w' => 75, 'h' => 75)); ?>
</td>
<td><?php echo $this->Form->input('title'.$image['medias']['id'], array('value' => $image['medias']['title']));?></td>
<td><?php echo $this->Form->input('description'.$image['medias']['id'], array('value' => $image['medias']['description']));?></td>
</tr>
<?php endforeach; ?>
</table>
<?php echo $this->Form->end(__('Submit')); ?>
After submit, i have an array like this:
array(
'Gallery' => array(
'title19' => 'test',
'description19' => '',
'title20' => '',
'description20' => '',
'title21' => '',
'description21' => '',
'title22' => '',
'description22' => ''
)
)
For sure, i cant use the save() method because the array isnt well formatted. I think the right format should be:
array(
'Gallery' => array(
array('id' => 19,
'title => 'test',
'description => ''),
array( 'id' =>20,
title => '',
description => '')
)
)
but, how can i get this ? Or some array that is right formatted?
When you iterate over them put the iterator or id in the right place:
$this->Form->input('Model.' . $i . 'field');
$this->Form->input('Model.' . $i . 'other_field');
References:
Saving your data
Form Helper

Resources