I made an API call and received the response in JSON format.
JSON:
{
"Specialities": [
{
"SpecialityID": 1,
"SpecialityName": "Eye Doctor"
},
{
"SpecialityID": 2,
"SpecialityName": "Chiropractor"
},
{
"SpecialityID": 3,
"SpecialityName": "Primary Care Doctor"
}
]
}
Controller File:
public function index(){
$data= json_decode(file_get_contents('some_url'));
$this->load->view('my_view',$data);
}
Above code doesn't work because in view I can't access the nested object properties. However I am able to echo the JSON properties in controller file just like this:
Controller File:
public function index(){
$data=json_decode(file_get_contents('some_url'));
foreach ($data as $key=>$prop_name){
for($i=0;$i < count($prop_name);$i++){
echo $prop_name[$i]->SpecialityID;
echo $prop_name[$i]->SpecialityName;
}
}
}
My question is how do I pass this JSON to view and how can I access those properties in view file?
In controller changes like
public function index(){
$data['json_data']= json_decode(file_get_contents('some_url'));
$this->load->view('my_view',$data);
}
and in the view
echo "<pre>";print_r($json_data);
As per Docs
Data is passed from the controller to the view by way of an array or
an object in the second parameter of the view loading method.
Here is an example using an array:
So you need to change your code in controller
Controller.php
$data = array();
$data['myJson'] = json_decode(file_get_contents('some_url'));
$this->load->view('my_view',$data);
my_view.php
<html>
....
<?php
//Access them like so
print_r($myJson);
// Rest of your code here to play with json
?>
....
</html>
Related
i tried to set $uses in cakePhp3, it's working in cakePhp2.6 but not in 3
public $uses = array('model1', 'model2', 'model3', .... );
but i get error like
{
"message": "Call to a member function find() on boolean",
"url": "/JobPosts/Test/1042.json",
"code": 500,
"file": "/home/task24/public_html/clientApi/src/Controller/JobPostsController.php",
"line": 1304
}
You don't use $uses anymore in Cake 3.
$this->loadModel('MyModel');
Try to load all models using array_map function
array_map([$this, 'loadModel'], ['Product', 'Orders', 'OrderItem']); //Pass each element of the array to loadModel with is accessable through $this object.
Or create a function in your AppController, like
function loadModels($models = []) {
foreach($models as $model) {
$this->loadModel($model);
}
}
//Then you can access this function anywhere from any controller function (Controller which are extending AppController)
$this->loadModels(['Products', 'Orders', 'SO-ON']);
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
Ok, so this is a question I hope can help other newbies as I'm running into errors pulling information from arrays in Blade and I'm unfamiliar with it's syntax to properly debug.
I understand how to send array data to the view normally, for instance:
public function index() {
$variable = DB::table('tablename')->where('ID', '535');
return view('viewname', compact('variable'));
}
This will send everything attached to the ID of 535 to the view. The title can then be printed out like so:
#foreach ($variable as $foo)
{{ $foo->title }}
#endforeach
Or if you want to print everything (I Think this is right?):
#foreach ($variable as $foo)
#foreach ($foo as $name)
{{ $name }}
#endforeach
#endforeach
That process I kind of understand.
But where I'm getting stuck is with models.
Let's say I set up some routes:
Route::get('User', 'UserEntryController#index');
route::get('User/{id}', 'UserEntryController#show');
And in the controller one that grabs the show route:
<?php
namespace App\Http\Controllers;
use App\UserEdit;
use Illuminate\Http\Request;
use App\Http\Requests;
class UserEntryController extends Controller
{
public function show(UserEdit $id) {
return $id;
}
}
This will return everything attached to the model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class UserEdit extends Model {
protected $table = 'users';
protected $fillable = ['ID', various', 'pieces', 'of', 'table', 'data'];
protected $hidden = [];
protected $casts = [];
protected $dates = [];
}
However if I change a line on the controller:
<?php
namespace App\Http\Controllers;
use App\UserEdit;
use Illuminate\Http\Request;
use App\Http\Requests;
class UserEntryController extends Controller
{
public function show(UserEdit $id) {
return view('UserEdit', compact('id'));
//return $id;
}
}
The aforementioned Blade code will not run. In fact, I can't parse the array sent out to the the view at all. Of course a straight {{ id }} will give me the actual contents of the array.
{"ID":535,"various":"Del","pieces":"22","of":"32","table":"54","data":"John"}
So I guess my question is. If I'm getting data that's in the form of an array like this. How do iterate through it to apply formatting, put it in tables, or put it in a form, etc?
You're naming convention actually confuses you.
As long as you're returning and using a Object, rename that $id variable to something more obvious.
like:
class UserEntryController extends Controller
{
...
public function show(UserEdit $object) {
return view('UserEdit', compact('object'));
}
...
}
For the case when your framework is not set to bind directly to the object and your show method receives the $id, than you should return the object by querying the DB.
class UserEntryController extends Controller
{
...
public function show($id) {
$object = UserEdit::findOrFail($id);
return view('UserEdit', compact('object'));
}
...
}
... and nou in your view blade file you can use it like in your above examples.
#foreach ($object as $foo)
#foreach ($foo as $name)
{{ $name }}
#endforeach
#endforeach`
I am new to cakephp and i am trying to create a simple rest api that deals with vehicles. I want to out my data that i get from mysql database in json format.
This is my controller
class VehiclesController extends AppController {
var $name = 'Vehicles';
var $layout = 'default';
function index() {
$this->set('vehicles', $this->Vehicle->find('all'));
$this->set('title_for_layout','Home');
}
}
How would i out the content as json in a view?
Create a view here Views/Vehicles/json/index.ctp.
In your view you should be able to use:
<?php echo json_encode($vehicles); ?>
To output the JSON
You can then access it on this url : /vehicles/index.json
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.