Freelance Status is a tool for freelancers to update clients about their work progress. You can download it for free.
Technologies used
Laravel
I have used Laravel framework for building this project basic structure and APIs. It is also a very good framework with many built-in security features. It can also be deployed on shared hosting as well.
React JS
All the pages on client and admin side are rendered in React JS. This is not a Single Page Application (SPA) but the HTML is rendered by React JS.
Bootstrap
Bootstrap is used for building structure and layout of website. It is also very helpful for responsive design.
Features
In “Freelance Status”, there are 2 panels. One for freelancer and one for client. Freelancer portal is actually the admin panel because he can add his clients, projects and tasks. He can update the status of his tasks etc. But client can only see the progress of their tasks from user side.
Admin panel (freelancer)
You (as a freelancer) holds the admin panel. You can:
Add, edit or delete clients. While adding clients, you can enter their name, email, phone (if have) and password. You can let them know their password via message or inbox so they can access the client side.
You can add projects for each client. While adding projects, you can enter the name of the project. Then you can select the client of that project via dropdown. In dropdown, you will see a list of all clients added from previous step.
Similarly, you can add tasks of each project. For adding tasks, you have to provide many values.
Task title and its description.
The price of that task.
The status (todo, progress or done).
The payment status. It can be either (paid, not paid, not finalized). Payment “not finalized” means that the amount is not yet decided between client and freelancer. But you are saving the task so it can be discussed later.
Select the client.
Select the project this task belongs to.
Client side
Clients will first have to login using the email and password provided by freelancer.
After login, they will see all their projects on home page.
With each project, they will see a link “View tasks”. On clicking that, they will be redirected to a new page.
On this page, they can see a list of all tasks in that project. They can also see the price, status and payment status of each task.
With each task, a button saying “Detail” is displayed. When clicked, will display a modal containing the details of the task.
Installation
Following steps helps you install this project on your localhost. If you want to learn how to deploy this on your live server, check our this guide.
Step 1
First you need to create a database named “freelance_status”, or any other name of your choice, in your phpMyAdmin.
Step 2
Then you need to set your database credentials in “config/database.php” file. Here you can set your database name, username and its password.
Note: If you are working on live server, make sure you have given that user all permissions to your database.
Step 3
Open command prompt or terminal at the root of this project and run the following commands:
COMPOSER_MEMORY_LIMIT=-1 composer update
This will install all the required libraries for this project. Make sure you have composer installed in your system. COMPOSER_MEMORY_LIMIT=-1 will prevent you from timeout exception.
Note: For live server, you can talk with your hosting provider customer support to install composer.
Step 4
Set storage link in your public folder by running the following command:
php artisan storage:link
This will create a shortcut link of storage/app/public folder into your public folder. It allows you to access your files stored in storage from public directory.
Step 5
Next step is to generate an application key for your project.
php artisan key:generate
This will generate a random string of 32 characters. The key will automatically be saved in APP_KEY variable of your .env file.
Step 6
If you have set your database credentials, you can run the following command.
php artisan migrate
It will create all the tables required for your project.
Step 7
After running the migration, we need to run the seeder.
A super admin will be added in “users” table. You can set your own name, email and password here.
Step 8
Finally you can run your project by running the following command.
php artisan serve
If you run the URL “http://127.0.0.1:8000” in your browser, you will see your project. If anything goes wrong, feel free to contact me.
“Freelance Status” allows you to add clients, their projects and tasks from admin panel. And clients can see them trough a user side. Clients do not have to keep asking you about update on the project. And you can focus more on work than on updating the client about progress.
I created an online free FTP manager in PHP that allows developers to work on their projects from anywhere. I created this tool in PHP and MySQL using Laravel framework. The frontend is designed in Bootstrap and React JS.
Let’s discuss each feature and I will also show you how I built this.
What you will learn:
Connect with FTP.
List files from FTP directory.
Fetch file content.
Edit FTP file.
Create a new file.
Create a new folder.
Upload files.
Download files.
Rename file.
Delete file.
Delete folder.
We created a PHP class named “FTP” in a file called “FTP.php”. All our functions will go in that class.
1. Connect with FTP
The first step is to connect with FTP server. Following code will create a function that will connect with your FTP server (we are not calling it yet).
class FTP
{
private $conn_id = null;
private $server = "";
private $username = "";
private $password = "";
private function do_connect()
{
try
{
// Establishing connection
$this->conn_id = ftp_connect($this->server);
if (!$this->conn_id)
{
echo json_encode([
"status" => "error",
"message" => "Could not connect to " . $this->server
]);
exit();
}
// Login with username and password
$login_result = ftp_login($this->conn_id, $this->username, $this->password);
if (!$login_result)
{
echo json_encode([
"status" => "error",
"message" => "Wrong password for '" . $this->username . "'."
]);
exit();
}
// Enable passive mode for better compatibility
ftp_pasv($this->conn_id, true);
}
catch (\Exception $exp)
{
echo json_encode([
"status" => "error",
"message" => "Could not connect to " . $this->server
]);
exit();
}
}
}
Comments has been added with each line for explanation. Make sure to enter your correct FTP server address, FTP account’s username and its password. In the next step, we will call this function to connect with FTP server.
2. List files from FTP directory
The next step is to list all files from FTP directory. Create the following function in your FTP class.
public function fetch_files()
{
$this->do_connect();
$path = "/directory-name";
// Get file listing
$file_list = ftp_nlist($this->conn_id, $path);
if ($file_list === false)
{
echo json_encode([
"status" => "error",
"message" => "Error retrieving file list."
]);
exit();
}
$files = [];
foreach ($file_list as $file)
{
$obj = [
"file" => $file,
"size" => ftp_size($this->conn_id, $file)
];
if ($obj["file"] != "." && $obj["file"] != "..")
{
array_push($files, $obj);
}
}
// Close the connection
ftp_close($this->conn_id);
echo json_encode([
"status" => "success",
"message" => "Data has been fetched.",
"files" => $files
]);
exit();
}
This function will first connect with the FTP server.
Then it will fetch all the files from $path variable.
If the directory does not exists or if it does not have read permission, then it will return an error.
All files from that directory will be put in an array along with the size of the file in bytes.
If it is a directory, then it’s size will be -1.
Finally, it returns the array with the response.
3. Fetch file content
Reading the content of FTP file is necessary because in order to edit the file, we need to first view the file. Following function will fetch the content of file and return it in response.
public function fetch_content()
{
$this->do_connect();
$file = "/directory-name/file-name.php";
// Local path for downloading the file
$local_file = tempnam(sys_get_temp_dir(), 'ftp_download');
// Download the file from FTP server to local file
if (!ftp_get($this->conn_id, $local_file, $file, FTP_BINARY))
{
echo json_encode([
"status" => "error",
"message" => "Failed to read '" . $file . "'"
]);
exit();
}
// Read contents of the local file
$file_content = file_get_contents($local_file);
// Display or process the file content as needed
if ($file_content === false)
{
echo json_encode([
"status" => "error",
"message" => "Failed to read file content."
]);
exit();
}
// Clean up: Delete the temporary local file
unlink($local_file);
echo json_encode([
"status" => "success",
"message" => "Data has been fetched.",
"content" => $file_content
]);
exit();
}
It will first download the file in a temporary directory to your server.
If the file does not exists, then it will return an error.
It will return an error if it fails to read the FTP file.
Usually it is because if the $path variable is a directory or an image or document file.
After the file’s content is fetched, we will remove the temporary file from our server.
4. Edit FTP file
After the file’s content is successfully fetched, the next step is to update the file. You are working in FTP, editing the code is what you will be doing most of the time.
Updating the content of file requires 2 steps:
Saving the file in temporary folder.
Uploading the temporary file on FTP server.
public function update_content()
{
$this->do_connect();
$file = "/directory-name/file-name.php";
$content = "console.log(\"Hello world\")";
// Local path for downloading the file
$local_file = tempnam(sys_get_temp_dir(), 'ftp_download');
// Write the new content to a local temporary file
file_put_contents($local_file, $content);
if (!ftp_put($this->conn_id, $remote_file, $local_file, FTP_ASCII))
{
echo json_encode([
"status" => "error",
"message" => "There was a problem updating '" . $remote_file . "'"
]);
exit();
}
unlink($local_file);
// Close the FTP connection
ftp_close($this->conn_id);
echo json_encode([
"status" => "success",
"message" => "File has been updated."
]);
exit();
}
5. Create a new file
Creating a new file in FTP in PHP is as simple as updating the file. We just need to set the content of file as empty string. So we will be uploading an empty file to FTP server.
public function create_file()
{
$this->do_connect();
$path = "/directory-name";
$name = "file-name.php";
// Local file content to be uploaded
$file_content = "";
// Local path for downloading the file
$local_file = tempnam(sys_get_temp_dir(), 'ftp_download');
// Write the content to a temporary local file
file_put_contents($local_file, $file_content);
// Remote file path where the file will be created
$remote_file = $path . "/" . $name; // Replace with the desired remote file path
// Upload the local file to the FTP server
if (!ftp_put($this->conn_id, $remote_file, $local_file, FTP_ASCII))
{
echo json_encode([
"status" => "error",
"message" => "There was a problem while creating '" . $name . "'"
]);
exit();
}
unlink($local_file);
// Close the FTP connection
ftp_close($this->conn_id);
echo json_encode([
"status" => "success",
"message" => "Successfully created '" . $name . "'"
]);
exit();
}
Create a temporary empty file on local directory.
Upload it to FTP.
Remove the file from local directory.
6. Create a new folder
Creating a folder is must easier than creating a file on FTP server.
public function create_folder()
{
$this->do_connect();
$path = "/directory-name";
$name = "folder-name";
$folder = $path . "/" . $name;
if (!ftp_mkdir($this->conn_id, $folder))
{
echo json_encode([
"status" => "error",
"message" => "There was a problem while creating '" . $name . "'"
]);
exit();
}
echo json_encode([
"status" => "success",
"message" => "Successfully created '" . $name . "'"
]);
exit();
}
Note: It will return an error if the directory already exists.
7. Upload files
To upload the file from local computer to FTP server, you need to first save it in your local server. Then upload the file to FTP server. After it is successfully uploaded, you can remove the file from local server.
public function upload()
{
$this->do_connect();
$path = "/directory-name";
$file_name = basename($_FILES["file"]["name"]);
$target_file = "uploads/" . $file_name;
if (!move_uploaded_file($_FILES["file"]["tmp_name"], $target_file))
{
echo json_encode([
"status" => "error",
"message" => "The file " . htmlspecialchars(basename( $_FILES["file"]["name"])) . " has been uploaded."
]);
exit();
}
if (!ftp_put($this->conn_id, $file_name, $target_file, FTP_ASCII))
{
echo json_encode([
"status" => "error",
"message" => "There was a problem updating '" . $file_name . "'"
]);
exit();
}
// Close the FTP connection
ftp_close($this->conn_id);
echo json_encode([
"status" => "success",
"message" => "File(s) has been uploaded."
]);
exit();
}
If you are working in Laravel, your upload function should be like this:
public function upload()
{
$this->do_connect();
$path = "/directory-name";
$files = request()->file("files");
foreach ($files as $file)
{
$remote_file = $file->getClientOriginalName();
$file_path = "ftp/" . $file->getClientOriginalName();
$file->storeAs("/private", $file_path);
if (!ftp_put($this->conn_id, $remote_file, storage_path("app/private/" . $file_path), FTP_ASCII))
{
return response()->json([
"status" => "error",
"message" => "There was a problem updating '" . $remote_file . "'"
]);
}
Storage::delete("private/" . $file_path);
}
// Close the FTP connection
ftp_close($this->conn_id);
return response()->json([
"status" => "success",
"message" => "File(s) has been uploaded."
]);
}
8. Download files
Downloading the file to local computer requires 2 steps.
First is to download the file on local server from FTP server.
Then download it to local computer from local server.
Download file from FTP to local server
Following code will be used to download the file on local server.
public function download()
{
$this->do_connect();
$path = "/directory-name";
$file = "file-name.php";
// Local path for downloading the file
$local_file = tempnam(sys_get_temp_dir(), 'ftp_download');
$remote_file = $path . "/" . $file;
// Download the file from FTP server to local file
if (!ftp_get($this->conn_id, $local_file, $remote_file, FTP_BINARY))
{
echo json_encode([
"status" => "error",
"message" => "Failed to download '" . $remote_file . "'"
]);
exit();
}
// Create a unique download URL for the file
$download_url = url('download.php?file=' . urlencode($local_file) . '&name=' . urlencode($file));
// Close the FTP connection
ftp_close($this->conn_id);
echo json_encode([
"status" => "success",
"message" => "File has been downloaded.",
"download_url" => $download_url
]);
exit();
}
It will also return the “download_url” variable. That will be link to file from where you can download the file.
Download from server to local computer
Create a new file named “download.php” in your server and write the following code in it:
if (isset($_GET['file']) && isset($_GET['name']))
{
$temp_file = $_GET['file'];
$file_name = $_GET['name'];
if (file_exists($temp_file))
{
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . $file_name . '"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($temp_file));
// Read the file and output it to the browser
readfile($temp_file);
// Delete the temporary file
unlink($temp_file);
exit();
}
echo "File does not exist.";
exit();
}
echo "Invalid request.";
exit();
9. Rename file
Renaming the file on FTP using PHP is very easy. You just have to provide 3 things:
Folder name
Old file name
New file name
public function rename()
{
$this->do_connect();
$path = "/directory-name";
$name = "new-file-name.php";
$file = "old-file-name.php";
// File to be renamed on the FTP server
$remote_file = $path . "/" . $file;
$remote_new_file = $path . "/" . $name;
// Try to rename the file or folder
if (!ftp_rename($this->conn_id, $remote_file, $remote_new_file))
{
echo json_encode([
"status" => "error",
"message" => "There was a problem renaming " . $file . " to " . $name
]);
exit();
}
echo json_encode([
"status" => "success",
"message" => "Successfully renamed " . $file . " to " . $name
]);
exit();
}
10. Delete file
Deleting a file from FTP in PHP is very simply. You just need to enter the full path of the file and call the PHP built-in ftp_delete function. Pass the FTP connection ID and file path as arguments.
public function delete_file()
{
$this->do_connect();
$path = "/directory-name/file-name.php";
// Delete the file on the FTP server
if (!ftp_delete($this->conn_id, $path))
{
echo json_encode([
"status" => "error",
"message" => "There was a problem while deleting " . $path
]);
exit();
}
echo json_encode([
"status" => "success",
"message" => "Successfully deleted " . $path
]);
exit();
}
11. Delete folder
Deleting a folder is NOT as simple as deleting a single file. There are 2 steps involved in deleting a folder from FTP in PHP.
Recursively delete all files and folders inside that folder.
Delete the folder itself.
So first we will create a function that will initialize the call to recursive function.
public function delete_folder()
{
// Set maximum execution time to unlimited (0 means no limit)
set_time_limit(0);
$path = "/directory-path/folder-name";
$this->do_connect();
$this->ftp_delete_dir($path);
echo json_encode([
"status" => "success",
"message" => "Folder has been deleted."
]);
exit();
}
Our recursive function ftp_delete_dir will look like this:
// Function to recursively delete a directory
private function ftp_delete_dir($path)
{
// Get the list of files in the directory
$files = ftp_nlist($this->conn_id, $path);
// Loop through each file
foreach ($files as $file)
{
$file = basename($file);
if ($file == '.' || $file == '..')
{
continue;
}
$file_path = "$path/$file";
// If it's a directory, delete recursively
if (@ftp_chdir($this->conn_id, $file_path))
{
ftp_chdir($this->conn_id, '..');
ftpDelete($this->conn_id, $file_path);
}
else
{
// If it's a file, delete it
ftp_delete($this->conn_id, $file_path);
}
}
// Finally, remove the directory itself
ftp_rmdir($this->conn_id, $path);
}
It does the following things:
Loops through all the files inside that folder.
Skip the “.” and “..” folders (they are just pointing towards current and parent directory respectively).
If the file is a directory, start the recursion.
Else delete the file.
Finally at line #33, we are deleting the current directory itself.
So these are all the features we have in FTP manager I created in PHP and MySQL using Laravel framework. If you have any quetions regarding FTP or if you are having any problem, feel free to contact me.
Real estate business that requires a website for their business, we are providing a free website for them in PHP and MySQL (Laravel framework).
Screenshots
Features
Following are the key features in this project. More features can be added on-demand.
Admin panel
There is a dedicated admin panel from where admin can manage all properties, set business email, phone and address. He can also manage the banners on home page. Administrator can also see all the messages received from “contact us” form from use side.
Properties
In this free real estate website, you can mention the properties available. From admin panel, you can add, edit or delete any property you want. You just need to enter the property name and its price. You can also upload an image of the property. For more information, you can write the detail on the “description” box.
Apart from these, you can also mention the following attributes of the property:
Area of property.
Number of floors.
Number of rooms.
Number of bedrooms.
Number of bathrooms.
Parking space.
And payment process (Cash, Bank, Cheque etc.).
Home banners
You can upload banners for home page. When user lands on your real estate website, he will see those banners right infront of him. You can upload as many banners as you want, but the ideal number is 3. You can delete any banner whenever you want.
Business information
To update the business information like phone, email and address. You don’t need to go into source code and update these on all places. On admin panel, you can goto “settings” and enter their values and they will be updated on all places in the website. You can also set the name of website from settings page.
Social network
Same as you can update your business information, you can enter your social media links from admin panel. Right now you can set the following social network links:
Facebook
Twitter
Instagram
LinkedIn
But more can be added on-demand.
Contact us
On user-side, we have a “contact us” form from where user can enter his name and email and send a message. You can see all user’s sent messages on admin panel. You can see their name and email, so if you want to contact them back, you can do easily.
Installation
Create a database “real_estate” in your phpMyAdmin.
If you are working in Laravel, you might have noticed that majority of the developers save sensitive information like database credentials, SMTP settings and API keys in the .env file. This file exists at the root level of your project.
I was also saving my credentials in .env files for a long time until I found some problems in it. So I had to find a better way to save sensitive credentials securely.
Problem with .env file
The problems I found while saving sensitive credentials in .env file in Laravel are:
Caches
The variables you set in .env file will be cached by Laravel. You might change the value of variable but the Laravel will be picking the old cached value.
However, you can refresh cache by running the following commands but it still an extra work:
Imagine you are using PayPal or Stripe in your Laravel application and you have saved their API keys in .env file. You have delivered the project but now the client has to change his account again and again. Instead of him messaging you everytime he needs to change his API keys, you can provide him a simple admin panel from where he can set those values dynamically.
Might be exposed
Wrong deployment or 1 bad configuration in .htaccess might lead to exposing your .env file to the public. Hence exposing all your sensitive credentials to everyone.
Database Credentials
Probably the first credential that developers set are the database credentials. Because without them, migrations and seeders won’t run.
I have commented out the database credentials in .env file:
Then in Javascript, I created a function that will be called when this form submits. This function will call an AJAX to save these credentials in the database:
This will save credentials in settings table if does not exists. If exists, then it will update its value.
Following is the schema of the settings table:
Schema::create('settings', function (Blueprint $table) {
$table->id();
$table->string("key")->nullable();
$table->longText("value")->nullable();
$table->timestamps();
});
settings-table
Now that you have saved the values in database, I will show you how to fetch the credentials from database.
$settings = DB::table("settings")->get();
$settings_obj = new \stdClass();
foreach ($settings as $setting)
{
$settings_obj->{$setting->key} = $setting->value;
}
echo $settings_obj->smtp_host;
This will fetch all the credentials from database and convert them into object using key value pairs. So you can access your values just like a normal object.
Hard-coded strings
There might be some scenarios where you do want to save some hard-coded strings. In that case, I have created a new file named “config.php” inside config folder and wrote all my hard-coded variables there:
config is a built-in function in Laravel. In “config.app_name”, config is the name of the file I created and app_name is the variable created inside it.
In order to get an authentication user without using sanctum middleware in Laravel, you just need to pass the string “sanctum” in auth() method.
Auth sanctum without middleware
Following route goes in the “routes/api.php” file:
# routes/api.phpRoute::post("/auth-without-sanctum", function () {returnauth("sanctum")->user();});
Auth sanctum with middleware
If you do not want to use the “sanctum” string in auth() method, then you need to wrap your route inside sanctum middleware. Like this:
Route::group(["middleware"=> ["auth:sanctum"]], function () {Route::post("/auth-without-sanctum", function () {returnauth()->user(); });});
Generate API Token
In order to check if the above code is working fine, we need to call an AJAX with authorization token. To create an authorization token (just for testing), we will use the following code:
createToken(secret_string) method accepts a secret string that will be used to generate plain text tokens. You can write any string you want. Copy the value of $token variable and use it in AJAX request later in this tutorial.
Note: If you face an error while generating a token, run the following command in your terminal:
phpartisaninstall:api
It will ask you to add Laravel\Sanctum\HasApiTokens trait in your User model. You can add it in the following way:
Open your browser inspect element and goto “Network” tab, you will see the user object in “Preview”.
Chrome inspect element network
Now try commenting out the line that sends authorization header in AJAX request. You will receive an empty or null response (make sure the API route is not wrapped in auth:sanctum middleware).
Error: Route [login] not defined
If you get an error “Route [login] not defined”.
Route [login] not defined – Laravel
Then it can also be fixed by adding the following 2 headers with your AJAX request.
A file manager web app is created in Laravel and React JS. We offer free 10 MB storage so you can test this script. Test it before you buy it. Easy deployment, you can just buy and upload the files on your server. Further instructions for deployment are in the file “README.md”. Check our tutorial if you need help in deployment.
We are using CloudBox Lite HTML template for this project.
I am using Laravel Sanctum API for handling authentication. It creates a token for each user and sends it in headers in AJAX requests. It is also useful so if you want to develop a mobile application for it, you can use the same authentication system. Because session authentication does not work on mobile.
2) Files and Folders
User can create as much folders as he wants and he can upload as much files as he wants unless his storage gets full. There is unlimited level of folder nesting just like in your computers, you can create folders and create folders inside it.
3) Rename
You can rename files and folders any time you want. You can also set the same name of different files in the same folder.
4) Private or public files
While uploading files, you can set if the file is publicly visible to other users. Or will it be only for you. You can share publicly available files with others.
User can change from public to private any time. Public files are saved in storage so they can be accessed by other users. While private files are saved in database in BLOB format. So they can only be accessible by the user who uploaded it.
5) Trash can
If you delete the file or folder by accident, it won’t be deleted permanently. It will be moved to trash where it remains unless you delete it. From trash can delete the file permanently or you can restore it. If you restore it, it will go to the same folder where it was before.
6) Share files
You can share files with other users as well if the file is public. While sharing file you can also set if the other user can just read it, or if he can modify the content of the file. Only text and source code file’s (txt, php, html, css, js, java, c, cpp, py, go, sql) content can be modified.
7) Realtime Collaboration
User can allow other’s to change the content of file without having to refresh the page. File owner can give write permission to a user and he will be able to edit the file. This is very useful for teams. Programmers can use this feature to work on the same project.
Making collaboration realtime using Node JS – File manager in Laravel and React JS
8) Profile
User can manage his personal information from his profile page. He can edit his name, phone and profile image. When user uploads a new profile image, we delete his old profile image. So only 1 image of user is saved in file system. The profile image is displayed when he shares a file with someone and also when someone adds him in his contact list.
9) Change Password
User can change his password. For that, he needs to enter his current password first. This is to prevent any other person to change his password. Passwords are stored using password_hash() PHP function that generates a store hash. It is a one-way hash, which means that once hashed, it cannot convert back to plain text. So even if someone sees your database, he won’t be able to tell the user’s passwords.
10) Email Settings
Now user can control when he wants to receive an email. Right now we are giving him 2 options:
When someone add me in his contact list.
When someone shares a file with me.
11) Contact List
If there are some people with whom you have files frequently. Then you do not need to type their email address everytime you share the file with them. Just add them in your contact list and next time you try to share a file with them, you will see a dropdown list with all your contacts. You can just pick the contact and hit “Share” button.
You can also see all the files you have shared with specific person from contact list.
If you keep getting 403 forbidden error on your Laravel storage files and you want to know how to fix this, you have landed on the right site.
403 forbidden error is typically when you do not have enough permission to read a file and it happens mostly on live servers (on production).
I was working on a Laravel project that allows users to upload and share files. To manage all user’s files, I am creating a sub-folder for each user with his ID. For example, if the user ID is 2, a folder named “2” will be created inside the storage sub-folder “files”. So the complete path to that folder will be: “storage/app/public/files/2”. I got this error due to permission of sub-folder “2”. I managed to fix it after a few hours, so I thought I might share the solution with others and it might help someone.
If you are seeing this error on your localhost, try running the following command:
phpartisanstorage:link
The solution that works for me is to set the permission of the parent folder as soon as the file is uploaded.
$file_path ="folder_name/". $file->getClientOriginalName(); // storage/app/public/folder_name/file.png$file->storeAs("/public", $file_path);// Get the full path to the folder$full_path =storage_path('app/public/folder_name');// Set permissions using PHP's chmod functionchmod($full_path, 0775);
This will ensure to give the read, write, and execute permission to the folder, not the files inside it. If you give the execute permission to the file, then a hacker can put a malicious file in it and execute it.
You might need to delete the folder “folder_name” and try again, it should work fine now. So that’s how you can fix the 403 forbidden error on your Laravel storage files. If you face any problem in following this, kindly do let me know.
If you are working in Laravel and want to get the size of uploaded file, you have come to the right place. Let’s say you are developing an application where it is required to see the total file size uploaded by user. In this case, you need to keep track of all the uploaded files.
You can either loop through all files in storage and get their sizes. Or you can get the file size during upload and save it in your database. Either way, this article will help you.
In this article, we will do the following:
Create an HTML form to upload file
Upload file and get uploaded file size
Convert bytes to readable format
1. Create an HTML form to upload file
First, we will create an HTML form to upload the file.
This will create an input-type file that will allow only images. It will be a required field, the form will not be submitted until a file is selected. And a submit button labeled as “Upload”, when clicked will submit the form.
This will also create a hidden CSRF field required for Laravel form submission.
One more thing you can do here is to allow the user to preview the image before uploading. Check this tutorial if you want to know how to do it.
2. Upload file and get uploaded file size
Next step is to upload the file to storage. For this, first, we need to create a route that will send the request to our controller.
The error you are having is because the double curly braces {{ which are used in React JS for styling the tag, are also used by Laravel blade template to render the value of a PHP variable. Laravel will think of it as a PHP variable and will throw an error.
To fix this error, you need to create a separate object in your React JS component. That object will have all the styles for each tag. Modify your React JS component to the following:
You can see that instead of setting the CSS directly in the style attribute, I have created a separate variable and used its value as a variable. This way your error gets fixed. Also, it will help you in setting CSS styles to multiple tags without duplicating them.
Most programmers find it difficult and confusing to deploy a Laravel website on a live server. Some don’t know where to start. Some get stuck in creating a virtual host. Some got attracted by cloud servers, but later realized that deploying on a cloud is very difficult.
Most of the developers starts tempering the directory structure of Laravel. Some create their own .htaccess files in order to cope with this problem.
Laravel entry point is public folder
The reason why programmers face difficulty in deploying a Laravel website is because Laravel entry point is its “public” folder, not the root folder (like core PHP or other CMS like WordPress etc). It means that if your domain is “adnan-tech.com”, then your website will be accessible from “adnan-tech.com/public”. This is not a good impression. User must access your site from main domain, not by appending “public” at the end.
Solution
In this article, I will not create a virtual host, nor temper the directory structure of Laravel. Each hosting has a file manager where all files of that server are stored. “public_html” is the primary folder for your domain. For the sake of simplicity, I will assume that you want to deploy your Laravel website in this folder. However, if you are deploying on sub-domain, you can select that sub-domain’s folder.
Upload all files inside “laravel/public” folder to the “public_html” folder.
Then you need to create a new folder at the root of your server.
I am naming it “laravel-server”.
Create a zip of your laravel project (except the “public” folder).
Upload the zip file to the “laravel-server” folder and extract it.
After extracting, you can delete the zip file.
Now open “public_html/index.php” and set the file’s paths to point to “laravel-server” folder.
At this point, you will see your Laravel project running live.
Storage files
Laravel uses a storage folder where all publicly uploaded files can be accessed. All your uploaded files will be stored at “laravel-server/storage/app/public”. We cannot give relative path to this folder. Because, imagine you have uploaded some images and they are now saved in storage folder. You create an <img /> tag and link the image to storage folder (like we did in index.php).
The only problem in this approach is, anyone can open “inspect element” from his browser and check the relative path to your “laravel-server”. Although, it is still very difficult to hack your server, but it is a good idea to keep your server hidden and secure as much as you can.
In order to hide the actual path of the file, we will create a symbolic link to this storage folder. Just like we create shortcuts of our games on Desktop, but the actual files are in some other location. User access the shortcut file and the shortcut file points towards the actual path of the file.
Open terminal from your cPanel.
At the root, you need to run the following command:
This will create a shortcut of “laravel-server/storage/app/public” folder in “public_html” folder and name the shortcut folder as “storage”.
Now, every file you upload at “laravel-server/storage/app/public” will be accessible from “public_html/storage”.
That’s how you can deploy your Laravel website on live server without compromising securety and without tweaking with the directory structure of Laravel. Although, I hope this tutorial helps you, but if you still face any problem to deploy your Laravel website, you can let me know.