csv contains HTML while exporting that file in cakephp - cakephp

I am trying to perform functions exporting and importing CSV file.
I have done importing file successfully, but while exporting file, the downloaded CSV file contains HTML code with header, body and footer. I think that was from default.ctp, not sure.
Why, and from where, is that code automatically embedded ?
<?php function export()
{
$fp = NULL;
$results = NULL;
$row = NULL;
$results = $this->Order->find('all',array('fields'=> array('Order.sku','Order.inventory')));
$fp = fopen('php://output','w+');
$filename = "results.csv";
header('Content-type: application/csv');
header('Content-Disposition: attachment;');
fputcsv($fp,array(
'sku',
'inventory'
));
$ctr = count($results);
print($ctr);
foreach($results as $row)
{
fputcsv($fp,array(
$row['Order']['sku'],
$row['Order']['inventory']
));
}
fclose($fp);
} ?>

You need to disable layout rendering, stick this in your controller action:
$this->autoRender = false;
Tehnichally, this is not the correct way to do CSV, you should create a CSV layout and view, but if it works, ce le vie.

Thats a simple solution, either create a CSV layout that contains the necessary headers, or just use the built in ajax layout:
$this->layout = 'ajax';
In your controller action. That should fix it for you.

Disable layout in controller
<?php
$this->layout=null;
?>

Related

How to load/execute a view template from a string in CakePHP

I've developed a CakePHP plugin that allows the site administrator to define custom reports as a list of SQL queries that are executed and the results displayed by a .ctp template.
Now I need to allow the administrator to edit the template, stored in the DB together with the report.
Therefore I need to render a template that is inside a string and not in a .ctp file and I could not find anything in the core that helps.
I considered initially the approach to write the templates in .ctp files and load them from there, but I suspect this solution is rigged with flaws re: the location of the files and related permissions.
A better solution seems to override the View class and add a method to do this.
Can anyone suggest a better approach ?
P.S. Security is not a concern here, since the administrator is basically a developer without access to the code.
In CakePHP 2.0:
The View::render() method imports the template file using
include
The include statement includes and evaluates the specified file.
The evaluated template is immediately executed in whatever scope it was included. To duplicate this functionality, you would need to use
eval()
Caution: The eval() language construct is very dangerous because it
allows execution of arbitrary PHP code. Its use thus is discouraged.
If you have carefully verified that there is no other option than to
use this construct, pay special attention not to pass any user
provided data into it without properly validating it beforehand.
(This warning is speaking to you, specifically)
...if you wish to continue... Here is a basic example of how you might achieve this:
$name = 'world';
$template = 'Hello <?php echo $name ?>... <br />';
echo $template;
// Output: Hello ...
eval(' ?>' . $template . '<?php ');
// Output: Hello world...
Which is (almost) exactly the same as:
$name = 'world';
$template = 'Hello <?php echo $name ?>... <br />';
file_put_contents('path/to/template.php', $template);
include 'path/to/template.php';
Except people won't yell at you for using eval()
In your CakePHP application:
app/View/EvaluatorView.php
class EvaluatorView extends View
{
public function renderRaw($template, $data = [])
{
if (empty($data)) {
$data = $this->viewVars;
}
extract($data, EXTR_SKIP);
ob_start();
eval(' ?>' . $template . '<?php ');
$output = ob_get_clean();
return $output;
}
}
app/Controller/ReportsController.php
class ReportsController extends AppController
{
public function report()
{
$this->set('name', 'John Galt');
$this->set('template', 'Who is <?php echo $name; ?>?');
$this->viewClass = 'Evaluator';
}
}
app/View/Reports/report.ctp
// Content ...
$this->renderRaw($template);
Alternatively, you may want to check out existing templating engines like: Mustache, Twig, and Smarty.
Hmmm.. Maybe create a variable that will store the generated code and just 'echo' this variable in ctp file.
I had similar problem (cakephp 3)
Controller method:
public function preview($id = null) {
$this->loadModel('Templates');
$tempate = $this
->Templates
->findById($id)
->first();
if(is_null($template)) {
$this->Flash->error(__('Template not found'));
return $this->redirect($this->referer());
}
$html = $template->html_content;
$this->set(compact('html'));
}
And preview.ctp is just:
<?= $html

