Joomla 2.5 custom component: create path on install - joomla

My custom component needs a certain path, say /images/example/photos.
How can I create it on installation, but only if it doesn't exist yet?

You will need an install script. To get is set up, have a look at this:
Adding an Install/Uninstall/Update script file
You can remove all the functions but keep the install function. Your final install function should look like this:
function install($parent) {
jimport('joomla.filesystem.folder');
jimport('joomla.filesystem.file');
if(!JFolder::exists(JPATH_ROOT . '/media/images/example/photos')) {
$path = JPATH_SITE . '/media/images';
$folder = 'example/photos';
JFolder::create( $path .'/'. $folder, 0755 );
}
}
Hope this helps

Related

How to delete photo from project's public folder before updating data in lumen/laravel?

I am trying to delete photo from my projects public folder before updating another photo. My code looks like-
if(File::exist( $employee->avatar)){
//$employee->avatar looks /uploads/avatars/1646546082.jpg and it exist in folder
File::delete($employee->avatar);
}
This is not working in my case. If I comment these code then another photo updated without deleting perfectly. How can I solve the issue!
try php unlink function
$path = public_path()."/pictures/".$from_database->image_name;
unlink($path);
This is the code which i use in update profile picture you can do this exactly like this
$data=Auth::user();
if($request->hasFile('image')){
$image = $request->file('image');
$filename = 'merchant_'.time().'.'.$image->extension();
$location = 'asset/profile/' . $filename;
Image::make($image)->save($location);
$path = './asset/profile/';
File::delete($path.$data->image);
$in['image'] = $filename;
$data->fill($in)->save();
}

Are laravel's routes safeguarding enough against file traversal attacks?

Route::get('/transaction/{name}', 'TransactionController#download');
public function download($name){
$path = storage_path('app/something/') . $name . '.xml';
return response()->download($path);
}
The user shall using this action only be able to download .xml files in app/something.
Is it possible to to download data outside of the specified app/something folder.
Laravel doesn't protect against traversal attacks - the router will return any value with your code example, meaning that someone could get access to your filesystem!
You an use PHP's basename() to sanitise $name by removing any path references from the string:
Route::get('/transaction/{name}', 'TransactionController#download');
public function download($name){
$path = storage_path('app/something/') . basename($name, '.xml') . '.xml';
return response()->download($path);
}
As far as i know Laravel will compile your path to:
#^/transaction/(?P<name>[^/]++)$#s
So simple / will not not work..
You could use more sophisticated backslash - but it depends on server..
At the end - Remember not to trust all user input.. No matter does it goes through routing or received directly..
Updated answer
As you can see below, it's definitely possible to do malicious stuff within Laravel routes. Given your function setup, the chance of someone doing something you don't want is small, because he/she can only alter the $name variable.
You can still write some extra code like this (found on viblo.asia):
$basepath = '/foo/bar/baz/'; // Path to xml file
$realBase = realpath($basepath);
$userpath = $basepath . $_GET['path'];
$realUserPath = realpath($userpath);
if ($realUserPath === false || strpos($realUserPath, $realBase) !== 0) {
//Directory Traversal!
} else {
//Good path!
}
To prevent users from accessing files they aren't allowed to.
Old, but relevant answer
Just tried this in Homestead:
Route::get(
'/',
function () {
dump(exec('ls ' . storage_path() . '/../../../'));
}
);
And that prints the corresponding folder just fine:
So I'd say that it's definitely possible to do stuff outside of the specified folder. Try this for yourself for example:
Route::get(
'/',
function () {
for ($i = 0; $i < 10; $i++) {
$path = str_repeat('/..', $i);
dump(exec('ls ' . storage_path() . $path));
}
}
);
And see your folders appear on screen when you hit the / route.

Laravel 5 Dotenv for specific subdomain

