I plan to upgrade my CakePHP v2 to v3 website. So I start to learn by looking at the Blog tutorial & it work fine.
Next, I start to customize base on my CakePHP v2 site.
The first thing I would like to do is using slug in URL instead of id. I add slug column in database.
But I always get an error when I click the url with the slug. The error is
Notice (8): Undefined property: Cake\ORM\Query::$created [APP/Template/Articles/view.ctp, line 3]
Help on this is greatly appreciated.
This is my routes
$routes->connect('/', ['controller' => 'Articles', 'action' => 'index']);
$routes->connect('/articles/:slug', ['controller' => 'Articles', 'action' => 'view'], ['pass' => ['slug']]);
This is my controller
public function index()
{
$this->set('articles', $this->Articles->find('all'));
}
public function view($slug = null)
{
$article = $this->Articles->findBySlug($slug);
$this->set(compact('article'));
}
This is my index.ctp
<h1>Blog articles</h1>
<table>
<tr>
<th>Id</th>
<th>Title</th>
<th>Created</th>
<th>Slug</th>
</tr>
<?php foreach ($articles as $article): ?>
<tr>
<td><?= $article->id ?></td>
<td>
<?= $this->Html->link($article->title, ['action' => 'view', $article->slug]) ?>
</td>
<td>
<?= $article->created ?>
</td>
<td>
<?= $article->slug ?>
</td>
</tr>
<?php endforeach; ?>
find() method returns a query object. Since you want the single entity that matches that slug, call first() on the query object:
$article = $this->Articles->findBySlug($slug)->first();
Table Unit(id, unitNo, summary).
id | unitNo
1 | 23
2 | 25
3 | 22
In UnitsController:
public function index() {
$this->set('units', $this->Unit->find('all'), array(
'order' => array('Unit.unitNo ASC'),
'fields' => array('Unit.id', 'Unit.unitNo'))
);
}
index.ctp
<table>
<tr>
<th>Unit</th>
<th>Summary</th>
</tr>
<!-- Here is where we loop through our $posts array, printing out post info -->
<?php foreach ($units as $unit): ?>
<tr>
<td>
<?php echo $this->Html->link($unit['Unit']['unitNo'], array('controller' => 'units', 'action' => 'view', $unit['Unit']['id']));
?>
</td>
<td><?php echo $unit['Unit']['summary']; ?></td>
</tr>
<?php endforeach; ?>
<?php unset($unit); ?>
</table>
I want to use order unitNo but the result is still ordering by id.
http://s1104.photobucket.com/user/thai92hp/media/Untitled.png.html
Can anyone help me to fix this problem?
Please give this a try:
public function index() {
$this->set('units', $this->Unit->find('all',
array(
'order' => array('Unit.unitNo ASC'),
'fields' => array('Unit.id', 'Unit.unitNo')
)
));
}
It seems to me that you've given your order settings to $this->set() as the third parameter but what you may want to do is to give it to $this->Unit->find() as the second parameter.
I have a table with a column 'read'. I'd like to be able to sort from a graphic rather than text, although can't seem to work it out.
Here's what I've tried:
<!-- none of these work...-->
<th class="read"><?php echo $this->Paginator->sort('read',$this->Html->image("read_no.png", array(
'width' => "26px",
'alt' => "Read",
array('escape' => false)))); ?></th>
<th class="read"><?php echo $this->Html->link(
$this->Html->image("read_no.png", array("alt" => "Read")),
$this->Paginator->sort('read'),
array('escape' => false)
);?></th>
<th class="read"><?php echo $this->Html->image("read_no.png", array(
'width' => "26px",
'alt' => "Read",
'url' => $this->Paginator->sort('read'),
array('escape' => false)
)); ?>
</th>
I get errors like:
The action <a href=" is not defined in controller
You need to add the escape option to the Paginator/sort Method rather than the HTML/image one:
<th class="read">
<?php
$imageTag = $this->Html->image("read_no.png", array(
'width' => "26px",
'alt' => "Read",
)
);
echo $this->Paginator->sort('read', $imageTag, array('escape' => false)); ?>
</th>
I'm trying to learn how CakePHP works but i'm stuck, i just want to display the user names . I'm working in the good controller and the good view... I don't understand .
View => Users => index.ctp
<h1>Users List</h1> <table>
<tr>
<th>Username</th>
</tr>
<?php foreach ($users as $k): ?>
<tr>
<td><?php echo $k['username']; ?></td>
</tr>
<?php endforeach; ?>
</table>
Controller => UsersController
<?php
class UsersController extends AppController{
public function index() {
$users = $this->User->find('all',array('fields' => array('id','username','created')));
debug($users);
}
}
?>
With debug, i have what i want but i can't display the result in my table with foreach .
array(
(int) 0 => array(
'User' => array(
'id' => '2',
'username' => 'CREAZ',
'created' => '2014-06-17 23:39:52'
)
),
(int) 1 => array(
'User' => array(
'id' => '3',
'username' => 'test2',
'created' => '2014-06-18 16:57:37'
)
)
)
The errors i get in my view :
Notice (8): Undefined variable: users [APP\View\Users\index.ctp, line 9]
Warning (2): Invalid argument supplied for foreach() [APP\View\Users\index.ctp, line 9]
Notice (8): Undefined variable: users [APP\View\Users\index.ctp, line 13]
Warning (2): Invalid argument supplied for foreach() [APP\View\Users\index.ctp, line 13]
You should set the users variable in the controller first as shown below:
<?php
class UsersController extends AppController{
public function index() {
$users = $this->User->find('all',array('fields' => array('id','username','created')));
debug($users);
$this->set('users', $users);
}
}
?>
and in the view index.ctp, do it like below:
<h1>Users List</h1>
<table>
<tr>
<th>Username</th>
</tr>
<?php foreach ($users as $k): ?>
<tr>
<td><?php echo $k['User']['username']; ?></td>
</tr>
<?php endforeach; ?>
</table>
I have two tables :
senderinfos :
id | Name | email_add | Address |
============================================
1 | Amit | 1#1.com | park Street|
receiverinfos:
id | Name | email_add| Address |
=======================================
1 | SOS | 2#2.com | park1
I am giving the model,view,And Controller Code :
Model
Senderinfo :
<?php
App::uses('AppModel', 'Model');
/**
* Admin Login Model
*
*/
class Senderinfo extends AppModel
{
public $name='Senderinfo';
public $usetables='senderinfos';
public $validate = array(
'contact' =>
array(
'rule' => 'notEmpty', // or: array('ruleName', 'param1', 'param2' ...)
'allowEmpty' => false,
'message' => 'Please Enter Contact.'
),
'name' =>
array(
'rule' => 'notEmpty', // or: array('ruleName', 'param1', 'param2' ...)
'allowEmpty' => false,
'message' => 'Please Enter Sender Name.'
),
'email_add' => array(
'email_add' => array(
'rule' => 'email',
'allowEmpty' => true,
'message' => 'Please Enter Valid Email',
'last' => true
)),
);
}
?>
Receiveinfo :
<?php
App::uses('AppModel', 'Model');
/**
* Admin Login Model
*
*/
class Receiverinfo extends AppModel
{
public $name='Receiverinfo';
public $usetables='receiverinfos';
public $validate = array(
'contact' =>
array(
'rule' => 'notEmpty', // or: array('ruleName', 'param1', 'param2' ...)
'allowEmpty' => false,
'message' => 'Please Enter Contact.'
),
'name' =>
array(
'rule' => 'notEmpty', // or: array('ruleName', 'param1', 'param2' ...)
'allowEmpty' => false,
'message' => 'Please Enter Sender Name.'
),
'email_add' => array(
'email_add' => array(
'rule' => 'email',
'allowEmpty' => true,
'message' => 'Please Enter Valid Email',
'last' => true
)),
);
}
?>
View
send_money.ctp
<content>
<div class="pg_title txtLeft">Send Money</div>
<?php echo $this->Form->create('Agents', array('action' => 'send_money'));?>
<div style="display:none;"><input type="hidden" value="POST" name="_method"></div>
<fieldset title="SENDER'S INFORMATION"><legend>SENDER'S INFORMATION</legend>
<table>
<tbody>
<tr>
<td><label>Contact No.<span class="red">*</span></label></td>
<td><?php echo $this->Form->input('Senderinfo.contact',array('label'=>false,'div'=>false,'size'=>50,'style'=>'width:330px')); ?></td>
</tr>
<tr>
<td><label>Sender's Name<span class="red">*</span></label></td>
<td><?php echo $this->Form->input('Senderinfo.name',array('label'=>false,'div'=>false,'size'=>50,'style'=>'width:330px')); ?></td>
</tr>
<tr>
<td><label>Email Address</label></td>
<td><?php echo $this->Form->input('Senderinfo.email_add',array('label'=>false,'div'=>false,'size'=>50,'style'=>'width:330px')); ?></td>
</tr>
<tr>
<td><label>Mailing Address</label></td>
<td><?php echo $this->Form->input('Senderinfo.address',array('label'=>false,'div'=>false,'type'=>'textarea','cols'=>39,'rows'=>3,'class'=>'textarea','style'=>'width:330px')); ?></td>
</tr>
</tbody>
</table>
</fieldset>
<fieldset title=""><legend>RECEIVER'S INFORMATION</legend>
<table>
<tbody>
<tr>
<td><label>Contact No.<span class="red">*</span></label></td>
<td><?php echo $this->Form->input('Receiverinfo.contact',array('label'=>false,'div'=>false,'size'=>50,'style'=>'width:330px')); ?></td>
</tr>
<tr>
<td><label>Receiver's Name<span class="red">*</span></label></td>
<td><?php echo $this->Form->input('Receiverinfo.name',array('label'=>false,'div'=>false,'size'=>50,'style'=>'width:330px')); ?></td>
</tr>
<tr>
<td><label>Email Address</label></td>
<td><?php echo $this->Form->input('Receiverinfo.email_add',array('label'=>false,'div'=>false,'size'=>50,'style'=>'width:330px')); ?></td>
</tr>
<tr>
<td><label>Mailing Address</label></td>
<td><?php echo $this->Form->input('Receiverinfo.address',array('label'=>false,'div'=>false,'type'=>'textarea','cols'=>39,'rows'=>3,'class'=>'textarea','style'=>'width:330px')); ?></td>
</tr>
</tbody>
</table>
</fieldset>
<fieldset><legend>MONEY TRANSFER</legend>
<table>
<tbody>
<tr>
<td><label>Amount(tk)<span class="red">*</span></label></td>
<td><?php echo $this->Form->input('Transaction.sending_amount',array('label'=>false,'div'=>false,'size'=>50,'style'=>'width:330px')); ?></td>
</tr>
<tr>
<td><label>Charge(tk)<span class="red">*</span></label></td>
<td><?php echo $this->Form->input('Transaction.charge',array('label'=>false,'div'=>false,'size'=>50,'style'=>'width:330px')); ?></td>
</tr>
<tr>
<?php
$foo = "";
$options = array('1' => 'Paid','0' => ' Due');
$attributes = array(
'legend' => false,
'value' => true,
'checked'=> ($foo == "Paid"),
);
?>
<td>
<?php echo $this->Form->radio('transaction.status',$options, $attributes);?>
</td>
</tr>
</tbody>
</table>
</fieldset>
<fieldset><legend>CUSTOM MESSAGE</legend>
<table>
<tbody>
<tr>
<td style="width: 158px;"><label>Message</label></td>
<td><?php echo $this->Form->input('transaction.message',array('label'=>false,'div'=>false,'type'=>'textarea','cols'=>39,'rows'=>3,'class'=>'textarea','style'=>'width:330px')); ?></td>
</tr>
</tbody>
</table>
</fieldset>
<table>
<tbody>
<tr>
<td colspan="2" align="right"><input type="reset" value="Reset"> | <?php echo $this->Form->submit('SEND', array('div' => false,'formnovalidate' => true));?></td>
</tr>
</tbody>
</table>
<?php print $this->Form->end();?>
</content>
<div class="clear"></div>
Controller :
public function send_money()
{
$this->layout='agent';
if(empty($this->data) == false)
{
if($this->Senderinfo->save($this->data))
{
$this->Receiverinfo->save($this->data);
//$this->Session->setFlash('Data inserted successfully.');
//$this->redirect('send_money');
}
/*if($this->Receiverinfo->save($this->data))
{
//$this->Session->setFlash('Data inserted successfully.');
$this->redirect('send_money');
}
*/
}
else
{
//$this->set('errors', $this->Senderinfo->invalidFields());
//$this->set('errors', $this->Receiverinfo->invalidFields());
}
}
I want to insert the records in two table with perfect validation.But my validation part in not working perfectly.That means when u see my view page u'll see sender information,receiver information,money which is wrapped by html legend.I want to do validation required field at a time after clicking submit button.In this code whats happening is that when i press submit button sender information validation is working but receiver information portion validation is not working.when i put any value in sender portion,that time receiver information portion's validation works only.What should i have to do?
First of all; apparently there is a 'relation' between the 'sender' and 'receiver' in your application, but NOT in your model/database definition. Relying on the 'auto-incrementing' ID of your database (e.g. receiver 1 and sender 1 belong together) is not reliable. Auto-incrementing IDs will come 'out of sync' between both tables and you will end up with a situation where 'receiver 123' should actually be 'connected' to 'sender 125'.
If I understand correctly what this form does, is create a 'money transaction' in the database. Sender and Receiver should (in this case) probably not be stored in separate databases, unless you're going to offer an option to 'pick' an existing sender/receiver from a list.
In both situations there should be a table/model in your application that 'connects' the two, otherwise you will just have a random list of people 'sending' and 'receiving' money, but no way to know which person wants to send money to which recipient
If you're not going to 're-use' the senders/receivers, than a correct database-design should be something like:
id| sender_name | sender_email | sender_address | receiver_name | receiver_email | receiver_address
1 | Amid | 1#1.com | Parkstreet | SOS | 2#2.com | park 1
I would name this table 'money transfers' and the model 'Moneytransfer'
Having both in 1 model will simplify the validation and will guarantee that both sender and receiver info is present and correct.
If you really want to manually save two separate records (Based on my explanation above, I would strongly advise you to not do this) you should do this;
validate both records manually via $this->Mymodel->validates($data)
enclose both saves in a transaction and rollback if one of them fails
More information on manually validating inside your controller can be found here:
http://book.cakephp.org/2.0/en/models/data-validation/validating-data-from-the-controller.html
More information on using transactions in CakePHP can be found here:
http://book.cakephp.org/2.0/en/models/transactions.html
[update]
Browsing further through your 'form', there 'seems' to be a 'transaction' model as well?
If this is the case and the Model-relations are properly defined in CakePHP, you will be able to save all related records using Model::saveAssociated(). This will also enclose all saves in a transaction (atomic)
See here:
http://book.cakephp.org/2.0/en/models/saving-your-data.html#model-saveassociated-array-data-null-array-options-array