Error in writing a function in Cakephp - cakephp

I'm working with cakephp for project development. I wrote a function to get data from the database and do a summation.I have created a table called user with height and weight in it. I want to retrieve that data,add them, and to return that. Here is the function I wrote.
public function calculate()
{
$Height=$this->set('user',$this->User->find('first'));
$Weight=$this->set('user1',$this->User->find('first'));
$sum=($Height+$Weight);
$this->set('SUM',$sum);
}
In the view I wrote the following code.
<div class="page-content">
<?php echo $user['User']['weight']; ?>
<?php echo $user1['User']['height']; ?>
<?php echo $SUM ?>
</div
Height and weight values are getting displayed. But the sum value is displayed as zero. Please help me to fix this.

I found a better way to do the above calculation. I used the following code in the controller.
public function calculate($id=null)
{
if (!$this->User->exists($id)) {
throw new NotFoundException(__('Invalid user'));
}
$this->set('user1',$this->User->find('first', array('fields' => ('height'),'conditions' => array('User.id' =>$id))));
$this->set('user',$this->User->find('first', array('fields' => ('weight'),'conditions' => array('User.id' =>$id))));
}
My view looks similar to the one mentioned above. This works fine with me...

First you need get the field from find. (You can use find condition to filter de user id for example).
$user = $this->User->find('first', array(
'conditions' => array('User.id' => $id),
'fields' => array('User.height', 'User.weight') // fields from your DB
));
So, you can do a pr($user) to see the data and know what use.
After do the sum and set to the view. Cakephp Set

Related

search bar using cakephp