Using CakePdf data not showing

I am in a problem with CakePDF. I am using CakePHP 2.3.6. I setup everything alright, bootstrap & core files are ok.
Now, I want to generate many pdf files and download them. Downloading is ok, but when I download the files, I see that the generated pdf files say that Undefined $data, where I send $data to the view file.
Here is my Controller code:
App::uses('CakePdf', 'CakePdf.pdf');
// ...
public function createPdf($id) {
$data = $this->DBTable->find('all', array(
'conditions' => array(
'DBTable.id' => $id
)
));
$CakePdf = new CakePdf();
$path = APP . DS . 'pdf' . DS;
foreach($data as $key => $var) {
$CakePdf->template('create', 'default');
$this->set('var', $var);
$this->pdfConfig = array(
'orientation' => 'portrait',
'filename' => $var['id'] . ".pdf"
);
$CakePdf->write($path . $var['id'] . ".pdf");
}
}
Here, I am downloading the files some other way, not related to this problem, because downloading is ok. When I run this, all files are downloaded, and when I see the files, they say "Udefined var", looks like they didn't receive and variable called "$var".
I put the view file & the layout exactly where ceeram said.
What should I do now ? Please help me.
At last I got a solution to this. In the Controller function :
$data=$this->ModelName->find('all');
$CakePdf=new CakePdf();
$CakePdf->template('view_file','default');
$this->pdfConfig=array('orientation'=>'portrait','filename'=>$data['name']);
$CakePdf->viewVars(array('data'=>$data));
$CakePdf->write($path.$data['name'].".pdf");
Here, we have to store view_file.ctp in View/Pdf/, and default in View/Layouts/pdf/, where view_file.ctp is the view file which we want to convert in pdf, and default is the layout for this specific view file.
Here, viewVars() function passes the data to the view file, just like :
$this->set->('data',$data);
Let me know if anything is not clear here.
Thanks.

PHP How to display "Text Empty" if all files in directory are empty?

Assume in my directory "my_dir/" contains files below:
file1.php
file2.php
file3.php
...
And assume each files is not empty..
<div id="file_data">
<?php $my_dir = glob("my_dir/*.php"); ?>
<!-- This will display all files -->
<?php foreach($my_dir as $file) { ?>
<?php include $file; ?><br>
<?php } ?>
</div>
If all or some file is not empty it will display some information in my page, but how to display custom text if all files are empty? I don't want in my page display no data/information.
Thanks for help, I am very beginner in programmer =)
To check the files for content, you can just add
return "finished"; //or some other return value
to the end of your files and use this code:
<div id="file_data">
<?php $my_dir = glob("my_dir/*.php");
$content = false; //no content echoed until now
foreach($my_dir as $file) {
$returnValue = include($file);
if ($returnValue == "finished"){ //or some other return-value to check
//some content was successfull echoed
$content = true;
echo "<br>\n";
}
}
if (!$content){
echo "No content here"; //or just echo something more useful
} ?>
By the way, loading your content from several files and just loading all files in that directory is no good programming practice. an attacker could insert his files in your directory and insert its own code. also, it a put an non-php-file in your directory (aware of it or just an accident), include will result in an error and your page will not be created. i would try to think of another way to create your site in the future.

Cakephp 2.3.x Sending Files and forcing the download of a mp4 file

