Simple AJAX / JSON response with CakePHP - ajax

I'm new to cakePHP. Needless to say I don't know where to start reading. Read several pages about AJAX and JSON responses and all I could understand is that somehow I need to use Router::parseExtensions() and RequestHandlerComponent, but none had a sample code I could read.
What I need is to call function MyController::listAll() and return a Model::find('all') in JSON format so I can use it with JS.
Do I need a View for this?
In what folder should that view go?
What extension should it have?
Where do I put the Router::parseExtension() and RequestHandlerComponent?
// Controller
public function listAll() {
$myModel = $this->MyModel->find('all');
if($this->request->is('ajax') {
$this->layout=null;
// What else?
}
}

I don't know what you read but I guess it was not the official documentation. The official documentation contains examples how to do it.
class PostsController extends AppController {
public $components = array('RequestHandler');
public function index() {
// some code that created $posts and $comments
$this->set(compact('posts', 'comments'));
$this->set('_serialize', array('posts', 'comments'));
}
}
If the action is called with the .json extension you get json back, if its called with .xml you'll get xml back.
If you want or need to you can still create view files. Its as well explained on that page.
// Controller code
class PostsController extends AppController {
public function index() {
$this->set(compact('posts', 'comments'));
}
}
// View code - app/View/Posts/json/index.ctp
foreach ($posts as &$post) {
unset($post['Post']['generated_html']);
}
echo json_encode(compact('posts', 'comments'));

// Controller
public function listAll() {
$myModel = $this->MyModel->find('all');
if($this->request->is('ajax') {
$this->layout=null;
// What else?
echo json_encode($myModel);
exit;
// What else?
}
}
You must use exit after the echo and you are already using layout null so that is OK.
You do not have to use View for this, and it is your wish to work with components. Well all you can do from controller itself and there is nothing wrong with it!
Iinjoy

In Cakephp 3.5 you can send json response as below:
//in the controller
public function XYZ() {
$this->viewBuilder()->setlayout(null);
$this->autoRender = false;
$taskData = $this->_getTaskData();
$data = $this->XYZ->getAllEventsById( $taskData['tenderId']);
$this->response->type('json');
$this->response->body(json_encode($data));
return $this->response;
}

Try this:
public function listAll(){
$this->autoRender=false;
$output = $this->MyModel->find('all')->toArray();
$this->response = $this->response->withType('json');
$json = json_encode($output);
$this->response = $this->response->withStringBody($json);
}

Related

how to save pdf inside controller and pass pdf patch

pdf api -> https://github.com/barryvdh/laravel-dompdf
I create some simple API, everyone who pass some data will recaive link to pdf file.
The thing is, i dont know how to save pdf after conroller make changes inside my blade template.
so...
i already try changing data by request and that was working.
something like :
class pdfGenerator extends Controller
{
public function show(Request $request)
{
$data = $request->json()->all();
return view('test2', compact('data'));
}
}
that work well, also pdf creator works well from web.php
Route::get('/test', function () {
$pdf = PDF::loadView('test2');
return $pdf->download('test2.pdf');
});
that one just download my pdf file as expected.
but, now i try to pust some changes from request and save file but... without efford... any idea?
My code after tray to save content
class pdfGenerator extends Controller
{
public function show(Request $request)
{
$data = $request->json()->all();
return $pdf = PDF::loadView('test2', compact('data'))->save('/pdf_saved/my_test_file.pdf');
}
}
But i get only some errors. Please help :D
How can I save a PDF inside my controller and pass the PDF patch?
$data = $request->json()->all();
$pdf = app('dompdf.wrapper');
$pdf->loadView('test2', $data);
return $pdf->download('test2.pdf');

How to access Model from Views in CodeIgniter

How to access Model from Views in Codeigniter.
I have a Model with a function, i need to call this function from view
Please Read the CI documentation First:
If You are using a MVC Structured Framework then you should be following the way it works.
You Need the Controller:
public function your_controller_function(){
// To load model
$this->load->model ('your_model');
//To Call model function form controller
$data = $this->your_model->model_function($ex_data);
//TO Send data to view
$this->load->view('your_view',['data'=>$data]);
}
Inside your model:
public function model_function($ex_data){
// Your Querys
// user return to send you query result to the controller anything
// Sample Example of query and return
$query = $this->db->select('*')
->where('your_column',$data['column_name'])
->get('your_table');
$your_result = $query->row_array();
if($this->db->affected_rows() > 0){
return your_result;
} else {
return FALSE;
}
}
Inside your view you can write :
<?php
$this->load->model('your_model');
$this->your_model->some_function();
?>
For example in User_controller load User Model $this->load->model('Users_model');
Then User View page $viewpage = this->Users_model->somefunction($id);

Cakephp 3 does not work for the default language

Sorry for my english, but I hope you will understand me.
Simplified code looks like this:
//in bootstrap.php
ini_set('intl.default_locale', 'deu');
// MainMenusTable.php
public function initialize(array $config)
{
parent::initialize($config);
...
$this->addBehavior('Translate', ['fields' => ['title']]);
...
}
//in controller - THIS WORKS!
public function add()
{
I18n::locale('eng');
$mainMenu = $this->MainMenus->newEntity();
if ($this->request->is('post')) {
$mainMenu = $this->MainMenus->patchEntity($mainMenu, $this->request->data);
$this->MainMenus->save($mainMenu)
}
$this->set(compact('mainMenu'));
}
// in controller BUT THIS DOES'T WORK:
public function add()
{
I18n::locale('deu');
$mainMenu = $this->MainMenus->newEntity();
if ($this->request->is('post')) {
$mainMenu = $this->MainMenus->patchEntity($mainMenu, $this->request->data);
$this->MainMenus->save($mainMenu)
}
$this->set(compact('mainMenu'));
}
I have the same problem when I read the record
//in controller - THIS WORKS!
I18n::locale('eng');
$query = $this->MainMenus->find('all')->order(['MainMenus.id' => 'ASC'])->all();
// in controller BUT THIS DOES'T WORK:
I18n::locale('deu');
$query = $this->MainMenus->find('all')->order(['MainMenus.id' => 'ASC'])->all();
For 'deu' I manually entered records.
Do you know what the problem is?
Thanks!
This is a solution to the problem from https://github.com/cakephp/cakephp/issues/8416:
The behavior assumes that you store the records in the default language. If the current locale is the same as the default language, then it will just return the records in the database instead of fetching from the translations table.
The title will not be saved in the i18n table for the default language, that is only done for other languages.

How to disable render view in zend framework 2?

I want to use some ajax, but I don't know how to use function as the same as setNoRender() in zend framework 2 to disable for render view.
How to disable rendering view in zend framework 2?
To disable your view :
public function myactionAction()
{
// your code here ...
return false;
}
"return false" disables the view and not the layout! why? because the accepted types are:
ViewModel
array
null
so "false" disable the view.
To disable layout and view, return a response object:
public function myactionAction()
{
// your code here ...
return $this->response;
}
To disable layout:
public function myactionAction()
{
// your code here ...
$view = new ViewModel();
$view->setTerminal(true);
return $view;
}
If you're using JSON, then look at the view's JsonStrategy and return a JsonModel from you controller. See this article.
Alternatively, you can return an Response from your controller and the whole view layer is skipped:
public function testAction()
{
$response = $this->getResponse();
$response->setStatusCode(200);
$response->setContent('foo');
return $response;
}
Proper and simple solution to do this
public function testAction()
{
$data = array(
'result' => true,
'data' => array()
);
return $this->getResponse()->setContent(Json::encode($data));
}
Details: http://cmyker.blogspot.com/2012/11/zend-framework-2-ajax-return-json.html
I found some answer.
Though $this->layout()->getLayout() returns the name/path of the newly selected layout... The layout does not change with any of the following commands...
within a controller
$this->getLocator()->get('view')->layout()->setLayout('layouts/ajax.phtml');
$this->getLocator()->get('view')->layout()->setLayout('ajax');
$this->getLocator()->get('view')->layout()->disableLayout();
within a view PHTML file
$this->layout()->setLayout('layouts/ajax.phtml');
$this->layout()->setLayout('ajax');
$this->layout()->disableLayout();
$view = new ViewModel();
$view->setTerminate(true);
...
use Zend\View\Model\JsonModel;
public function myAction() {
...
$view = new JsonModel($myArray);
$view->setTerminal(true);
return $view;
}

RedBean ORM and Codeigniter, how to make Fuse recognize models loaded from CI default models path?

Codeigniter has its own Models path, where models extend from CI_Model. I'm using RedBean has a library in Codeigniter, loading it on a controller. After loading Rb, I try to use CI Loader to load a model that extends redbean_simplemodel (wish works, there's no error), but the events / methods inside the model have no effect when they're called on bean.
For example,
APPPATH/application/libraries/rb.php
class Rb {
function __construct()
{
// Include database configuration
include(APPPATH.'/config/database.php');
// Get Redbean
include(APPPATH.'/third_party/rb/rb.php');
// Database data
$host = $db[$active_group]['hostname'];
$user = $db[$active_group]['username'];
$pass = $db[$active_group]['password'];
$db = $db[$active_group]['database'];
// Setup DB connection
R::setup("mysql:host=$host;dbname=$db", $user, $pass);
} //end __contruct()
} //end Rb
And then on
APPPATH/application/models/model_song.php
class Model_song extends RedBean_SimpleModel {
public function store() {
if ( $this->title != 'test' ) {
throw new Exception("Illegal title, not equal «test»!");
}
}
}
while on
APPPATH/application/controllers/welcome.php
class Welcome extends CI_Controller {
public function index()
{
$this->load->library('rb');
$this->load->model('model_song');
$song = R::dispense('song');
$song->title = 'bluuuh';
$song->track = 4;
$id = R::store($song);
echo $id;
}
}
My question is, how to make RedBean (FUSE http://redbeanphp.com/#/Fuse) work on Codeigniter ?
Thanks for looking!
----- FOUND SOLUTION!
Actually, it's working! I was trying to place code under my model, method store(). That wont work! I tryed to place a new method called update() and it does work! Check the example below:
class Model_song extends RedBean_SimpleModel {
public function update() {
if ( $this->title != 'test' ) {
throw new Exception("Illegal title!");
}
}
}
The solution is the following:
"Assuming that you've already installed RedBean on Codeigniter"
1) Load the library for «redbean»
2) Using ci_loader, load the desired model (the model must extend redbean_simplemodel)
Thanks for looking! I hope this helps other people too.
The solution is the following:
"Assuming that you've already installed RedBean on Codeigniter"
Load the library for «redbean»
Using ci_loader, load the desired model (the model must extend redbean_simplemodel)

Resources