I'm new when it comes to work with CakePHP. I'm facing a problem that is bothering me since i started doing it. I got a form with an input and when a person types in what he/she wants (it is a classified website where you can search for something that you'd like to buy eg. a blue pen) it shows the page that refers to the desired object. For example. if i type in 'blue pen', it retrieves all the data that i have in my database related to the blue pen.
Hope you can help me, there is my code:
index.ctp
<?php
echo $this->Form->create('Location', array('type' => 'get'));
echo $this->Form->input('Find');
echo $this->Form->end();
?>
and my ArticlesController
public function search() {
$obj = '';
if (!empty($this->data)) {
$obj = $this->data['Location']['Procurar'];
$opts = array(
'conditions' => array('Location.Procurar' => $obj)
);
}
$this->set('obj', $obj); // so the keyword is saved. Can also get it via $this->data
}

cakephp passedArgs empty

I have a simple form in a a view and I am trying to access the $this=>passedArgs but it is coming back empty.
I am actualy trying to use the cakeDC search plugin which uses the $this=>passedArgs. It must be something simple I have not done to get the results from the form submit.
find view
<?php
echo $this->Form->create('Member', array(
'url' => array_merge(array('action' => 'find'), $this->params['pass'])
));
echo $this->Form->input('name', array('div' => false));
echo $this->Form->submit(__('Search'), array('div' => false));
echo $this->Form->end();
?>
Controller
public function find() {
debug($this->passedArgs);
exit;
}
I have tried $this->request->params
array(
'plugin' => null,
'controller' => 'members',
'action' => 'find',
'named' => array(),
'pass' => array(),
'isAjax' => false
)
I have add method get to the form.
This question has been asked before but their solution of having lower cases in the public $uses = array('order', 'product'); when it should be public $uses = array('Order', 'Product'); did not work.
Cakephp version 2.3.5
Thanks for any help
Update:
I have set my form to method get and this is the url:
http://localhost/loyalty/members/find?name=searchtext
I have removed the plugin and I still do not get anything $this->passedArgs, but I now get data for $this->request->data['name']. Once I put public $components = array('Search.Prg'); I get noting again for $this->request->data['name'].
I have tried again $this->Prg->parsedParams() with the Search plugin and I just get array()
The documentation is pretty clear on that.
You cannot just debug something that has not been set yet.
So including the plugin itself (and its component) is not enough.
From the readme/documenation:
public function find() {
$this->Prg->commonProcess();
$this->paginate['conditions'] = $this->ModelName->parseCriteria($this->passedArgs);
$this->set('...', $this->paginate());
}
Note the commonProcess() call which then only makes passedArgs contain what you need.

Cakephp HABTM: View generating drop down instead of multi value selectbox

I am trying to work with HABTM association between Profiles and Qualifications tables.
Model: Profile.php
App::uses('AppModel', 'Model');
class Profile extends AppModel {
public $hasAndBelongsToMany = array(
'Qualification' => array(
'className' => 'Qualification',
'joinTable' => 'profile_qualifications',
'foreignKey' => 'profile_id',
'associationForeignKey' => 'qualification_id',
'unique' => 'keepExisting'
)
);
}
Model: Qualification.php
App::uses('AppModel', 'Model');
class Qualification extends AppModel {
public $hasAndBelongsToMany = array(
'Profile' => array(
'className' => 'Profile',
'joinTable' => 'profile_qualifications',
'foreignKey' => 'qualification_id',
'associationForeignKey' => 'profile_id',
'unique' => 'keepExisting',
)
);
}
Controller: ProfilesController.php
App::uses('AppController', 'Controller');
class ProfilesController extends AppController {
public function edit() {
$this->Profile->id = $this->Auth->user('profile_id');
if ($this->request->is('post') || $this->request->is('put')) {
if ($this->Profile->save($this->request->data)) {
$this->Session->setFlash(__('The profile has been saved'));
$this->redirect(array('action' => 'view'));
} else {
$this->Session->setFlash(__('The profile could not be saved. Please, try again.'));
}
} else {
$this->request->data = $this->Profile->read(null, $this->Auth->user('profile_id'));
}
$salutations = $this->Profile->Salutation->find('list', array('fields' => array('Salutation.id', 'Salutation.abbr_name')));
$qualifications = $this->Profile->Qualification->find('list', array('fields' => array('Qualification.id', 'Qualification.abbr_name')));
$this->set(compact('salutations', 'qualifications'));
}
}
Vew: edit.ctp
<div class="profiles form">
<?php echo $this->Form->create('Profile'); ?>
<fieldset>
<legend><?php echo __('My Profile'); ?></legend>
<?php
echo $this->Form->input('salutation_id');
echo $this->Form->input('first_name');
echo $this->Form->input('middle_name');
echo $this->Form->input('last_name');
echo $this->Form->input('qualification'); /* gives drop down not multi select */
echo $this->Form->input('bio');
echo $this->Form->input('email');
echo $this->Form->input('mobile');
echo $this->Form->input('phone');
?>
</fieldset>
<?php echo $this->Form->end(__('Submit')); ?>
</div>
The edit view thus generated contains drop down to select a single value at a time for Qualifications attribute.
I want to know how can I generate a view with multi value selection box for qualifications ?
Moreover, what is the mistake in my code right now ?
First time poster, long time user.
I stumbled across this question today, and ended up using the subsequent solution which indeed does work quite nicely. However, I left myself wondering "why wouldn't CakePHP pickup on the HABTM relationship properly?" Especially considering (at least in my case) that the majority of the files had been baked in the cake console.
If we dive a little deeper into the issue, we discover that the problem is actually quite simple. A closer look at this snippet in the PostsController.php reveals how Cake builds in the HABTM relationship to the function, and uses $this->set() in order to pass it to the view (IMPORTANT: using lower-case plural versions "salutations"):
$salutations = $this->Profile->Salutation->find('list', array('fields' => array('Salutation.id', 'Salutation.abbr_name')));
$qualifications = $this->Profile->Qualification->find('list', array('fields' => array('Qualification.id', 'Qualification.abbr_name')));
$this->set(compact('salutations', 'qualifications'));
According to the Cake Cook Book, in order to take advantage of this HABTM in the front end when using the form helper is to specify the variable in singular form & title case (ie: "Salutation")
Snippet from the cook book:
Assuming that User hasAndBelongsToMany Group. In your controller, set a camelCase plural variable (group -> groups in this case, or ExtraFunkyModel -> extraFunkyModels) with the select options. In the controller action you would put the following:
$this->set('groups', $this->User->Group->find('list'));
And in the view a multiple select can be created with this simple code:
echo $this->Form->input('Group');
Should solve your issue without any necessary field tweaking.
Cheers!
Bake on.
Perhaps you need further configuration of your input:
echo $this->Form->input('Qualification',array(
'label' => 'Qualifications',
'type' => 'select',
'multiple' => true, // or 'checkbox' if you want a set of checkboxes
'options' => $qualifications,
'selected' => $html->value('Qualification.Qualification'),
));
I've used this blog post whenever I've come up against HABTM associations. It seems to me that a set of checkboxes maybe desired by default over a select input - maybe someone with greater CakePHP insight can chime in here?
Change
echo $this->Form->input('qualification');
to
echo $this->Form->input('qualification', array(
'multiple' => true
));
The CakePHP manual has more information on the form helper input options.

Deleting Multiple selected items from table

In my table I have a column with a check box for each row. I want to be able to delete all the selected items. I found the code from this website and modified it for my own stuff.
Link
I followed the website's naming convention for the check boxes and it is as follows:
<td> <?php echo $this->Form->checkbox('LocalClocks.id.['.$LocalClock['LocalClock']['id'].']', array('value' => $LocalClock['LocalClock']['id'])); ?></td>
This is the code in my controller for the deleteSelected() function:
public function deleteSelected()
{
foreach($this->data['LocalClocks'] as $key => $value)
{
if($value != 0)
{
$this->LocalClock->del($value);
}
}
$this->redirect($this->referer());
}
This is the code for the actual delete button (just in case it is needed):
<?php echo $this->Form->postLink('Delete Selected', array('action' => 'deleteSelected'), array('confirm' => 'Are you sure?')); ?>
There are a couple things I think might be the problem:
The code was written for an older version of cake, I think the website said 1.3, but I don't know what to update/correct in the existing code to make it work.
The delete button is the same as the one on cakephp's website on the blog tutorial. The only change I made was removing the id of the item to delete, because im not deleting a single item but multiple items.
Any help would be great.
Your checkbox input should be something like this
echo $this->Form->checkbox('LocalClocks.'.$LocalClock['LocalClock']['id'], array(
'value' => $LocalClock['LocalClock']['id'],
'hiddenField' => false
));
This will create a data array that will look like this
array(
'LocalClocks' => array(
1 => 1,
42 => 1
)
);
And will omit any unchecked ones from the data array because we're not using the hidden field. Finally, just a couple changes to your action
public function deleteSelected()
{
foreach($this->request->data['LocalClocks'] as $key => $value)
{
$this->LocalClock->delete($key);
}
$this->redirect($this->referer());
}
I prefer using Model::delete() to Model::deleteAll() because it runs the callbacks, where deleteAll does not.
Finally, your link will actually be a submit button. This will POST the data to the controller.
echo $this->Form->end('Submit');
If you want to use ajax, use the JsHelper to submit it instead. The following creates an Ajax submission that updates the dom element #mytable with the results of the action (in this case the referer that you redirect to).
echo $this->Js->submit('Submit', array(
'update' => '#mytable'
));
echo $this->Form->end();
once you got the list of your checked boxes; rather than using foreach loop to delete your ids one by one try this:
$this->Model->deleteAll(array('Model.column' => array($keys)));

Validation problems with multiple checkboxes (HABTM) on CakePHP form

Short version
I have some HABTM checkboxes on a form. Validation is working correctly (at least one checkbox needs to be checked for validation to pass) but the CakePHP error message divs aren't being generated as they should be.
Long Version
I have a from which allows users to fill in their name and email address and then choose from a list of brochures (checkboxes) they'd like to receive.
The form looks like this:
<?php
echo $this->Form->create('Request',array('action' => 'index'));
echo $this->Form->input('id');
echo $this->Form->input('name');
echo $this->Form->input('email');
echo $this->Form->input('Brochure',array(
'label' => __('Information Required:',true),
'type' => 'select',
'multiple' => 'checkbox',
'options' => $list,
'selected' => $this->Html->value('Brochure.Brochure'),
));
echo $this->Form->submit('Submit');
echo $this->Form->end();
?>
In my controller, $list is set as like this:
$this->Request->Brochure->find('list',array('fields'=>array('id','name')));
After reading the 2nd answer (posted by user448164) in HABTM form validation in CakePHP on Stack Overflow, I set my Request model up like this:
<?php
class Request extends AppModel {
var $name = 'Request';
function beforeValidate() {
foreach($this->hasAndBelongsToMany as $k=>$v) {
if(isset($this->data[$k][$k]))
{
$this->data[$this->alias][$k] = $this->data[$k][$k];
}
}
}
var $validate = array(
'name' => array(
'rule' => 'notEmpty',
'message' => 'Please enter your full name'
),
'email' => array(
'rule' => 'email',
'message' => 'Please enter a valid email address'
),
'Brochure' => array(
'rule' => array('multiple', array('min' => 1)),
'message' => 'Please select 1'
),
);
?>
This actually works 99% well. If none of the checkboxes are checked, validation fails as it should do. However, the only problem is that Cake isn't setting the "error" class on the <div>, nor is it creating the <div class="error-message">Please select 1</div> as it should.
For name and email, there is no problem - the error divs are being created properly.
So, to clarify, validation is working for my HABTM checkboxes. The only problem is that the error divs aren't being generated.
I'm posting this here as this is actually a much better question than the related question you found.
I was banging my head against a wall trying to handle the same problem of getting the validation error to show up in the page. I'm using CakePHP v1.2 and I hit a similar problem although I have actually split out the HABTM into the individual tables i.e. Request->BrochuesRequest->Brochure. This is because I can't have it deleting and re-adding the joining table rows at will.
Firstly I think the accepted answer from your linked question assumes that you are doing a save / saveAll when the beforeValidate call is triggered, however I was doing it through a validates call. The difference is that you need to call the Request->set method first. It was an article by Jonathan Snook on Multiple Validation Sets pointed me to that issue.
The second issue is actually getting the error message to appear was down to the $field value you use when calling invalidate. For ages I was including the model as well as the field assuming that this was how it matched the invalidate call to the input, i.e. you have $form->input('BrochuresRequest.brochures_id') so you need $this->BrochuresRequest->invalidate('BrochuresRequest.brochures_id').
However that is wrong you just want $this->BrochuresRequest->invalidate('brochures_id').
<?php
// requests/add view
echo $form->input('BrochuresRequest.brochures_id', array('multiple' => true));
// requests_controller
function add() {
if (!empty($this->data)) {
$this->Request->create();
// critical set to have $this->data
// for beforeValidate when calling validates
$this->Request->set($this->data);
if ($this->Request->validates()) {
$this->Request->saveAll($this->data);
}
}
}
// request model
function beforeValidate() {
if (count($this->data['BrochuresRequest']['brochures_id']) < 1) {
$this->invalidate('non_existent_field'); // fake validation error on Project
// must be brochures_id and not BrochuresRequest.brochures_id
$this->BrochuresRequest->invalidate('brochures_id', 'Please select 1');
return false;
}
return true;
}
?>
A few of the other things that I picked up on the way through:
You don't need a separate $form->error in the view
I couldn't for the life of me get the 'multiple' validation rule to work in the model
The accepted answer checks for an isset but I believe that this isn't required and masked the problem of there being no $this->data being passed through.
The beforeValidate should return false if you want it to prevent any save action.

Resources