Laravel function to convert a realpath() to an absolute URL - php

I have declared a path pointing to a folder like this:
$path = realpath(public_path('uploads'));
This gives me that value: /var/www/mywebsite/public/uploads
Now, I want to turn this into an absolute URL, like this: http://www.mywebsite.com/uploads
Here is what I did:
dd(asset($path)); // Wrong: http://www.mywebsite.com/var/www/mywebsite/public/uploads
dd(url($path); // Same.
dd(asset('uploads')); // Right, but I only want to use $path
Is there a pre-built way to achieve this in Laravel 5?

You were almost there with asset($path).
Just amend this to asset('uploads') and this will resolve to http://www.mywebsite.com/uploads.
The asset URL helper generates a URL to the public folder of your Laravel application. You then just add the folder you want to go to from there.

Yours $path is taken relatively to public folder with public_path('uploads'), so, 'uploads' by itself points to absolute path. Just add host part to it. Like:
$inPublic = 'uploads';
$localPath = realpath(public_path($inPublic));
// then, either
$url = url("/" . trim($inPublic, "/\\"));
// or
$publicPath = realpath(public_path());
$relativePart = str_replace($publicPath, '', $localPath);
$url = url("/" . trim($relativePart, "/\\"));

Related

How to use Laravel Storage::file();

I wanted to check the files inside my public path 'public/img/certs' but it returns an array. Im currently using laravel 5.5 and my first time using the 'Storage' file system.
use Illuminate\Support\Facades\Storage;
public function index(Request $request)
{
$path = base_path() . '/public/img/certs';
$files = Storage::files($path);
dd($files);
return view('dashboard.index');
}
try this code, reference link
$files = File::allFiles($directory);
foreach ($files as $file)
{
echo (string)$file, "\n";
}
First, $files = Storage::files('$path'); won't work at all, because the variable won't be interpreted.
Second, Storage::files will return an array because you asked for files and gave it a directory. The array will contain all the files in that directory.
Third, consider the public_path helper for this:
$path = public_path('img/certs');
It's a bit cleaner and will work if you ever put your public files somewhere non-standard.
Try below code in your controller hope this will help you to store the file in storage location of your application.
if($request->hasFile('image')){
$image_name=$request->image->getClientOriginalName();
$request->image->storeAs('public',$image_name);
}
$request->user()->profile_pic=$request->image;
$request->user()->save();
return back();
Modified it according to your requirement so this code work definately.

Laravel Access Images outside public folder

I need to store images in a backend for logged in users. The stored images need to be protected and not visible from the outside (public). I choosed a "storage" folder for this.
I came up with this in my Controller:
public function update(Request $request, $id)
{
//Show the image
echo '<img src="'.$_POST['img_val'].'" />';
//Get the base-64 string from data
$filteredData=substr($_POST['img_val'], strpos($_POST['img_val'], ",")+1);
//Decode the string
$unencodedData=base64_decode($filteredData);
//Save the image
$storagepath = storage_path('app/images/users/' . Auth::user()->id);
$imgoutput = file_put_contents($storagepath.'/flyer.png', $unencodedData);
return view('backend.flyers.index')->withImgoutput($imgoutput)
//->withStoragepath($storagepath);
}
after hitting the save button, which triggers the update() I am able to see the image in my view, and it is also stored in my folder (current users=10) "storage/app/images/users/10/flyer.png"
my question is how can I access the image path?
I want to show the stored image with img src="">. I have no idea what to put inside "src= ..."
While dealing with user file uploads in web applications, the major aspect is about user's content's security.
One should use secure way to upload private files of a user in web applications.
As in your case, you want to access user's image outside public folder.
This can be done in a most secure way as given below.
First of all create a directory right in the root directory of Laravel (where the public folder is located), let the directory's name be uploads. Use this directory to upload private user files.
In the case of images create an another directory inside uploads as uploads/images/ inside uploads directory so that you can have a different storage locations for different type of files.
Remember to upload the image in images directory with a different name and without their extensions so that it looks like a extension-less file.
Keep the file name and its extension in the database which can be used later to retain image's location.
Now you need to create a separate route to show user's image.
Route::get('users/{id}/profile_photo', 'PhotosController#showProfilePhoto')->name('users.showProfilePhoto');
PhotosController.php
class PhotosController extends Controller {
private $image_cache_expires = "Sat, 01 Jan 2050 00:00:00 GMT";
public function showProfilePhoto($id) {
$user = User::find($id);
$path = base_path() . '/uploads/images/';
if($user && $user->photo) // Column where user's photo name is stored in DB
{
$photo_path = $path . $user->photo; // eg: "file_name"
$photo_mime_type = $user->photo_mime_type; // eg: "image/jpeg"
$response = response()->make(File::get($photo_path));
$response->header("Content-Type", $photo_mime_type);
$response->header("Expires", $this->image_cache_expires);
return $response;
}
abort("404");
}
}
The method above inside PhotosController - showProfilePhoto($user_id) will run as soon as you access the route named - users.showProfilePhoto.
Your HTML code will look like this.
<img src="<?php echo route('users.showProfilePhoto', array('id' => $user->id)); ?>" alt="Alter Text Here">
The above code will work like a charm and the image will be shown to the user without declaring/publishing the proper image path to public.
According to me this is the secure way to deal with file uploads in web applications.
You can do this like this:
Route::get('images/{filename}', function ($filename)
{
$path = storage_path() . '/' . $filename;
if(!File::exists($path)) abort(404);
$file = File::get($path);
$type = File::mimeType($path);
$response = Response::make($file, 200);
$response->header("Content-Type", $type);
return $response;
});
Reference:
Laravel 5 - How to access image uploaded in storage within View?
Or Alternatively you can use this library: https://github.com/thephpleague/glide
Just use composer to install it in your project
By default, this will render images from your storage, and allow you to do all sorts of things with it such as cropping, color correction etc.
Reference:
http://glide.thephpleague.com/
https://laracasts.com/discuss/channels/laravel/laravel-5-how-can-we-access-image-from-storage?page=1
Atimes you might have some images you do not wish to store in public directory for some various reasons.
Although storing your images has lots of advantages.
There are many ways you can achieve this, however I have this simple solution.
You should create a helper class like so if already don't have one
<?php namespace App\Services;
class Helper
{
public function imageToBase64($path)
{
$type = pathinfo($path, PATHINFO_EXTENSION);
$data = file_get_contents($path);
return 'data:image/' . $type . ';base64,' . base64_encode($data);
}
}
Then in your view (blade)
#inject('helper', 'App\Services\Helper')
<img width="200" height="250" src="{{$helper->imageToBase64(storage_path('app/images/users/' . Auth::user()->id)}}">
It will work 100% work. Open file filesystem in app/config/filesystem.php and write like that
'profile' => [
'driver' => 'profile',
'root' => '/home/folder/public_html/projectname/public/profiles',
],
Add this file at top
use Illuminate\Support\Facades\Storage;
My variable name is
$directoryName = 'profile';
$imageName = $request->image; // image is array of base64 encoded urls
$directory_path ='profiles';
Below function save your file in public/profiles folder.
function UploadImagesByBase64($directoryName, $imageName,$directory_path)
{
$data = array();
$image = $imageName;
foreach ($image as $image_64) {
if($image_64 !=null){
$extension = explode('/', explode(':', substr($image_64, 0, strpos($image_64, ';')))[1])[1]; // .jpg .png .pdf
$replace = substr($image_64, 0, strpos($image_64, ',')+1);
// find substring fro replace here eg: data:image/png;base64,
$image = str_replace($replace, '', $image_64);
$image = str_replace(' ', '+', $image);
$imageName = Str::random(10).time().'.'.$extension;
Storage::disk($directoryName)->put($imageName, base64_decode($image));
$data[] = $directory_path.'/'.$imageName;
}
}
$imageName = implode(',', $data);
return $imageName;
}

How to output file above public folder Laravel 5.1

I have debian machine and my site is in /var/www/laravel-site/ folder.
In laravel-site folder i have FILES and PUBLIC folders. How can i output file to FILES folder to protect the file from web reading?
I guess base_path() will help
Simple usage example:
<?php
$file = base_path('FILES').'/people.txt';
// Open the file to get existing content
$current = file_get_contents($file);
// Append a new person to the file
$current .= "John Smith\n";
// Write the contents back to the file
file_put_contents($file, $current);
?>
function base_path($path = '') is a Laravel helper function. It gets the path to the base of the install:
function base_path($path = '')
{
return app()->basePath().($path ? '/'.$path : $path);
}
So, to get your /var/www/laravel-site folder just use
echo base_path();
To get FILES folder (or whatever path you need inside the Laravel's base) use echo base_path('FILES');
it will output /var/www/laravel-site/FILES

Codeigniter deleting files in a directory not working

I am trying to delete pdf files from a folder. I have written the delete_files function as follows
public function delete_files($company_id)
{
$this->load->model('search_model');
$company = $this->search_model->get_company($company_id);
$username = $company[0]['username'];
$path=$this->config->base_url('/uploads/'.$username . '/' . 'uploaded');
$this->load->helper("file"); // load the helper
delete_files($path, true); // delete all files/folders
}
when i did echo $path; it shows the right path where i want the files deleted but when i run the entire function nothing happens and i just get a white screen.
You need to use path to file and not resource locator.
$path = FCPATH . "uploads/$username/uploaded";
try this code
Use
$path = FCPATH . "uploads/$username/uploaded";
unset($path);

PHP Get Relative Path from Parent to Included File

I have a directory structure like this:
www/
index.php
my-library/
my-library.php
assets/
my-library.css
images/
loading.gif
I need my-library.php to inject stylesheets into index.php. To do so, I need to get the relative path from index.php to my-library/ -- which in this particular case, would simply be "my-library".
From within my-library.php, is it possible for me to acquire this relative path?
Or must index.php supply it, with something like the following?
<?php
require "my-library/my-library.php";
$mlib->linkroot='my-library';
?>
To clarify, below I have included a more detailed representation of what I'm trying to do:
index.php:
<?php require "my-library/my-library.php"; ?>
<!doctype html>
<head>
<title>Testing My Library</title>
<?php $mlib->injectAssets(); ?>
</head>
<body>..</body>
my-library.php:
<?php
class MyLibrary(){
public $rootpath;
public $linkroot;
function __construct(){
$this->rootpath= __DIR__; // absolute path to my library's root directory (for serverside use)
$this->linkroot = "???"; // relative path to my library's root from index.php (for clientside use, like linking in stylesheets)
}
function injectAssets(){
$csslink = $this->linkroot.'/assets/my-library.css';
echo '<link href="'.$csslink.'" rel="stylesheet" />';
}
}
$mlib = new MyLibrary();
?>
The line I'm interested in figuring out, would be $this->linkroot = "???";.
I'm practically trying to acquire the string that was used to include/require the current script.
I got it! I only had to build a Rube Goldberg Machine to do it!
Thanks PHP.
$linkroot = ascertainLinkroot();
function ascertainLinkroot(){
return makeRelativePath(
getTopScriptPath(),
__DIR__
);
}
function getTopScriptPath(){
$backtrace = debug_backtrace(
defined( "DEBUG_BACKTRACE_IGNORE_ARGS")
?DEBUG_BACKTRACE_IGNORE_ARGS
:FALSE );
$top_frame = array_pop($backtrace);
$top_script_path = $top_frame['file'];
return $top_script_path;
}
function makeRelativePath($from,$to){
// Compatibility
$from = is_dir($from) ?rtrim($from,'\/').'/' :$from;
$to = is_dir($to) ?rtrim($to,'\/').'/' :$to;
$from = str_replace('\\','/',$from);
$to = str_replace('\\','/',$to);
//----------------------------
$from = explode('/',$from);
$to = explode('/',$to);
$path = $to;
foreach($from as $depth => $dir) {
if ($dir === $to[$depth]) { // find first non-matching dir
array_shift($path); // ignore it
} else {
$remaining = count($from)-$depth; // get number of remaining dirs to $from
if ($remaining>1){
// add traversals up to first matching dir
$padLength = -(count($path)+$remaining-1);
$path = array_pad($path, $padLength, '..');
break;
} else {
$path[0] = './'.$path[0];
}
}
}
return rtrim(implode('/', $path),'\/');
}
So, basically, I use the makeRelativePath function to calculate a relative path from the top script's absolute path to the current script's absolute directory path (__DIR__).
I realized that I'm actually looking for the relative path to the library from the top script, not just the parent script -- because the top script is the one where clientside assets will need to be referenced in relation to.
Naturally, PHP doesn't just give you the top script's absolute path. On some environments, the top script's path can be available as a $_SERVER variable, however environment independence is important for me, so I had to find a way.
getTopScriptPath was my solution, as it uses debug_backtrace to find it (creepy, I know), but it is the only environment-independent way to fetch it (to my knowledge).
Still hoping for a more elegant solution, but am satisfied that this one works.
I believe this is what you're looking for:
$this->linkroot = basename(pathinfo($_SERVER['REQUEST_URI'], PATHINFO_DIRNAME));
You can remove basename() to get the full path. Basically, you can run the following code:
echo '<pre>';
var_dump($_SERVER);
echo '</pre>';
If the path you're looking for isn't there in some shape or form, then it simply isn't available and you will have no other choice but to hard code it, or at least hard code part of it.
Have you tried doing a relative link from the root? If not, you might try something like this, if I understand your folder structure.
<link href="/my-library/assets/my-library.css" rel="stylesheet" type="text/css" />
Links like this in any page within your site will pull the same stylesheet, up or down the site structure.

Categories