Hi all I'm currently using cake 2.1, I am trying to get a page to render as a pdf in the browser however I believe I'm not loading the engine correctly. I believe it is because I'm not loading anything in routes.php.
here is the relevant code in routes.php
Router::connect('/', array('controller' => 'pages', 'action' => 'display', 'home'));
/**
* ...and connect the rest of 'Pages' controller's urls.
*/
Router::connect('/pages/*', array('controller' => 'pages', 'action' => 'display'));
/**
* Load all plugin routes. See the CakePlugin documentation on
* how to customize the loading of plugin routes.
*/
CakePlugin::routes();
Router::mapResources(array('Invoices'));
/**
* Load the CakePHP default routes. Remove this if you do not want to use
* the built-in default routes.
*/
require CAKE . 'Config' . DS . 'routes.php';
here is boostrap.php
<?php CakePlugin::load('DebugKit');
CakePlugin::load('CakePdf', array('bootstrap' => true, 'routes' => true));
CakePlugin::loadAll();
here is the function in the controller
public function view($id = null) {
$this->set('title_for_layout', 'Invoices');
$this->set('stylesheet_used', 'homestyle');
$this->set('image_used', 'eBOXLogoHome.png');
$this->layout='adminpdf';
Configure::write('CakePdf', array(
'engine' => 'CakePdf.WkHtmlToPdf',
'download'=>true,
'binary'=>'C:\Program Files (x86)\wkhtmltopdf\wkhtmltopdf.exe'));
$this->pdfConfig = array('engine' => 'CakePdf.WkHtmlToPdf');
$this->Invoice->id = $id;
if (!$this->Invoice->exists()) {
throw new NotFoundException(__('Invalid invoice'));
}
$this->pdfConfig = array(
'orientation' => 'potrait',
'filename' => 'Invoice_' . $id
);
$this->set('invoice', $this->Invoice->read(null, $id));
//Retrieve Account Id of current User
$accountid=$this->Auth->user('account_id');
//Find all Invoices where $conditions are satisfied
$invoicedetails=$this->Invoice->find('first', array(
'conditions' => array('Invoice.id'=>$id)));
//prints fieldsInvoice details, including invoice and field information
$invoices=$this->FieldsInvoice->find('all',array(
'conditions'=>array(
'invoice_id'=>$id)));
$itemInvoice=$this->InvoicesItem->find('all',array('conditions'=>array('invoice_id'=>$id)));
//Set variables
$this->set('invoicedetails', $invoicedetails);
$this->set('invoice', $invoices);
$this->set('accountid', $accountid);
$this->set('itemInvoice', $itemInvoice);
}
I am using this method of loading the pdf - https://github.com/ceeram/CakePdf/
and am using this engine wkhtmltopdf
I have been stuck on this for several days so any help would be greatly appreciated.
you use WkHtmlToPdf you need to download that engine because its not default.
check here : app/plugin/cakepdf/Vendor.
you see default : dompdf , mpdf and tcpdf.
i use DomPdf.
in your bootstrap.php load the engine like this :
Configure::write('CakePdf', array(
'engine' => 'CakePdf.DomPdf',
'pageSize'=>'A4',
'orientation' => 'landscape',
));
and use inside your controller :
$this -> pdfConfig = array (
'orientation' => 'landscape',
'download' => true,
'filename' => 'Invoice_' . $id
);
you can also take a look at : http://www.slideshare.net/jellehenkens/building-php-documents-with-cakepdf-cakefest-2012
good luck i hope this will help.
Related
I use themes on my cakePHP 2.6 project and would like to test my application.
I have a view file in /app/View/Pages/view.ctp
I overwrite it here /app/View/Themed/Theme/Pages/view.ctp
How can I change the $this->theme to get the result of the themed view?
I tried this (without result):
public function testView() {
$this->theme = 'Theme';
$url = Router::url(array('controller' => 'Pages', 'action' => 'view'));
$options = array(
'return' => 'contents'
);
$result = $this->testAction($url, $options);
$this->assertNotEmpty($result);
}
I want to write new route for RSS-View. The call /news/index.rss must open the RSS-Feed, but it open wrong methode.
routes.php
Router::parseExtensions('rss');
...
// don't work
Router::connect('/news/index.rss', array('controller' => 'news', 'action' => 'index'));
...
// open News:indexForPage()
Router::connect('/news/indexForPage/*', array('controller' => 'news', 'action' => 'indexForPage'));
...
// List width pagignation (News:index())
Router::connect('/news/*/:slug/:page',
array(
'controller' => 'news',
'action' => 'index'
),
array(
'competence_id'=>'[a-z,0-9,A-Z,\-]+',
'page'=>'[a-z,0-9,A-Z,\-]+'
)
);
...
// After call '/news/{Title-of-the-Article}-{ID}', it open News:view(ID)
Router::connect('/news/**', array('controller' => 'news', 'action' => 'view'));
That are all rules width "/news".
And wenn I call in browser "localhost/news/index.rss", it open News:view(), but not News:index(). If I deactivate the last line, it works, but I need this line.
How can I correct it?
You need to add 'ext' => 'rss' to your route as you are using Router::parseExtensions('rss');:-
Router::connect(
'/news/index.rss',
array('controller' => 'news', 'action' => 'index', 'ext' => 'rss')
);
I accepted the answer from drmonkeyninja quickly and not tested all functions.
I'm pleased width actually functions, but it is not perfect.
What I want, what I have, and what works:
localhost/news/index.rss – It opens RSS-Feed. It works.
localhost/news/, localhost/news/index – It opens all news sorted by publish date width pagignation (AJAX). It works.
localhost/news/{CATEGORY-ID} – It must open news filtered by CATEGORY-ID (integer) sorted by publish date width pagignation (AJAX). It don't work. (It opens localhost/news/view/{NEWS-ID}, see next point.) But it is not important, see "my alternative solution".
localhost/news/{NEWS-TITLE}-{NEWS-ID}, localhost/news/view/{NEWS-ID} – It opens the content of the one news width id={NEWS-ID}. It works. Where {NEWS-TITLE} is string (characters, numbers and '-'), and {NEWS-ID} is integer.
My code:
routes.php
// RSS-Feed. See point 1.
Router::connect('/news/index.rss', array('controller' => 'news', 'action' => 'index', 'ext' => 'rss'));
// See point 2. localhost/news/index
Router::connect('/news/index', array('controller' => 'news', 'action' => 'index'));
// It is for other methode. It works, and it isn't interesting.
Router::connect('/news/indexForPage/*', array('controller' => 'news', 'action' => 'indexForPage'));
// It is easy. localhost/news/view/{NEWS-ID} See point 4.
Router::connect('/news/view/*', array('controller' => 'news', 'action' => 'view'));
// localhost/news/{NEWS-TITLE}-{NEWS-ID} See point 4.
Router::connect('/news/*', array('controller' => 'news', 'action' => 'view'));
// My alternative solution for point 3. (e.g. localhost/breaking-news/3 It works fine with filter and AJAX-pagignation.)
Router::connect('/breaking-news/*/:slug/:page',
array(
'controller' => 'news',
'action' => 'index'
),
array(
'competence_id'=>'[0-9]+',
'page'=>'[a-z,0-9,A-Z,\-]+'
)
);
NewsController.php
class NewsController extends AppController {
public $helpers = array('Paginator');
public $components = array('RequestHandler', 'Paginator');
/**
* See points 1-3.
* #param string $competence_id
*/
public function index($competence_id = NULL) {...}
/**
* It isn't interesting.
* #param int $count
* #param int $sector
*/
public function indexForPage($count = NULL, $sector = NULL) {...}
/**
* See point 4.
* #param string $id
*/
public function view($id = NULL) {...}
}
Points for betterment are welcome:
New rooles in routes.php for cases localhost/news/{integer} (point 3) and localhost/news/{string}-{integer} (point 4)
Alternative solutions
I am developing a site in cakephp2.5. I have two plugin Webmaster and debugKit. When I write
CakePlugin::load('Webmaster', array('bootstrap' => false, 'routes' => false));
CakePlugin::load('webmaster');
CakePlugin::load( 'DebugKit');
The site works correctly on local system but not on live server. However if I remove one of the above Webmaster it shows error on local system and also on live
Error: The application is trying to load a file from the webmaster plugin
Error: Make sure your plugin webmaster is in the app\Plugin directory and was loaded
I also tried but no luck. Struggling from 2 days. Also seen these links
link1
link2
Here is my WebmasterAppController
<?php
App::uses('AppController', 'Controller');
class WebmasterAppController extends AppController{
public $theme= "beyond";
//public $layout=NULL;
public function beforeFilter(){
//$this->Auth->allow('login');
$this->Auth->loginAction= array('controller'=>'users', 'action'=>'login');
$this->Auth->loginRedirect= array('controller'=>'users', 'action'=>'index');
$this->Auth->loginError= 'Invalid Email/Password!';
$this->Auth->authError= 'You are not authorised to access!';
$this->Auth->logoutRedirect= array('controller'=>'users', 'action'=>'login');
AuthComponent::$sessionKey = 'Auth.Webmaster';
//we don't need to load debug kit
$this->Components->unload('DebugKit.Toolbar');
parent::beforeFilter();
}
}
And here is AppController
class AppController extends Controller{
public $cakeDescription = "CakePhp | ";
public $theme = "alpus";
public $ext = 'html';
public $helpers = array('NiceForms', 'coolFun');
public $components = array(
'DebugKit.Toolbar',
'Common',
'Session',
'Auth' => array(
'loginRedirect' => array(
'controller' => 'pages',
'action' => 'dashboard'
),
'logoutRedirect' => array(
'controller' => 'users',
'action' => 'login',
),
'authenticate' => array(
'Form' => array(
'passwordHasher' => 'Blowfish',
'fields' => array('username' => 'email')
)
),
'sessionKey' => 'Admin'
)
);
public function beforeFilter(){
if (isset($this->params['prefix']) && $this->params['prefix'] == 'admin') {
$this->theme = 'smart';
$this->Auth->loginAction = array('controller' => 'users', 'action' => 'admin_login', 'plugin' => false);
}
$this->Auth->allow('register');
}
}
Edit 1:
For cakephp 3.0 we can use
public function beforeFilter(Event $event) {
$this->Auth->sessionKey ='Auth.User';
}
in AppController.php to set different sessionKey for frontend and backend.
Why do you have multiple load calls for the same plugin anways? There should be only one per plugin!
That being said, mind your casing, the second CakePlugin::load() call uses webmaster instead of Webmaster. Plugin names should start with an uppercased letter, just like the corresponding directory name.
Your local filesystem is most probably case insensitive, so it can find the plugin directory even though the casing doesn't match.
Update It looks like I intially got you wrong, if CakePHP would tell you to load the plugin webmaster without you already having added a CakePlugin::load('webmaster') call, then you must have used the lowercased webmaster somewhere else in your code.
I'm using CakePHP v2.42 & would like to have SEO friendly URL in page pagination.
My current pagination is like
http://www.website.com/ubs/page/page:2
What to do to change to
http://www.website.com/ubs/page/2
My Controller is
<?php
class UbsController extends AppController {
public $helpers = array('Html', 'Form');
public function index() {
$this->paginate = array(
'limit' => 100,
);
$ubs = $this->paginate();
$this->set('ubs', $ubs);
}}
My Router is
Router::connect('/ubs', array('controller' => 'ubs', 'action' => 'index'));
Router::connect('/ubs/page/*', array('controller' => 'ubs', 'action' => 'index'));
EDIT - ADD MORE QUESTION
Answer by #kicaj is perfectly correct for the Router & Controller. However, the navigation link only display correctly on the first page.
In the first page navigation link show like this which is correct
http://www.website.com/ubs/
http://www.website.com/ubs/page/2/
http://www.website.com/ubs/page/3/
But navigation link show like this in second/third page page
http://www.website.com/ubs/index/2/
http://www.website.com/ubs/index/2/page:3/
I guess need to edit index.ctp file but not sure what to do.
My current navigation link in index.ctp show like this
$paginator = $this->Paginator;
$paginator->prev("« Prev");
$paginator->numbers(array('modulus' => 200, 'separator' => ' '));
$paginator->next("Next »");
What to change to correct this
Try this:
Router::connect('/ubs/page/:page', array(
'controller' => 'ubs',
'action' => 'index'
), array(
'pass' => array(
'page'
),
'page' => '[\d]+'
));
and in index action in ubs controller add code bellow:
public function index($page = 1) {
// ...
$this->request->params['named']['page'] = $page;
// ...
}
In your Paginator Helper you can choose the right friendly url you want with setting some options
url The URL of the paginating action. ‘url’ has a few sub options as well:
sort The key that the records are sorted by.
direction The direction of the sorting. Defaults to ‘ASC’.
page The page number to display.
There here an example .
$this->Paginator->options(array(
'url' => array(
'sort' => 'email', 'direction' => 'desc', 'page' => 6,
'lang' => 'en'
)
));
the source : Modifying the options PaginatorHelper uses
I'm working Cake 2.1.3, and the routes.php file, everything worked fine except the login management, for example I want my url be as follows:
http://mysite.com/companyx/users/login
where companyx is the slug, however when you run that url in the browser is as follows:
http://mysite.com/users/login
In this file routes.php I have defined as follows:
Router::connect(
'/:slug/users/login', // E.g. /companyx/users/login
array('controller' => 'users', 'action' => 'login'), array(
// order matters
'pass' => array('slug')
)
);
With other controllers I have no problems such as:
Router::connect(
'/:slug/users', // E.g. /companyx/users
array('controller' => 'users', 'action' => 'index'), array(
// order matters
'pass' => array('slug')
)
);
Best Regards ;)
CakePHP has a default login action defined in the AuthComponent. (line 171)
/**
* A URL (defined as a string or array) to the controller action that handles
* logins. Defaults to `/users/login`
*
* #var mixed
*/
public $loginAction = array(
'controller' => 'users',
'action' => 'login',
'plugin' => null
);
You can override this action with the beforeFilter in your own UsersController.
thanks for you answer. I solved this case this way:
public function beforeFilter() {
parent::beforeFilter();
if (!$this->request->is('post')) {
$this->Auth->loginAction = 'this is:slug/users/login/';
}
}
Where "this is slug", should be the slug.
Best Regards.