CakePHP 3 - Downloading regardless of the host and project name - cakephp

On any particular View, if I include this link:
<?php echo $this->Html->link('Download', ['controller' => 'Uploads', 'action' => 'download',$upload->id]) ?>
A user can download a file based on the $upload->id provided.
I'm using this as my download function in my Uploads controller:
$upload = $this->Uploads->find('all')->first();
$filePath = '\xampp\htdocs\project\webroot\uploads'; //file path to where the uploaded file is
$this->response->file($filePath . DS . $upload->name,
array('download' => true, 'name' => $upload->name)); //finds the corresponding name attribute in the Uploads table of the database, finds a matching name in the uploads directory and then downloads that file.
$this->set(compact('upload'));
However, I was wondering if there was a way to be able to have the file path be more flexible. In my config.php, I have set two variables called $host and $basepath to refer to the web host (localhost) and the project name (project) respectively. I pass these variables to the AppController, and they can be accessed by any View.
But I can't seem to use these variables in the $filePath variable of the download function, so if I or anyone else were to change hosts or the project name, instead of being able to simply change config.php, I or anyone else would have to go and find this and change it as well (and if I had multiple download functions in multiple controllers, they'd have to go and change each and every one of them).

Take a look at the CakePHP global constants. You can easily access the path to your webroot by using WWW_ROOT.
https://book.cakephp.org/3.0/en/core-libraries/global-constants-and-functions.html

Related

Laravel - allow to download files from a folder in blade view

I'm stuck somewhere in the middle and I can't go on. Have folder, in folder files. In blade.view wants them download via link.
$fileNameGlob = glob($directory."*.*", GLOB_BRACE);
dd($fileNameGlob) return array
array:3 [▼
0 => "/var/www/html/domain/storage/app/apiFiles/611106/extract/1.png"
1 => "/var/www/html/domain/storage/app/apiFiles/611106/extract/2.png"
2 => "/var/www/html/domain/storage/app/apiFiles/611106/extract/3.jpg"
]
when i try return response()->download($fileNameGlob) have problem with array. If i have file path how continue to download file ?
Do you want to provide one link to download all files? Then you should zip the files beforehand and then deliver the zipfile path.
You could also use:
return response->download('apiFiles/611106/extract/1.png');
return response()->download('apiFiles/611106/extract/1.png', $name, $headers);
But this would not work for the array, but for the single elements, so you should provide something like $fileNameGlob[i].

how to set base url in cake php 3 in config/app.php file and get that url in all view

i would like to set base 'url' like "codeigniter" and that can be access in all views. I want to get full url like "http://localhost/somepath"
You probably don't need to do that, as the Helpers in Cake do that automatically.
For example, if your app is under http://localhost/somepath, creating a link like this
echo $this->Html->link('home', '/');
will automatically point to http://localhost/somepath
Links to actions work the same way:
echo $this->Html->link('login', ['controller' => 'Users', 'action' => 'login']);
will automatically point to http://localhost/somepath/Users/login
And if you do need to get the url anywhere else than in a view, you can do it like this:
use Cake\Routing\Router;
$path = Router::url('/', true);
In CakePHP 3 You can define "BASE_URL" constant in
yourAppFolder/config/paths.php as
define('BASE_URL', 'www.yoursite.com/');
and use BASE_URL anywhere in your project.

CakePHP generate and save PDF

I am using CakePHP for an application that does auto generation of vouchers to a PDF file. But they work through user clicks. Now I wish to create it automatically and have the file written to the server hard disk. Then later on, these files will get zipped up and sent to an email of my choice.
For the PDFs I use Html2ps/Html2pdf component found in CakePHP. You can view it here http://bakery.cakephp.org/articles/Casmo/2010/06/26/creating-pdf-files-with-html2ps-html2pdf
One issue I have is the formatting doesn't look right. If I have links that look like this:
http://www.mydomain.com/this-is-my-perma-link
They will render this way in the generated PDF:
http://www.mydomain.com/this- is- my- perma- link
And that would be a broken link. I've tried to use other characters to replace the dash but it doesn't work. I am not sure why.
Another issue is, how can I write the generated PDF file to my server hard disk? Is there an option for me to do that and how do I define the destination. Any examples?
Maybe thanks in advance!
Hi you can to use FPDF library . and you can to save file in the server and then redirect to other function.
check the next code.
///Call to library
<?php
App::uses('AppController', 'Controller');
require_once APP . 'Vendor' . DS . 'fpdf17' . DS . 'fpdf.php';
class TestController extends AppController {
public function test(){
--Create fpdf.
$pdf = new FPDF();
$pdf->AddPage();
$pdf->Output('files/Report.pdf');
$pdf->text($x,$y,'Txt');
return $this->redirect(
array('controller' => 'Test', 'action' => 'test_new')
);
}
}

