Response URL has a backslash in Laravel 8 - file-upload

I have this code that returns the array of images with the link, but the problem is it has a backslash in my URL return.
public function getImagesAttribute(): array
{
return [
'thumbnail' => $this->getImagePath('thumbnail'),
'large' => $this->getImagePath('large'),
'original' => $this->getImagePath('original'),
];
}
protected function getImagePath($size): string
{
return Storage::disk('public')->url("uploads/user-account/${size}/" .
$this->file_name);
}
Here's the result:

Related

laravel 8 session doesn't save data

I'm trying to save an array for checkout but when i print session it gives null
namespace App\Http\Livewire;
use App\Orders;
use Livewire\Component;
use Illuminate\Support\Facades\Auth;
use Illuminate\Http\Request;
use Cart;
use Carbon\Carbon;
public function setAmountForCheckout()
{
if(session()->has('coupon'))
{
session()->put('checkout',[
'discount'=>$this->discount,
'subtotal'=>$this->subtotalAfterDiscount,
'total'=>$this->totalAfterDiscount,
]);
}
else
{
session()->put('checkout',[
'discount'=>0,
'tax'=>Cart::instance('cart')->tax(),
'subtotal'=>Cart::instance('cart')->subtotal(),
'total'=>Cart::instance('cart')->total(),
]);
session()->save();
}
}
public function placeOrder(Request $request)
{
dd(session()->get('checkout'));
$this->validate([
'first_name' => 'required|min:4|string',
'Phone_number' => 'required|digits:11'
]);
$order=new Orders();
$order->user_id=Auth::id();
$order->cust_name=$this->first_name;
$order->phone=$this->Phone_number;
$order->subtotal=session()->get('checkout')['subtotal'];
$order->discount=session()->get('checkout')['discount'];
$order->total=session()->get('checkout')['total'];
$order->status='ordered';
$order->is_shipping=$this->haveShipping ? 1:0;
foreach(Cart::instance('cart')->content() as $items)
{
$orderItem= new OrderItems();
$orderItem->product_id=$items->id;
$orderItem->price=$item->price;
$orderItem->order_id=$order->id;
$orderItem->quantity=$item->qty;
$orderItem->save();
}
if($this->haveShipping)
{
$this->validate([
'Address'=>'required|min:4',
'shipping_fee'=>'required|numeric'
]);
$order->address=$this->Address;
$order->delivery=$this->shipping_fee;
}
$order->save();
Cart::instance('cart')->destroy();
session()->forget('checkout');
}
when i remove dd it gives me the error "Trying to access array offset on value of type null"
I'm trying to find what's wrong with the session.
also i have checked the cart if it works or not but i found that it works well and delivers data.
Remove
session()->save();
This is not needed as per https://laravel.com/docs/8.x/session#storing-data

how can i Cache object and its relations in laravel 6

In RatingController:
<?php
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use App\Http\Resources\RatingResource;
use App\Models\Rating\Rating;
class RatingController extends Controller
{
public function getRatingsByCategory($id)
{
$ratings = cache()->rememberForever('test', function () use ($id) {
return new RatingResource(Rating::findOrFail($id));
});
return response()->json([
'data' => $ratings
]);
}
}
in RatingResource class
<?php
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\JsonResource;
use Illuminate\Http\Resources\Json\ResourceCollection;
class RatingResource extends JsonResource
{
/**
* Transform the resource collection into an array.
*
* #param \Illuminate\Http\Request $request
* #return array
*/
public function toArray($request)
{
return [
'id' => $this->rating_id,
'is_active' => $this->is_active,
'created_at' => '2020',
];
}
}
when i send request to this controller, i get this result
{
"data": {
"id": 3,
"is_active": 1,
"created_at": "2020"
}
}
but when i change each of column in RatingResource like created_at, the result changes.
indeed laravel does not cache final result, it cache the object of my request and when i return that object,it start to convert my object to resource format.
how can i cache the result of ApiResource till i delete this cache key.
You could cache the whole response, this way you would have to add the id to the cache key though, in order to differentiate between the different rating ids.
Something like this:
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use App\Http\Resources\RatingResource;
use App\Models\Rating\Rating;
use Illuminate\Support\Facades\Cache;
class RatingController extends Controller
{
public function getRatingsByCategory($id)
{
return Cache::rememberForever("test:{$id}", function () use ($id) {
return RatingResource(Rating::findOrFail($id));
});
}
}

Amazon S3 PHP SDK, Transfer folder, but skip specific files?

I am using the Amazon PHP SDK to upload a folder on my server to a bucket. This is working great:
$skip = ['index.html', '_metadata.txt', '_s3log.txt'];
$meta = [
'key' => $options->EWRbackup_s3_key,
'region' => $options->EWRbackup_s3_region,
'bucket' => $options->EWRbackup_s3_bucket,
'directory' => 's3://'.$options->EWRbackup_s3_bucket.'/'.$subdir,
];
$client = new S3Client([
'version' => 'latest',
'region' => $meta['region'],
'credentials' => [
'key' => $meta['key'],
'secret' => $options->EWRbackup_s3_secret,
]
]);
$s3log = fopen($subpath.'/_s3log.txt', 'w+');
fwrite($s3log, "-- Connecting to ".$meta['region'].":".$meta['bucket']."...\n");
$manager = new Transfer($client, $subpath, $meta['directory'], [
'before' => function ($command)
{
$filename = basename($command->get('SourceFile'));
fwrite($this->s3log, "-- Sending file $filename...\n");
},
]);
$manager->transfer();
fwrite($s3log, "-- Disconnecting from ".$meta['key'].":".$meta['bucket']."...");
fclose($s3log);
However, in the folder I am uploading using the Transfer method, there are 3 files I want to skip. They are defined in the $skip variable on line one. I was wondering if there was a way I could get the Transfer to skip these 3 files...
I modified the AWS client in a WordPress plugin I created. The AWS/S3/Transfer.php file is where the uploads are managed, in this case. I modified the private function upload($filename) to look for a boolean return value from the before function:
private function upload($filename)
{
$args = $this->s3Args;
$args['SourceFile'] = $filename;
$args['Key'] = $this->createS3Key($filename);
$command = $this->client->getCommand('PutObject', $args);
if ($this->before) {
if (false!==call_user_func($this->before, $command)) {
return $this->client->executeAsync($command);
}
} else {
return $this->client->executeAsync($command);
}
}
This replaces the original lines:
$this->before and call_user_func($this->before, $command);
return $this->client->executeAsync($command);
with
if ($this->before) {
if (false!==call_user_func($this->before, $command)) {
return $this->client->executeAsync($command);
}
} else {
return $this->client->executeAsync($command);
}
Then, in your declared before function, you can return false if you do not want this particular file uploaded.
I was able to do this because I can control when the AWS PHP SDK is updated and can therefore modify the code it contains. I have not found any hooks in the PHP SDK to do this in a better way.

