CakePHP3 Render View to a Variable - cakephp

I want to render the view to a variable without directly sending it to the browser. I used to do it with cakephp2.*. But, I cannot figure out how to do it in CakePHP3. Could you please tell me how to do it?

ViewBuilder was introduced in CakePHP 3.1 and handles the rendering of views. When ever I want to render to a variable I always go look at how send email works.
From a controller:
function index() {
// you can have view variables.
$data = 'A view variable';
// create a builder (hint: new ViewBuilder() constructor works too)
$builder = $this->viewBuilder();
// configure as needed
$builder->layout('default');
$builder->template('index');
$builder->helpers(['Html']);
// create a view instance
$view = $builder->build(compact('data'));
// render to a variable
$output = $view->render();
}

For Ajax request/response, I use this:
public function print(){
if ($this->request->is('ajax')) {
$data = $this->request->getData();
$builder = $this->viewBuilder()
->setTemplatePath('ControllerName')
->setTemplate('print');
->setLayout('ajax');
->enableAutoLayout(false);
$view = $builder->build(compact('data'));
$html = $view->render();
$res = ['html' => $html];
$this->set('response',$res);
$this->set("_serialize",'response');
}
}
And the print.ctp is under Template/ControllerName

Related

CakePHP 'autoRender = false' does not working. Still gives missing view error

I am using cakephp 2.0.4 (Doing Changes in existing project)
My controller function is..
class PagesController extends AppController {
public function getlocations($string = ''){
$this->autoRender = false;
$aResult = array(0=>'Florida', 1=>'London');
echo json_encode($aResult);
}
}
And also I have try $this->autoLayout = $this->autoRender = false;
When I am calling this action directly in browser mysite/app/pages/getlocations it will give following error
View file "/home/mysite/public_html/testing/app/View/Pages/g.ctp" is missing.
Create a /View/Ajax/json.ctp view:
<?php
if(!empty($data)) echo json_encode($data);
Then in the action:
$this->set('data', array(0=>'Florida', 1=>'London'));
$this->layout = false;
$this->render('/Ajax/json');
You could also make it work following the Cake way.
First you have to add the following code to your routes file:
Router::parseExtensions('json');
Next, in the controller add the 'RequestHandler' to your components array and serialize your result in your getlocations function:
public $components = array('RequestHandler');
public function getlocations($string = ''){
$this->set('aResult', array(0=>'Florida', 1=>'London'));
$this->set('_serialize', 'aResult');
}
Finally, you can see the results in your browser mysite/app/pages/getlocations.json
Doing this way CakePHP will add the application/json headers automatically.
More info: http://book.cakephp.org/2.0/en/views/json-and-xml-views.html

CakePHP URL Parameter

