CakePHP saveAll() function problems - php

Im trying to save a record to a table aswell as an accociated record. The main table is called quotes and it has a hasmany link to the table quote_items. quote_items belongsto quote
When i try and save it saves the record in quote but does not save the record in quote_items
.
Below is my quote add function
function add() {
if (!empty($this->data)) {
$this->Quote->create();
if ($this->Quote->saveAll($this->data)) {
$this->Session->setFlash(__('The Quote has been saved', true));
//$this->redirect(array('action'=>'index'));
} else {
$this->Session->setFlash(__('The Quote could not be saved. Please, try again.', true));
}
}
$this->Quote->recursive = 2;
$statuses = $this->Quote->Status->find('list');
$contacts = $this->Quote->Contact->find('list');
$this->set(compact('statuses', 'contacts'));
}
Quote view / form setup
<?php echo $form->create('Quote', array('action' => 'add'));?>
<fieldset>
<legend><?php __('Add Quote');?></legend>
<?php
echo $form->input('Quote.name');
echo $form->input('Quote.revision');
echo $form->input('Quote.status_id');
echo $form->input('Quote.contact_id');
echo $form->input('quote_item.product_id');
echo $form->input('quote_item.name');
echo $form->input('quote_item.price');
echo $form->input('quote_item.description');
echo $form->input('Quote.totalcost');
?>
</fieldset>
<?php echo $form->end('Submit');?>
Array that is returned when the form is submitted
Array (
[quote] => Array (
[name] => Test
[revision] => 1
[status_id] => 1
[contact_id] => 1
[totalcost] => 123
)
[quote_item] => Array (
[product_id] => 1
[name] => test
[price] => 123
[description] => tes 1234
)
)
This seems to follow exactly what is listed in the cakephp documentation so i cant work out why its not working - http://book.cakephp.org/view/84/Saving-Related-Model-Data-hasOne-hasMany-belongsTo
Thanks in advance

The correct way to build the form would be:
echo $form->input('Quote.name');
...
echo $form->input('QuoteItem.0.product_id');
echo $form->input('QuoteItem.0.name');
...
echo $form->input('QuoteItem.1.product_id');
echo $form->input('QuoteItem.1.name');
The resulting array should look like this:
array(
'Quote' => array(
'name' => 'Test'
....
),
'QuoteItem' => array(
0 => array(
'product_id' => 1
'name' => 'test'
...
)
1 => array(
'product_id' => 2
'name' => 'test'
...
)
)
)
According to naming conventions, model names are camelized (ModelName, not model_name). Also, since Quote hasMany QuoteItems, the QuoteItem array needs to consist of many QuoteItem arrays. Hope that makes sense. :)

Related

Objects Array Get Specific Object and display together PHP

