cakephp2 can't get file data array through $this->request->data - ajax

usually, we get all the data we need from $this->request->data. but if I'm using ajax file upload, I can't get that data e.g: tmp_name, size, etc.
my javascript code is like:
function uploadFile(file_blob_chunk, file_name, file_part, total_file_chunk, file_id) {
fd = new FormData();
fd.append("file_for_upload", file_blob_chunk);
fd.append("somestring", "This is some extra data");
xhr = new XMLHttpRequest();
xhr.open("POST", "files/index/" + file_id + '/' + file_part, true);
//Onload happened after file finished uploaded
xhr.onload = function(e) {
//alert(file_name + "done");
};
xhr.upload.addEventListener("progress", function(evt) {
if (evt.lengthComputable) {
}}, false);
xhr.send(fd);
}
and in FilesController.php
public function index($file_id = null, $file_part = null) {
if ($this->request->is('post')) {
//I can't use $this->request->data, to get the file details
}
}
If I use
debug($this->request->data);
I will only get
array(
'somestring' => 'This is some extra data'
)
I can't get the file data
Unless Im using debug($_FILES), I won't get
array(
'file_for_upload' => array(
'name' => 'blob',
'type' => 'application/octet-stream',
'tmp_name' => 'C:\xampp\tmp\phpAC42.tmp',
'error' => (int) 0,
'size' => (int) 9304862
)
)

If you want to use $this->request->data your post data should be in the format cake expects, eg: data[Model][some_field]
you have CustomField

Related

how can I customize json responses of laravel api and show them in vuex