I'm using cakephp 2.3.1
I want to force download a mp4 file per http://book.cakephp.org/2.0/en/controllers/request-response.html#cake-response-file
In my 'view' I have the following code which is correctly searching for the filename, and finding the file name, and displaying the download link:
<?php $filename = APP . 'webroot/files/' . $dance['Dance']['id'] . '.mp4';
if (file_exists($filename)) {
echo $this->Html->link('DOWNLOAD', array('controller' => 'dances', 'action' => 'sendFile', $dance['Dance']['id']));
} else {
echo 'Coming soon: available April 16th';
}
?>
When the user clicks on the link I want to force the download of the mp4 file. In my controller I have the following code that doesn't work:
public function sendFile($id) {
$file = $this->Attachment->getFile($id); //Note: I do not understand the 'Attachment' and the 'getFile($id)'
$this->response->file($file['webroot/files/'], array('download' => true, 'name' => 'Dance'));
//Return reponse object to prevent controller from trying to render a view
return $this->response;
}
I don't understand 'Attachment' and the 'getFile()'
I'm getting the following error:
Error: Call to a member function getFile() on a non-object
What am I doing wrong and is there any other documentation I can be looking at to understand this better?
The line you don't understand is simply part of the example - it assumes the application has a model called Attachment and that it has a method called getFile. Since you don't have an Attachment model (or at least it isn't visible to the controller) you get a "call to member function on a non-object" error. That's not important though: all you need to worry about is providing a full system path to this->response->file(). In your example, you can probably get that by changing that line to:
$this->response->file(WWW_ROOT.'files/'. $id .'.mp4', array('download' => true, 'name' => 'Dance'));
You can get rid of the $this->Attachment->getFile line as it is irrelevant in your case.
Let me know if that helped!
public function downloadfile($id= null) {
$this->response->file(APP.'webroot\files\syllabus'.DS.$id,array('download'=> true, 'name'=>'Syllubus'));
return $this->response;
}
<?php echo $this->Html->link('Syllabus',
array('controller' => 'coursesubjects',
'action'=>'downloadfile',
$courseSubject['CourseSubject']['subject_syllabus']));
?>

Problem when trying to upload zip/rar files with the milesjohnson's upload plugin

I'm new to cakephp and I have found this milesjohnson's upload plugin ,
and I kind of like it, mostly because it gives me the chance of renaming the file once uploaded.Unfortunately, I can't get it to upload any zip/rar files.
This is the action where I upload the file:
function add() {
if (!empty($this->data)) {
if ($data = $this->Uploader->upload('link_referencia', array('name' => date("dmYhis")))) {
debug($data);
$this->data['Publicacione']['link_referencia']=$data['name'];
}
$this->Publicacione->create();
if ($this->Publicacione->save($this->data)) {
$this->Session->setFlash(__('The publicacione has been saved', true));
//$this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash(__('The publicacione could not be saved. Please, try again.', true));
}
}
$users = $this->Publicacione->User->find('list');
$this->set(compact('users'));
}
And this is the error I get everytime I attempt to upload any zip/rar file :
EDIT
Full insert query:
INSERT INTO `publicaciones` (`vigencia`, `tipo`, `titulo`, `descripcion`, `fecha_publicacion`, `fecha_caducidad`, `link_referencia`, `modified`, `created`) VALUES (1, 'c', 'there\'s nothing you can\'t do', '
fsdfsdfsdf
', '2011-06-07', '2011-06-30', Array, '2011-06-07 16:47:23', '2011-06-07 16:47:23')
Does anyone have any ideas on what the problem might be?
Thanks in advance.
i think there is nothing with the code what you have written but you should look at in to the plugin and find out whether it gives permission you to upload zip or not.
there will be conditions in your pluggin that you can upload only some kind of files like jpg,png,txt something like that.
I hope that helps you.
Regards,
Archit
Are you totally sure your File input on the form has type=>file specified, and same for your form?
Also I would look at other uploaders - MeioUpload can allow renaming and so on and is a bit more up to date. There is also the Cuploadify plugin (uploadify for cake) you can find on github.
Make sure your form is set to multipart/form-data like so:
<?php echo $this->Form->create('File', array('enctype' => 'multipart/form-data')); ?>
The following code will upload a file:
if ($this->request->is('post')) {
if ( $this->data['File']['file']['error'] <= 0 && $this->data['File']['file']['size'] <= 8388608 ) { // Check for no errors and that File size is around 8mb.
$folder = new Folder (ROOT . DS . 'app' . DS . 'filestorage' . DS, true); // create folder in /app/filestorage/
$path = $folder->path . $this->data['File']['file']['name']; // Set path to newly created folder + uploaded file name.
$tmpUrl = new File ( $this->data['File']['file']['tmp_name'] ); // Create temporary file object
if ($tmpUrl->copy($path , true) ) { // If copying file to path is successful,
$this->Session->setFlash(__('File uploaded succesfully!'));
}
}

Resources