I have a few subdomain in my laravel 5 application, each sub domain have a specific configuration, like mail, nocaptcha, etc.
how to set .env file to work with my-specific subdomain ?
Yes, you can use separate .env files for each subdomain so if you use env variables in your config it will work without great modifications.
Create bootstrap/env.php file with the following content:
<?php
$app->detectEnvironment(function () use ($app) {
if (!isset($_SERVER['HTTP_HOST'])) {
Dotenv::load($app['path.base'], $app->environmentFile());
}
$pos = mb_strpos($_SERVER['HTTP_HOST'], '.');
$prefix = '';
if ($pos) {
$prefix = mb_substr($_SERVER['HTTP_HOST'], 0, $pos);
}
$file = '.' . $prefix . '.env';
if (!file_exists($app['path.base'] . '/' . $file)) {
$file = '.env';
}
Dotenv::load($app['path.base'], $file);
});
Now modify bootstrap/app.php to load your custom env.php file. Just add:
require('env.php');
after
$app = new Illuminate\Foundation\Application(
realpath(__DIR__.'/../')
);
Now you can create separate env files for each domains for example if you use testing.app, abc.testing.app and def.testing.app you can have .env file for main domain (and for all subdomains that don't have custom env files) and .abc.env and .def.env files for custom env variables your your subdomains.
The best solution I found is to use .htaccess plus env variables.
In .htaccess add these lines:
<If "%{HTTP_HOST} == 'sub.domain'">
SetEnv APP_DOMAIN sub
</If>
In bootstrap/app.php add after the app initialisation:
//own env directory for separate env files
$app->useEnvironmentPath( realpath(__DIR__ . '/../env/') );
//separate files for each domain (see htaccess)
$app->loadEnvironmentFrom( getenv('APP_DOMAIN') . '.env' );
Create a new directory called "env" in your Laravel root and add your config files as:
"sub1.env",
"sub2.env" ..etc
(Of course you can keep it in your root as is currently, but for many subdomains it's better to move into a directory => looks much cleaner => everyone's happy! :) )
You can’t. Each subdomain will be running in the same environment.
If you want per-subdomain configuration then your best bet is to either create a configuration file in the config directory with each subdomain’s settings, or use a database approach.
I had the same issue, Based on #Marcin's answer I built this one (Works with laravel 5.2.X)
I added in the bootstrap/app.php
if (isset($_SERVER['HTTP_HOST'])) {
$hostArray = explode('.', $_SERVER['HTTP_HOST']);
//if the address is a subdomain and exist the .xxx.env file
$envFile = sprintf('.%s.env', $hostArray[0]);
if (count($hostArray) > 2 && file_exists(sprintf('%s/%s', $app['path.base'], $envFile))) {
$app->loadEnvironmentFrom($envFile);
}
}
after
$app = new Illuminate\Foundation\Application(
realpath(__DIR__.'/../')
);
I hope that helps someone
Greetings

Can't write image data to path in laravel

