so I am working in a social network, and I want once a post is done to be able to edit it, but I am having the error:
message: "This action is unauthorized."
is seems something simple to me, I get the info in the component send it throuhg an axios call that goes through a route I have defined and it just goes to the controller and from there to the service, but I must be missing something which I do not know what it is. Any hint is much appreciated as I am getting a bit mad...
this would be the function in the component:
editPost() {
let formData = new FormData();
let headers = { headers: { "Content-Type": "multipart/form-data" } };
let updatedPost = this.post_to_update;
formData.append("post", updatedPost.description);
formData.append("file", this.file);
formData.append("video_link", updatedPost.video_link);
axios
.post("/posts/update/" + updatedPost.id, formData, headers)
.then(response => {
updatedPost.attach_file = response.data.attach_file;
updatedPost.id = response.data.id;
serverBus.$emit("post_edited", updatedPost);
});
this.file = "";
this.post_to_update = {
id: "",
index: null,
description: "",
attach_file: "",
video_link: "",
name: this.profile_info.name,
surname_1: this.profile_info.surname_1,
surname_2: this.profile_info.surname_2,
nick: this.profile_info.nick,
picture: this.profile_info.picture,
id_rol: this.profile_info.id_rol,
time_ago: "0 minutes",
code: this.profile_info.code
};
$("#EditModal").modal("hide");
},
this is the web.php:
########################################################################################################################
# Post Routes
########################################################################################################################
Route::post('/posts/recommend', 'PostController#recommend')
->name('recommendPost');
Route::post('/posts/update/{id}', 'PostController#update');
Route::post('/posts/report', 'PostController#report')
->name('reportPost');
Route::get('/posts/{post}/comments', 'PostController#retrieveComments')
->where('post', '[0-9]+')
->name('commentsByPost');
Route::resource('/posts', 'PostController')
->only(['index', 'store', 'update', 'destroy']);
Route::get('/reportedPosts', 'PostController#reportedPosts');
The controller:
public function update(StorePostRequest $request, $post_id)
{
return $this->postService->updatePost($request, $post_id);
}
and the service:
public function updatePost(StorePostRequest $request, $post_id)
{
$post_to_update = Post::where('id', $post_id)->first();
$post_to_update->description = $request->post;
$post_to_update->attach_file = $request->file ? $filename = sha1(time()) : null;
$post_to_update->file_name = $request->file ? $request->file->getClientOriginalName() : null;
$post_to_update->file_type = $request->file ? $request->file->getClientOriginalExtension() : null;
$post_to_update->save();
if ($request->file) {
Storage::disk('s3')->putFileAs('storage/user_uploads/post_files/' . $post_to_update->id, $request->file, $filename, 'public');
Storage::disk('local')->putFileAs('public/user_uploads/post_files/' . $post_to_update->id, $request->file, $filename, 'public');
}
return $post_to_update;
}
I think StorePostRequest class cause the block of user authorization.
Try add following lines at StorePostRequest to pass the authorization check.
public function authorize()
{
return true; //Default false;
}
Related
I'm working on a Vue.js/Laravel web application for a company that offers school workshops. I've managed to make it possible to add an image to a workshop when it doesn't yet have one (POST), but when I try to update an existing workshop picture (PUT), $request->file always returns null and I can't seem to figure out why.
Workshops table:
Uploads table:
(workshop_picture contains the id of the corresponding upload in the uploads table)
onFileSelected function in the workshop edit page:
onFileSelected (event) {
this.selectedFile = event.target.files[0]
let formData = new FormData()
formData.append('file', event.target.files[0])
if (this.workshop.workshop_picture) {
console.log('Workshop already has a picture, updating current picture...')
axios.put('/api/upload/' + this.workshop.workshop_picture.id,
formData,
{ headers: { 'Content-Type': 'multipart/form-data' } })
.then(response => {
this.workshop.workshop_picture = response.data.id
this.workshop_picture_preview = '/uploads/' + response.data.internal_name
})
.catch(function () {
alert('Uploaden mislukt!')
})
}
}
UploadController.php:
class UploadController extends Controller
{
public function store(Request $request)
{
$request->validate(['file' => 'mimes:jpeg,png,jpg']);
$internal_name = Str::random(32) . '.' . $request->file->extension();
$upload = new Upload();
$upload->name = $request->file->getClientOriginalName();
$upload->internal_name = $internal_name;
$upload->size = $request->file->getSize();
$upload->save();
$request->file->move(public_path('uploads'), $internal_name);
return response($upload, 200)->header('Content-Type', 'json');
}
public function update(Request $request, $id)
{
$request->validate(['file' => 'mimes:jpeg,png,jpg']);
$internal_name = Str::random(32) . '.' . $request->file->extension();
$upload = Upload::find($id);
$upload->name = $request->file->getClientOriginalName();
$upload->internal_name = $internal_name;
$upload->size = $request->file->getSize();
$upload->save();
$request->file->move(public_path('uploads'), $internal_name);
return response($upload, 200)->header('Content-Type', 'json');
}
}
The form data clearly contains the selected file, so I have absolutely no clue why it says $request->file is null.
I currently have a working controller that extends WP_REST_Controller in a file under the current theme. These are being called using jQuery ajax. (all code below)
The issue I am facing is that I receive this error ONLY when accessing with a mobile device.
{"code": "rest_no_route", "message": "No route was found matching the URL and request method" "data": {"status": 404}}
settings -> permalinks -> save changes
tried using controller namespace "api/v1" and "wp/v2"
javascript
function getAllClients() {
jQuery.ajax({
url: "http://myurl.com/index.php/wp-json/wp/v2/get_all_clients",
type: "GET",
data: { /*data object*/},
success: function (clientList) {
// success stuff here
},
error: function (jqXHR, textStatus, errorThrown) {
alert(jqXHR.statusText);
}
})
}
api/base.php
<?php
class ApiBaseController extends WP_REST_Controller
{
//The namespace and version for the REST SERVER
var $my_namespace = 'wp/v';
var $my_version = '2';
public function register_routes()
{
$namespace = $this->my_namespace . $this->my_version;
register_rest_route(
$namespace,
'/get_all_clients',
array(
array(
'methods' => 'GET',
'callback' => array(new ApiDefaultController('getAllClients'), 'init'),
)
)
);
$ApiBaseController = new ApiBaseController();
$ApiBaseController->hook_rest_server();
api/func.php
<?php
class ApiDefaultController extends ApiBaseController
{
public $method;
public $response;
public function __construct($method)
{
$this->method = $method;
$this->response = array(
// 'Status' => false,
// 'StatusCode' => 0,
// 'StatusMessage' => 'Default'
// );
}
private $status_codes = array(
'success' => true,
'failure' => 0,
'missing_param' => 150,
);
public function init(WP_REST_Request $request)
{
try {
if (!method_exists($this, $this->method)) {
throw new Exception('No method exists', 500);
}
$data = $this->{$this->method}($request);
$this->response['Status'] = $this->status_codes['success'];
$this->response['StatusMessage'] = 'success';
$this->response['Data'] = $data;
} catch (Exception $e) {
$this->response['Status'] = false;
$this->response['StatusCode'] = $e->getCode();
$this->response['StatusMessage'] = $e->getMessage();
}
return $this->response['Data'];
}
public function getAllClients()
{
// db calls here
return json_encode($stringArr,true);
}
}
These are registered in the Functions.php file
require get_parent_theme_file_path('api/base.php');
require get_parent_theme_file_path('api/func.php');
Turns out the issue was a plugin my client installed called "oBox mobile framework" that was doing some weird routing behind the scenes. Disabling it resolved the issue, though there is probably a way to hack around this and get both to play together.
I am using symfony 3.4 and I would like to send some data to controller but I do not know why I can not access it like it is show in symfony documentation:
This is my js function:
function sendQuantitiesToController() {
// Validate data
var validation = validateQuestionnaireReviewFormData();
if (validation === false) {
return false;
}
// Get form data
var data = getReviewFormComponentsData();
var id = document.getElementById('questionnaire-id').innerText;
// Send data
$.post("http://localhost:8000/questionnaire/"+id+"/review", {
components: data.components,
optional_components: data.optional_components
},
function(response, status) {
if (status == 'success') {
return true;
} else {
return false;
}
});
}
And this is my Controller function:
/**
* Questionnaire result review
*
* #Route("/questionnaire/{id}/review", name="_questionnaire_review", requirements={"id" = "\d+"})
* #Template()
*/
public function questionnaireReviewAction(Request $request, $id)
{
$form = $this->createForm(ResultOverviewType::class, $result);
$contactForm = $this->createForm(ContactType::class, $contact);
if ($request->isMethod('POST')) {
// Get data from request
$components = $request->request->get('components');
$optionalComponents = $request->request->get('optional_components');
...
}
}
return [
'form' => $form->createView(),
'contactForm' => $contactForm->createView(),
'questionnaire' => $questionnaire
];
}
Twig Template:
{{ form_start(contactForm, {'attr': {'onsubmit': 'return sendQuantitiesToController();'}}) }}
{{ form_widget(form) }}
{{ form_widget(contactForm) }}
{{ form_end(form) }}
The problem is that the $request->request->get('components') in controller is always null, but I checked getReviewFormComponentsData() with console.log and there is data there so the problem is probably with ajax post request. What I am doing wrong? Can anyone help me?
Thanks for help!
To get request data from ajax request in Symfony Controller you should simply do that:
public function questionnaireReviewAction(Request $request, $id)
{
$form = $this->createForm(ResultOverviewType::class, $result);
$contactForm = $this->createForm(ContactType::class, $contact);
if ($request->isMethod('POST')) {
// Get data from request
$data = $request->getContent();
$data = json_decode($data, true);
$components = $data['components'];
$optionalComponents = $data['optional_components'];
...
}
...
}
I want to send post request with ajax to controller in laravel. The ajax request send two input arguments and I want controller to find the column in the database with the first argument and then to set the name attribute with the second input argument. But I have this error message Creating default object from empty value
Ajax function:
$('#saveUserProfile').on('click', function () {
var $finduser = $('input[name=findUser]').val();
var $name = $('input[name=userprofilename]').val();
$.ajax({
type:"POST",
url:'/code/task1/public/updateUser',
data: {
'name' : $name,
'finduser' : $finduser,
// 'email' : $email,
},
success:function(data){
$("#input1").val(data[0].name);
}
});
});
and the function in my controller
public function updateUser(Request $request){
$return_array = array();
$findUserInput = $request->get('finduser');
$user = User::where('name',$findUserInput) -> first();
$user->name = $request->get('name');
$user->save();
$data = DB::select("SELECT * FROM users where name='$findUserInput'");
if(count($data) > 0){
foreach($data as $da){
$return_array[] = $da;
}
}
return $return_array;
}
Update: I also make ajax function and controller for finding user which is working good.
ajax function:
$('#buttonFindUser').on('click', function () {
var $name = $('input[name=findUser]').val();
$.ajax({
type:"GET",
url:'/code/task1/public/findUser',
data: {
'name' : $name,
},
success:function(data){
$("#input1").val(data[0].name);
$("#input2").val(data[0].email);
$("#input3").val(data[0].created_at);
}
});
});
Function in my controller:
public function findUser(Request $request){
$return_array = array();
$findUserInput = $request->get('name');
$data = DB::select("SELECT * FROM users where name='$findUserInput'");
if(count($data) > 0){
foreach($data as $da){
$return_array[] = $da;
}
}
return $return_array;
}
Any ideas?
But I have this error message Creating default object from empty value
What's happening is that you are trying to save a user that doesn't exist. You need to check if the $user is null or not in your controller. Right now, the user couldn't be found with the provided name so $user becomes null.
So, you can modify your code to do a null check on $user like so:
public function updateUser(Request $request){
$return_array = array();
$findUserInput = $request->get('finduser');
$user = User::where('name',$findUserInput) -> first();
if(!$user)
return response()->json(['status'=>false,'Description' => 'User could not be found.']);
$user->name = $request->get('name');
$user->save();
$data = DB::select("SELECT * FROM users where name='$findUserInput'");
if(count($data) > 0){
foreach($data as $da){
$return_array[] = $da;
}
}
return $return_array;
}
Here's the null check:
if(!$user)
return response()->json(['status'=>false,'Description' => 'User could not be found.']);
When we don't have a valid user, we just reply back with a json response stating that it couldn't be found.
Update:
Seeing as your input is not being retrieved in the controller, you need to make some changes in JS:
First, you are doing a post request and I cannot see a CSRF token. To add it, follow this answer: https://stackoverflow.com/a/37582060/6270112
So, your data will now become:
data: '_token=' + $('#token').val() + '&name=' + $name + '&finduser=' + $finduser
Also, as aleksejjj mentioned, you need to fix your jquery selectors as well. So, your existing selectors:
var $finduser = $('input[name=findUser]').val();
var $name = $('input[name=userprofilename]').val();
will become:
var $finduser = $('input[name^="findUser"]').val();
var $name = $('input[name^="userprofilename"]').val();
Next, in your controller you need to replace $request->get(...) with $request->input(...).
$findUserInput = $request->get('finduser');
will become
$findUserInput = $request->input('finduser');
and repeat the same with the name field as well.
You need to check your user exist
$user = User::where('name', $findUserInput)->first();
if($user)
{
$user->name = $request->get('name');
$user->save();
}
change this code
$user = User::where('name',$findUserInput) -> first();
to
$user = User::where('name','=',$findUserInput) -> first();
I hope this will work. :)
I defined a custom function to a resource controller like this :
public function publish (Request $request, $post_id = NULL)
{
if (!is_null($post_id)) {
$result = $this->update($request, $post_id);
} else {
$result = $this->store($request);
}
if ($result['success']) {
return ['success' => true, 'msg' => $result['msg']];
} else {
return ['success' => false, 'msg' => $result['msg']];
}
}
And in a blade template I want to link to it like so:
$('#publishBtn').click(function () {
$.post('{{action('CourseController#publish')}}', $('#createCourseForm').serialize() + '&post_status=published', function (data) {
data.success ? location.href = '/admin/course' : showMsg(data.msg, 'danger');
});
});
but after opening page error below is shown while really that method exists :
Action App\Http\Controllers\CourseController#publish not defined.
(View: D:\wamp\www\lms\resources\views\admin\pages\course\course-create.blade.php)
Just before CourseController Resource route add a route for publish method
Route::post('publish', [
'uses' => 'CourseController#publish',
'as' => 'publish'
]);
....
Route::resource('course', 'CourseController');
Then in your template
$('#publishBtn').click(function () {
$.post('{{route('publish')}}', $('#createCourseForm').serialize() + '&post_status=published', function (data) {
data.success ? location.href = '/admin/course' : showMsg(data.msg, 'danger');
});
});
You need to create a route for that as well.