cake php 500 internal server error - php

this is my view code working on auto complete , but its showing me 500 internal server error
I am not sure what is going wrong if i'm not using the right url or some other problem.
public function search(){
$this->loadComponent('RequestHandler');
if ($this->request->is('ajax'))
{
$name = $this->request->query['term'];
$resultArr = $this->Invoices
->find()
->where(
['Invoices.name LIKE' => ($name . '%')],
['Invoices.name' => 'string']);
$resultsArr = [];
foreach ($resultArr as $result)
{
$resultsArr[] = ($result['name']);
}
$this->set('resultsArr', $resultsArr);
// This line is what handles converting your array into json
// To get this to work you must load the request handler
$this->set('_serialize', ['resultsArr']);
}
}
this is my view code:
<?php echo $this->Form->input('name', ['type' => 'text']); ?>
$.ajax({
type: "POST",
url: "<?php echo Router::url(array('controller' => 'Clinics','action' => 'search')); ?>",
success: function(response) {
$("#name").autocomplete({ source: response });
}
});

According to the error message in your comments, the loadComponent method isn't defined.
I would suggest loading the RequestHandler component near the top of your controller, for example:
class ClinicController extends AppController {
public $components = array('Request');
There is also another syntax for loading components on the fly:
$this->Request = $this->Components->load('Request');
Reference: https://book.cakephp.org/2.0/en/controllers/components.html

Related

clear blade laravel for render new response ajax

I'm trying to use the same blade to return a response from ajax.
In my first controller function I return a view with data:
public function index()
{
$data = (object) array(
'title' => trans('web.blog_title'),
'description' => trans('web.blog_header_info'),
);
$posts = \DB::table('blogs')->paginate(3);
return view('web.blog')->with('data', $data)->with('posts', $posts);
}
But now I'm doing a search with ajax and I want to use the same blade template for the response.
My second function that should render my response is:
public function getLocalNews($restaurant_id) {
$data = (object) array(
'title' => trans('web.blog_title'),
'description' => trans('web.blog_header_info'),
);
$news = Blog::query()->where('restaurant_id', '=', $restaurant_id)->paginate(3);
return view('web.blog')->with('data', $data)->with('posts', $news);
}
but it doesn't do anything...
ajax:
$("#submit_btn_blog_res").on("click", function(e){
e.preventDefault();
var form = $('#searchRestaurant');
$(this).find('input').removeClass('is-invalid');
$(this).find('.error').html('');
$.ajax({
url: "blog/getLocalNews/" + $(".suggest-element").attr('id'),
data: form.serializeArray(),
type: 'GET',
dataType: form.data('type'),
success: function(data){
console.log(data);
$(".post-article").remove();
},
error: function(jqXHR){
var response = JSON.parse(jqXHR.responseText);
if (response.errors.name) {
$(form).find('input[name="name"]').addClass('is-invalid');
$(form).find('.name-error').html(response.errors.name);
} else if (response.errors.email) {
$(form).find('input[name="email"]').addClass('is-invalid');
$(form).find('.email-error').html(response.errors.email);
} else if (response.errors.phone) {
$(form).find('input[name="phone"]').addClass('is-invalid');
$(form).find('.phone-error').html(response.errors.phone);
} else if (response.errors.comments) {
$(form).find('input[name="comments"]').addClass('is-invalid');
$(form).find('.comments-error').html(response.errors.comments);
} else if (response.errors.gRecaptchaResponse) {
$(form).find('input[name="g-recaptcha-response"]').addClass('is-invalid');
$(form).find('.g-recaptcha-response-error').html(response.errors.gRecaptchaResponse);
}
}
});
}); //submit search form restaurant
You should pass your response with a content-type of application/json. Hopefully, laravel has a function as response() which do this for you.
public function getLocalNews($restaurant_id){
$data = (object) array(
'title' => trans('web.blog_title'),
'description' => trans('web.blog_header_info'),
);
$news = Blog::query()->where('restaurant_id', '=', $restaurant_id)->get();
$response_data = ['data'=>$data, 'posts'=>$news];
return response()->json($response_data, 200);
}
As said in laravel helpers functions doc First parameter of response() receives the data that you want to be included in the body. If you pass an array, it will be converted to json, and the second parameter is the http status code of the response.
Notice: If you want to send your results with pagination. You can use laravel api resource.
Update: Use your ajax to add new received data to your html.
success: function(response){
console.log(response);
$('#desired-element-for-data').html('');
$.each(response.data, function(item){
html1 += '<p>item</p>';
});
$('#desired-element-for-posts').html('');
$.each(response.posts, function(item){
html2 += '<p>item</p>';
});
$('#desired-element-for-data').html(html1);
$('#desired-element-for-posts').html(html2);
$(".post-article").remove();
},

Why am I getting HTML response from jquery ajax call

I am trying to use jQuery UI autocomplete in my Laravel project to show some suggestions as the user is typing in. Here is the script triggered when the user types in:
$(".autocomplete").autocomplete({
source: function(request, response) {
$.ajax({
url: '/autocomplete',
dataType: "json",
data: {
term : request.term,
field : $(this.element).prop("id")
},
success: function(data) {
console.log(data);
response(data);
},
error: function(result, status, error) {
console.log(result);
console.log(status);
console.log(error);
}
});
},
min_length: 0, });
Here is my route in web.php
Route::get('/autocomplete', 'SitesController#autocomplete');
And finally my controller which retrieves results from the database.
public function autocomplete(Request $request) {
$term = \Request::get('term');
$field = \Request::get('field');
$sites = Site::where($field, 'ILIKE', '%'.$term.'%')
->distinct()
->get([$field]);
$data = [];
foreach($sites as $key => $site) {
$data[] = $site->$field;
}
return \Response::json($data);
}
This is currently not working, but when I directly add the above code to my route files, it does work well.
Route::get('/autocomplete', function()
{
$term = \Request::get('term');
$field = \Request::get('field');
$sites = Site::where($field, 'ILIKE', '%'.$term.'%')
->distinct()
->get([$field]);
$data = [];
foreach($sites as $key => $site) {
$data[] = $site->$field;
}
return \Response::json($data);
});
My script is returning a HTML response, and here is the error I get from the console:
SyntaxError: Unexpected token < in JSON at position 0
at parse (<anonymous>)
at ajaxConvert (VM258 app.js:18060)
at done (VM258 app.js:18530)
at XMLHttpRequest.<anonymous> (VM258 app.js:18832)
I can't see why my script is not returning JSON but HTML, while it does when I put my script in the web.php file.
As suggested by aynber, looking closely at the returned HTML page, I realized it was an error page that I throw thanks to a middleware, when someone is trying to access a page without having the rights. And my controller was of course checking for this middleware first. I made an exception for the autocomplete function and now everything is working fine, though I feel I'm not handling my middlewares the good way...
in app/Exceptions/Handler.php file you can do something like this
public function render($request, Exception $e)
{
if ($request->wantsJson()) {
$response = ... // put your response data here
return response()->json($response);
}
...
}

Ajax request in WP plugin return 0

I know it's a commun question and I red nearly all the subject about it, but i can't find an answer who fit my case.
I wrote a plugin to add country and languages related (USA->English|Sapnish for example) I am using Class and constructor for the plugin's functions. It is fully working expect the following function :
I get a select in front with all the country, and on change of this select action another function with ajax, the data passed are ok but the response is always returning 0, connected as admin or not.
Here is my ajax :
$('#sel-country-back').change(function(){
var post_id = $(this).val();
change_status(post_id);
})
function change_status(id) {
$.ajax({
url: window.location.origin + '/wp-admin/admin-ajax.php',
data: {
action: 'wmu-display-lang-select',
post_id: id,
},
type: 'post',
success:function(data){
$('#lang-back').html(data);
},
error: function(errorThrown){
$('#lang-back').html('<select name="langBack" id="sel-lang-back"><option value="default" class="no-lang-option">Aucune langue associée</option></select>');
}
});
}
and my function
public function wmu_display_lang_select()
{
if ($_POST['post_id']) {
$id = sanitize_text_field($_POST['post_id']);
$lang = self::getLang($id);
if ($lang !== false) {
$response = array(
'status' => 200,
'content' => $lang
);
}
else {
$response = array(
'status' => 201,
'message' => __('Le fichier demandé n\'existe pas', 'cadwork')
);
}
die(json_encode($response));
}
}
with the action added to the constructor
public function __construct()
{
add_action('admin_menu', array($this, 'wmu_add_menu'));
add_action('wp_ajax_wmu_display_lang_select', 'wmu_display_lang_select');
add_action('wp_ajax_nopriv_wmu_display_lang_select', 'wmu_display_lang_select');
}
I tried to place the add_action outside the class after the class instantiation
$wmu = new WB_MultiLang_URL();
add_action('wp_ajax_wmu_display_lang_select', 'wmu_display_lang_select');
add_action('wp_ajax_nopriv_wmu_display_lang_select', 'wmu_display_lang_select');
but it doesn't seem to work,
Do you have any ideas why ? I think it's a dumb error or mistake somewhere but I can't find it...
Change action: 'wmu-display-lang-select', in your JS request to action: 'wmu_display_lang_select', and it should work.

CakePHP trying to send a ajax request

I'm trying to send a ajax requistion to a controller, that it should returns something, but isn't.
My element (View/Elements/list.ctp):
<script type="text/javascript">
$(document).ready(function(){
$('#click').click(function(){
$.ajax({
type: "POST",
url: '<?php echo Router::url(array('controller' => 'products', 'action' => 'showProducts')); ?>',
success: function(data){
alert(data);
}
});
});
});
</script>
<p id="click">Click me!</p>
Controller products:
<?php
class ProductsController extends AppController {
public $helpers = array('Js' => array('Jquery'));
public $components = array('RequestHandler');
var $name = 'Products';
function showProducts(){
return 'This should to return in jQuery data';
}
}
?>
In cakePHP 2.x your controller needs to be in this way to return json data to the $.ajax request :
<?php
App::uses('AppController', 'Controller');
App::uses('JsBaseEngineHelper', 'View/Helper');
class AjaxtestsController extends AppController {
function beforeFilter() {
parent::beforeFilter();
}
public function returnsSomthing()
{
$layout = 'ajax'; // you need to have a no html page, only the data.
$this->autoRender = false; // no need to render the page, just plain data.
$data = array();
$jquerycallback = $_POST["callback"];
//do something and then put in $data those things you want to return.
//$data will be transformed to JSON or what you configure on the dataType.
echo JsBaseEngineHelper::object($data,array('prefix' => $jquerycallback.'({"totalResultsCount":'.count($data).',"ajt":','postfix' => '});'));
}
}
Improved Answer
You can use your controller's methods to search data on the db: find(), but I move the search queries to the Model:
First: Add the marked lines at the model code
App::uses('AppModel', 'Model');
App::uses('Sanitize', 'Utility'); // <---
App::uses('JsBaseEngineHelper', 'View/Helper'); // <---
Second: Create a Model method that executes the search:
public function getdata(){
$input = NULL;
$query = array();
$sql = NULL;
$data = array();
$i = 0;
$input = $_GET["name_startsWith"]; // <-- obtains the search parameter
$input = Sanitize::clean($input); // <-- prepares the search parameter
$sql = "select * from atable where condition like '".$input."%';";
$query = $this->query($sql); // <-- the model execute the search
if ($query){
$c = count($query);
for($i=0;$i<$c;$i++){ // <-- iterate over the returned data
$json['id'] = $query[$i][0]['id'];
$json['column1'] = $query[$i][0]['column1'];
$json['column2'] = $query[$i][0]['column2'];
$data[] = $json; // <-- the data it's stored on an multiarray, to be converted to JSON
}
}
$jquerycallback = $_GET["callback"];
echo JsBaseEngineHelper::object($data,array('prefix' => $jquerycallback.'({"totalResultsCount":'.count($query).',"search":','postfix' => '});')); //<-- the data it´s returned as JSON
}
Then: On the controller create a method to call the search
public function getdata()
{
$layout = 'ajax'; //<-- No LAYOUT VERY IMPORTANT!!!!!
$this->autoRender = false; // <-- NO RENDER THIS METHOD HAS NO VIEW VERY IMPORTANT!!!!!
$this->Cliente->getclient(); // <-- Get the data
}
You can call this method via ajax like this:
$.ajax({
url: "/application/controller/getdata",
dataType: "jsonp",
data: {
featureClass: "P",
style: "full",
maxRows: 10,
name_startsWith: request.term
},
success: function( data ) {
response( $.map( data.search, function( item ) {
return {
value: item.id,
label: item.column1+" "+item.column2
}
}));
}
});
Check this for more info:
CakePHP Controller:autorender
CakePHP JsonView
Typo Quotes mismatch
Use double quotes to wrap
url: "<?php echo Router::url(array('controller' => 'products', 'action' => 'showProducts')); ?>",
^ ^
Problem
url: '<?php echo Router::url(array('controller' => 'products',
var ^ str^ var
controller and products are treated as variables not strings

How do I use the PUT feature in REST

Using this git-hub library:
http://github.com/philsturgeon/codeigniter-restserver
How do I use the PUT feature to save its data?
example: example.com/put/some-data/some-data/...
you can use it like this: but take in count that PUT is less commonly used and not supported by most browsers
function somename_put()
{
$data = array('somedata: '. $this->put('some-data'));
$this->response($data);
}
You can do it with an ajax request e.g.
(assumes use of jQuery)
$.ajax({
url: '/index.php/my_controller/somedata',
type: 'PUT',
success: function(result) {
console.log(result);
}
});
According this (link: https://github.com/philsturgeon/codeigniter-restserver/blob/master/application/libraries/REST_Controller.php#L915), $this->put only return if passed a param to it (so that works: $username = $this->put('username')). But in REST_Controller, $this->_put_args is protected so, you will extend this class and can access it like: $params = $this->_put_args.
In short (this is just an example, you may improve it as you need);
<?php
// route: /api/users/123
class Users extends REST_Controller
{
...
// update a user's data
public function user_put() {
$params = $this->_put_args;
// you need sanitize input here, "db" is a pseudo
$username = $db->escape($params['username']);
$userpass = $db->escape($params['userpass']);
$db->update(array(
'username' => $username,
'userpass' => $userpass
), (int) $params['id']);
if (!$db->error) {
// suppose right code should be 201 for PUT
$this->response('Created', 201);
} else {
$this->response('Internal Server Error', 500);
}
}
}
?>
<script>
// Some ajax library
Ajax("/api/users/123", {
method: "PUT",
data: {username:"John", userpass:"new pass"},
onSuccess: function(){ console.log("Success!"); }
...
});
</script>

Categories