I am facing a problem problem here and need some help.
I have saved in my database a json_aray array with objects.
After decoding and print_r it I get this result.
Array (
[0] => stdClass Object (
[Title] => Image
[Info] => info
[ImageURL] => url.jpg )
[1] => stdClass Object (
[Title] => Image
[Info] => info
[ImageURL] => url.jpg )
[2] => stdClass Object (
[Title] => Accommodation
[Info] => info
[ImageURL] => image.jpg )
[3] => stdClass Object (
[Title] => Accommodation
[Info] => info
[ImageURL] => image.jpg )
[4] => stdClass Object (
[Title] => Accommodation
[Info] => info
[ImageURL] => image.jpg )
[5] => stdClass Object (
[Title] => Image
[Info] => info
[ImageURL] => image.jpg )
[6] => stdClass Object (
[Title] => Location
[Info] => info
[ImageURL] => image.jpg )
)
So here is the CASE:
I am trying to create a div for every different Object->Title e.g
I tried to check that with foreach loop but the result was creating 5 different divs instead of one.
Is there any built-in function in php to get all the $obj->Info if the $obj->Title == 'foo' or somehow check before the foreach loop what data the array has and separate them?
What i did in my code is below
while($row = sqlsrv_fetch_array($get_details)) {
$a = $row['additionalInformation'];
$b = json_decode($a);
$c = $b->AdditonalInfo;
foreach ($c as $d){
echo '<div class="class">';
if(($d->Title !== 'Image')){
echo '<h2>'.$d->Title.'</h2>';
echo '<p>'.$d->Info.'</p>';
}
echo "</div>";
}
}
UPDATE
Change my code with the actual one
This is what I get
But I need to create Accommodation or every same Title just once and all Info that has Title == 'Accommodation' under that div.
IF my question is clear enough please let me know so I can update it.
So to sum up i need to display all [Info] that has same [Title] in one div and create different div for each unique '[Title]'
Thanks In Advance
Requirements: Show 'nested groups' in a sequential stream of records.
Here we have a nested group indicated by a field called 'Title'.
The input records must be sorted so that all the records in each group are together and in the required order.
Now, the first thought is to use a 'foreach' loop. This is not the clearest approach because you cannot detect the end of the group by looking at the current record. Also, the foreach loop reads the next record at the end of the loop. So, you end up trying to work out where you are in the group to know what to do.
I use a technique called 'read ahead'. The idea is to read a record before the loop and the read the next record immediately after you have processed the current one. The 'trick' is that you process all the records in a group inside a loop.
So, the logic is an iteration of:
Process start of group - already has the first record of the group - important.
Process all the detail records belonging to the group - records are read inside this loop.
Process the end of the group - the current record is the first of the next group
repeat for each group.
It results in easier to understand code.
I have split all the separate actions into function so that you easily modify the individual actions.
Notice the code matches the structure of the data. There is always one place in the code to put the required action for that particular data item.
Full working Source Code at eval.in
Run the code
outputAllGroups($src);
exit();
Process All the Groups
function outputAllGroups(&$inputList)
{
reset($inputList);
$currentDetails = current($inputList); // read the first record
while ($currentDetails !== false) { // not end of records
// start the title group
$currentTitle = $currentDetails->Title;
outputGroupHeader($currentDetails);
// process all records in the group
while ( $currentDetails !== false
&& $currentDetails->Title === $currentTitle) {
outputDetails($currentDetails);
$currentDetails = readNextDetails($inputList); // may end group
}
// end the title group
outputGroupFooter($currentTitle);
}
}
Functions for the individual actions
function outputGroupHeader($details)
{
echo '<div class="TitleGroup">'. "<!-- Start Group: {$details->Title} -->". PHP_EOL
. '<div class="Title">'. $details->Title .'</div>' . PHP_EOL;
}
function outputGroupFooter($title)
{
echo '</div>'. "<!-- End Group: {$title} -->". PHP_EOL;
}
function outputDetails($details)
{
echo '<div class="details">'. PHP_EOL,
$details->Info . PHP_EOL,
$details->ImageURL .PHP_EOL,
'</div>' . PHP_EOL;
}
function readNextDetails(&$inputList)
{
$allOk = next($inputList); // advance next
return $allOk !== false ? current($inputList) : $allOk; // advance next
}
Output
<div class="TitleGroup"><!-- Start Group: Image -->
<div class="Title">Image</div>
<div class="details">
info1
url1.jpg
</div>
<div class="details">
info2
url2.jpg
</div>
</div><!-- End Group: Image -->
<div class="TitleGroup"><!-- Start Group: Accommodation -->
<div class="Title">Accommodation</div>
<div class="details">
info3
image3.jpg
</div>
<div class="details">
info4
image4.jpg
</div>
<div class="details">
info5
image5.jpg
</div>
</div><!-- End Group: Accommodation -->
<div class="TitleGroup"><!-- Start Group: Image -->
<div class="Title">Image</div>
<div class="details">
info6
image6.jpg
</div>
</div><!-- End Group: Image -->
<div class="TitleGroup"><!-- Start Group: Location -->
<div class="Title">Location</div>
<div class="details">
info7
image7.jpg
</div>
</div><!-- End Group: Location -->
Data
$src = Array (
'0' => (object) array(
'Title' => 'Image',
'Info' => 'info1',
'ImageURL' => 'url1.jpg', ),
'1' => (object) array(
'Title' => 'Image',
'Info' => 'info2',
'ImageURL' => 'url2.jpg', ),
'2' => (object) array(
'Title' => 'Accommodation',
'Info' => 'info3',
'ImageURL' => 'image3.jpg', ),
'3' => (object) array(
'Title' => 'Accommodation',
'Info' => 'info4',
'ImageURL' => 'image4.jpg', ),
'4' => (object) array(
'Title' => 'Accommodation',
'Info' => 'info5',
'ImageURL' => 'image5.jpg', ),
'5' => (object) array(
'Title' => 'Image',
'Info' => 'info6',
'ImageURL' => 'image6.jpg', ),
'6' => (object) array(
'Title' => 'Location',
'Info' => 'info7',
'ImageURL' => 'image7.jpg', ),
);
Hi please do so to get for each result unique div. For the 2 quetion (Is there any built-in function in php to get all the $obj->Info if the $obj->Title == 'foo' or somehow check before the foreach loop what data the array has and separate them?) I will find some solution late :)
$a = $row['additionalInformation'];
$b = json_decode($a);
$c = $b->AddInfo;
$createDivArray = array();
echo '<div class="style1">';
foreach ($c as $value){
if (in_array($value->Title, $createDivArray)) {
continue;
}
$createDivArray[] = $value->Title;
echo "<h4>$value->Title</h4>";
echo "<p>$value->Info</p>";
}
echo "</div>";

