CakePHP placing array items into diferrent cells CsvView plugin - cakephp

I have started to export csv files with the help of CsvView plugin, but am stuck at one place.
So here is the controller code:
function export(){
$data = array(
array('37899810', '50001', '1', '7616'),
);
$_serialize = 'data';
$this->response->download('export.csv');
$this->viewClass = 'CsvView.Csv';
$this->set(compact('data', '_serialize'));
}
The problem is that the whole array is printed in a single cell, where I would like every item of an array to be placed in its own cell.
Any help is much appreciated.

this seems working for me :-
$result contains :-
Array
(
[0] => Array
(
[Eshop] => Array
(
[name] => test shop
)
[Productlps] => Array
(
[name] => product
)
[ProductViewLog] => Array
(
[credits_left] => 4999
[ip_address] => 10.0.0.1
[created] => 2013-12-02 06:25:07
)
)
)
$excludePaths = array(); // Exclude all id fields
$_extract = $this->CsvView->prepareExtractFromFindResults($results, $excludePaths);
$customHeaders = array('ProductViewLog.created' => 'Date Accessed','Eshop.name'=>'Shop Name','Productlps.name'=>'Product Name','ProductViewLog.credits_left'=>'Credit Balance','ProductViewLog.ip_address'=>"Accessed From");
$_header = $this->CsvView->prepareHeaderFromExtract($_extract, $customHeaders);
$_serialize = 'results';
$this->response->download('my_file.csv');
$this->viewClass = 'CsvView.Csv';
$this->set(compact('results', '_serialize', '_header', '_extract'));

Related

Get first Smarty Array-Element

