CakePHP
CakePHP - Save page output as HTML
In this article, we are going to discuss about How to Save page output as HTML with cakePHP. As of now, I am working on a project that requres store the dynamically created output HTML files on a CDN (Content Delivery Network). I need to dynamically create a HTML page with database data and then store that HTML file on a CDN (Amazon S3) which cannot parse PHP.
I was looking for a way to output a view, and save it as an HTML file which could then be uploaded via the S3 API. In the CakePHP API, we see the Controller render method returns the output of the View model's render method which returns a string of the HTML output to be loaded in the browser. But we don't want to call the Controller's render method as that will send the user's browser to that page. Instead we want to use the View's render method so we get the string value that can be saved into an HTML file.
Assume we have a publish controller method which is called when the user wants to publish the HTML file. We also have a private method to generate the HTML and save it as a file in the local filesystem.
<?php
class VideosController extends AppController {
protected function publish( $id ){
$html_file = $this->generate( (int)$id );
//do whatever needs to be done with the HTML file
//for example, this is where I upload the file to S3
}
private function generate( $id ){
//set whatever data is required to build the page;
//be sure this is done before instantiating the View class so all
//set variables are passed when you pass this controller object in the constructor
$video = $this->Video->read( null, $id );
$this->set('video', $video);
//instantiate a new View class from the controller
$view = new View($this);
//call the View object's render method which will return the HTML.
//Note, I'm setting the layout to HTML and telling the view to render the html.ctp file in /app/views/videos/ directory
$viewdata = $view->render(null,'html','html');
//set the file name to save the View's output
$path = WWW_ROOT . 'files/html/' . $id . '.html';
$file = new File($path, true);
//write the content to the file
$file->write( $viewdata );
//return the path
return $path;
}
}
Let me know if you run into any problems. But so far, seems to be working well.
PHP CMS Frameworks
October 28, 2013
Read more →
CakePHP
Setting Error page layout based on Auth status with CakePHP
In this tutorial, we are going to discuss about How to setting the separate layout for the error pages based on the Auth Status with CakePHP. By default, CakePHP error pages load within the default layout. This is enough for most of the applications. But in some applications we need a separate layout for logged in users. So here I'm going to explain about how to set the separate layout for the error pages based on the Auth status with CakePHP.
For example, the navigation changes when a user logged in. Basically including the proper elements based in the user's login status. But for the some projects, the entire layout needs to be changed based on the user status. Therefore I needed to find a way to be sure the proper layout was loaded when 404 errors appeared.
To achieve this, we need to create an app_error.php file in our /app directory. Our AppError class should extend the ErrorHandler class. Now extend the error404 method. You'll have a reference to the controller via $this->controller so that you can access the Auth component. So just see if we have a valid logged in user, and if not, set the layout to 'guest', or whatever your layout happens to be named.
Be sure to call the parent method, passing in the $params variable to be sure the error is handled properly by the ErrorHandler's error404 method.
<?php
class AppError extends ErrorHandler {
function error404($params) {
if( !$this->controller->Auth->User() ){
$this->controller->layout = "guest";
}
parent::error404($params);
}
}
For example, the navigation changes when a user logged in. Basically including the proper elements based in the user's login status. But for the some projects, the entire layout needs to be changed based on the user status. Therefore I needed to find a way to be sure the proper layout was loaded when 404 errors appeared.
To achieve this, we need to create an app_error.php file in our /app directory. Our AppError class should extend the ErrorHandler class. Now extend the error404 method. You'll have a reference to the controller via $this->controller so that you can access the Auth component. So just see if we have a valid logged in user, and if not, set the layout to 'guest', or whatever your layout happens to be named.
Be sure to call the parent method, passing in the $params variable to be sure the error is handled properly by the ErrorHandler's error404 method.
<?php
class AppError extends ErrorHandler {
function error404($params) {
if( !$this->controller->Auth->User() ){
$this->controller->layout = "guest";
}
parent::error404($params);
}
}
PHP CMS Frameworks
October 21, 2013
Read more →
CakePHP
Pagination Caching in CakePHP - Step by step tutorial
In this article, we are going to discuss about How to achieve pagination cachin in CakePHP. Pagination is nothing but, it is a mechanism which provides users with additional navigation options for browsing through single parts of the given article. Parts of the article are usually referred to by numbers, hints, arrows as well as "previous" and "next"-buttons. In this, we are going to discuss about How to achieve this in CakePHP.
In most cases pagination is better than traditional "previous – next" navigation as it offers visitors a more quick and convenient navigation through the site. It's not a must, but a useful nice-to-have-feature.
If we have large number of datas it will producing unneccessary high load on the database. To reduce the load in database, we can use "Caching". Unlike normal returned data from the database paginated data can not be cached as easily, as the paginate method needs to be called to generate the pagination numbers etc. So we need to do a custom pagination query with cache built in.
To implement pagination caching in CakePHP, add the below code in your app_model.php file.
function paginate ($conditions, $fields, $order, $limit, $page = 1, $recursive = null, $extra = array())
{
$args = func_get_args();
$uniqueCacheId = '';
foreach ($args as $arg) {
$uniqueCacheId .= serialize($arg);
}
if (!empty($extra['contain'])) {
$contain = $extra['contain'];
}
$uniqueCacheId = md5($uniqueCacheId);
$pagination = Cache::read('pagination-'.$this->alias.'-'.$uniqueCacheId, 'paginate_cache');
if (empty($pagination)) {
$pagination = $this->find('all', compact('conditions', 'fields', 'order', 'limit', 'page', 'recursive', 'group', 'contain'));
Cache::write('pagination-'.$this->alias.'-'.$uniqueCacheId, $pagination, 'paginate_cache');
}
return $pagination;
}
function paginateCount ($conditions = null, $recursive = 0, $extra = array()) {
$args = func_get_args();
$uniqueCacheId = '';
foreach ($args as $arg) {
$uniqueCacheId .= serialize($arg);
}
$uniqueCacheId = md5($uniqueCacheId);
if (!empty($extra['contain'])) {
$contain = $extra['contain'];
}
$paginationcount = Cache::read('paginationcount-'.$this->alias.'-'.$uniqueCacheId, 'paginate_cache');
if (empty($paginationcount)) {
$paginationcount = $this->find('count', compact('conditions', 'contain', 'recursive'));
Cache::write('paginationcount-'.$this->alias.'-'.$uniqueCacheId, $paginationcount, 'paginate_cache');
}
return $paginationcount;
}
This will then take over from any paginate calls and generate a cached version of the dataset for the paginated items and the pagination controls, unique to each page and query set.
You need to specify the caching rule in core.php, something like:
Cache::config('paginate_cache', array(
'engine' => 'File',
'path' => CACHE .'sql'. DS,
'serialize' => true,
'duration' => '+1 hour',
));
In most cases pagination is better than traditional "previous – next" navigation as it offers visitors a more quick and convenient navigation through the site. It's not a must, but a useful nice-to-have-feature.
If we have large number of datas it will producing unneccessary high load on the database. To reduce the load in database, we can use "Caching". Unlike normal returned data from the database paginated data can not be cached as easily, as the paginate method needs to be called to generate the pagination numbers etc. So we need to do a custom pagination query with cache built in.
To implement pagination caching in CakePHP, add the below code in your app_model.php file.
function paginate ($conditions, $fields, $order, $limit, $page = 1, $recursive = null, $extra = array())
{
$args = func_get_args();
$uniqueCacheId = '';
foreach ($args as $arg) {
$uniqueCacheId .= serialize($arg);
}
if (!empty($extra['contain'])) {
$contain = $extra['contain'];
}
$uniqueCacheId = md5($uniqueCacheId);
$pagination = Cache::read('pagination-'.$this->alias.'-'.$uniqueCacheId, 'paginate_cache');
if (empty($pagination)) {
$pagination = $this->find('all', compact('conditions', 'fields', 'order', 'limit', 'page', 'recursive', 'group', 'contain'));
Cache::write('pagination-'.$this->alias.'-'.$uniqueCacheId, $pagination, 'paginate_cache');
}
return $pagination;
}
function paginateCount ($conditions = null, $recursive = 0, $extra = array()) {
$args = func_get_args();
$uniqueCacheId = '';
foreach ($args as $arg) {
$uniqueCacheId .= serialize($arg);
}
$uniqueCacheId = md5($uniqueCacheId);
if (!empty($extra['contain'])) {
$contain = $extra['contain'];
}
$paginationcount = Cache::read('paginationcount-'.$this->alias.'-'.$uniqueCacheId, 'paginate_cache');
if (empty($paginationcount)) {
$paginationcount = $this->find('count', compact('conditions', 'contain', 'recursive'));
Cache::write('paginationcount-'.$this->alias.'-'.$uniqueCacheId, $paginationcount, 'paginate_cache');
}
return $paginationcount;
}
This will then take over from any paginate calls and generate a cached version of the dataset for the paginated items and the pagination controls, unique to each page and query set.
You need to specify the caching rule in core.php, something like:
Cache::config('paginate_cache', array(
'engine' => 'File',
'path' => CACHE .'sql'. DS,
'serialize' => true,
'duration' => '+1 hour',
));
PHP CMS Frameworks
October 13, 2013
Read more →
CakePHP
Steps to Install CakePHP on Shared Hosting
In this article, we are going to discuss about How to install CakePHP on Shared Hosting. I have installed cakaPHP on my hosted web but I Couldn't get it to work quite right. After a few hours playing around with cakePHP, finally I got the correct installation.
My hosting service allows me to publish multiple websites/domains on the one account. They have FTP access to upload the websites and each website/domain appears as a separate directory off the root directory.
/
/site1.com
site1_files.htm
/site2.com
site2_files.htm
/site3.com
site3_files.htm
My original installation was to simply unzip the CakePHP files to my new site. The result was something like:
/
/site1.com
site1_files.htm
/site2.com
site2_files.htm
/site3.com
site3_files.htm
/site4.com
/cake
/config
/console
/libs
/tests
basics.php
bootstrap.php
dispatcher.php
/app
/config
/controllers
/models
/tests
/tmp
/vendors
/webroot
/css
/files
/img
/js
.htaccess
index.php
.htaccess
index.php
.htaccess
index.php
I have not listed all files and directories here. My webhost doesn't allow the DocumentRoot to be changed in the .htaccess file nor via the CPanel. I moved the 'app', 'cake' and 'vendors' directories and contents into the root directory. I deleted the .htaccess and index.php files from the site4.com directory (i.e the first level).
I moved the contents of the 'webroot' directory into the site4.com directory and then deleted the empty webroot directory. I also changed the name of my 'app' directory to 'site4app', this allows me to run multiple cake apps from the one server, one cake app for each domain.
This is the resulting structure:
/
/cake
/config
/console
/libs
/tests
basics.php
bootstrap.php
dispatcher.php
/site4app
/config
/controllers
/models
/tests
/tmp
/vendors
.htaccess
index.php
/site1.com
site1_files.htm
/site2.com
site2_files.htm
/site3.com
site3_files.htm
/site4.com
/css
/files
/img
/js
.htaccess
index.php
/vendors
/css
/js
I then had to edit the index.php file in the site4.com directory (the old app/webroot directory) to point to the 'cake' and 'app' (now called site4app) directories. The CPanel of my account listed the actual directory of my site4.com domain as /hsphere/local/home/my_account_name/site4.com. Therefore I had to change;
ROOT to look at /hsphere/local/home/my_account_name
APP_DIR to look at /hsphere/local/home/my_account_name/site4app
CAKE_CORE_INCLUDE_PATH to look at /hsphere/local/home/my_account_name/cake
ROOT = /hsphere/local/home/my_account_name, APP_DIR = site4app, and
CAKE_CORE_INCLUDE_PATH = /hsphere/local/home/my_account_name.
The web document root has already been set in the CPanel settings from my web host as /hsphere/local/home/my_account_name/site4.com and therefore doesn't need to be set anywhere in cakephp.
The section below is what the relevant section in my index.php file looks like.
/**
* The full path to the directory which holds "app", WITHOUT a trailing DS.
*
*/
if (!defined('ROOT')) {
define('ROOT', DS.'hsphere'.DS.'local'.DS.'home'.DS.'my_account_name');
}
/**
* The actual directory name for the "app".
*
*/
if (!defined('APP_DIR')) {
define('APP_DIR', 'site4app');
}
/**
* The absolute path to the "cake" directory, WITHOUT a trailing DS.
*
*/
if (!defined('CAKE_CORE_INCLUDE_PATH')) {
define('CAKE_CORE_INCLUDE_PATH', DS.'hsphere'.DS.'local'.DS.'home'.DS.'my_account_name');
}
/**
I used the standarf .htaccess file in the site4.com directory (the old webroot) so it would load the correct page when someone went to www.site4.com. Anyway, mine looks like this:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ /index.php?url=$1 [QSA,L]
</IfModule>
I went to www.site4.com and it was all working. Nice! There was only one problem, I was getting the session ID appended to the URL. The advice of setting the "php_flag session.trans_id off" only caused a web server error.
To fix the problem I changed a setting in the core.php file in the site4app/config (old app/config) directory. Change the session.save value from 'php' to 'cake'. It's about line 104 in my file.
Configure::write('Session.save', 'cake');
Now when I loaded the page at www.site4.com it displayed some errors. This turned out to be due to a missing directory. I went to site4app/tmp (old app/tmp) directory and created a directory called 'sessions'. Loaded the page again. Now No errors.
I hope this method also works for you. Good luck. Have a great day.
My hosting service allows me to publish multiple websites/domains on the one account. They have FTP access to upload the websites and each website/domain appears as a separate directory off the root directory.
/
/site1.com
site1_files.htm
/site2.com
site2_files.htm
/site3.com
site3_files.htm
My original installation was to simply unzip the CakePHP files to my new site. The result was something like:
/
/site1.com
site1_files.htm
/site2.com
site2_files.htm
/site3.com
site3_files.htm
/site4.com
/cake
/config
/console
/libs
/tests
basics.php
bootstrap.php
dispatcher.php
/app
/config
/controllers
/models
/tests
/tmp
/vendors
/webroot
/css
/files
/img
/js
.htaccess
index.php
.htaccess
index.php
.htaccess
index.php
I have not listed all files and directories here. My webhost doesn't allow the DocumentRoot to be changed in the .htaccess file nor via the CPanel. I moved the 'app', 'cake' and 'vendors' directories and contents into the root directory. I deleted the .htaccess and index.php files from the site4.com directory (i.e the first level).
I moved the contents of the 'webroot' directory into the site4.com directory and then deleted the empty webroot directory. I also changed the name of my 'app' directory to 'site4app', this allows me to run multiple cake apps from the one server, one cake app for each domain.
This is the resulting structure:
/
/cake
/config
/console
/libs
/tests
basics.php
bootstrap.php
dispatcher.php
/site4app
/config
/controllers
/models
/tests
/tmp
/vendors
.htaccess
index.php
/site1.com
site1_files.htm
/site2.com
site2_files.htm
/site3.com
site3_files.htm
/site4.com
/css
/files
/img
/js
.htaccess
index.php
/vendors
/css
/js
I then had to edit the index.php file in the site4.com directory (the old app/webroot directory) to point to the 'cake' and 'app' (now called site4app) directories. The CPanel of my account listed the actual directory of my site4.com domain as /hsphere/local/home/my_account_name/site4.com. Therefore I had to change;
ROOT to look at /hsphere/local/home/my_account_name
APP_DIR to look at /hsphere/local/home/my_account_name/site4app
CAKE_CORE_INCLUDE_PATH to look at /hsphere/local/home/my_account_name/cake
ROOT = /hsphere/local/home/my_account_name, APP_DIR = site4app, and
CAKE_CORE_INCLUDE_PATH = /hsphere/local/home/my_account_name.
The web document root has already been set in the CPanel settings from my web host as /hsphere/local/home/my_account_name/site4.com and therefore doesn't need to be set anywhere in cakephp.
The section below is what the relevant section in my index.php file looks like.
/**
* The full path to the directory which holds "app", WITHOUT a trailing DS.
*
*/
if (!defined('ROOT')) {
define('ROOT', DS.'hsphere'.DS.'local'.DS.'home'.DS.'my_account_name');
}
/**
* The actual directory name for the "app".
*
*/
if (!defined('APP_DIR')) {
define('APP_DIR', 'site4app');
}
/**
* The absolute path to the "cake" directory, WITHOUT a trailing DS.
*
*/
if (!defined('CAKE_CORE_INCLUDE_PATH')) {
define('CAKE_CORE_INCLUDE_PATH', DS.'hsphere'.DS.'local'.DS.'home'.DS.'my_account_name');
}
/**
I used the standarf .htaccess file in the site4.com directory (the old webroot) so it would load the correct page when someone went to www.site4.com. Anyway, mine looks like this:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ /index.php?url=$1 [QSA,L]
</IfModule>
I went to www.site4.com and it was all working. Nice! There was only one problem, I was getting the session ID appended to the URL. The advice of setting the "php_flag session.trans_id off" only caused a web server error.
To fix the problem I changed a setting in the core.php file in the site4app/config (old app/config) directory. Change the session.save value from 'php' to 'cake'. It's about line 104 in my file.
Configure::write('Session.save', 'cake');
Now when I loaded the page at www.site4.com it displayed some errors. This turned out to be due to a missing directory. I went to site4app/tmp (old app/tmp) directory and created a directory called 'sessions'. Loaded the page again. Now No errors.
I hope this method also works for you. Good luck. Have a great day.
PHP CMS Frameworks
October 07, 2013
Read more →
No more posts to load.
About this blog
PHPCMSFramework.com
Tutorials for WordPress, Laravel, Drupal, Joomla, Symfony & more — including AI-powered PHP guides. Publishing since 2012.
Trending posts
- Building a RAG System in Laravel from Scratch
- Steps to create a Contact Form in Symfony With SwiftMailer
- Build an AI Code Review Bot with Laravel — Real-World Use Case
- Build a WhatsApp AI Assistant Using Laravel, Twilio and OpenAI
- CIBB - Basic Forum With Codeigniter and Twitter Bootstrap
- Drupal 7 - Create your custom Hello World module
- Laravel and Prism PHP: The Modern Way to Work with AI Models
- Create Front End Component in Joomla - Step by step procedure
- A step by step procedure to develop wordpress plugin
- Migrating a wordpress website to Joomla website