php-crud-api icon indicating copy to clipboard operation
php-crud-api copied to clipboard

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

Open nik2208 opened this issue 3 years ago • 3 comments

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?

nik2208 avatar Oct 26 '22 08:10 nik2208

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?

mevdschee avatar Oct 26 '22 12:10 mevdschee

yes sorry.. custom controller.. not middleware

nik2208 avatar Oct 26 '22 13:10 nik2208

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?

nik2208 avatar Oct 26 '22 17:10 nik2208