How do I get zend to recognize the paths to Propel ORM

I am trying to get Propel to work in my Zend app, it seems that I can get the Propel library to load (from library/propel) but when called I get the exception: 'No connection information in your runtime configuration file for datasource [default]' (when I try to make a connection: 'Propel::getConnection'). My Db is not even named 'default'. I have this in my bootstrap.php from another SO question/answer:
require_once 'propel/Propel.php';
Propel::setConfiguration($this->getOptions('propel/MyPropel-conf.php'));
Propel::initialize();
// so we can get the connection from the registry easily
return Propel::getConnection();
I want the Propel configs (classmap conf as well) to be in the '/application/configs' (copies are there too right now), but I thought If I can get Propel to load from library/propel, then maybe moving my 'conf' files there, I may get them to load too. It seems that if I 'force' the config, by manually loading the params, or if I seem to get it in a temporary 'right' location (or use an absolute path), the exception I then get is this:
'Unable to open PDO connection [wrapped: SQLSTATE[28000] [1045] Access denied for user 'www-data'#'localhost'
As if Propel is not paying any attention to my configs.
My config looks like this; converted from the xml:
$conf = array (
'datasources' =>
array (
'unmActTestDB' =>
array (
'adapter' => 'mysql',
'connection' =>
array (
'dsn' => 'mysql://root:PASSWORD#localhost/unmActTestDB',
),
),
'default' => 'unmActTestDB',
),
'log' =>
array (
'ident' => 'propel-act',
'level' => '7',
),
'generator_version' => '1.5.6',
);
$conf['classmap'] = include(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'classmap-unmActTestDB-conf.php');
return $conf;
If it helps, I still have the Zend PDO DB adapter loading in the application.ini file too, would that cause a clash?. Is there a standard way to get Propel to work with Zend? Or can anyone see what I'm doing wrong?
I have been to several posts here on SO, and a couple popular posts like this one The Adventures Of Merging Propel With Zend Framework and this one at Zend's dev zone Integrating Propel with the Zend Framework, among others including the Propel Docs. They have been helpful, but I am really struggling with this. Thanks in advance! My current Zend Directory structure looks like this (w/ the two propel confs also in the library/propel folder:
What I ended up doing is this:
I got a good grip on how to generate my models from a 'reverse' using Propel. It created (as before) a 'schema.xml' file for me to build my models with.
Also my 'runtime.xml' file was incorrect for my needs, after the build I was not connecting to the right database because of my omission of a few tags, overall it is quite simple though:
<?xml version="1.0" encoding="UTF-8"?>
<config>
<log>
<ident>unmActTestDB</ident>
<level>7</level>
</log>
<propel>
<datasources default="unmActTestDB">
<datasource id="unmActTestDB">
<adapter>mysql</adapter>
<connection>
<dsn>mysql:host=localhost;dbname=unmActTestDB</dsn>
<user>zend</user>
<password>PASSWORD</password>
<database>unmActTestDB</database>
</connection>
</datasource>
</datasources>
</propel>
</config>
The 'dsn' tag has to be in the format above with the addition of the 'user', 'password', and the 'database' tags. This fixed my issue with the database connection errors. As quoted above (and here) the exception thrown was: 'No connection information in your runtime configuration file for datasource [default]'
As far as the loading of my models goes, I ended up putting them in my 'library' folder, I already have that folder autoloading in my app, plus it seemed like a good place form them.
here is an image of my 'updated' directory structure:
Note the addition of the 'unmActTestDB' folder in my directory, this is my ORM models.
Another thing to note is that I put my generated 'conf' files into my 'application/configs' folder. These are correct now, after the correction of the runtime.xml file and a 'rebuild'.
As a side note, I had to edit my 'schema.xml' file by hand (several times :) )...The original database used plural names for the tables, so I edited all the 'phpname' declarations (attributes actually, on the declaration tag) to be singular so I wouldn't access an object called 'Users'...instead I can now access a 'User' object. I kept the table names the same (tables are plural, and I won't have any issues importing the existing data, etc.) This was suggested by an answer to another one of my questions, see here How to get related object Propel ORM.
The other big edit I made was to add primary key declarations (again, attributes) for the many SQL views in the DB, also I added a 'readonly' and a 'noSQL' attributes to the declarations, this way I will have access (through the Propel models) to my views.
And, just to be thorough, and for those who are interested here is the addition to my 'bootstrap.php' file that does my 'Propel Init' for me...
protected function _initPropel()
{
$this->_logger->info('Bootstrap ' . __METHOD__);
require '../library/propel/Propel.php';
Propel::init(APPLICATION_PATH . '/configs/unmActTestDB-conf.php');
Propel::initialize();
return Propel::getConnection();
}
Another NOTE: the '$this->_logger->info('Bootstrap ' . METHOD);' calls my 'logging' method that just tells 'firePHP' that this method has loaded. The /configs/unmActTestDB-conf.php' calls the second 'conf' file that Propel generates... and here is the 'corrected' version of that file (the unmActTestDB.conf file that is), Note the changes in the 'connection' array.
<?php
// This file generated by Propel 1.5.6 convert-conf target
// from XML runtime conf file runtime-conf.xml
$conf = array (
'datasources' =>
array (
'unmActTestDB' =>
array (
'adapter' => 'mysql',
'connection' =>
array (
'dsn' => 'mysql:host=localhost;dbname=unmActTestDB',
'user' => 'zend',
'password' => 'PASSWORD',
'database' => 'unmActTestDB',
),
),
'default' => 'unmActTestDB',
),
'log' =>
array (
'ident' => 'unmActTestDB',
'level' => '7',
),
'generator_version' => '1.5.6',
);
$conf['classmap'] = include(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'classmap-unmActTestDB-conf.php');
return $conf;
I am off and running now! This was a great way to go, otherwise I was looking and writing sooo many mapping classes for my app. Propel (currently) generates over 300 models for this application! Plus the base classes, it would take me forever...

