I am using MySQL
as the database connection adapter for all my models. I have a downloads model and controller with an index function that renders either an HTML
table or a CSV
file depending on the type passed from the request. I also have a CSV
media type to handle an array of data, which is working as expected (outputs array keys as headers then array values for each row of data).
I wish to do the same find query but then remove ID
fields from the record set if a CSV
file is going to be rendered. You'll notice that the download ID is being fetched even though it is not in the fields array, so simply changing the fields array based on the request type will not work.
I have tried the following in the index action of my downloads controller:
<?php
namespace app\controllers;
use app\models\Downloads;
class DownloadsController extends \lithium\action\Controller {
public function index() {
// Dynamic conditions
$conditions = array(...);
$downloads = Downloads::find('all', array(
'fields' => array('user_id', 'Surveys.name'),
'conditions' => $conditions,
'with' => 'Surveys',
'order' => array('created' => 'desc')
));
if ($this->request->params['type'] == 'csv') {
$downloads->each(function ($download) {
// THIS DOES NOT WORK
unset($download->id, $download->user_id);
// I HAVE TRIED THIS HERE AND THE ID FIELDS STILL EXIST
// var_dump($download->data());
// exit;
return $download;
});
return $this->render(array('csv' => $downloads->to('array')));
}
return compact('downloads');
}
}
?>
I thought there was an __unset()
magic method on the entity object that would be called when you call the standard PHP
unset()
function on an entity's field.
It would be great if there was a $recordSet->removeField('field')
function, but I can not find one.
Any help would be greatly appreciated.
Perhaps you should do
$downloads = $downloads->to('array');
, iterate the array with a for loop, remove those fields from each row, then return that array. If you have to do this same thing for a lot of actions, you could setup a custom Media handler that could alter the data without needing logic for it in your controller.Take a look at this example in the Lithium Media class unit test.
You can also avoid having much logic for it in your controller at all through the use of a custom handler. This example also auto-generates a header row from the keys in your data.
In
config/bootstrap/media.php
:Your controller:
Why not then just dynamically set your
$fields
array?You can see in this example how I send the array for your CSV handler, otherwise it's the
$downloads
RecordSet object that goes to the view.