How can i get the first smarty array element ?
Actually i know how to do this... but i have following issue.
I get a array passed that looks like this
[DATA] => Array
(
[12] => Array
(
[content] => foobar
)
[1] => Array
(
[content] =>
)
[2] => Array
(
[content] =>
)
[3] => Array
(
[content] =>
)
//this is a snipit of {$myVar|#print_r}
this goes down until [11]
For some reason there is no [0] and a [12] at this position.
I don't know if this will allways be 12 but I know it allways be at the first position.
I can't sort this array because there is another array that has the same sortorder and I have to keep this order for later output.
Is there a way to select the first element without using array[0] or array.0 ?
Info: The project im working on uses Smarty 2
EDIT
I would re-index the array if i knew how :)
Since there is now answere after a couple of hours, i solved my problem temporarly.
To solve this, I opened {php} in smarty, got the array I need, splitted it into two arrays (re-indexing them of course so it starts at 0). Than I temp-save pos 0 from each array to a temp array. Override the orig 0 with underscore (_) and than multisort them, put back the original value to 0 and pass them back to $this->_tpl_vars very complicated way. (all inside the tpl)
{php}
// get array data and re-index it
$i=0;
foreach( $this->_tpl_vars['options'] as $option )
{
foreach( $option['DATA'] as $data )
$array[$i][] = $data;
$i++;
}
//delete empty entrys
$i=0;
foreach( $array[1] as $data ){
if(trim($data['content']) != ""){
$s[] = $array[0][$i];
$a[] = $array[1][$i];
}
$i++;
}
//temp save first values
$tmp_s = $s[0];
$tmp_a = $a[0];
//override first values to have a clean sort and keep them values on pos 0
$s[0] = $a[0] = "_";
//sort the arrays
array_multisort($s,$a);
//putting back the original values
$s[0] = $tmp_s;
$a[0] = $tmp_a;
//pass the array back to tpl_vars
$this->_tpl_vars['new_options'][] = $s;
$this->_tpl_vars['new_options'][] = $a;
{/php}
IF in PHP you have:
$smarty->assign(
'myVar',
array('DATA' =>
array(
12 => array('content' => 'first element'),
1 => array('content' => 'second element')
))
);
In Smarty you can use:
{assign var=first value = $myVar.DATA|#key}
{$myVar.DATA.$first.content}
And you will get displayed:
first element
However if in PHP you use:
$data = array(
12 => array('content' => 'first element'),
1 => array('content' => 'second element')
);
next($data);
$smarty->assign(
'myVar',
array('DATA' => $data
)
);
And in Smarty have the same as I showed at the beginning, the result will be:
second element
You would need to call:
reset($data);
after
next($data);
I think you cannot call reset for array in Smarty but I could be wrong.
It's also possible to reset array in Smarty but it's not so easy.
If in PHP you have:
$data = array(
12 => array('content' => 'first element'),
1 => array('content' => 'second element')
);
next($data);
$smarty->assign(
'myVar',
array('DATA' => $data
)
);
In Smarty you could use:
{assign var=$myVar.DATA value=$myVar.DATA|#reset}
{assign var=first value = $myVar.DATA|#key}
{$myVar.DATA.$first.content}
And you will get:
first element
as result
If your data is in array {$data} then using Smarty 3 you can just
{$firstData = $data|reset}

save all data in single statement without loop

How to save all data in cakePHP. Suppose I have number of records regarding single model I wish to save all data at a time. My array is in format.
Array
(
[Attendance] => Array
(
[0] => Array
(
[date] => 2013-10-09
[user_id] => 10
[attendance] => 1
)
[1] => Array
(
[date] => 2013-10-09
[user_id] => 8
[attendance] => 0
)
)
)
Is this possible to save all data a single time. I tried to do it using saveMany but it was not successful.
Do I need to do it in loop
foreach ($result as $data) {
$this->Attendance->create();
$this->request->data['Attendance'] = $data;
$this->Attendance->save($this->request->data);
}
Try saveMany instead of save
$this->Attendance->saveMany($this->request->data);
data should be in this format :
Array
(
[1] => Array
(
[Attendance] => Array
(
[field] => value
[field] => value
)
)
[2] => Array
(
[Attendance] => Array
(
[field_1] => value
[field_2] => value
)
)
)
CakePHP will save each record for each id you have on the array. The only requirement is to use the array structure convention by them, then use:
// Check method request
if ($this->request->is('post')) {
// Check not empty data
if (!empty($this->data)) {
// Save the data
if ($this-> Attendance->save($this->request->data)) {
// Set a session flash message and redirect.
$this->Session->setFlash('Attendance saved.');
$this->redirect('/Attendances');
} else {
$this->Session->setFlash('Error saving the data.');
}
}
}

Extracting values from arrays in custom fields

I'm trying to come up with a single array of all values in specific custom fields. The values themselves are also arrays. I've tried all sorts of array functions but haven't come across the right one or the right combination. Here is my code thus far:
$args = array(
'post_type' => 'match_report',
'post_status' => 'publish',
'meta_query' => array(
'relation' => 'OR',
array(
'key' => 'report_home-scorers'
),
array(
'key' => 'report_away-scorers'
)
)
);
$reportscore = new WP_Query($args);
$scorersResults = array();
if ( $reportscore->have_posts() ) {
while ( $reportscore->have_posts() ) {
$reportscore->the_post();
$homescorers = get_post_meta($post->ID,'report_home-scorers',false);
$awayscorers = get_post_meta($post->ID,'report_away-scorers',false);
foreach ($homescorers as $homescorer){
array_push($scorersResults, $homescorer);
}
foreach ($awayscorers as $awayscorer){
array_push($scorersResults, $awayscorer);
}
?>
<?php } wp_reset_postdata(); //endif
}//endwhile
$scorerResults = remove_empty($scorersResults);
function remove_empty($array) {
return array_filter($array, '_remove_empty_internal');
}
function _remove_empty_internal($value) {
return !empty($value) || $value === 0;
}
Here what I get if I print_r($scorerResults); :
Array
(
[1] => Array
(
[0] => 1
[1] => 63
)
[2] => Array
(
[0] => 263
[1] => 195
)
[3] => Array
(
[0] =>
)
[4] => Array
(
[0] =>
)
)
I just want the values in the internal arrays in an array.
Assuming you want the $scoreResults array to end up as array(1,63,263,195) you could use the array_reduce function like this:
function gatherScores($lhs, $rhs) {
foreach ($rhs as $key => $value)
if ($value)
$lhs[] = $value;
return $lhs;
}
$scorerResults = array_reduce($scorerResults, "gatherScores", array());
I'm not sure what the blank values are in your third and fourth arrays and how they should be handled, so you may need to change the if ($value) condition to check for something different. As it stands it'll obviously also filter out zero scores.

Trying to edit multiple records at once, saveAll not working

I'm saving multiple Widgets and associated WidgetsItems to a menu, which I have working fine.
The problem is, my edit function is not working. I understand that the data array structure needs to be as following, as it is what is saving my data properly in the first place:
Array (
[Widget] => Array
(
[23] => Array
(
[title] => Cocktails
[id] => 23
[WidgetsItem] => Array
(
[147] => Array
(
[item] => Martini: Noilly Pratt, Ginor Vodka
[price] => 24
[id] => 147
)
[148] => Array
(
[item] => Negroni: Campari, Gin, Sweet Vermouth
[price] => 16
[id] => 148
)
)
)
using the following controller code:
foreach($this->data['Widget'] as $widgetKey => $widget) :
$widgetData = array(
'title' => $widget['title'],
'id' => $widget['id']
);
$saveableWidget = Set::insert($widget, 'Widget', $widgetData);
if($this->Widget->saveAll($saveableWidget)) : $saveSuccess = true; endif;
endforeach;
Which is copied and pasted from the initial save function, then modified a little for editing. Instead, it's creating new entries, not editing them. I know it's something to do with the IDs, but it's just not saving. What am I doing wrong?
Please help, I feel like I'm very close to a nearly finished product.
Thanks,
~harley

Save multiple records for one model in CakePHP

I would like to save several records for one model. This would have been done pretty easily with saveAll() if it hadn't been for a problem:
I have a notification form, where I select multiple users from a <select> and two fields, for subject and content respectively. Now, when I output what $this->data contains, I have:
Array([Notification] => Array
(
[user_id] => Array
(
[0] => 4
[1] => 6
)
[subject] => subject
[content] => the-content-here
)
)
I've read on Cake 1.3 book, that in order to save multiple records for a model, you have to have the $this->data something like:
Array([Article] => Array(
[0] => Array
(
[title] => title 1
)
[1] => Array
(
[title] => title 2
)
)
)
So, how do I 'share' the subject and content to all selected users?
First off, this database design needs to be normalized.
It seems to me like a Notification can have many Users related to it. At the same time, a User can have many Notifications. Therefore,
Introduce a join table named users_notifications.
Implement the HABTM Relationship: Notification hasAndBelongsToMany User
In the view, you can simply use the following code to automagically bring up the multi-select form to grab user ids:
echo $this->Form->input('User');
The data that is sent to the controller will be of the form:
Array(
[Notification] => Array
(
[subject] => subject
[content] => contentcontentcontentcontentcontentcontent
),
[User] => Array
(
[User] => Array
(
[0] => 4
[1] => 6
)
)
)
Now, all you have to do is called the saveAll() function instead of save().
$this->Notification->saveAll($this->data);
And that's the Cake way to do it!
Those values have to be repeat like this
Array([Notification] => Array(
[0] => Array
(
[user_id] => 4
[subject] => subjects
[content] => content
)
[1] => Array
(
[user_id] => 6
[subject] => subject
[content] => contents
)
)
)
$this->Notification->saveAll($data['Notification']); // should work
If you don't pass any column value, this cake will just ignore it
You're going to have to massage your form's output to suit Model::saveAll. In your controller:
function action_name()
{
if ($this->data) {
if ($this->Notification->saveMany($this->data)) {
// success! :-)
} else {
// failure :-(
}
}
}
And in your model:
function saveMany($data)
{
$saveable = array('Notification'=>array());
foreach ($data['Notification']['user_id'] as $user_id) {
$saveable['Notification'][] = Set::merge($data['Notification'], array('user_id' => $user_id));
}
return $this->saveAll($saveable);
}
The benefit here is your controller still knows nothing about your model's schema, which it shouldn't.
In fact, you could probably redefine saveAll in your model, which hands off correctly formatted input arrays to parent::saveAll, but handles special cases itself.
There might be a more cakey way of doing this, but I've used this kind of technique: First, change the form so that you get an array like this:
Array(
[Notification] => Array
(
[subject] => subject
[content] => contentcontentcontentcontentcontentcontent
),
[selected_users] => Array
(
[id] => Array
(
[0] => 4
[1] => 6
)
)
)
(Just change the multiselect input's name to selected_users.id)
Then loop through the user ids and save each record individually:
foreach( $this->data[ 'selected_users' ][ 'id' ] as $userId ) {
$this->data[ 'Notification' ][ 'user_id' ] = $userId;
$this->Notification->create(); // initializes a new instance
$this->Notification->save( $this->data );
}

Resources