Trying different solutions, I am fooling around with
response()->json([ ])
To create responses that I can read in my vue / vuex application
The Laravel api function that stores a new Speler ( dutch for player ;)):
I have trouble sending the created, or found Speler-object, through the response to the vuex-store.
Tried to set the status to 202 when succesfully logged, yet the actual status sent is 200..
It is clear that I do not understand it well enough. Can anyone help and explain?
public function store(Request $request)
{
if (Game::where('id',$request['game_id'])->exists() ){
if (!Speler::where('name',$request['name'])->where('game_id',$request['game_id'])->exists()){
$newSpeler = Speler::create(
[
'name' => $request['name'],
'pass_code' => $request['pass_code'],
'game_id' => $request['game_id']
])->first());
return $newSpeler;
}
elseif ( Speler::where('name',$request['name'])->where('game_id',$request['game_id'])->where('pass_code', $request['pass_code'])->exists()){
$speler = Speler::where('name',$request['name'])->where('game_id',$request['game_id'])->where('pass_code', $request['pass_code']);
return response()->json(['speler'=> $speler, 202]);
}
return response()->json(['status' => 'This name is already used, pass-code is not correct', 409]);
}
return response()->json([ 'status' => 'The game-pin does not exist', 403 ]);
}
This is called form the vuex actions:
export const addSpeler = ({commit}, formData) => {
return new Promise((resolve, reject) => {
fetch(`api/speler`, {
method: 'post',
body:formData,
})
.then(res => {
if (res.status === 202){
resolve('De speler is succesfully logged on');
commit('SET_CURRENT_SPELER', res.data.speler);
}
else if (res.status === 201){
commit('SET_CURRENT_SPELER', res.data);
resolve('De speler is succesfully added')
}
else {
reject('De speler is not logged in. Name exists and does not match passcode');
}
})
.catch(err => {
reject(err.message)
});
})
}
and this is called from a vue method:
methods: {
addSpeler(){
this.errorMessage ='';
this.spelerAdded =false;
const formData = new FormData();
formData.append('name', this.name);
formData.append('pass_code',this.pass_code);
formData.append('game_id', this.currentGame.id);
this.$store.dispatch('addSpeler', formData )
.then(res => {
this.spelerAdded = true;
console.log(res.status);
})
.catch(err => {
this.errorMessage = err;
this.spelerAdded = false;
});
},
mutations.js:
export const SET_CURRENT_SPELER = (state, speler) => {
state.currentSpeler = speler;
}
state.js:
export default{
currentGame:{},
currentSpeler:{}
}
The comment by porloscerros answered the question perfectly :
the status goes as the second argument of the json method return response()->json(['speler'=> $speler], 202); (and not inside the array as you are doing). If you don't pass a second argument, the argument value is assigned to 200 by default json(mixed $data = [], int $status = 200, array $headers = [], int $options = 0)

Laravel send image from vue to controller

I'm trying to save an image when updating an item but I'm having trouble sending the file to the controller in order to save it. This is how I'm sending it
submit(item) {
this.$refs.ruleForm.validate((valid) => {
if (valid) {
this.loading = true;
this.$inertia.post('/courses/' + item.id, {
name: this.ruleForm.name,
summary: this.ruleForm.summary,
description: this.ruleForm.description,
price: this.ruleForm.price,
hours: this.ruleForm.hours,
min_grade: this.ruleForm.min_grade,
file: this.imagen,
matery: this.matery,
remover: this.remover,
strict: this.strict
}).then(
() => {
this.$message({
type: 'success',
message: 'Guardado correctamente.'
});
this.loading = false
},
(res) => {
this.$message.error(parseError(res)[0]);
this.loading = false;
})
} else {
return false;
}
});
},
If I {{imagen}} and {{imageUrl}} in the vue this is the result respectively, this is why I'm sending the imagen and not the url
[object File]
blob:http://dev.inae.com/9c77fa72-b778-45c9-8ab2-0a9084282415
When I Log::info($request) this is the output, when adding a file and changing text and saving,
local.INFO: array (
'name' => 'Principiante Clase 3 (automático)',
'summary' => 'Enseñaremos a compresionar el vehículo y la utilización de
cambios en vehículo automático',
'description' => '<p>Enseñaremos a compresionar el vehículo y la utilización de
cambios en vehículo automático (viaje a fraijanes).</p>',
'price' => 52000,
'hours' => 2,
'min_grade' => 70,
'file' =>
array (
'uid' => 1576507762527,
),
'matery' => NULL,
'remover' => false,
'strict' => false,
)
However if I only add the image and don't change anything else, nothing happens in the Log
Code for updating the image in the controller, in the update function
//Log is here
$editCourse = Course::find($id);
$destino = "img/courses";
$link = public_path();
if ($request->hasFile('file')) {
if (!empty($editCourse->image) && file_exists($link . $editCourse->image)) {
unlink($link . $editCourse->image);
}
$image = $request->file('file');
$imageName = Uuid::generate(4)->string . '.' . $image->getClientOriginalExtension();
$editCourse->image = '/' . $destino . '/' . $imageName;
$request->file('file')->move($destino, $imageName);
}
What could I be doing wrong?
You likely need to use the FormData object like so:
let data = new FormData();
data.append('file', this.imagen);
// Attach the other properties.
data.append(...);
$inertia.post(data);
This is because you shouldnt upload files using x-www-form-urlencoded, instead you should be using multipart/form-data which allows you to upload binary data. This also means that the backend will not receive a JSON string anymore, but a form-data response. Laravel should handle this automatically though.

How fix Facebook login error in codeigniter

Facebook SDK returned an error:
Cross-site request forgery validation failed. The "state" param from the URL and session do not match.
I use fblogin() and fbcallback() in same controller. But face this error. Also do all steps in developer.facebook.com. Session is also started. But error says, do not match.
public function fblogin(){
$this->load->library('session');
$this->load->view('../libraries/facebook-php-sdk/src/Facebook/autoload.php');
$fb = new Facebook\Facebook([
'app_id' => 'APP_ID', // Replace {app-id} with your app id
'app_secret' => '{APP_SECRET}',
'default_graph_version' => 'v2.5',//v2.5
]);
$helper = $fb->getRedirectLoginHelper();
// if (isset($_GET['state'])) {
// $helper->getPersistentDataHandler()->set('state', $_GET['state']);
// }
// $sURL = $helper->getLoginUrl(FACEBOOK_AUTH_CALLBACK, FACEBOOK_PERMISSIONS);
$permissions = ['email']; // Optional permissions
$loginUrl = $helper->getLoginUrl('https://www.collegeprintsusa.com/maintenance/signin/fbcallback', $permissions);
// echo 'Log in with Facebook!';
header("location: ".$loginUrl);
}
public function fbcallback() {
$this->load->view('../libraries/facebook-php-sdk/src/Facebook/autoload.php');
$fb = new Facebook\Facebook([
'app_id' => 'APP_ID',
'app_secret' => 'APP_SECRET',
'default_graph_version' => 'v2.5',//v2.5
]);
// $serializedFacebookApp = serialize($fb);
// $unserializedFacebookApp = unserialize($serializedFacebookApp);
// echo $unserializedFacebookApp->getAccessToken();
$helper = $fb->getRedirectLoginHelper(); //'https://www.collegeprintsusa.com/maintenance/signin/fblogin'
// $_SESSION['FBRLH_state'] = $_REQUEST['state'];
$permissions = ['email']; // optional
try {
if (isset($_SESSION['facebook_access_token'])) {
$accessToken = $_SESSION['facebook_access_token'];
} else {
$fbClient = $fb->getClient();
$accessToken = $helper->getAccessToken($fbClient);
}
} catch(Facebook\Exceptions\facebookResponseException $e) {
// When Graph returns an error
echo 'Graph returned an error: ' . $e->getMessage();
exit;
} catch(Facebook\Exceptions\FacebookSDKException $e) {
// When validation fails or other local issues
echo 'Facebook SDK returned an error: ' . $e->getMessage();
exit;
}
if (isset($accessToken)) {
if (isset($_SESSION['facebook_access_token'])) {
$fb->setDefaultAccessToken($_SESSION['facebook_access_token']);
} else {
// getting short-lived access token
$_SESSION['facebook_access_token'] = (string) $accessToken;
// OAuth 2.0 client handler
$oAuth2Client = $fb->getOAuth2Client();
// Exchanges a short-lived access token for a long-lived one
$longLivedAccessToken = $oAuth2Client->getLongLivedAccessToken($_SESSION['facebook_access_token']);
$_SESSION['facebook_access_token'] = (string) $longLivedAccessToken;
// setting default access token to be used in script
$fb->setDefaultAccessToken($_SESSION['facebook_access_token']);
}
// redirect the user to the profile page if it has "code" GET variable
if (isset($_GET['code'])) {
header('Location: collegeprintsusa.com');
}
// getting basic info about user
try {
$profile_request = $fb->get('/me?fields=name,first_name,last_name,email', $accessToken);
$requestPicture = $fb->get('/me/picture?redirect=false&height=200'); //getting user picture
$picture = $requestPicture->getGraphUser();
$profile = $profile_request->getGraphUser();
$fbid = $profile->getProperty('id'); // To Get Facebook ID
$fbfullname = $profile->getProperty('name'); // To Get Facebook full name
$fbemail = $profile->getProperty('email'); // To Get Facebook email
$fbpic = "<img src='".$picture['url']."' class='img-rounded'/>";
// echo $fbid.','.$fbfullname; die();
# save the user nformation in session variable
$get_user_email = $this->user_model->get_single_user(['email' => $fbemail]);
if($get_user_email){
$res_user_fbid_update = $this->user_model->update_users(['id' => $get_user_email['id']],['facebook_id' => $fbid]);
if($res_user_fbid_update){
$this->session->set_userdata(['username' => $get_user_email['usename'],
'name' => $get_user_email['name'],
'last' => $get_user_email['last_name'],
'email' => $get_user_email['email'],
'type' => $get_user_email['user_type'],
'uid' => $get_user_email['id'],
'phone' => $get_user_email['phone'],
'address' => $get_user_email['address'],
'profile_image' => $get_user_email['profile_image'],
'disable' => $get_user_email['sms_update']]);
$this->output->set_output(json_encode(['result' => 1]));
return FALSE;
}else{
$this->output->set_output(json_encode(['result' => 2]));
return FALSE;
}
}else{
$res_user_reg = $this->user_model->add_users([
'name' => $fbfullname,
'email' => $fbemail,
'phone' => 0,
'user_type' => 'customer',
'username' => $fbemail,
'password' => SALT . sha1($fbemail),
'token' => SALT . sha1($fbemail),
'facebook_id' => $fbid
]);
if($res_user_reg){
$this->output->set_output(json_encode(['result' => 1]));
return FALSE;
}else{
$this->output->set_output(json_encode(['result' => 2]));
return FALSE;
}
}
} catch(Facebook\Exceptions\FacebookResponseException $e) {
// When Graph returns an error
echo 'Graph returned an error: ' . $e->getMessage();
session_destroy();
// redirecting user back to app login page
header("Location: index.php");
exit;
} catch(Facebook\Exceptions\FacebookSDKException $e) {
// When validation fails or other local issues
echo 'Facebook SDK returned an error: ' . $e->getMessage();
exit;
}
} else {
// replace your website URL same as added in the developers.Facebook.com/apps e.g. if you used http instead of https and you used
$loginUrl = $helper->getLoginUrl('http://phpstack-21306-56790-161818.cloudwaysapps.com', $permissions);
echo 'Log in with Facebook!';
}
}
Here I would like to suggest a better solution to log in with Facebook. Please use JavaScript instead of PHP, because PHP will redirect on facebook page & JavaScript will not redirect, It will open facebook login popup on own website, and it`s very quick & easy process according to performance.
Please follow below code to login with facebook using JavaScript.
$(document).ready(function($) {
window.fbAsyncInit = function() {
FB.init({
appId : '186770818730407', // Set YOUR APP ID
status : true, // check login status
cookie : true, // enable cookies to allow the server to access the session
xfbml : true // parse XFBML
});
};
function fbLogin()
{
FB.login(function(response) {
if (response.authResponse) {
getFBUserInfo();
}else {
showToaster('error','User cancelled login or did not fully authorize.');
return false;
}
},{scope: 'email,user_photos,user_videos'});
}
function getFBUserInfo() {
FB.api('/me',{fields: "id,picture,email,first_name,gender,middle_name,name"}, function(response) {
$.ajax({
url : "http://example.com/welcome/facebook_login",
type : "POST",
data : {response:response},
dataType : "JSON",
beforeSend:function(){
ajaxindicatorstart();
},
success: function(resp){
ajaxindicatorstop();
if(resp.type == "success"){
fbLogout();
showToaster('success',resp.msg);
setTimeout(function(){
window.location.href = base_url() + 'account-setting';
},1000);
}
else{
showToaster('error',resp.msg);
}
},
error:function(error)
{
ajaxindicatorstop();
}
});
});
}
function fbLogout()
{
FB.logout(function(){ console.log('facebook logout') });
}
// Load the SDK asynchronously
(function(d){
var js, id = 'facebook-jssdk', ref = d.getElementsByTagName('script')[0];
if (d.getElementById(id)) {return;}
js = d.createElement('script'); js.id = id; js.async = true;
js.src = "//connect.facebook.net/en_US/all.js";
ref.parentNode.insertBefore(js, ref);
}(document));
});
Hope You will like it.
Thanks

Need JSON to pass values to AJAX from specific content type fields

Im new to PHP.
I'd like to build a module and i need json to pass specific content type fields.
Im trying with this but i dont know how to deal with callback function.
here is my ajax in .js
$.ajax({
type: 'GET',
url: '/mappy/ajax/poi',
data: {
nid: nid
},
dataType: 'json',
success: function(data){
alert(data)
}
});
})
here is my php in .module
function mappy_menu() {
$items = array();
$items['/mappy/ajax/poi'] = array(
'title' => 'Mappy Pois',
'page callback' => 'mappy_get',
'access arguments' => array('access content'),
'type' => MENU_CALLBACK,
);
return $items;
}
function mpapy_get() {
$nid = $_GET('nid');
$title = field_get_items('node', $node, 'field_title');
$result = json_encode(
db_query("SELECT nid,title FROM {node}", $nid)
);
drupal_json_output($result);
print $result;
}
Many thanks for advice.
Once you get the JSON response you need to convert it to a javascript array. For that, you can do:
var javaArray = $.parseJSON(data);
Now you can retrieve the data, using code like javaArray['key1']['key2'], etc.
.js
$.ajax({
type: 'GET',
// Do not use slash at the beginning, use Drupal.settings.basePath instead
url: Drupal.settings.basePath + 'mappy/ajax/poi',
data: {
nid: nid
},
dataType: 'json',
success: function(data) {
alert(data)
}
});
.module
function mappy_menu() {
$items = array();
// Never use slash at the beginning in hook_menu
$items['mappy/ajax/poi'] = array(
'title' => 'Mappy Pois',
'page callback' => 'mappy_get',
'access arguments' => array('access content'),
'type' => MENU_CALLBACK,
);
return $items;
}
function mappy_get() {
$node = node_load($_GET('nid'));
// Or equivalent
/* $node = db_select('node', 'n')
->fields('n', array('nid', 'title'))
->condition('n.nid', $_GET('nid')))
->execute()
->fetchAll(); */
$values = array(
'nid' => $node->nid,
'title' => $node->title
);
#$result = json_encode(
# db_query("SELECT nid,title FROM {node}", $nid)
#);
// drupal_json_output already print the value
// print $result;
drupal_json_output($values);
drupal_exit();
}

Drupal.attachBehaviors not effect to returned ajax form

I'm working on Drupal 7, I have a form constructed like this
function qt_debate_response_form($form, &$form_state, $node_id){
$form['node_id'] = array(
'#type' => 'value',
'#value' => $node_id,
);
$form['response_body'] = array(
'#type' => 'textarea',
'#required' => TRUE,
'#row' => 4,
'#default_value' => '',
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Post'),
'#ajax' => array(
'callback' => 'qt_debate_response_form_js',
'wrapper' => 'response-message-' . $node_id,
'method' => 'append',
'effect' => 'fade',
),
);
return $form;
}
And an ajax callback function to add new comment
function qt_debate_response_form_js($form, $form_state) {
global $user;
$body_text = $form_state['values']['response_body'];
$node_id = $form_state['values']['node_id'];
$message_js = '
<script language="javascript" type="text/javascript">
qt_debate_response_load_new_item(' . $node_id . ',' . $user->uid . ');
jQuery(".response-form-wrapper textarea").val("");
</script>';
$comment = new stdClass();
$comment->nid = $form_state['values']['node_id']; // Node Id the comment will attached to
$comment->cid = 0;
$comment->pid = 0;
$comment->uid = $user->uid;
$comment->is_anonymous = 0;
$comment->homepage = '';
$comment->status = COMMENT_PUBLISHED;
$comment->language = LANGUAGE_NONE;
$comment->subject = text_summary($body_text, null, 60);
$comment->comment_body[$comment->language][0]['value'] = $body_text;
$comment->comment_body[$comment->language][0]['format'] = 'filtered_html';
comment_submit($comment);
comment_save($comment);
$output = $message_js;
return $output;
}
here are my Javascript that load new created comment into Div (ajax)
function qt_debate_user_post_load_new_items(debate_id) {
// get the latest comment id in context
$top_comment = jQuery(".view-debate-user-posts .views-row").first();
$top_comment_id = jQuery(".nid-field-hidden", $top_comment).html();
jQuery.ajax({
type: "GET",
url: "/qt_debate/ajax/load_new_items/" + debate_id + "/" + $top_comment_id,
data: "",
success: function(html){
$new_items = jQuery(".view-content", html);
jQuery("form", $new_items).attr("action","/debate/199");
jQuery(".form-submit", $new_items).attr("id","edit-submit--5");
if ($new_items.html() != null) {
html = '<div class="new_items_wrapper" style="display: none">' + $new_items.html() + '</div>';
if (jQuery(".view-debate-user-posts .view-content").length == 0) {
jQuery(".view-debate-user-posts .view-empty").remove();
jQuery(".view-debate-user-posts").append('<div class="view-content"></div>');
}
jQuery(".view-debate-user-posts .view-content").prepend(html);
jQuery(".view-debate-user-posts .view-content .new_items_wrapper").fadeIn(500, function() {
jQuery(".views-row", this).unwrap();
Drupal.attachBehaviors();
});
}
},
});
var t = setTimeout("qt_debate_user_post_load_new_items(" + debate_id + ")", 30000)
}
The hook_menu which is return the views content to jQuery call back
function qt_debate_ajax_load_new_items() {
$debate_id = arg(3);
print views_embed_view('debate_user_posts_load_new_items_', 'default', array($debate_id));
exit(0);
}
View template file, i also return a new form inside
print drupal_render(drupal_get_form('qt_debate_response_form', $row->nid));
The return view content rendered good, with Drupal.attachBehaviors in Javascript, all others effect in returned view content also work well. Except the form submit ajax.
Can any one help please ? The attachBehaviors not work with return ajax form.
Thanks so much!
Drupal.attachBehaviors(context);
basically re-runs any functions defined by
Drupal.behaviors.yourFunctionName = function(context) {
$('div.someSelectorclass:not(.already-processed-class)', context).addClass('already-processed-class').bind(someMethod);
}
and these methods must add a selector [already-processed-class] to test for whether the bind(); [ or click(function(e){}); or each(function(){}); or whatever ] has already been added. The "context" is to pass less-than 'document' - say, if your new content is known to be inside a smaller context that will still be found by original behaviors function: in this example I could pass the parent container selector of my new 'div.someSelectorclass'
Drupal.attachBehaviors('div.parentContainerClass');
instead of
Drupal.attachBehaviors(document);

Resources