I am having the same error as this guy is :
Another thread
basically the error i have is uploading the image to the specific path, my code is as follows :
public function postCreate() {
$validator = Validator::make(Input::all() , Product::$rules);
if ($validator->passes()) {
$product = new Product;
$product->category_id = Input::get('category_id');
$product->title = Input::get('title');
$product->description = Input::get('description');
$product->price = Input::get('price');
$image = Input::file('image');
$filename = date('Y-m-d-H:i:s')."-".$image->getClientOriginalName();
Image::make($image->getRealPath())->resize(468, 249)->save('public/img/products'.$filename);
$product->image = 'public/img/products'.$filename;
$product->save();
return Redirect::to('admin/products/index')
->with('message' , 'Product created');
}
return Redirect::to('admin/products/index')->with('message' , 'something went wrong')
->withErrors($validator)->withInput();
}
I was just trying to follow a tutorial on laravel e-commerce web application.
I guess the problem is that i don't have write permisson in my directory , how do i add write permission in my directory. I.E. the public folder, I googled a few places , but i don't understand what is it that i have to edit ?
I.E the htaccesss file or can i make write changes on the cmd ? also how do i check what weather a directory is write protected .
PS. i am using windows . i am attaching a screenshot of the error .
Thank you.
You might want to change the dateformat since windows doesn't allow colons in filenames:
$filename = date('Y-m-d-H:i:s')."-".$image->getClientOriginalName();
And you also might want to add a trailing slash to your path so it doesn't concatenate the filename to the folder path:
Image::make($image->getRealPath())->resize(468, 249)->save('public/img/products'.$filename);
Generally this error occurs when you do not yet have the directory that will store the image inside the public directory. Sometimes it can be a permission issue.
Does you img directory exists in your public directory?
To fix this, follow the steps:
Use this snippet:
$relPath = 'img/'; //your path inside public directory
if (!file_exists(public_path($relPath))) { //Verify if the directory exists
mkdir(public_path($relPath), 666, true); //create it if do not exists
}
Or manually create the img directory in public
2.Then you can save your image:
Image::make($image)->resize(468, 249)->save(public_path('img/products'.$filename)); //save you image
$product->image = 'img/products'.$filename; //note
$product->save();
**NOTE: We do not need to specify the public directory in the path because we are using a relative path. The img directory will be created inside public directory.
Along with this, you need to make sure the folder path exists and which has right permissions set.
$relPath = 'img/product/';
if (!file_exists(public_path($relPath))) {
mkdir(public_path($relPath), 777, true);
}
Where $relPath is the path relative to public directory.
This requirement is however windows specific. In linux, folder directory will be created if it does not exist.
I also recommend all of you to check if $path exists. Like Jose Seie use native PHP check, I recommend you to thought about build-in helpers.
This can be achieved with File Facade helper:
File::exists($imagePath) or File::makeDirectory($imagePath, 777, true);
Advice you to use Laravel built-in functions, classes & helpers to improve the performance of your application!
well , i made the correction that john suggested and then made the following corrections :
I replaced the below code :
Image::make($image->getRealPath())->resize(468, 249)->save('public/img/products'.$filename);
with :
$path = public_path('img/products/'.$filename);
Image::make($image->getRealPath())->resize(468, 249)->save($path);
problem solved , i don't know why public_path works , but never mind .

CodeIgniter - Delete file, pathing issue

I have 3 folders in my root, "application", "system", and "uploads". In application/controllers/mycontroller.php I have this line of code.
delete_files("../../uploads/$file_name");
The file does not get deleted and I have tried a number of pathing options like ../ and ../../../ any ideas? Thanks.
Use the FCPATH constant provided to you by CodeIgniter for this.
unlink(FCPATH . '/uploads/' . $filename);
base_url() generates HTTP urls, and cannot be used to generate filesystem paths. This is why you must use one of the CI path constants. They are defined in the front controller file (index.php).
The three ones you would use are:
FCPATH - path to front controller, usually index.php
APPPATH - path to application folder
BASEPATH - path to system folder.
$file_name is a variable. You should concatenate it to your own string in order to execute the function:
delete_files("../../uploads/" . $file_name);
EDIT:
Make sure that this sentence:
echo base_url("uploads/" . $file_name);
Is echoing a valid path. If the answer is YES, try this:
$this->load->helper("url");
delete_files(base_url("uploads/" . $file_name));
Supposing that your "uploads" folder is in your root directory.
EDIT 2:
Using unlink function:
$this->load->helper("url");
unlink(base_url("uploads/" . $file_name));
Try this one.. this just a very simple solution to your problem..
If you notice CI has there on defining of base_path to your directory e.g. in the upload library's config:
$imagePath = './picture/Temporary Profile Picture/';
$config['upload_path'] = $imagePath;
$config['allowed_types'] = 'gif|jpg|jpeg|png';
$this->load->library('upload', $config);
if you notice the upload_path is './picture/Temporary Profile Picture/'
so if you want to delete a file from a directory all you have to do is use unlink() function.
unlink($imagePath . $file_name);
or
#unlink($imagePath . $file_name);
Enjoy..^^
This code was working for me. Try this in your Model or Controller. Change the file path according to yours.
file path -->> project_name/assets/uploads/file_name.jpg
public function delete_file()
{
$file = 'file_name.jpg';
$path = './assets/uploads/'.$file;
unlink($path);
}
You should try this code:
$imagepath = $config['upload_path'];
unlink($imagepath . $images);
or
delete_files($imagepath . $images);
public function deleteContent($id)
{
$this->db->where('Filename',$id);
$this->db->delete('tableName',array('Filename'=>$id));
if (unlink("upload/folderName/".$id))
{
redirect($_SERVER['HTTP_REFERER']);
}
}

Resources