CakePHP View change extension

How can I change the extension for CakePHP Views from .ctp to .php
I have seen there is this line in /cake/libs/view.php var $ext = '.ctp'; that sets the extension but how can I do it from my /app/ folder so it doesn't effect Cake core files.
Thanks
You can set the extension in your AppController with
public $ext = '.yourext';
This is is reply to Cameron's comment regarding the issue of using multiple extensions in light of the fact cakephp does not allow you to specify multiple extensions.
I am using Mustache for a single site that uses merb, rails2, rails3 and cakephp for different sections of the site. The cake site "receives" mustache files for common layout elements but these templates have a '.mustache' file extension which my cake site will not recognize. My workaround is basically what dhofstet suggests just framed in the context of your specific usecase. In short, create a wrapper that might look something like this:
<?
$tmp = $this->ext;
$this->ext = '.mustache';
?>
<?= $m->render($this->renderElement('moznav/advanced_header'), array('foo' => $bar)) ?><br />
<? $this->ext = $tmp; ?>
When flow returns to the caller, you keep on using your native file extension.
How can I change the extension for CakePHP Views from .ctp to .php
I have seen there is this line in /cake/libs/view.php var $ext =
'.ctp'; that sets the extension but how can I do it from my /app/
folder so it doesn't effect Cake core files.
example:
you have view posts/add.ctp
now you rename add.ctp into add.php
and then you run .../posts/add the message error show:
Error: The view for PostsController::add() was not found.
to your app can understand extention .php, you add line public $ext = '.php' in PostsController.php
now, you run again ..posts/add => okie, cakephp understand extention .php
Notice: if you use atrribute $ext = '.php' but file view named .ctp, cakephp extention .ctp will use by default
I found this post because I had the same problem. This is not mentioned in the Predominant TwigView plugin documentation on Github. I'm tired of those documentations that explains only half of things and with which we have to guess the second half. This is a big waste of time that slows down projects pointlessly.

Resources