Get the intersect of tables

I have a question. So I have this array :
$a_list_id = array(
0 => 1234
1 => 739
3 => 538
);
And this array :
$a_users = array(
0 => array(
id => 15627,
name => test
),
1 => array(
id => 1234,
name => test1
),
2 => array(
id => 739,
name => test2
)
)
The result should be :
$a_response = array(
0 => array(
id => 1234,
name => test1
)
)
Because the id 1234 is in both arrays.
I try with array_intersect but not work. Can you help me please ?
Just use loops :
$a_response = array();
foreach ($a_users as $array) {
if (in_array($array['id'], $a_list_id)) {
$a_response []= $a_users;
}
}
array_intersect will only produce useful results if the values of both arrays can be cast to the same type. You've got an array of integers and another array of arrays, they can never* match so intersect will always be empty
If you want an intersection between the arrays then you have two options:
Index the arrays so their keys are the values you want to intersect and use array_intersect_key
Implement your own array comparison logic with array_uintersect and a callback function that knows the structure of the arrays being compared
example of the former:
$a_list_id = array(
1234 => 1234
739 => 739
538 => 538
);
$a_users = array(
15627 => array(
id => 15627,
name => test
),
1234 => array(
id => 1234,
name => test1
),
739 => array(
id => 739,
name => test2
)
)
var_dump (array_intersect_key ($a_users, $a_list_id));
Example of the latter:
var_dump (array_uintersect ($a_users, $a_list_id, function ($user, $id) {
return $user ["id"] - $id; // Result should be 0 if they match, as per documentation
}))
*They can be considered the same in the case where one value is integer 0 and the other is an empty array, but that's not very useful
Try the below code using array_search() function:
$a_list_id = array(1234, 538,739);
$a_users = array(
array(
'id'=> 15627,
'name' => 'test'
),
array(
'id' => 1234,
'name' => 'test1'
),
array(
'id' => 739,
'name' => 'test2'
)
);
foreach($a_users as $a_user){
if (in_array($a_user['id'], $a_list_id)) {
$a_response[array_search($a_user['id'], $a_list_id)] = $a_user;
}
}
print_r($a_response);
Have you tried using array_intersect_uassoc? http://php.net/manual/en/function.array-intersect-uassoc.php
function compare_ids($a, $b)
{
return $a - $b['id'];
}
print_r(array_intersect_uassoc($a_list_id, $a_users, "compare_ids"));

