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;
Related
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);
}
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,
]);
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
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
I have a page that is supposed to render as a pdf with the help of WKHTMLTOPDF engine. When I click the link to load the page, I get this error:
WKHTMLTOPDF didn't return any data
Error: An Internal Error Has Occurred.
The stack trace is as follows:
APP\Plugin\CakePdf\Pdf\CakePdf.php line 234 → WkHtmlToPdfEngine->output()
}
}
$output = $Engine->output();
APP\Plugin\CakePdf\View\PdfView.php line 97 → CakePdf->output(string)
prints this
$this->response->download($this->getFilename());
}
$this->Blocks->set('content', $this->renderer()->output($content));
return $this->Blocks->get('content');
then prints out the page exactly how i want it too
CORE\Cake\Controller\Controller.php line 956 → PdfView->render(null, null)
null
null
CORE\Cake\Routing\Dispatcher.php line 193 → Controller->render()
}
if ($render && $controller->autoRender) {
$response = $controller->render();
} elseif ($response->body() === null) {
CORE\Cake\Routing\Dispatcher.php line 161 → Dispatcher->_invoke(InvoicesController, CakeRequest, CakeResponse)
object(InvoicesController) {
helpers => array(
[maximum depth reached]
)
uses => array(
[maximum depth reached]
)
paginate => array(
[maximum depth reached]
)
components => array(
[maximum depth reached]
)
name => 'Invoices'
request => object(CakeRequest) {}
response => object(CakeResponse) {}
viewPath => 'Invoices'
layoutPath => 'pdf'
viewVars => array(
[maximum depth reached]
)
view => 'view'
layout => 'adminpdf'
autoRender => false
autoLayout => true
Components => object(ComponentCollection) {}
viewClass => 'Pdf'
View => object(PdfView) {}
ext => '.ctp'
plugin => null
cacheAction => false
passedArgs => array(
[maximum depth reached]
)
scaffold => false
methods => array(
[maximum depth reached]
)
modelClass => 'Invoice'
modelKey => 'invoice'
validationErrors => null
Toolbar => object(ToolbarComponent) {}
Session => object(SessionComponent) {}
Auth => object(AuthComponent) {}
RequestHandler => object(RequestHandlerComponent) {}
pdfConfig => array(
[maximum depth reached]
)
Invoice => object(Invoice) {}
FieldsInvoice => object(FieldsInvoice) {}
InvoicesItem => object(InvoicesItem) {}
}
object(CakeRequest) {
params => array(
[maximum depth reached]
)
data => array([maximum depth reached])
query => array([maximum depth reached])
url => 'Invoices/view/1.pdf'
base => '/pra'
webroot => '/pra/'
here => '/pra/Invoices/view/1.pdf'
}
object(CakeResponse) {
}
APP\webroot\index.php line 92 → Dispatcher->dispatch(CakeRequest, CakeResponse)
object(CakeRequest) {
params => array(
[maximum depth reached]
)
data => array([maximum depth reached])
query => array([maximum depth reached])
url => 'Invoices/view/1.pdf'
base => '/pra'
webroot => '/pra/'
here => '/pra/Invoices/view/1.pdf'
}
object(CakeResponse) {
}
here is my bootstrap.php
<?php
CakePlugin::loadAll();
CakePlugin::load('DebugKit');
CakePlugin::load('CakePdf', array('bootstrap' => true, 'routes' => true));
Configure::write('CakePdf', array(
'engine' => 'CakePdf.WkHtmlToPdf',
'download'=>true,
'binary'=>'C:\\Program Files (x86)\\wkhtmltopdf\\wkhtmltopdf.exe'));
// Enable the Dispatcher filters for plugin assets, and
// CacheHelper.
Configure::write('Dispatcher.filters', array(
'AssetDispatcher',
'CacheDispatcher'
));
// Add logging configuration.
CakeLog::config('debug', array(
'engine' => 'FileLog',
'types' => array('notice', 'info', 'debug'),
'file' => 'debug',
));
CakeLog::config('error', array(
'engine' => 'FileLog',
'types' => array('warning', 'error', 'critical', 'alert', 'emergency'),
'file' => 'error',
));
the view in my controller
public function view($id = null) {
$this->set('title_for_layout', 'Invoices');
$this->set('stylesheet_used', 'homestyle');
$this->set('image_used', 'eBOXLogoHome.png');
$this->layout='adminpdf';
$this->pdfConfig = array('engine' => 'CakePdf.WkHtmlToPdf');
$this->Invoice->id = $id;
if (!$this->Invoice->exists()) {
throw new NotFoundException(__('Invalid invoice'));
}
$this->pdfConfig = array(
'engine'=>'CakePdf.WkHtmlToPdf',
'orientation' => 'potrait',
'filename' => 'Invoice_' . $id
);
$this->set('invoice', $this->Invoice->read(null, $id));
//Retrieve Account Id of current User
$accountid=$this->Auth->user('account_id');
//Find all Invoices where $conditions are satisfied
$invoicedetails=$this->Invoice->find('first', array(
'conditions' => array('Invoice.id'=>$id)));
//prints fieldsInvoice details, including invoice and field information
$invoices=$this->FieldsInvoice->find('all',array(
'conditions'=>array(
'invoice_id'=>$id)));
$itemInvoice=$this->InvoicesItem->find('all',array('conditions'=>array('invoice_id'=>$id)));
//Set variables
$this->set('invoicedetails', $invoicedetails);
$this->set('invoice', $invoices);
$this->set('accountid', $accountid);
$this->set('itemInvoice', $itemInvoice);
}
//End of Controller
}
my app controller
class AppController extends Controller {
public $components = array(
'DebugKit.Toolbar',
'Session',
'Auth'=>array(
'loginRedirect'=>array('controller'=>'users', 'action'=>'login'),
'logoutRedirect'=>array('controller'=>'users', 'action'=>'login'),
'invoiceRedirect'=>array('controller'=>'invoices', 'action'=>'viewinvoice'),
'authError'=>"You can't access this page",
'authorize'=>array('Controller')
),
'RequestHandler'
);
routes.php
*/
CakePlugin::routes();
Router::mapResources(array('Invoices'));
Router::connect('/', array('controller' => 'pages', 'action' => 'display', 'home'));
/**
here is the view i want rendered as a pdf
<div id = "content">
<h2>View Invoice</h2>
<table id="data">
<?php
if($invoicedetails['Invoice']['scheduled']==1)
{
$status = 'Scheduled';
$fcol = 'Black';
$bgcol = '#EBD8E8';
$pay = NULL;
$dispute = NULL;
}
else if($invoicedetails['Invoice']['paid']==1)
{
$status = 'Paid';
$fcol = 'Black';
$bgcol = '#B9FAEA';
$pay = NULL;
$dispute = NULL;
}
else if($invoicedetails['Invoice']['sender_id']==$accountid)
{
$status = 'Sent';
$fcol = 'Black';
$bgcol = '#F8FAC0';
$pay = NULL;
$dispute = NULL;
}
else if($invoicedetails['Invoice']['receiver_id']==$accountid)
{
$status = 'Received';
$fcol = 'Black';
$bgcol = '#FAB9B9';
$pay = $this->Html->link('Pay', array('controller' => 'Invoices','action'=>'pay_admin',$invoicedetails['Invoice']['id'] )) ;
$dispute = $this->Html->link('Dispute', array('controller' => 'Disputes','action'=>'add_admin',$invoicedetails['Invoice']['id'] ));
}
?>
<tr>
<th>Sender: </th>
<td><?php echo $invoicedetails['SenderAccount']['account_name'];?> </td>
</tr>
<tr>
<th>Receiver: </th>
<td><?php echo $invoicedetails['ReceiverAccount']['account_name'];?> </td>
</tr>
<tr>
<th>Invoice ID: </th>
<td><?php echo $invoicedetails['Invoice']['id'];?> </td>
</tr>
<tr>
<th>Invoice Date: </th>
<td><?php echo date('d.m.Y', strtotime($invoicedetails['Invoice']['created'])); ?></td>
</tr>
<tr>
<th>Due Date: </th>
<td><?php echo date('d.m.Y', strtotime($invoicedetails['Invoice']['expiry_date'])); ?></td>
</tr>
<tr>
<th>Status: </th>
<td bgcolor='<?php echo $bgcol ?>'><?php echo $status ;?> </td>
</tr>
<tr>
<th>Actions: </th>
<td><?php echo $pay ?> <?php echo $dispute ?></td>
</tr>
</table>
<br>
<table id="data">
<tr>
<th>Item Name</th>
<th>Description</th>
<th>Price Per Unit</th>
<th>Quantity</th>
</tr>
<?php foreach($itemInvoice as $itemInvoices):?>
<tr>
<td><?php echo $itemInvoices['Item']['name']; ?></td>
<td><?php echo $itemInvoices['Item']['description']; ?></td>
<td>$<?php echo number_format($itemInvoices['Item']['price'], 2, '.', ','); ?></td>
<td><?php echo $itemInvoices['InvoicesItem']['quantity']; ?></td>
</tr>
<?php endforeach; ?>
</table>
<br>
<table id="data">
<tr>
<th>Field Name</th>
<th>Entered Value</th>
</tr>
<?php foreach($invoice as $invoices):?>
<tr>
<td><?php echo $invoices['Field']['name']; ?> :</td>
<td><?php echo $invoices['FieldsInvoice']['entered_value']; ?></td>
</tr>
<?php endforeach; ?>
</table>
<br><br>
One HUGE PROBLEM on Windows and the php proc_open that CakePdf is using are SPACES in the binary and the Exception in https://github.com/ceeram/CakePdf/blob/master/Pdf/Engine/WkHtmlToPdfEngine.php#L35 is only throwing back a generic message and NOT the error that occured.
On /WkHtmlToPdfEngine.php#L36 extend with content['stderr] to see the real error:
throw new CakeException("WKHTMLTOPDF didn't return any data. Returned Error: ".$content['stderr']);
Simple solution:
will not work
'binary'=> 'C:\\Program Files\\wkhtmltopdf\\wkhtmltopdf.exe'
WORKS
'binary'=> 'C:\\Progra~1\\wkhtmltopdf\\wkhtmltopdf.exe'
there was two issues with this code that needed resolving
was the binary in the bootstrap.php
Original:
Configure::write('CakePdf', array(
'engine' => 'CakePdf.WkHtmlToPdf',
'download'=>true,
'binary'=>'C:\Program Files (x86)\wkhtmltopdf\wkhtmltopdf.exe'));
new
Configure::write('CakePdf', array(
'engine' => 'CakePdf.WkHtmlToPdf',
'download'=>false,
'binary'=>'C:\\wkhtmltopdf\\wkhtmltopdf.exe',
'orientation'=>'portrait'));
in my invoices controller I had a spelling mistake with the word portrait.