I have the images uploading to google cloud, however I am not able to rename them to a random string before the image is uploaded.
I am wondering if anyone has a solution to this please.
Code:
<?php
# Includes the autoloader for libraries installed with composer
require '../vendor/autoload.php';
use Google\Cloud\Storage\StorageClient;
putenv('GOOGLE_APPLICATION_CREDENTIALS=/PATH TO JSON');
$client = new Google_Client();
$client->useApplicationDefaultCredentials();
$client->setSubject($user_to_impersonate);
$storage = new StorageClient([
'projectId' => 'XXXXXXXXXX'
]);
$bucket = $storage->bucket('abcd');
// Upload a file to the bucket.
$bucket->upload(
fopen('./test.jpg', 'r') // I WANT TO RENAME THIS FILE BEING UPLOADED AND YES i UNDERSTAND IT WILL BE A $_FILE TYPE WHEN I FINISH THE CODE.
);
// Download and store an object from the bucket locally.
$object = $bucket->object('test.jpg');
$object->downloadToFile('/cache/test2.jpg');
?>
Ok the answer is really easy, first you need to read the file that you want to upload. second you will want to generate your new filename, for this i used two user properties (these will most likely stay the same or change very rarely). I also used the timestamp of the request. My theory is no two people should have the same personal information (IP address & user agent) [I will add the users UID once i have finished the prototype.
If anyone else would like the code please see below, and please improve it & share the changes you would make (be great to see what we all come up with.
THIS IS FREE TO USE AND NO NEED TO GIVE CREDIT
$new_file_name = md5(time().md5($_SERVER['REMOTE_ADDR']).md5($_SERVER['HTTP_USER_AGENT']));
$path = "./test.jpg";
$ext = pathinfo($path, PATHINFO_EXTENSION);
$current = file_get_contents('./test.jpg');
$rand = $new_file_name.".".$ext;
echo $rand;
file_put_contents("./cache/".$rand, $current);
// Upload a file to the bucket.
$bucket->upload(
fopen('./cache/'.$rand, 'r')
);
The only problem with it is that you are left with the new files in cache folder but you can add a delete function after the file has been uploaded.
Full code on github
OFFICIAL GITHUB REPO
Related
I am trying to convert a local Excel.xlsx file with all existent design, format and formulas existent in my local Excel file. How can I do that using Google API with PHP?
What I was doing but not working was :
$client = new \Google_Client();
$client->setApplicationName('Name');
$client->setScopes([\Google_Service_Drive::DRIVE]);
$client->setAccessType('offline');
$client->setAuthConfig($_SERVER['DOCUMENT_ROOT'] . '/credentials.json');
$service = new Google_Service_Drive($client);
$fileID = '';
$path = $_SERVER['DOCUMENT_ROOT'] . '/includes/files/';
$fileName = 'MAIN.xlsx';//this is the file I want to convert to Google sheet
$filePathName = $path.$fileName;
$mimeType = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
$file->setMimeType($mimeType);
$createdFile = $service->files->copy($file, array(
'data' => $filePathName,
'mimeType' => $mimeType,
'convert' => true,
));
But that is not working. How should I correct?
I believe your goal as follows.
You want to upload a XLSX file from the local PC to Google Document.
When the XLSX file is uploaded, you want to convert it to Google Spreadsheet.
You want to achieve this using googleapis for PHP.
Modification points:
In your script, the method of "Files: copy" is used. This method copies the file on Google Drive. So I think that this cannot be used for achieving your goal. I think that this is the reason of your issue.
From your error message, I thought that you might be using Drive API v3. I guess that this might be also the reason of your issue.
From above points, when your script is modified, it becomes as follows.
Modified script:
$service = new Google_Service_Drive($client); // Please use your $client here.
$path = $_SERVER['DOCUMENT_ROOT'] . '/includes/files/';
$fileName = 'MAIN.xlsx';//this is the file I want to convert to Google sheet
$filePathName = $path.$fileName;
$file = new Google_Service_Drive_DriveFile();
$file->setName('MAIN.xlsx');
$file->setMimeType('application/vnd.google-apps.spreadsheet');
$data = file_get_contents($filePathName);
$createdFile = $service->files->create($file, array(
'data' => $data,
'uploadType' => 'multipart'
));
printf("%s\n", $createdFile->getId());
Note:
In this modified script, it supposes that you have already been able to get and out values for Google Drive using Drive API. Please be careful this.
In this method, the maximum file size is 5 MB. Please be careful this. When you want to upload the large file, please use the resumable upload. Ref
References:
Upload file data
Create files
I am using laravel-google-cloud-storage to store images and retrieve them one by one. Is it possible that I can get all the folders and images from the Google Cloud Storage? If possible, how do I get this done?
I was trying to use this flysystem-google-cloud-storage to retrieve it but they are similar to the first link I have provided.
What I want to achieve is I want to select an image using the Google Cloud Storage with all the folders and images in it and put it in my form instead of selecting an image from my local.
UPDATE:
This is what I have tried so far base from this documentation.
$storageClient = new StorageClient([
'projectId' => 'project-id',
'keyFilePath' => 'myKeyFile.json',
]);
$bucket = $storageClient->bucket('my-bucket');
$buckets = $storageClient->buckets();
Then tried adding foreach which returns empty and also I have 6 folders in my Bucket.
foreach ($buckets as $bucket) {
dd($bucket->name());
}
It's been a week since my post has not been answered. I'll just post and share to anyone of what I did since last week.
I am using Laravel 5.4 at the moment.
So I installed laravel-google-cloud-storage and flysystem-google-cloud-storage in my application.
I created a Different controller since I am retrieving the images from Google Cloud Storage via Ajax.
All you need to do is to get your Google Cloud Storage credentials which can be located in your Google Cloud Storage Dashboard > Look for the APIs then click the link below that stated "Go to APIs overview > Credentials. Just download the credentials which is in JSON file format and put it in your root or anywhere you wanted to (I still don't know where should I properly put this file). Then the next is we get your Google Cloud Storage Project ID which can be located in the Dashboard.
Then this is my setup in my controller that connects from my Laravel application to Google Cloud Storage which I am able to Upload, Retrieve, Delete, Copy files.
use Google\Cloud\Storage\StorageClient;
use League\Flysystem\Filesystem;
use League\Flysystem\Plugin\GetWithMetadata;
use Superbalist\Flysystem\GoogleStorage\GoogleStorageAdapter;
class GoogleStorageController extends Controller
{
// in my method
$storageClient = new StorageClient([
'projectId' => 'YOUR-PROJECT-ID',
'keyFilePath' => '/path/of/your/keyfile.json',
]);
// name of your bucket
$bucket = $storageClient->bucket('your-bucket-name');
$adapter = new GoogleStorageAdapter($storageClient, $bucket);
$filesystem = new Filesystem($adapter);
// this line here will retrieve all your folders and images
$contents = $filesystem->listContents();
// you can get the specific directory and the images inside
// by adding a parameter
$contents = $filesystem->listContents('directory-name');
return response()->json([
'contents' => $contents
]);
}
I started working on uploading a file to akamai netstorage using PHP and referred few API's in GitHub. I couldn't upload a video file. Though i can create and write contents in them.
<?php
require 'Akamai.php';
$service = new Akamai_Netstorage_Service('******.akamaihd.net');
$service->authorize('key','keyname','version');
$service->upload('/dir-name/test/test.txt','sample text');
?>
I referred this API. I also referred few others but couldn't get the right way to upload a video/image file. The code which i wrote above is working perfectly. Now i need to upload a video file instead of writing contents to a text file.
There is a more modern library for Akamai's NetStorage, which is built as a plugin for FlySystem, the akamai-open/netstorage.
Once you have it installed, you need to setup the authentication and the HTTP client (based on Guzzle):
$signer = new \Akamai\NetStorage\Authentication();
$signer->setKey($key, $keyName);
$handler = new \Akamai\NetStorage\Handler\Authentication();
$handler->setSigner($signer);
$stack = \GuzzleHttp\HandlerStack::create();
$stack->push($handler, 'netstorage-handler');
$client = new \Akamai\Open\EdgeGrid\Client([
'base_uri' => $host,
'handler' => $stack
]);
$adapter = new \Akamai\NetStorage\FileStoreAdapter($client, $cpCode);
And then you can create the filesystem object, and upload the file:
$fs = new \League\Flysystem\Filesystem($adapter);
// Upload a file:
// cpCode, action, content signature, and request signature is added transparently
// Additionally, all required sub-directories are created transparently
$fs->write('/path/to/write/file/to', $fileContents);
However, because you're uploading a video file I would suggest you use a stream rather than reading the contents in to memory. To do this, you use writeStream() instead:
$fs = new \League\Flysystem\Filesystem($adapter);
$stream = fopen('/path/to/local/file', 'r+');
$fs->writeStream('/path/to/write/file/to', $stream);
I have a form which lets the user upload the image file.
<div id="imageDiv">
Image Path : <input class="imageOption" type="file" id= "uploadImageFile" name="uploadImageFile" >
</div>
The problem comes when I try to fetch the path from temp folder. I won't be needing the image files after processing the request. When I try to fetch the path with something like this
$imagePath = $_FILES['uploadImageFile']['tmp_name'];
The path looks like C:\wamp\tmp\phpA123.tmp.
The API I'm using would require a path with extension of an uploaded image like this
C:\wamp\tmp\image.png
Couldn't figure out a way to do so unless I want to copy this image to some other upload folder and use it. I don't want these images logged in a server
Thanks
It would be helpful to know the specific API in use, but no well written file storage API should ever have to rely on the uploaded file name being used to store a file. You should be able to use the temp file contents in the API, and specify the file name separately.
In L5:
// Get the UploadedFile object
$file = Request::file('uploadImageFile');
// You can store this but should validate it to avoid conflicts
$original_name = $file->getClientOriginalName();
// This would be used for the payload
$file_path = $file->getPathName();
// Example S3 API upload
$s3client->putObject([
'Key' => $original_name, // This will overwrite any other files with same name
'SourceFile' => $file_path,
'Bucket' => 'bucket_name'
]);
If you want to get same output as -
$imagePath = $_FILES['uploadImageFile']['tmp_name'];
in Laravel, you can do something like this as described by #cdbconcepts -
$file = Request::file('uploadImageFile');
$imagePath = $file->getPathName()
I need to display videos / images file with ACL:PRIVATE uploaded to my Amazon S3 account on my wordpress blog.
I am a newbie to PHP oops based coding. Any script help, link references, free plugins or even Logical Algorithm will be great help :)
Thanks in advance.
This issue could be solved by implementing the following steps:
Download latest stable version of SDK from here
Extract the .zip file & place in wamp/www folder
Rename config-sample.inc.php file to config.inc.php
Add the access key & secret key (retrieved from Amazon S3 account) into above file, save & exit
create a sample file to display public / private objects from Amazon S3
The content of the file should look as follows:
require('sdk.class.php');
require('services/s3.class.php');
$s3 = new AmazonS3();
$bucket = "bucketname";
$temp_link = $s3->get_object_url($bucket, 'your/folder/path/img.jpg', '5 minute');
echo $temp_link;
In above code, the URL you receive as output is a signed URL for your private object, thus it is valid only for 5 minutes.
You may grant access for a future date and allow only authorized users to access your private content or media on Amazon S3.
This question is a little bit old, but I'm posting it anyway. I had a simliar issue today and found out there's a simple answer.
aws doc explains it clearly and has an example as well.
http://docs.aws.amazon.com/aws-sdk-php-2/guide/latest/service-s3.html#amazon-s3-stream-wrapper
Basically, you need to register AWS' stream wrapper and use s3:// protocol.
Here's my code sample.
use Aws\Common\Aws;
use Aws\S3\Enum\CannedAcl;
use Aws\S3\Exception\S3Exception;
$s3 = Aws::factory(array(
'key' => Config::get('aws.key'),
'secret' => Config::get('aws.secret'),
'region' => Config::get('aws.region')
))->get('s3');
$s3->registerStreamWrapper();
// now read file from s3
// from the doc.
// Open a stream in read-only mode
if ($stream = fopen('s3://bucket/key', 'r')) {
// While the stream is still open
while (!feof($stream)) {
// Read 1024 bytes from the stream
echo fread($stream, 1024);
}
// Be sure to close the stream resource when you're done with it
fclose($stream);
}