Laravel API give json response when got error This action is unauthorized

I newbie in Laravel API. There is an update function which only allows users to update their own post. It worked. When users try to update other user's post, it alswo worked, but it shows the error like this image. Actually i want it show in response json.
I want to show message like this
{
"status": "error",
"message": "This action is unauthorized",
}
This is my code for PostController.
public function update(Request $request, Post $post)
{
$this->authorize('update', $post);
//this will check the authorization of user but how to make if else statement, if the post belong to the user it will show this json below but if the post belong to other, it will show error message(response json)
$post->content = $request->get('content', $post->content);
$post->save();
return fractal()
->item($post)
->transformWith(new PostTransformer)
->toArray();
}
This code for PostPolicy
public function update(User $user, Post $post)
{
return $user->ownsPost($post);
}
This is code for User model
public function ownsPost(Post $post)
{
return Auth::user()->id === $post->user->id;
}
This code for AuthServiceProvider
protected $policies = [
'App\Post' => 'App\Policies\PostPolicy',
];
Hope anyone can help me.
I'm using Laravel 5.4
In the app/Exceptions/Handler.php class you can change the render function like so
public function render($request, Exception $exception)
{
$preparedException = $this->prepareException($exception);
if ($preparedException instanceof HttpException) {
return response(
[
'message' => sprintf(
'%d %s',
$preparedException->getStatusCode(),
Response::$statusTexts[$preparedException->getStatusCode()]
),
'status' => $preparedException->getStatusCode()
],
$preparedException->getStatusCode(),
$preparedException->getHeaders()
);
}
return parent::render($request, $exception);
}
Or if you look further in the rendering, overriding the renderHttpException might be a little safer. This will remove the custom error pages in views/errors
protected function renderHttpException(HttpException $e)
{
return response(
[
'message' => sprintf(
'%d %s',
$e->getStatusCode(),
Response::$statusTexts[$e->getStatusCode()]
),
'status' => $e->getStatusCode()
],
$e->getStatusCode(),
$e->getHeaders()
);
}

Yii2 autologin doesn't work

I try to realize the autologin feature in yii2.
So I've enabled autologin in configuration:
'user' => [
'identityClass' => 'app\models\User',
'enableAutoLogin' => true,
'loginUrl' => ['account/login', 'account', 'account/index'],
],
Also I've added rememberMe field in form configuration
public function scenarios() {
return [
'login' => ['username','password','rememberMe'],
'activate' => ['password','passwordrepeat'],
'register' => ['username', 'mail'],
'setup' => ['username', 'password', 'passwordrepeat', 'mail', 'secretkey'],
];
}
// ...
[
['rememberMe'],
'boolean',
'on' => 'login',
],
I'm using this now at login:
public function login() {
//var_dump((bool) ($this->rememberMe)); exit();
if (!$this->validate()) {
return false;
}
return Yii::$app->user->login($this->getUser(), (bool) ($this->rememberMe) ? 3600*24*30 : 0);
}
If I log in, users function getAuthKey function is called and a new auth_key is generated.
public function generateAuthKey() {
$this->auth_key = Yii::$app->getSecurity()->generateRandomString();
Helper::save($this);
// Helper is a database helper which will update some rows like last_modified_at and similar in database
}
/**
* #inheritdoc
*/
public function getAuthKey()
{
$this->generateAuthKey();
return $this->auth_key;
}
But always, I log in, it doesn't set some cookie variables.
My cookies are always
console.write_line(document.cookie)
# => "_lcp=a; _lcp2=a; _lcp3=a"
And if I restart my browser I'm not logged in.
What am I doing wrong?
It seems that Yii doesn't work with cookies correctly:
var_dump(Yii::$app->getRequest()->getCookies()); exit();
Results in:
object(yii\web\CookieCollection)#67 (2) { ["readOnly"]=> bool(true) ["_cookies":"yii\web\CookieCollection":private]=> array(0) { } }
If I access via $_COOKIE I have the same values as in JS.
Thanks in advance
I guess you don't have to generate auth key every time in your getAuthKey method. Your app tries to compare database value to the auth key stored in your cookie. Just generate it once before user insert:
/**
* #inheritdoc
*/
public function getAuthKey()
{
return $this->auth_key;
}
/**
* #inheritdoc
*/
public function beforeSave($insert)
{
if (!parent::beforeSave($insert)) {
return false;
}
if ($insert) {
$this->generateAuthKey();
}
return true;
}
Could be your timeout for autologin is not set
Check if you have a proper assignment to the value assigned to the variable:
$authTimeout;
$absoluteAuthTimeout;
See for more