Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A controller to store blobs (pictures, videos, docs) in the file system #930

Open
nik2208 opened this issue Oct 26, 2022 · 3 comments
Open
Assignees

Comments

@nik2208
Copy link
Contributor

nik2208 commented Oct 26, 2022

to store and delete files I wrote a simple php file that reads the folder where to store the file and the file/files, giving back the name of the saved files or an empty array if something failed. Same process to delete them.

save

<?php
	/*
	folder structure:
		root
		  |-api.php => backend file
		  |-images/ => all saved images
		  |-tools/  => images saving handlers (save, delete..)
	
	.htassess rewrites all requests not containing 'api.php', 'images' and 'tools' to api.php/$received_path
	for this reason it is needed to go 1 directory up to save the image in the correct directory
	*/
	function sendResponse($status = 200, $body = '', $content_type = 'application/json; charset=utf-8'){
                $status_header = 'HTTP/1.1 ' . $status ;
                header($status_header);
                header('Content-type: ' . $content_type);
                echo $body;
    }
    
    header("Content-Type: application/json");
    header("Access-Control-Allow-Origin: *");
    header("Access-Control-Allow-Methods: PUT, GET, POST, OPTIONS");
    header("Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept");
        
    //REMEMBER TO sudo chcon -t httpd_sys_rw_content_t **FOLDER** -R
    $postdata = file_get_contents('php://input');
    $request = json_decode($postdata,true);
    $folder = $request['path'];//example "images/mapIcons/" - relative path received
	$folder_relativePath = '../'.$folder; // - 1 level up to find 'image' directory
    
    $response = array();
    foreach ($request['files'] as  $file) {
        $img = explode(";base64,", $file);      
        $img_aux = explode("image/", $img[0]);
        $image_type = $img_aux[1];
        $img_base64 = base64_decode($img[1]);
        $uniqfn = uniqid().'.'.$image_type;
        $image_relativePath = $folder_relativePath . $uniqfn; // saving path
		$image = $folder . $uniqfn; //relative path given as response
        $r = file_put_contents($image_relativePath, $img_base64);
        if($r) {
            array_push($response,array('filePath'=>$image));
        }
    }
    sendResponse(200,json_encode($response));
?>

delete

<?php
	/*
	folder structure:
		root
		  |-api.php => backend file
		  |-images/ => all saved images
		  |-tools/  => images saving handlers (save, delete..)
	
	.htassess rewrites all requests not containing 'api.php', 'images' and 'tools' to api.php/$received_path
	for this reason it is needed to go 1 directory up to save the image in the correct directory
	*/

	function sendResponse($status = 200, $body = '', $content_type = 'application/json; charset=utf-8'){
		$status_header = 'HTTP/1.1 ' . $status ;
		header($status_header);
		header('Content-type: ' . $content_type);
		echo $body;
    }

    header("Content-Type: application/json");
    header("Access-Control-Allow-Origin: *");
    header("Access-Control-Allow-Methods: PUT, GET, POST, OPTIONS");
    header("Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept");
        
    $postdata = file_get_contents('php://input');
    $request = json_decode($postdata,true);
    

    //REMEMBER TO sudo chcon -t httpd_sys_rw_content_t **FOLDER** -R
    $response = array();
    foreach ($request['files'] as $file) {
        foreach (glob($file . '*') as $filename) {
            if(unlink(realpath('../'.$filename))){ //1 directory up @#@#@#@#@#@#@#@#@#@#@
                array_push($response,array($filename));
            };
        }
    }    
    sendResponse(200,json_encode($response)); //'{"file_path":"'.$image.'"}')
?>

this is the content of the .htaccess file or the apache config file

RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_URI} save [NC]
RewriteRule ^([^/]+)(.*)?$ tools/saveImages.php/$1$2   [L]
RewriteCond %{REQUEST_URI} delete [NC]
RewriteRule ^([^/]+)(.*)?$ delete/deleteImages.php/$1$2   [L]
RewriteCond %{REQUEST_URI} !api\.php [NC] //if none of the previous condition, if REQUEST_URI does't contain api.php redirect to api.php - this is meant to mask api.php from the endpoint string
RewriteRule ^([^/]+)(.*)?$ api.php/$1$2   [L]

sorry for my primitive php..

so before storing the record in the db I save the file, get the path, and send the post request to store the record.
Would be nice to dedicate an endpoint to it and have it annoverated in the openapi, won't it?

@mevdschee mevdschee changed the title a middleware to store blobs (pictures, videos, docs) in the file system A controller to store blobs (pictures, videos, docs) in the file system Oct 26, 2022
@mevdschee mevdschee self-assigned this Oct 26, 2022
@mevdschee
Copy link
Owner

mevdschee commented Oct 26, 2022

Did you see this?

https://github.com/mevdschee/php-crud-api/blob/main/examples/clients/upload/vanilla.html

It is my example showing how to upload a base64 encoded file to a database (LONGBLOB) field.

Anyway, I had the same idea 6 years ago, but never implemented it. I started a repo for it back then:

https://github.com/mevdschee/php-file-api

It contains no files yet :-) Maybe we can make it a Custom Controller in this project?

@nik2208
Copy link
Contributor Author

nik2208 commented Oct 26, 2022

yes sorry.. custom controller.. not middleware

@nik2208
Copy link
Contributor Author

nik2208 commented Oct 26, 2022

I've forked the project.
I need your advice on how to proceed.
I suppose we should add a file (like FileUploadController) in the controller folder, then.. dedicate an entire folder to its files like u did in geojson? or is it enough the controller itself?

This is how I imagine it to work.
the controller could have a default, configurable folder setting, and accept post request to the endpoints save and delete, containing the relative path for the files to be saved and the files blob array (for batch saving/deleting). Eventually it should answer with the array of actually saved/deleted relative paths (only the effectively saved/deleted files to give the possibility to check possible errors).
Another setting could be to create the folder in the case it doesn't exist (if set to true), or fail (if set to false) if the folder is missing.
Eventually (the last in my mind at this step) saving the files with random names (keeping their extension) or leave the name untouched with a config flag.

How did u imagine it?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants