undefined variable in cakephp - cakephp

So how do I fix this? It gives me:
Notice (8): Undefined variable: products
[APP/View/Categories/category_filter.ctp, line 10] Warning (2):
Invalid argument supplied for foreach()
[APP/View/Categories/category_filter.ctp, line 10]
<? if (!empty($categories)) { ?>
<? foreach($categories as $row): ?>
<h1>Category: <?= $row['Category']['category'] ?></h1>
<table>
<tr>
<th>Name</th><th>Description</th><th>Price</th><th>Category</th>
<th>Thumbnails</th>
</tr>
<? foreach($products as $row): ?>
<tr><<td>
<?=$row['Product']['name']?>
</td><td>
<?=$row['Product']['description']?>
</td><td>
<?=$row['Product']['price']?>
</td><td>
<?=$row['Product']['category_id']?>
</td><td>
<?
if(!empty($row['Picture'])){
?>
<?= $this->Html->image('/img/'. $row['Picture'][0]['filename'], array('width'=>'50', 'alt'=>$row['Picture'][0]['title'])); ?>
<p><?= $row['Picture'][0]['description']; ?></p>
<? } ?>
</td><tr>
<? endforeach; ?>
<? endforeach; ?>
</table>
<? } ?>
In the controller
function category_filter($category_id) {
$this->set('categories',$this->Category->findAllById($category_id));
}

You can simply do this by making a Category Model class.
//app/Model/Category.php
class Category extends AppModel
{
public $name = 'Category';
public $useTable = 'categories';
public $primaryKey = 'id';
public $hasMany = array('Products' => array('className' => 'Product',
'foreignKey' => 'category_id'
));
}
//app/Model/Product.php
class Product extends AppModel
{
public $name = 'Product';
public $useTable = 'products';
public $primaryKey = 'id';
}
In your controller:
function category_filter($category_id) {
$this->set('category_details',$this->Category->findById($category_id));
}
In your view:
<h1>Category: <?php echo $category_details['Category']['category'] ?></h1>
<table>
<tr>
<th>Name</th><th>Description</th><th>Price</th><th>Category</th>
<th>Thumbnails</th>
</tr>
<?php if(!empty($category_details['Products'])): foreach($category_details['Products'] as $row): ?>
<tr><td>
<?php echo $row['Product']['name']?>
<?php echo $this->Html->image('/img/'. $row['Picture'][0]['filename'], array('width'=>'50', 'alt'=>$row['Picture'][0]['title'])); ?>
<p><?php echo $row['Picture'][0]['description']; ?></p>
<?php } ?>
</td><tr>
<?php endforeach;endif; ?>
As I do not much aware about your Picture Model. Kindly do the association for that model also in your Product model.

<?php
function category_filter($category_id) {
$this->set('categories',$this->Category->findAllById($category_id));
$products=$this->Product->find('all');
$this->set(compact('products'));
}
?>
set your product variable

Related

cakephp, link to retrieve status variable

Total n00b in CakePhp
Im trying to link to the view retrieved data from variable $status, defined in the controller, given the simple condition "done" or "pending".
Given the model:
<?php
class Task extends AppModel {
var $name = 'Task';
var $validate = array(
'title' => array(
'rule' => 'notEmpty',
'message' => 'Title of a task cannot be empty'
)
);
}?>
The Task Controller:
function index($status=null) {
if($status == 'done')
$tasks = $this->Task->find('all', array('conditions' => array('Task.done' => '1')));
else if($status == 'pending')
$tasks = $this->Task->find('all', array('conditions' => array('Task.done' => '0')));
else
$tasks = $this->set('Tasks', $this->Task->find('all'));
$this->set('tasks', $tasks);
$this->set('status', $status);
}
And finally The View:
<h2>Tasks</h2>
<?php if(empty($Tasks)): ?>
There are no tasks in this list
<?php else: ?>
<table>
<tr>
<th>Title</th>
<th>Status</th>
<th>Created</th>
<th>Modified</th>
<th>Actions</th>
</tr>
<?php foreach ($Tasks as $Task): ?>
<tr>
<td>
<?php echo $Task['Task']['title'] ?>
</td>
<td>
<?php
if($Task['Task']['done']) echo "Done";
else echo "Pending";
?>
</td>
<td>
<?php echo $Task['Task']['created'] ?>
</td>
<td>
<?php echo $Task['Task']['modified'] ?>
</td>
<td>
<?php echo $this->Html->link('Edit', array('action'=>'edit', $Task['Task']['id'])); ?>
<?php echo $this->Html->link('Delete', array('action'=>'delete', $Task['Task']['id']), null, 'Are you sure you want to delete this task?'); ?>
</td>
</tr>
<?php endforeach; ?>
</table>
<?php endif; ?>
<?php echo $this->Html->link('List Done Tasks', array('action'=>'index','done')); ?><br />
<?php echo $this->Html->link('List Pending Tasks', array('action'=>'index', 'pending')); ?><br />
Clicking the "Done Task" returns an empty list (There are no tasks in this list). Can anyone see what is wrong on the link? Thanks in advance!
You are mixing up the casing in the variable name $Tasks. In your example you are assigning the array to $tasks, but then in your view, your are trying to check a variable names $Tasks, which will turn up empty because it has never been properly set.
Change this line:
$this->set('tasks', $tasks);
To:
$this->set('Tasks', $tasks);
As mentioned by McWayWeb above to case of the variable is incorrect.
As you are setting lower case vars to use in your view i would make the change there. Change all counts of Task in the view to task.
I would also consider setting all viewVars at the same time using the below
$this->set(compact('tasks','status));

Edit table-cells in a view

Yii Version 1.1.15
I have a model which contains a serialized array (table) in an attribut. Showing this array as a table in a view works fine.
But I want to update the table-cells and then again save the array serialized in the model. And this does not work. The output stops there (*) without errors.
Here you can see what I did:
$model->table contains a serialized array. The unserialized array looks like this:
array(
array('dog', 'cat', 'cow'),
array('meat', 'milk', 'gras'),
)
I unserialize the table in the controller:
controller: contactController.php
$model = Contact::model()->findByPk((int) $id);
$table = unserialize($model->input)
$this->render('contact_form', array(
'table' => $table));
}
And now I want to show and edit the array $table in a form as a html-table:
view: contact_form.php
<?php
$form = $this->beginWidget('CActiveForm', array(
'id' => 'contact-form',
));
?>
<table border="2">
<?php foreach ($table as $row): ?>
<tr>
<?php foreach ($row as $value): ?>
<td>
<!-- (*) output stops here, without errors -->
<?= $form->textArea($value, '', array('rows' => 3, 'cols' => 20)); ?>
</td>
<?php endforeach ?>
</tr>
<?php endforeach ?>
</table>
<div class="row buttons">
<?php echo CHtml::submitButton("save"); ?>
</div>
<?php $this->endWidget(); ?>
The output stops before "... textArea ...".
If I only show $table in a view (without a form) it works like a charme:
<table border="2">
<?php foreach ($table as $row): ?>
<tr>
<?php foreach ($row as $value): ?>
<td><?= CHtml::encode($value) ?></td>
<?php endforeach ?>
</tr>
<?php endforeach ?>
</table>
Hope this helps to help me :-) How can I get this nice idea working?
Actually you are missing the arguments of CactiveForm.textArea(.......)
http://www.yiiframework.com/doc/api/1.1/CActiveForm#textArea-detail
textArea($value, '', array('rows' => 3, 'cols' => 20)); ?>
Instead of it your code should be
textArea($model, $value, array('rows' => 3, 'cols' => 20)); ?>

how working with view and controller

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>

Cake PHP Pagination changes to limit records per page

I have the following code in my calls/index.ctp. At the moment it is showing all records in one page. I want to limit 20 records per page. When I baked the project, the pagination was provided, but I'm still a beginner and doesn't know how to change the pagination. Can someone please help?
calls/index.ctp:
<div class="callsIndex">
<h2><?php echo __('Call Details'); ?> </h2>
<div class="bottomButtonnew"><?php echo $this->Html->link(__('Add Calls'), array('action' => 'add')); ?></div>
<table cellpadding="0" cellspacing="0">
<tr>
<th><?php echo $this->Paginator->sort('Call Date'); ?></th>
<th><?php echo $this->Paginator->sort('Call Time'); ?></th>
<th><?php echo $this->Paginator->sort('Comments'); ?></th>
<th><?php echo $this->Paginator->sort('Next Call Date'); ?></th>
<th><?php echo $this->Paginator->sort('Customer Name'); ?></th>
<th><?php echo $this->Paginator->sort('Company Name'); ?></th>
<th><?php echo $this->Paginator->sort('Employee Name'); ?></th>
<th class="actions"><?php echo __(''); ?></th>
</tr>
<?php foreach ($calls as $call): ?>
<tr>
<td><?php echo date("d-m-Y", strtotime($call['Call']['call_date'])); ?> </td>
<td><?php echo h($call['Call']['call_time']); ?> </td>
<td><?php echo h($call['Call']['comments']); ?> </td>
<td><?php echo date("d-m-Y", strtotime($call['Call']['next_call_date'])); ?> </td>
<td>
<?php echo $this->Html->link($call['Customers']['customer_name'], array('controller' => 'customers', 'action' => 'view', $call['Customers']['id'])); ?>
</td>
<td>
<?php echo $this->Html->link($call['Companies']['company_name'], array('controller' => 'companies', 'action' => 'view', $call['Companies']['id'])); ?>
</td>
<td>
<?php echo $this->Html->link($call['Employees']['employee_name'], array('controller' => 'employees', 'action' => 'view', $call['Employees']['id'])); ?>
</td>
<td class="actions">
<?php echo $this->Html->link(__('View'), array('action' => 'view', $call['Call']['id'])); ?>
</td>
</tr>
<?php endforeach; ?>
</table>
<p>
<?php
echo $this->Paginator->counter(array(
'format' => __('Page {:page} of {:pages}, showing {:current} records out of {:count} total')
));
?> </p>
<div class="paging">
<?php
echo $this->Paginator->prev('< ' . __('previous'), array(), null, array('class' => 'prev disabled'));
echo $this->Paginator->numbers(array('separator' => ''));
echo $this->Paginator->next(__('next') . ' >', array(), null, array('class' => 'next disabled'));
?>
</div>
<br>
</div>
callsController:
<?php
App::uses('AppController', 'Controller');
class CallsController extends AppController {
public $components = array('Paginator');
public $paginate = array(
'limit' => 10
);
public function index() {
$userid=$this->Session->read('User.userid');
if(isset($userid)&&$userid!=null)
{
$this->Call->recursive = 0;
$this->set('calls', $this->Paginator->paginate());
$result=$this->Call->getcalls($userid);
$this->set('result', $result);
}
else{
$this->set('loggedout',"loggedout");
$this->render("../Pages/home");
$this->layout = '../Pages/home';
}
}
//some code
}
You can do it easily by using pagination component.You should do it in your AppController.In your AppController you can type below code
Public $components =array('paginator');
public function beforeFilter()
{
parent::beforeFilter();
$this->Paginator->settings=array(
'limit'=>10
);
}
Than in you index method just change this line
$this->set('calls', $this->Paginator->paginate());
I think that will work fine now.This code will work for all controller.But if you want to change this only your CallsController. Do this code.
<?php
App::uses('AppController', 'Controller');
class CallsController extends AppController {
public $components = array('Paginator');
public function index() {
$this->Paginator->settings = array(
'limit' => 10
);
$userid=$this->Session->read('User.userid');
if(isset($userid)&&$userid!=null)
{
$this->Call->recursive = 0;
$this->set('calls', $this->Paginator->paginate());
$result=$this->Call->getcalls($userid);
$this->set('result', $result);
}
else{
$this->set('loggedout',"loggedout");
$this->render("../Pages/home");
$this->layout = '../Pages/home';
}
}
//some code
}
Note : There is two way to apply pagination one is by using component another is in controller.
The correct call in your example should be like this:
$this->set('calls', $this->paginate());
So your code is:
<?php
App::uses('AppController', 'Controller');
class CallsController extends AppController {
public $components = array('Paginator');
public $paginate = array(
'limit' => 10 //Here can you change the default limit
);
public function index() {
$userid=$this->Session->read('User.userid');
if(isset($userid)&&$userid!=null)
{
$this->Call->recursive = 0;
$this->set('calls', $this->paginate());
$result=$this->Call->getcalls($userid);
$this->set('result', $result);
}
else{
$this->set('loggedout',"loggedout");
$this->render("../Pages/home");
$this->layout = '../Pages/home';
}
}
//some code
}
<?php
App::uses('AppController', 'Controller');
class CallsController extends AppController {
public $components = array('Paginator');
public $paginate = array(
'limit' => 20
);
}

cakephp Cannot use string offset as an array

hi all in my view I'm getting this error when trying to print out information in my array.
here is my function in the controller
public function view($name)
$fields = $this->Template->Field->find('list',array(
'fields'=> array('name'),
'conditions' => array(
'template_id'=> $name)));
$this->set('field', $fields);
here is the view
</br><h2>Here is your template fields</h2></br>
<?php if(!empty($field))
{
foreach($field as $name)
{?>
<tr>
<td>
<?php echo $name['Field']['name']; ?>
</tr></br>
<?php
}
}
else
{?>
<tr> <td>No Templates Found.</td></tr>
<?php
}?>
As I already answer some of your questions. So what I understood about your project is "Template hasMany Fields" and you already defined an association-ship in the corresponding models.
You should use the following code into your view:
<?php if(!empty($field))
{
foreach($field as $name)
{?>
<tr>
<td>
<?php echo $name; ?>
</td>
</tr>
<?php
}
}
else
{?>
<tr> <td>No Template Fields Found.</td></tr>
<?php
}?>
you have operation with type list so the result will be an array in [field.id] => [field.name]
then you will require following in view
<?php foreach($field as $name): ?>
<?= $name ?>
<?php endforeach ?>

Resources