How to add array values in CHtml::activeDropDownList in Yii

I want to add $cluster1 values to CHtml::activeDropDownList
$cluster_name_models = new ClusterForm();
$records = $cluster_name_models->get_list('grade');
$cluster_details=$records['0']['grade'];
$cluster1=explode(';',$cluster_details);
$cluster1=Array ( [0] => JMC [1] => MMC [2] => SMC );
Assuming that grade is the name of the related model's attribute
$cluster_name_models = new ClusterForm();
$records = $cluster_name_models->get_list('grade');
$cluster_details=$records['0']['grade'];
$cluster1=explode(';',$cluster_details);
echo CHtml::activeDropDownList($model,
'grade',
$cluster1,
array('empty'=>'Select Option'));

passing query fields n rows to array

I'm trying to fetch all rows to an array variable
array that i want is like this
$data1 = array('fields'=>array(
array(
'id' => 1,
'nama_file' => "sunset.jpg",
'judul' => "Sunset",
'isi' => "Matahari terbenam indah sekali",
),
array(
'id' => 2,
'nama_file' => "water_lilies.jpg",
'judul' => "Bunga Lilly",
'isi' => "Bunga lilly air sangat indah",
),)
And I've done this:
$q = $this->db->query('select id, nama_file, judul, isi from tfoto where dihapus ="T" ');
$data1=array('fields');
foreach($q->result() as $row) {
$data1['fields']=array('id'=>$row->id,'nama_file'=>$row->nama_file,'judul'=>$row->judul, 'isi'=>$row->isi);
}
test output:
<?php
foreach($fields as $field){
echo $field['nama_file'];
.
.
.
};?>
and I got Message: Illegal string offset 'nama_file';'judul'; etc.
I am a newbie to MySQL/PHP, so forgive me if this is a very basic question. I tried looking all over but I could not find an answer to it.
This line:
$data1['fields']=array('id'=>$row->id,'nama_file'=>$row->nama_file,'judul'=>$row->judul, 'isi'=>$row->isi);
Should be:
$data1['fields'][] = array('id'=>$row->id,'nama_file'=>$row->nama_file,'judul'=>$row->judul, 'isi'=>$row->isi);
Because you have to append new arrays to $data1 and not replacing it.

How to make form field a hyperlink in CakePHP?

I have an options array:
$allAmazonMatches = Array ( [1] => B002I0HJZO [2] => B002I0HJzz [3] => B002I0HJccccccccc )
I display them using a Form helper:
<?php
echo $this->Form->create('AmazonMatches', array('action' => 'selectMatches'));
echo $this->Form->input('option_id', array('options' => $allAmazonMatches, 'type' => 'radio'));
echo $this->Form->end(__('Submit', true));
?>
What I want to show is:
option1 http://somewebsite/B002I0HJZO (hyper link that opens in new tab)
option2 http://somewebsite/B002I0HJzz (hyper link that opens in new tab)
How can I style my options array to do that?
You can do it, but I'm not sure it's a recommend practice. Clicking the label should really check the radio box - but if you really have to:
$allAmazonMatches = array(
'B002I0HJZO' => 'http://somewebsite/B002I0HJZO',
'B002I0HJzz' => 'http://somewebsite/B002I0HJzz',
'B002I0HJccccccccc' => 'http://somewebsite/B002I0HJccccccccc'
);
Have you tried something like this:
$label1 = $this->Html->link('blabla1', 'http://www.google.de', array('target' => '_blank'));
$label2 = $this->Html->link('blabla2', 'http://www.google.de', array('target' => '_blank'));
$options = array(0 => $label1, 1 => $label2);
echo $this->Form->input('accept', array('type' => 'radio', 'options' => $options));

Categories