How can I get the parameter in the URL and save it to a varialble so I can save it to my database?
example: www.mydomain.com/item/products/3 <-
This is for my upload image, so I can specify what product ID will I use for that image.
function add() {
if ($this->request->is('post')) {
$this->Upload->create();
if(empty($this->data['Upload']['image']['name'])) {
unset($this->request->data['Upload']['image']);
}
if(!empty($this->data['Upload']['image']['name'])) {
$filename = $this->request->data['Upload']['image']['name'];
$new_filename = STring::uuid().'-'.$filename;
$file_tmp_name = $this->request->data['Upload']['image']['tmp_name'];
$dir = WWW_ROOT.'img'.DS.'uploads';
move_uploaded_file($file_tmp_name,$dir.DS.$new_filename);
$this->request->data['Upload']['image'] = $new_filename;
if($this->Upload->save($this->request->data)) {
$this->Session->setFlash(__('Uploaded.'));
$this->redirect(array('action' => 'index'));
}
}
}
}
How will I add it here. Thank you in advance :)
Im using cakePHP
Just add the product id as a hidden input in the Form.
Then it will be included in the $this->data variable when you get the POST request.
For example in a controller method like the following
public function product($id) {
.....
}
You access it by the url (for example): www.mydomain.com/item/products/3 where Item is the controller, product is the method you are calling in that controller and 3 represent a parameter that is required to the function to work in this case $id. (assuming you don't have any routing configuration)
Is treated as a normal php variable, just do whatever you wanna do with it. Just make sure you pass the correct value

retrieve single record with kohana 3.3 with request->param() is NULL

i try to use kohana framework but i have a little issue wen i try to retrieve a single record from table of my database.
my table:
ads
id_ads
title_ads
description_ads
my controller:
public function action_single()
{
$ads_id = $this->request->param('id_ads');
$ads = ORM::factory('ads', $ads_id);
$view = new View('ads/single'); // load the view/ads/single.php
$view->set('ads', $ads); // set 'ads' object to view
$this->template->set('content', $view);
}
my view
<h2><?php echo $ads->title_ads; ?></h2>
<pre><?php echo $ads->description_ads; ?></pre>
when i go to to localhost/kohana/index.php/ads/single/1 the browser display nothing, where is the problem?
try this:
$ads_id = $this->request->param('id_ads');
$ads =ORM::factory('ads'->find($ads_id);
or
$ads_id = $this->request->param('id_ads');
$ads =ORM::factory('ads')->where("id","=",$ads_id)->find();
to pass parameters, i think, is better (easier) to extend Controller_Template
in this way:
class Controller_News extends Controller_Template{
...
public function action_single()
{
...
$view->ads=$ads;
$this->template->content = $view;
}
}

Accessing Arguments using $_GET

I am adding an email validation step to my user registration. I cannot seem to get access to the arguments that are being passed in the emailed link;
link: activation.php?email=someone#somewhere.com&key=5614c46be05a95f55f2231d8dea41418d17b197a
Here is the page code;
class page_activation extends Page {
function init(){
parent::init();
if($this->api->auth->isLoggedIn())$this->api->redirect('index');
$loginAccount = $_GET['email'];
$activationKey = $_GET['key'];
$this->add('H1')->set('Activated');
$this->add('H3')->set('Account: '.$loginAccount);
$this->add('H3')->set('Key: '.$_GET['key']);
}
var_dump($_GET);
check network tab in inspector to make sure get params are actually passed.
check mod rewrite rules
I have found a solution in case it might help someone. It seems you can access the $_SERVER vars but the $_GET vars are lost by the time you get to the page. Here is some code that I used to accesses the passed vars from the email link;
class page_activation extends Page {
function init(){
parent::init();
if($this->api->auth->isLoggedIn())$this->api->redirect('index');
$data = parse_url($_SERVER['REQUEST_URI'], PHP_URL_QUERY);
$queryParts = split('[;&]', $data);
$params = array();
foreach ($queryParts as $param) {
$item = explode('=', $param);
$params[$item[0]] = $item[1];
}
$loginAccount = $params['email'];
$activationKey = $params['key'];
$this->add('H1')->set('Activated');
$this->add('H3')->set('Account: '.$loginAccount);
$this->add('H3')->set('Key: '.$activationKey);
}
}

AppModel aftersave, get controller function name

I'm trying to log every write operation so I'm using the afterSave and afterDelete callbacks in AppModel. Basically I need to log(for the moment): the model , the controller function, the loggedin user data and the remote ip
It seems that I was able to get all of them but I don't know how to get the controller function name.
This is the aftersave function I have now:
public function afterSave($created) {
App::uses('Folder', 'Utility');
$month = date("y-m");
if(!is_dir('../tmp/logs/'.$month)) {
$dir = new Folder('../tmp/logs/'.$month, true);
}
App::uses('CakeSession', 'Model/Datasource');
$user_id = CakeSession::read('Auth.User.username');
if($created) {
$id = 'New';
} else {
$id = $this->data[$this->alias]['id'];
}
$str = 'WRITE Action. Model: '.$this->alias.'. Controller: functon_name. ID:'.$id.'. Username: '.$user_id.'. Client IP: '.$this->getIP();
CakeLog::write($month.'/'.date("d-m-y"), $str);
}
Thanks
You're doing this on the model, which has no knowledge of the controller (and really shouldn't). I'd suggest copying the CakeRequest object to the model so you have that information. Here's one way:
//controller
function beforeFilter() {
$this->{$this->modelClass}->request = $this->request;
}
Then you can access the request object from the model. Use $this->request['params']['action'] to get the current dispatched action.
It's worth suggesting that you might want to move this to the read() method on a custom datasource, as afterSave() can possibly be skipped and therefore not logged.

Resources